Assembly language issue??
Jack Buffington
Posts: 115
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.