Shop OBEX P1 Docs P2 Docs Learn Events
[PASM] waitcnt duration problem — Parallax Forums

[PASM] waitcnt duration problem

WossnameWossname Posts: 174
edited 2011-10-10 09:40 in Propeller 1
I have a puzzling problem with some Propeller Assembly code I'm writing to have my propeller chip talk to an LCD module.

Using my Saleae Logic analyser I can see that my pins are going high and low just as I want them to, but I can't get the timing right for some reason...

Here's the code:
{{
This program requires a DEM16217 SYH-LY LCD panel (16x2 characters)
}}

CON 
  _clkmode = RCFAST

VAR
  byte HUBRAM_DIPSWITCH_VALUE_ADDRESS                         'declare the byte of hub ram where we'll store the bits from the dipswitches

PUB Main 

  'coginit(0, @,             0)
  coginit(0, @LCDPanel_4Bit_Init, 0)      'do cog 0 last otherwise the other cogs won't get assigned 
  

DAT
 
              org       0

              
LCDPanel_4Bit_Init '-------------------------

              'propeller pins used to control the LCD panel need to be configured as outputs
              mov       dira, #%1_1_1111                'E pin, RS pin and the 4 data bits all as outputs
              andn      outa, #%1_1_1111                'clear out LCD panel pins
              or        outa, #%1_0_0000                'raise E pin ready for data transfer


              
              mov       time, cnt
              add       time, #9             
              waitcnt   time, POWER_ON_DELAY        '[COLOR="red"][B]<-------- PROBLEM HERE[/B][/COLOR]

              'FUNCTION SET...
              or        outa, #%0_0_0010                'set 4 bit comms mode
              andn      outa, #%1_0_0000                'clear E pin to clock in data
              or        outa, #%1_0_0000                'raise E pin again                        
              
              or        outa, #%0_0_0010                'hard coded as per datasheet
              andn      outa, #%1_0_0000                'clear E pin to clock in data
              or        outa, #%1_0_0000                'raise E pin again

              or        outa, #%0_0_1100                '2 line mode and 5x11 font
              andn      outa, #%1_0_0000                'clear E pin to clock in data
              or        outa, #%1_0_0000                'raise E pin again                                      
 
              waitcnt   time, FUNCTION_SET_DELAY
              








              
              

: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    500000
FUNCTION_SET_DELAY      long    600 
DISPLAY_CONTROL_DELAY   long    600
DISPLAY_CLEAR_DELAY     long    28_000
ENTRY_MODE_DELAY        long    28_000
LONG_WAIT               long    1000_000                                   

LCD_RS_Pin              long    |< 4
LCD_E_Pin               long    |< 5
                                                                                   
time          res       1
 
              fit
                                   




I want to make an 80 millisecond delay at the line indicated above. But no matter what value I set POWER_ON_DELAY to, the delay is always 1.3333 microseconds according to the Logic probe output.

I'm sure I'm missing out an obvious step somewhere, but I can't figure this out.

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2011-10-09 05:58
    PASM waitcnt works slightly different from SPIN. It waits for time to match cnt and then adds POWER_ON_DELAY for the next waitcnt invocation. Your setup is for 14 cycles (minimum). If you want the delay to happen right there replace the #9 with your initial delay, e.g.
    mov     time, cnt
    add     time, POWER_ON_DELAY
    waitcnt time, next_offset
    
    And you probably want to change your clock setup from RCFAST to crystal based.
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-10-09 10:58
    kuroneko wrote: »
    PASM waitcnt works slightly different from SPIN. It waits for time to match cnt and then adds POWER_ON_DELAY for the next waitcnt invocation. Your setup is for 14 cycles (minimum). If you want the delay to happen right there replace the #9 with your initial delay, e.g.
    mov     time, cnt
    add     time, POWER_ON_DELAY
    waitcnt time, next_offset
    
    And you probably want to change your clock setup from RCFAST to crystal based.

    Like me, tried the example right out of the prop manual looks like. Min delay assures that the wait will not be missed I guess and then it does a very short wait and adds the offset for the next time around. But that does not get any real treatment in the example. Personally, after I figured this one out from the instructions description, I just added my delay to the time value after getting the current count value. I don't at this point see a reason to use the offset added after the wait, so I simply used #0 for the offset. Perhaps if I put this instruction inside a loop after initializing the count before entry I would use the offset, but otherwise I don't see the value of adding an offset if you are going to get the cnt value, add a delay value to it, wait and add offset after wait, and do it all again (wiping out the post wait added offset).

    If I missed something important in my reasoning here, I am sure someone will point it out.

    Frank
  • kuronekokuroneko Posts: 3,623
    edited 2011-10-09 17:48
    @Frank, reason for adding something here is that the OP has another waitcnt after the function set block relying on time. OTOH, if there is no subsequent target then you're free to add #0 to make it clear/obvious. It doesn't really matter in the end as you spend the same amount of time (adding #0 or ina) :)
  • WossnameWossname Posts: 174
    edited 2011-10-09 23:49
    Ahh, thank you guys. This makes more sense now.

    Yes I did literally lift my waitcnt straight out of the manual (which I'm increasingly of the opinion is too brief in most of it's information). Weirdly enough it seems like I've only ever used it in loops before (I've written probably half a dozen small programs so far) and so never really understood how waitcnt was intended to be used.

    I'll try out your suggestions tonight.

    I appreciate your help and friendly explanation - this forum rocks :)
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-10-10 00:02
    @Kuroneko,
    By example I was referring to the prop manual example early in the PASM chapter. You have done the same thing it took me a couple hours to figure out from that example and the waitcnt description. While the truth tables are nice addition for some instructions, here a commented example would have made it clearer for me. As to the OP (assume you mean original post), I saw the waitcnt following the function structure, and had to think about the results of it being that way with no add before the second one, your note pointing it out got me to see what had been done. Neat trick for the tool bag! So he does not have to reacquire the cnt into time and do the add etc. just rely on the added offset at that point. With a delay of 600, should give him about 554 clocks of delay at that waitcnt and 600 at the end of the first loop to donothing and followed forever by waits of 1M counts If I understand the flow here.

    Thanks,
    Frank
  • Mark_TMark_T Posts: 1,981
    edited 2011-10-10 03:49
    There is nothing unclear about the waitcnt instruction documentation, to quote the manual:
    The WAITCNT instruction pauses the cog until the global System Counter equals the value in the Target register, then it adds Delta to Target and execution continues at the next instruction.
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-10-10 09:16
    Mark_T wrote: »
    There is nothing unclear about the waitcnt instruction documentation, to quote the manual:

    Whatever....
  • WossnameWossname Posts: 174
    edited 2011-10-10 09:40
    The more I think about this the less I like the notation. Since this is part of a communications protocol - it uses several different delays in sequence with code in between. Actually when you look at the waitcnt statements for the entire protocol sequence, the delays are always mentioned one code block ahead of where they actually get used - which is weird looking and non intuitive. Sure the answer is simply to pepper your code with comments but that gets annoying after you paste the same comment into the code for the 15th time.. Either that or rename all your DELAY constatnts by adding "PRE_" to the front of each one, but that's misleading and gross.

    Well whatever, I'm not really complaining too much, the platform still kicks Arduino's butt :D
Sign In or Register to comment.