Wossname
10-26-2011, 07:48 PM
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.
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.
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.