[PASM] Subroutine causing coginit() to fail
Wossname
Posts: 174
I seem to have a problem where the placement of a subroutine seems to prevent execution of the function nominated by the call to coginit. I've used my logic analyser to verify this behaviour.
I want Cog zero to run beginning at the line marked "AAAA". Now this works fine ONLY if I move the subroutine called "LCD_WriteNibbles" so that it is not above the line marked AAAA.
This program is clearly a work in progress but I can't figure out why the position of the subroutine would make any difference if I'm specifying the label of the line that I want cog zero to begin at. All I want to do right how is have cog zero blink a led by calling the code starting at AAAA, but that doesn't happen apparently, the chip just sits there seemingly doing nothing I expect it to. If I move that "LCD_WriteNibbles" subroutine down to just before the final declarations then hey presto the code flashes the LED as expected and I can trigger my logic analyser like I wanted to 2 hours ago.
I'm stumped.
I want Cog zero to run beginning at the line marked "AAAA". Now this works fine ONLY if I move the subroutine called "LCD_WriteNibbles" so that it is not above the line marked AAAA.
CON _clkmode = RCFAST VAR PUB Main coginit(0, @AAAA, 0) DAT org 0 '################################################################# LCD_WriteNibbles :lcdwritenibbles_loop mov lcd_temp, lcd_data shl lcd_data, #4 'shift the low nibble into position ready for the next iteration and lcd_temp, #$f0 'mask off all unwanted bits shl lcd_temp, #8 'shift the nibble into the positions corresponding to the IO pins andn outa, LCD_DATA_MASK 'clear data lines to LCD or outa, lcd_temp 'put the nibble on the data lines andn outa, LCD_E_PIN 'clock the nibble into the LCD by clearing the E pin or outa, LCD_E_PIN 'raise E again to reset clock djnz lcd_nibblecount, #:lcdwritenibbles_loop LCD_WriteNibbles_ret ret '################################################################# '----------------------------z- SET IO PIN ASSIGNMENTS AAAA mov dira, #0 'default all IO pins to inputs or dira, LCD_DATA_MASK 'set LCD control pins to outputs or dira, LCD_E_PIN ' " or dira, LCD_RS_PIN ' " or dira, #1 '----------------------------- mov outa, #0 'zero all IO pins or outa, LCD_E_PIN 'raise E pin ready for data transfer andn outa, LCD_DATA 'clear LCD data pins andn outa, LCD_RS_PIN 'clear RS pin mov time, cnt add time, POWER_ON_DELAY waitcnt time, #0 mov time, cnt add time, LED_DELAY :loop waitcnt time, LED_DELAY xor outa, #1 jmp #:loop LCD_FUNCTION_SET '-------------------------- '0010 == set 4 bit comms mode '0010 == hard coded as per datasheet mov lcd_data, #%0010_0010 mov lcd_nibblecount, #2 call #LCD_WriteNibbles '2 line mode and 5x11 font mov lcd_data, #%1100_0000 mov lcd_nibblecount, #1 call #LCD_WriteNibbles mov time, cnt add time, FUNCTION_SET_DELAY waitcnt time, #0 LCD_DISPLAY_CONTROL '-------------------------- '0000 == hard coded as per datasheet '1111 == display on, cursor on, blink on mov lcd_data, #%0000_1111 mov lcd_nibblecount, #2 call #LCD_WriteNibbles mov time, cnt add time, DISPLAY_CONTROL_DELAY waitcnt time, #0 LCD_DISPLAY_CLEAR '-------------------------- '0000 == hard coded as per datasheet '0001 == hard coded as per datasheet mov lcd_data, #%0000_0001 mov lcd_nibblecount, #2 call #LCD_WriteNibbles mov time, cnt add time, DISPLAY_CLEAR_DELAY waitcnt time, #0 LCD_ENTRY_MODE '-------------------------- '0000 == hard coded as per datasheet '0110 == increment cursor, entire shift off mov lcd_data, #%0000_0110 mov lcd_nibblecount, #2 call #LCD_WriteNibbles mov time, cnt add time, ENTRY_MODE_DELAY waitcnt time, #0 LCD_WRITE_CHARACTERs '------This is a nasty hardcoded sequence to write "ADAM" to the LCD panel-------- mov lcd_data, #%0100_0001 mov lcd_nibblecount, #2 call #LCD_WriteNibbles mov time, cnt add time, CHAR_DELAY waitcnt time, #0 mov lcd_data, #%0100_0100 mov lcd_nibblecount, #2 call #LCD_WriteNibbles mov time, cnt add time, CHAR_DELAY waitcnt time, #0 mov lcd_data, #%0100_0001 mov lcd_nibblecount, #2 call #LCD_WriteNibbles mov time, cnt add time, CHAR_DELAY waitcnt time, #0 mov lcd_data, #%0100_1011 mov lcd_nibblecount, #2 call #LCD_WriteNibbles mov time, cnt add time, CHAR_DELAY waitcnt time, #0 :donothing waitcnt time, LONG_WAIT jmp #:donothing 'for delay timings please see the datasheet for the DEM16217 LCD panel ("4 bit interface mode" initialisation info) POWER_ON_DELAY long 1_200_000 FUNCTION_SET_DELAY long 600 DISPLAY_CONTROL_DELAY long 600 DISPLAY_CLEAR_DELAY long 50_000 ENTRY_MODE_DELAY long 50_000 'arbitrary - ANW CHAR_DELAY long 1000 LONG_WAIT long 1_000_000 LCD_DATA_MASK long %1111_0000_0000_0000 LCD_E_PIN long %0000_1000_0000_0000 LCD_RS_PIN long %0000_0100_0000_0000 LED_DELAY long 10_000 time res 1 lcd_data res 1 lcd_nibblecount res 1 lcd_temp res 1 fit
This program is clearly a work in progress but I can't figure out why the position of the subroutine would make any difference if I'm specifying the label of the line that I want cog zero to begin at. All I want to do right how is have cog zero blink a led by calling the code starting at AAAA, but that doesn't happen apparently, the chip just sits there seemingly doing nothing I expect it to. If I move that "LCD_WriteNibbles" subroutine down to just before the final declarations then hey presto the code flashes the LED as expected and I can trigger my logic analyser like I wanted to 2 hours ago.
I'm stumped.
Comments
Further, it starts the code expecting it to be compiled to offset zero in the COG. I.e. the initial program counter is zero. If you have any instructions or data before that start location in DAT the code will be compiled as if it is executed at some other address in COG. Unless you have an ORG 0 just prior to the start label.
Anyway problem solved, cheers for that.
:thumb:
Yes ORG does have "advanced" uses. Such as creating "overlays". Chunks of code that are not loaded at start of COG but perhaps your COG program loads them into some free space and runs them when required. Thus allowing one to have PASM code bigger than the 496 LONGs that fits in a COG. Have a look for Cluso's overlay loader to see how that works.