Shop OBEX P1 Docs P2 Docs Learn Events
[PASM] Subroutine causing coginit() to fail — Parallax Forums

[PASM] Subroutine causing coginit() to fail

WossnameWossname Posts: 174
edited 2011-10-27 02:01 in Propeller 1
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.

Comments

  • Heater.Heater. Posts: 21,230
    edited 2011-10-26 13:24
    When the PASM code is started by cogint it loads the 496 longs of code from the given address and starts it. Anything before that in the DAT section will not be loaded.
    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.
  • WossnameWossname Posts: 174
    edited 2011-10-26 23:50
    Thank you for the explanation, now I understand. It seems a bit redundant to have to include both ORG and a start label for the cog's entry point though. Perhaps it is implemented that way to enable more advanced tricks that I haven't learned yet :)

    Anyway problem solved, cheers for that.
    :thumb:
  • Heater.Heater. Posts: 21,230
    edited 2011-10-27 02:01
    Actually for normal PASM coding I don't think you need the ORG 0 as that will be the default anyway. Just put your start label at the beginning, don't have any data or instructions before that.

    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.
Sign In or Register to comment.