Assembly language issue??
I'm working with the C compiler to make a device that can read VITC timecode, drive a display, receive and send serial data, and read three quadrature encoders. The propeller is making that pretty easy for the most part. I'm hitting one snag though and I think it isn't anything to do with the C compiler so I am posting it over here.
I'm writing some code to read my encoders and am having an issue. For some reason, I have to add a small amount of delay in or the whole cog hangs.
Here is my C code (simplified to the minimum amount to still have the issue still happen:
Here is the assembly listing that I get from that:
If I modify things so that I do a bit more calculation, I need to add more delay. Here I copy my port into a temp variable that I then multiply by 3 before writing to my HUB variable. In this case, I have to wait 112 clock ticks for the program to work.
The problem doesn't have anything to do with my code (on another COG) that displays my values. That is still working because I am seeing some simulated timecode ticking away, which is generated by a third COG. There shouldn't be any issue with two COGs working with my 'iris' value because it is just one long and it isn't possible for two cogs to access it simultaneously. Does anyone have any idea what is going on here?
I'm writing some code to read my encoders and am having an issue. For some reason, I have to add a small amount of delay in or the whole cog hangs.
Here is my C code (simplified to the minimum amount to still have the issue still happen:
#include <propeller.h>
static _COGMEM unsigned int nextcnt;
static _COGMEM unsigned int waitdelay;
extern unsigned int iris;
_NATIVE
void main ()
{
waitdelay = 48; // 48 works, 47 doesn't
nextcnt = _CNT + waitdelay;
while(1)
{
iris = INA & 0b11;
nextcnt = waitcnt2(nextcnt, waitdelay);
}
}
Here is the assembly listing that I get from that:
1 .text
2 .Ltext0
3 .balign 4
4 .global _main
5 .global _main_ret
6 _main
7 .LFB0
8 .file 1 "encoder.cogc"
1:encoder.cogc **** #include <propeller.h>
2:encoder.cogc ****
3:encoder.cogc **** static _COGMEM unsigned int nextcnt;
4:encoder.cogc **** static _COGMEM unsigned int waitdelay;
5:encoder.cogc ****
6:encoder.cogc **** extern unsigned int iris;
7:encoder.cogc ****
8:encoder.cogc **** _NATIVE
9:encoder.cogc **** void main ()
10:encoder.cogc **** {
9 .loc 1 10 0
11:encoder.cogc **** waitdelay = 48; // 48 works, 47 doesn't
12:encoder.cogc **** nextcnt = _CNT + waitdelay;
10 .loc 1 12 0
11 0000 0000BCA0 mov r7, CNT
11:encoder.cogc **** waitdelay = 48; // 48 works, 47 doesn't
12 .loc 1 11 0
13 0004 3000FCA0 mov _waitdelay, #48
14 .loc 1 12 0
15 0008 3000FC80 add r7, #48
16 .L3
17 000c 0000BCA0 mov _nextcnt, r7
13:encoder.cogc ****
14:encoder.cogc **** while(1)
15:encoder.cogc **** {
16:encoder.cogc **** iris = INA & 0b11;
18 .loc 1 16 0
19 0010 0000BCA0 mov r7, INA
20 0014 0300FC60 and r7, #3
21 0018 00003C08 wrlong r7, .LC0
17:encoder.cogc **** nextcnt = waitcnt2(nextcnt, waitdelay);
22 .loc 1 17 0
23 001c 0000BCA0 mov r7, _nextcnt
24 0020 0000BCF8 waitcnt r7,_waitdelay
25 0024 00007C5C jmp #.L3
26 .LFE0
27 .balign 4
28 .LC0
29 0028 00000000 long _iris
30 _waitdelay
31 002c 00000000 long 0
32 _nextcnt
33 0030 00000000 long 0
61 .Letext0
62 .file 2 "c:\\propgcc\\bin\\../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/include/cog.h"
If I modify things so that I do a bit more calculation, I need to add more delay. Here I copy my port into a temp variable that I then multiply by 3 before writing to my HUB variable. In this case, I have to wait 112 clock ticks for the program to work.
1 .text 2 .Ltext0
3 .balign 4
4 .global _main
5 .global _main_ret
6 _main
7 .LFB0
8 .file 1 "encoder.cogc"
1:encoder.cogc **** #include <propeller.h>
2:encoder.cogc ****
3:encoder.cogc **** static _COGMEM unsigned int nextcnt;
4:encoder.cogc **** static _COGMEM unsigned int waitdelay;
5:encoder.cogc **** static _COGMEM unsigned int temp;
6:encoder.cogc ****
7:encoder.cogc ****
8:encoder.cogc **** extern unsigned int iris;
9:encoder.cogc ****
10:encoder.cogc **** _NATIVE
11:encoder.cogc **** void main ()
12:encoder.cogc **** {
9 .loc 1 12 0
13:encoder.cogc **** waitdelay = 112;
14:encoder.cogc **** nextcnt = _CNT + waitdelay;
10 .loc 1 14 0
11 0000 0000BCA0 mov r7, CNT
13:encoder.cogc **** waitdelay = 112;
12 .loc 1 13 0
13 0004 7000FCA0 mov _waitdelay, #112
14 .loc 1 14 0
15 0008 7000FC80 add r7, #112
16 .L3
15:encoder.cogc ****
16:encoder.cogc **** while(1)
17:encoder.cogc **** {
18:encoder.cogc **** temp = INA & 0b11;
17 .loc 1 18 0
18 000c 0000BCA0 mov r0, INA
14:encoder.cogc **** nextcnt = _CNT + waitdelay;
19 .loc 1 14 0
20 0010 0000BCA0 mov _nextcnt, r7
19:encoder.cogc **** temp *= 3;
21 .loc 1 19 0
22 0014 0300FCA0 mov r1, #3
18:encoder.cogc **** temp = INA & 0b11;
23 .loc 1 18 0
24 0018 0300FC60 and r0, #3
25 .loc 1 19 0
26 001c 0000FC5C call #__MULSI
20:encoder.cogc **** iris = temp;
21:encoder.cogc **** nextcnt = waitcnt2(nextcnt, waitdelay);
27 .loc 1 21 0
28 0020 0000BCA0 mov r7, _nextcnt
19:encoder.cogc **** temp *= 3;
29 .loc 1 19 0
30 0024 0000BCA0 mov _temp, r0
20:encoder.cogc **** iris = temp;
31 .loc 1 20 0
32 0028 00003C08 wrlong r0, .LC0
33 .loc 1 21 0
34 002c 0000BCF8 waitcnt r7,_waitdelay
35 0030 00007C5C jmp #.L3
36 .LFE0
37 .balign 4
38 .LC0
39 0034 00000000 long _iris
40 _waitdelay
41 0038 00000000 long 0
42 _nextcnt
43 003c 00000000 long 0
44 _temp
45 0040 00000000 long 0
73 .Letext0
74 .file 2 "c:\\propgcc\\bin\\../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/include/cog.h"
The problem doesn't have anything to do with my code (on another COG) that displays my values. That is still working because I am seeing some simulated timecode ticking away, which is generated by a third COG. There shouldn't be any issue with two COGs working with my 'iris' value because it is just one long and it isn't possible for two cogs to access it simultaneously. Does anyone have any idea what is going on here?

Comments
If you want the loop to execute as fast as possible, then you might as well remove the waitcnt. If you loop has to be deterministic, then you'll need to figure out at what frequency you want it to run at, and set nextcnt appropriately. At 112 clock ticks per loop, that's 714kHz. As you have it (with the minimum non-locking value in nextcnt) your waitcnt doesn't actually add much delay, if any.
Thanks!
When I originally read your reply, I thought "but I did declare it as volatile", since I thought that it only mattered in my main C file that launches the other cogs. Now that I have declared it in both files it is working.