Shop OBEX P1 Docs P2 Docs Learn Events
Delay PASM — Parallax Forums

Delay PASM

MazziniMazzini Posts: 58
edited 2011-09-12 14:01 in Propeller 1
Hello ,


I'm still working on my Lcd driver...
I noticed that my timers are " messed up "
lcd_reset has need almost 2 second to reach ret (??)

for example
wait100us
                        rdlong  delay100us, #5
                        mov     t2, cnt    ' setup
                        add     t2, delay100us  ' first add
                        waitcnt t2,delay100us
wait100us_ret           ret
I know #5 is the 5th location as see
delay                   long    80_000_000 ' 1 second = 12.5ns*80KK      loc 0
delay20ms               long    1_600_000'............................... '  1
delay10ms               long    800_000'................................. '  2
delay6ms                long    480_000'................................. '  3
delay200us              long    16_000'.................................. '  4
delay100us              long    8_000'................................... '  5
delay1us                long    8'....................................... '  6   ' or byte
so 8000*12.5ns@80Mhz = 100us

http://pastebin.com/pQdy7mgN

any tips ?
Thanks :)

Comments

  • tonyp12tonyp12 Posts: 1,951
    edited 2011-08-29 16:06
    From the manual:
    There are two values stored in the initialization area that might be of interest to your program:
    a long at $0000 contains the initial master clock frequency, in Hertz
    (e.g how many cnt you should wait for, to wait 1second)

    I don't see any mention of a table in hub that you are referring to.
    So I think you gone have to make your own table. (btw it's 80 cnt cycles in a micro second)
    Your code already have a hardcoded one, so skip the rdlong #5 etc

    And you could change it to:
    waitcnt t2,#0

    As delay is added to t2 after the wait, so unless you know what value t2
    should have for next waitcnt, you just as might add 0 to it.


    But it's good idea to not have a hardcoded table, so read hub location 0
    Though dividing by 10 and 100 is not that easy in pasm, but by 4, 8 and 16 is
            org 0    'Reset assembly pointer
    Toggle  rdlong Delay, #0  'Get clock frequency
            shr Delay, #2   'Divide by 4
            mov Time, cnt   'Get current time
            add Time, Delay   'Adjust by 1/4 second
            waitcnt Time, Delay   'Wait for 1/4 second
    

    Personally I think you use CALL a little to much in your code.

    When something can be done in 3 lines of code I would not use a subroutine.

    mov cnt,delay100ms ' leftside cnt is a shadow and can be used as "regular memory".
    add cnt,cnt
    waitcnt cnt, #0
  • jazzedjazzed Posts: 11,803
    edited 2011-08-29 16:28
    Mazzini,

    "rdlong delay100us, #5" reads the contents of HUB address 4 (rdlong ignores lower 2 bits).

    Why don't you do this instead ?
    wait100us
                            mov     t2, delay100us
                            add     t2, cnt           ' better practice is to add here
                            waitcnt t2,delay100us
    wait100us_ret           ret
    
  • MazziniMazzini Posts: 58
    edited 2011-08-29 17:37
    because I learned it on manual afterward I had need to load a long value... but your solution is smarter
    When you say rdlong ignores lower 2 bits , you mean that they are step by 4 ( so it is 32) bit) ?
    I thought it was already "formatted" , I mean #0 ->0,1,2,3 #1->4,5,6,7 and so on...
    thanks again,
    start from scratch is not easy but I feel I am near to solution and I have some trouble to feedback my code. PASD doesnt keep the timing right (?) so I just add one led....
    I am sure the trouble is the timing and the Register Select......
    Thank to all
  • MazziniMazzini Posts: 58
    edited 2011-08-29 17:52
    tonyp12 wrote: »

    Personally I think you use CALL a little to much in your code.

    When something can be done in 3 lines of code I would not use a subroutine.

    mov cnt,delay100ms ' leftside cnt is a shadow and can be used as "regular memory".
    add cnt,cnt
    waitcnt cnt, #0

    may I wrong, but I use call to keep code readable ( by my opinion) as write DelayUs (100); or Lcd_dat(0x80); and so on
  • MazziniMazzini Posts: 58
    edited 2011-08-29 17:57
    oh ! it Works
    the code is useless but it works and I learned some stuff .D
    CON 
      _clkmode = xtal1 + pll16x 
      _xinfreq = 5_000_000 
     
    
    PUB Main 
      
      cognew(@entry, 0)    
      
       
    DAT 
                            org     0               
    entry                   mov dira,port
                            Call #wait
                            Call #lcd_reset
                            Call #lcd_init                                
    :Main                                                                    
                            or outa,rs                                       
                            mov cmd,#104              'H
                            Call #LcdDat
    
                            mov cmd,#101              'E
                            Call #LcdDat
    
                            mov cmd,#108              'L
                            Call #LcdDat
    
                            mov cmd,#108              'L
                            Call #LcdDat
    
                            mov cmd,#111              'O
                            Call #LcdDat                                     
                                 
     :Loop                               
                            jmp #:Loop                                          
                                                                             
    lcd_reset '4 Bit mode                                                    
                           andn outa,RS  
                           andn outa,CLR                                     
    
                           or outa,DB4              '0x3                     
                           or outa,DB5                                      
                           Call #TogglE                                      
                           Call #wait6ms                                     
                                                                             
                           or outa,DB4              '0x3                     
                           or outa,DB5                                       
                           Call #TogglE                                      
                           Call #wait200us                                   
                                                                             
                           or outa,DB4              '0x3                     
                           or outa,DB5                                       
                           Call #TogglE                                    ' 
                           Call #wait200us                                   
                                                                             
                           andn outa,DB4            '0x2                     
                           or outa,DB5                                       
                           Call #TogglE                                      
                           Call #wait6ms                                     
                                                       '
    Lcd_reset_ret          ret                              
    Lcd_init
                            andn outa,RS
                            mov cmd,#$28           '4 bit,2linee,5x7
                            Call #LcdDat
    
                            mov cmd,#$08           'Display OFF
                            Call #LcdDat
    
                            
                            mov cmd,#$0C           'Display ON, cursor & blink off
                            Call #LcdDat
    
    
                            mov cmd,#$06           'Entry mode
                            Call #LcdDat
    
                            mov cmd,#$01           'Clear Screen
                            Call #LcdDat                   
    
                            mov cmd,#$06           'Entry mode
                            Call #LcdDat
    
                            mov cmd,#$02           'Cursor Home
                            Call #LcdDat
    
                            mov cmd,#$80           'Cursor prima riga 
                            Call #LcdDat                                                                   
    Lcd_init_ret            ret
    
    LcdDat
    'MSB                     
    '-----                  
                            mov t2,cmd
                            or cmd,RS
                            shr t2,#4
                            shl t2,#10
                            andn outa,CLR
                            OR outa,t2
                            Call #TogglE  
    
    'LSB
    '-----
                            mov t2,cmd
                            or cmd,RS
                            and t2,#$0F
                            shl t2,#10
                            andn outa,CLR
                            OR outa,t2
                            Call #TogglE
                              
                            Call #wait200us
                            Call #wait200us 
    LcdDat_ret              ret
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    wait
                            mov     t2,delay
                            add     t2,cnt          
                            waitcnt t2,delay
    wait_ret                ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    wait20ms
                            mov     t2, delay20ms
                            add     t2, cnt          
                            waitcnt t2,delay20ms
    uswait20ms_ret          ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    
    wait6ms
                            mov     t2, delay6ms
                            add     t2, cnt          
                            waitcnt t2,delay6ms
    wait6ms_ret             ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    wait200us
                            mov     t2, delay200us
                            add     t2, cnt          
                            waitcnt t2,delay200us
    wait200us_ret           ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    wait1us
                            mov     t2, delay1us
                            add     t2, cnt          
                            waitcnt t2,delay1us
    wait1us_ret             ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    TogglE
                            or outa,En
                            Call #wait1us
                            andn outa,En
                            Call #wait1us     
    TogglE_ret              ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'delay @80MHz
    
    delay                   long    80_000_000 ' 1 second = 12.5ns*80KK      loc 0
    delay20ms               long    1_600_000'............................... '  1
    delay10ms               long    800_000'................................. '  2
    delay6ms                long    480_000'................................. '  3
    delay200us              long    16_000'.................................. '  4
    delay100us              long    8_000'................................... '  5
    delay1us                long    8'....................................... '  6   ' or byte
    
    RS                      long    |< 15
    RW                      long    |< 14
    EN                      long    |< 24
    
    DB4                     long    |< 10
    DB5                     long    |< 11
    DB6                     long    |< 12
    DB7                     long    |< 13
    Led23                   long    |< 23
    Led22                   long    |< 22
    Pin21                   long    |< 21
    Pin20                   long    |< 20
    
    
    
    'port                     long    RS | RW | EN | DB7 | DB6 | DB5 | DB4
    port                    long    $100BC00 
    poweron                 long    $FFFFFFFF                 
    DataMask                long    %1111000
    CLR                     long    %1111 << 10
    cmd                     long    0
    t1                      res     1
    t2                      res     1
    
    ' MSB       LSB
    '7 6 5 4  3 2 1 0        SET
    '-----------------------------------------------------------
    '0 0 1 1  0 0 0 0        8 bit mode
    '0 0 1 0  0 0 0 0        4 bit
    '0 0 1 0  1 0 0 0        4-bits, 2-lines, 5x7
    '0 0 0 0  1 0 0 0        display off, cursor off, blink off
    '0 0 0 0  1 1 0 0        display on
    '0 0 0 0  0 0 0 1        Clear display
    '0 0 0 0  0 1 1 0        increment, no display shift
     
    'P32........P24..........P14 P13 P12 P11 P10           P0
    '           En           RS  DB7 DB6 DB5 DB4
    '0  0000000 X 000000000  X   X   X   X   X  0000000000 0
    '                             
    
    '             P10     DB4
    '             P11     DB5
    '             P12     DB6
    '             P13     DB7
    '             P14     RW
    '             P15     RS
    

    Thsnks
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-08-29 17:59
    It's a little hard to follow your broken English (but I bet your Italian is superb) as to get the help you need.

    Your code does have some "wrong" way of doing things and repeated code like mov dira, port

    rdlong will only read from 4n values, reading from 5,6,7 is the same as reading from 4
  • jazzedjazzed Posts: 11,803
    edited 2011-08-29 18:12
    Mazzini wrote: »
    because I learned it on manual afterward I had need to load a long value... but your solution is smarter
    When you say rdlong ignores lower 2 bits , you mean that they are step by 4 ( so it is 32) bit) ?
    I thought it was already "formatted" , I mean #0 ->0,1,2,3 #1->4,5,6,7 and so on...
    thanks again,

    rdlong and friends read data from a given HUB memory location. The only "formatting" you get is the "data type" width. rdlong get 32 bits, rdword gets 16 bits, rdbyte gets 8 bits. There is nothing automatic about the addresses that rdlong uses other than it will read on a 32 bit boundary.

    rdlong value, #0 reads the content of HUB address 0 into value. this is usually the propeller startup clock frequency. If you want to read from HUB address 4, you would say rdlong value, #4, if you want to read from HUB address 12, you would say rdlong value, #12.

    rdword value, #14 reads the content of HUB address 14. Address 14 is word 1 of address 12.

    if you have this:
    address long 0
    rdlong value, address
    
    It will read the content of hub address 0 into value.

    If you want to read contiguous longs, do something like this:
    address long 0
    rdlong value, address
    add address, #4
    rdlong value, address
    add address, #4
    rdlong value, address
    

    If you want to read contiguous words, do something like this:
    address long 0
    rdword value, address
    add address, #2
    rdword value, address
    add address, #2
    rdword value, address
    

    But where does address come from? Usually it is passed to the COG using a mailbox via the PAR register - that is the best practice. If you need to read the first 512 bytes and know what your doing, you can use the # syntax as described before.
    Mazzini wrote: »
    start from scratch is not easy but I feel I am near to solution and I have some trouble to feedback my code. PASD doesnt keep the timing right (?) so I just add one led....
    I am sure the trouble is the timing and the Register Select......
    Thank to all

    You can set a breakpoint in PASD and run to the break. It will run real-time. If you're unlucky your break point will not get hit, and you'll have to reload the program.
  • MazziniMazzini Posts: 58
    edited 2011-08-29 18:13
    sry for my broken english. I go ( 3:15 am here :) )
  • jazzedjazzed Posts: 11,803
    edited 2011-08-29 18:14
    Mazzini wrote: »
    oh ! it Works
    Congratulations.
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-08-29 18:53
    Mazzini wrote: »
    oh ! it Works
    the code is useless but it works and I learned some stuff .D

    Thsnks


    I would not say that. The proper statement would be "The code is not needed now. But I made it work and learned from it." Now that is code with value.

    Frank
  • MazziniMazzini Posts: 58
    edited 2011-08-30 04:44
    tonyp12 wrote: »
    It's a little hard to follow your broken English (but I bet your Italian is superb) as to get the help you need.

    Your code does have some "wrong" way of doing things and repeated code like mov dira, port

    rdlong will only read from 4n values, reading from 5,6,7 is the same as reading from 4


    I agree , I have to improve the code
    jazzed wrote: »
    rdlong and friends read data from a given HUB memory location. The only "formatting" you get is the "data type" width. rdlong get 32 bits, rdword gets 16 bits, rdbyte gets 8 bits. There is nothing automatic about the addresses that rdlong uses other than it will read on a 32 bit boundary.

    rdlong value, #0 reads the content of HUB address 0 into value. this is usually the propeller startup clock frequency. If you want to read from HUB address 4, you would say rdlong value, #4, if you want to read from HUB address 12, you would say rdlong value, #12.

    rdword value, #14 reads the content of HUB address 14. Address 14 is word 1 of address 12.

    if you have this:
    address long 0
    rdlong value, address
    
    It will read the content of hub address 0 into value.

    If you want to read contiguous longs, do something like this:
    address long 0
    rdlong value, address
    add address, #4
    rdlong value, address
    add address, #4
    rdlong value, address
    
    If you want to read contiguous words, do something like this:
    address long 0
    rdword value, address
    add address, #2
    rdword value, address
    add address, #2
    rdword value, address
    
    But where does address come from? Usually it is passed to the COG using a mailbox via the PAR register - that is the best practice. If you need to read the first 512 bytes and know what your doing, you can use the # syntax as described before.



    You can set a breakpoint in PASD and run to the break. It will run real-time. If you're unlucky your break point will not get hit, and you'll have to reload the program.

    Thanks for detailed answer . I have to improve my code or/and add new functions
    I would not say that. The proper statement would be "The code is not needed now. But I made it work and learned from it." Now that is code with value.

    Frank

    I agree! You're right
  • MazziniMazzini Posts: 58
    edited 2011-09-01 13:14
    jazzed wrote: »
    rdlong and friends read data from a given HUB memory location. The only "formatting" you get is the "data type" width. rdlong get 32 bits, rdword gets 16 bits, rdbyte gets 8 bits. There is nothing automatic about the addresses that rdlong uses other than it will read on a 32 bit boundary.

    rdlong value, #0 reads the content of HUB address 0 into value. this is usually the propeller startup clock frequency. If you want to read from HUB address 4, you would say rdlong value, #4, if you want to read from HUB address 12, you would say rdlong value, #12.

    rdword value, #14 reads the content of HUB address 14. Address 14 is word 1 of address 12.

    if you have this:
    address long 0
    rdlong value, address
    
    It will read the content of hub address 0 into value.

    If you want to read contiguous longs, do something like this:
    address long 0
    rdlong value, address
    add address, #4
    rdlong value, address
    add address, #4
    rdlong value, address
    

    If you want to read contiguous words, do something like this:
    address long 0
    rdword value, address
    add address, #2
    rdword value, address
    add address, #2
    rdword value, address
    

    But where does address come from? Usually it is passed to the COG using a mailbox via the PAR register - that is the best practice. If you need to read the first 512 bytes and know what your doing, you can use the # syntax as described before.



    You can set a breakpoint in PASD and run to the break. It will run real-time. If you're unlucky your break point will not get hit, and you'll have to reload the program.

    It looks easy but
                            rdlong cmd,#4
                            Call #LcdDat
                            Call #wait
    
    where
    delay                   long    80_000_000 ' 1 second = 12.5ns*80KK      loc 0
    prova                   long    65 ' A ascii
    
    delay20ms               long    1_600_000'............................... '  1
    delay10ms               long    800_000'................................. '  2
    delay6ms                long    480_000'................................. '  3
    delay200us              long    16_000'.................................. '  4
    delay100us              long    8_000'................................... '  5
    delay1us                long    8'....................................... '  6   ' or byte
    
    It doesnt print char 'A' on LCD
  • jazzedjazzed Posts: 11,803
    edited 2011-09-01 15:25
    Mazzini wrote: »
    It looks easy but
                            rdlong cmd,#4
                            Call #LcdDat
                            Call #wait
    
    where
    delay                   long    80_000_000 ' 1 second = 12.5ns*80KK      loc 0
    prova                   long    65 ' A ascii
    
    delay20ms               long    1_600_000'............................... '  1
    delay10ms               long    800_000'................................. '  2
    delay6ms                long    480_000'................................. '  3
    delay200us              long    16_000'.................................. '  4
    delay100us              long    8_000'................................... '  5
    delay1us                long    8'....................................... '  6   ' or byte
    
    It doesnt print char 'A' on LCD

    Why would "rdlong cmd,#4" let you print 'A' on the LCD?
    "mov cmd, prova" might work.

    The longs in the dat section are not referenced by #4

    try this in start:
    cognew(@entry,@prova)

    then use "rdlong cmd,par"
    that should work if "mov cmd,prova" works.

    you could try "rdlong cmd,prova" directly but I'm not sure if that would work or not.
  • MazziniMazzini Posts: 58
    edited 2011-09-02 10:48
    Hello,

    I need to save one or more strings in order to show it on lcd

    example :
    message1 byte "message 1 test"
    message2 byte "message 2 test"


    The char 'A' is just an test
    Yesterday I read the manual but I forgot to add "msg" to COGNEW
    cognew(@entry, @msg)
                           
                            mov msg,par
                            rdbyte cmd,par
                                 
                            Call #LcdDat
                            Call #wait
    
    
    msg                    byte     "Hello"
    

    PAR is a pointer ?I dont know like scan the whole string :innocent:
  • jazzedjazzed Posts: 11,803
    edited 2011-09-02 13:03
    Mazzini wrote: »
    PAR is a pointer ?I dont know like scan the whole string :innocent:
    Yes, par is a pointer. Below it shows that it is the hub address of msg
    pub start
      cognew(@entry, @msg)
      repeat ' the spin stops here
    
    dat       ' separate dat section to show msg is independent
    
      msg                byte     "Hello",0
                           
    dat org 0
                         rdlong ndx,par   ' read the address of msg to ndx
    :loop
                         rdbyte cmd,ndx   ' read the character from ndx
                         tjz cmd, #done   ' if the character is 0, exit the loop
    
                         Call #LcdDat     ' character is not 0, print it
                         Call #wait
                         add ndx, #1      ' get the next character address
                         jmp #:loop       ' repeat the loop
    
    done                 jmp #done        ' nothing left to do, just jmp #done forever
    
    ndx     long 0       ' use ndx as an index into the msg array
    
  • MazziniMazzini Posts: 58
    edited 2011-09-02 14:14
    Sound a bit weird because with your code I get the same result , that is the lcd is blank
    CON 
      _clkmode = xtal1 + pll16x 
      _xinfreq = 5_000_000 
     
    
    PUB Main 
      
      cognew(@entry, @msg)    
      
      repeat ' the spin stops here
    
    dat       ' separate dat section to show msg is independent
    
      msg                byte     "Hello",0
    
    dat org 0
                                        
    entry                mov dira,port
                         Call #wait                'Wait for powerUp lcd
                         Call #lcd_reset           'Reset LCD software
                         Call #lcd_init            'Init
    
    
                          or outa,rs                '                       
                          mov cmd,#104              'Test Display
                          Call #LcdDat
                                             
    
                         rdlong ndx,par   ' read the address of msg to ndx
    :loop
                         rdbyte cmd,ndx   ' read the character from ndx
                         tjz cmd, #done   ' if the character is 0, exit the loop
    
                         Call #LcdDat     ' character is not 0, print it
                         Call #wait
                         add ndx, #1      ' get the next character address
                         jmp #:loop       ' repeat the loop
    
    done                 jmp #done        ' nothing left to do, just jmp #done forever
    
    
    
                                              
    {********************************************************************************}                                                                         
    lcd_reset 'reset for 4 Bit mode                                                    
    
                           mov cont,#3
                           mov cmd,#$03             '0x03 for 4bit mode, 0x30 for 8bit
    :Again                        
                           Call #LcdDat                                      
                           Call #wait6ms                                     
                           djnz cont,#:Again
    
                           mov cmd,#$02
                           Call #LcdDat                                      
                           Call #wait6ms
    Lcd_reset_ret          ret                              
    
    
    Lcd_init
                            andn outa,RS
                            mov cmd,#$28           '4 bit,2linee,5x7
                            Call #LcdDat
    
                            mov cmd,#$08           'Display OFF
                            Call #LcdDat
    
                            mov cmd,#$0C           'Display ON, cursor & blink off
                            Call #LcdDat
      
                            mov cmd,#$06           'Entry mode
                            Call #LcdDat
    
                            mov cmd,#$01           'Clear Screen
                            Call #LcdDat                   
    
                            mov cmd,#$06           'Entry mode
                            Call #LcdDat
    
                            mov cmd,#$02           'Cursor Home
                            Call #LcdDat
    
                            mov cmd,#$80           'Cursor prima riga 
                            Call #LcdDat                                                                   
    Lcd_init_ret            ret
    
    LcdDat                  'Send MSB aftwerward LSB
    'MSB                     
    '-----                  
                            mov t2,cmd
                            shr t2,#4
                            shl t2,#10
                            andn outa,CLR
                            OR outa,t2
                            Call #TogglE  
    
    'LSB
    '-----
                            mov t2,cmd
                            and t2,#$0F
                            shl t2,#10
                            andn outa,CLR
                            OR outa,t2
                            Call #TogglE
                              
                            Call #wait200us         'There is no Busy Flag , wait an while..
                            Call #wait200us 
    LcdDat_ret              ret
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    wait
                            mov     t2,delay
                            add     t2,cnt          
                            waitcnt t2,delay
    wait_ret                ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    wait20ms
                            mov     t2, delay20ms
                            add     t2, cnt          
                            waitcnt t2,delay20ms
    uswait20ms_ret          ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    
    wait6ms
                            mov     t2, delay6ms
                            add     t2, cnt          
                            waitcnt t2,delay6ms
    wait6ms_ret             ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    wait200us
                            mov     t2, delay200us
                            add     t2, cnt          
                            waitcnt t2,delay200us
    wait200us_ret           ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    wait1us
                            mov     t2, delay1us
                            add     t2, cnt          
                            waitcnt t2,delay1us
    wait1us_ret             ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
    TogglE
                            or outa,En
                            Call #wait1us
                            andn outa,En
                            Call #wait1us     
    TogglE_ret              ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'delay @80MHz
    
    
    delay                   long    80_000_000 ' 1 second = 12.5ns*80KK      loc 0
    prova                   long    65 
    delay20ms               long    1_600_000'............................... '  4
    delay10ms               long    800_000'................................. '  8
    delay6ms                long    480_000'................................. '  12
    delay200us              long    16_000'.................................. '  16
    delay100us              long    8_000'................................... '  20
    delay1us                long    8'....................................... '  24 
    
    RS                      long    |< 15
    RW                      long    |< 14
    EN                      long    |< 24
    
    DB4                     long    |< 10
    DB5                     long    |< 11
    DB6                     long    |< 12
    DB7                     long    |< 13
    Led23                   long    |< 23
    Led22                   long    |< 22
    Pin21                   long    |< 21
    Pin20                   long    |< 20
    
    port                    long    $100BC00 
    poweron                 long    $FFFFFFFF                 
    DataMask                long    %1111000
    CLR                     long    %1111 << 10
    cmd                     long    0
    cont                    long    0
    
    ndx                     long    0       ' use ndx as an index into the msg array
     
    t1                      res     1
    t2                      res     1
    
    

    I am debbuging it
  • jazzedjazzed Posts: 11,803
    edited 2011-09-02 15:56
    Please forgive my error.

    This should not be rdlong.
                         rdlong ndx,par   ' read the address of msg to ndx
    
    Use mov instead.
                         mov    ndx,par   ' read the address of msg to ndx
    
    Par is a pointer already and we want to dereference the pointer, not the contents.
  • kuronekokuroneko Posts: 3,623
    edited 2011-09-02 18:59
    As a general note, be careful with passing addresses of arbitrary DAT byte arrays. You'll silently lose the lower two bits.
  • jazzedjazzed Posts: 11,803
    edited 2011-09-02 20:12
    kuroneko wrote: »
    As a general note, be careful with passing addresses of arbitrary DAT byte arrays. You'll silently lose the lower two bits.

    I forgot :) just putting long in front of msg "should" ensure msg starts on a long boundary.
    dat       ' separate dat section to show msg is independent
      long
      msg                byte     "Hello",0
    
  • MazziniMazzini Posts: 58
    edited 2011-09-03 07:27
    jazzed wrote: »
    I forgot :) just putting long in front of msg "should" ensure msg starts on a long boundary.
    dat       ' separate dat section to show msg is independent
      long
      msg                byte     "Hello",0
    

    Hello,

    it works :). thank

    but manage DAT section is a bit "dungerous"


    for example I cant use _delayus here:
    Delayus                mov     t2,_delayus      ' because _delayus doesn't work( blank lcd) I have to use _delayms   
                           add     t2,cnt           'Set the counter = counter +delayus
    
            :_Delay
                           waitcnt t2,_delayus       'Waiting..
                           djnz _tmpDelay,#:_Delay  'every loop is about 1us ( our delay is 1us(micro)*_tmpDelay )
    Delayus_ret            ret               
    
    
    
    RS                      long    |< 15
    RW                      long    |< 14
    EN                      long    |< 24
    
    DB4                     long    |< 10
    DB5                     long    |< 11
    DB6                     long    |< 12
    DB7                     long    |< 13
    Led23                   long    |< 23
    Led22                   long    |< 22
    
    port                    long    $100BC00 
    
    CLR                     long    %1111 << 10
    cmd                     long    0
    ndx                     long    0       ' use ndx as an index into the msg array
    
    _tmp                    long    0
    _delayms                long    80_000
    _delayus                long    8
    _tmpDelay               long    0
    
     
    t1                      res     1
    t2                      res     1
    
    

    If I change my section DAT in
    _tmp                    long    0
    _delayms                long    80_000
    _tmpDelay               long    0
    
    _delayus                long    8
    

    The code works at 90% :
    it print "ello World" not "Hello world"
    CON 
      _clkmode = xtal1 + pll16x 
      _xinfreq = 5_000_000 
     
    
    PUB Main 
      
      cognew(@entry, @msg)
     repeat ' the spin stops here
    dat       ' separate dat section to show msg is independent
    long
    msg                     byte     "Hello "     'Test First message
    msg2                    byte     "World !",0   'Test second message
    
    dat org 0
    
                                                                           
    entry                mov dira,port             'Config Port I/O
                         mov _tmpDelay,#500
                         Call #Delayms             'Wait for powerUp lcd  about 0.5s
                         
                         Call #lcd_init          'Init Lcd
    
                         or outa,rs              '                       
                         mov ndx,par             ' read the address of msg to ndx
    :loop
                         rdbyte cmd,ndx          ' read the character from ndx
                         tjz cmd, #done          ' if the character is 0, exit the loop
    
                         Call #LcdDat            ' character is not 0, print it
                         mov _tmpDelay,#511
                         Call #Delayms            
    
                         add ndx, #1      ' get the next character address
                         jmp #:loop       ' repeat the loop
    
    done                 jmp #done        ' nothing left to do, just jmp #done forever
    
                                              
    {********************************************************************************}                                                                         
    Lcd_init
    'reset for 4 Bit mode                                                    
    
    
                           mov _tmp,#3              'Send 0x03 three times
    :Again                        
                           mov cmd,#$03             '0x03 for 4bit mode, 0x30 for 8bit 
                           Call #LcdDat             'Send data
    
                           mov _tmpDelay,#5         '5ms delay
                           Call #Delayms
                           djnz _tmp, #:Again        'need to Send 0x03 three times                
      
                           mov cmd,#$02             'last command
                           Call #LcdDat                                      
                           mov _tmpDelay,#5         '5ms delay
                           Call #Delayms
    'Initialization sequence
                            andn outa,RS
                            mov cmd,#$28           '4 bit,2linee,5x7
                            Call #LcdDat
    
                            mov cmd,#$08           'Display OFF
                            Call #LcdDat
    
                            mov cmd,#$0C           'Display ON, cursor & blink off
                            Call #LcdDat
      
                            mov cmd,#$06           'Entry mode
                            Call #LcdDat
    
                            mov cmd,#$01           'Clear Screen
                            Call #LcdDat                   
    
                            mov cmd,#$06           'Entry mode
                            Call #LcdDat
    
                            mov cmd,#$02           'Cursor Home
                            Call #LcdDat
    
                            mov cmd,#$80           'Cursor prima riga 
                            Call #LcdDat                                                                   
    Lcd_init_ret            ret
    
    LcdDat                  'Send MSB aftwerward the LSB
    'MSB                     
    '-----                  
                            mov t2,cmd
                            shr t2,#4
                            shl t2,#10
                            andn outa,CLR
                            OR outa,t2
                            Call #TogglE  
    
    'LSB
    '-----
                            mov t2,cmd
                            and t2,#$0F
                            shl t2,#10
                            andn outa,CLR
                            OR outa,t2
                            Call #TogglE
                            
                       '     mov _tmpDelay,#1
                       '     Call #Delayms         'There is no Busy Flag , wait an while..
    
                            mov _tmpDelay,#400
                            Call #Delayus         'DELAYUS doesn't work , display is blank
    LcdDat_ret              ret
    
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Delayus                mov     t2,_delayms        
                           add     t2,cnt           'Set the counter = counter +delayms
    
            :_Delay
                           waitcnt t2,_delayms       'Waiting..
                           djnz _tmpDelay,#:_Delay  'every loop is about 1us ( our delay is 1us(micro)*_tmpDelay )
    Delayus_ret            ret
    
    '*************************************************************************************
    
    Delayms                mov     t2,_delayms      ' becouse _delayus doesn't work I have to use _delayms   
                           add     t2,cnt           'Set the counter = counter +delayms
    
            :_Delay
                           waitcnt t2,_delayms       'Waiting..
                           djnz _tmpDelay,#:_Delay  'every loop is about 1ms ( our delay is 1ms(mili)*_tmpDelay )
    Delayms_ret            ret                       
    '***************************************************************************************
    TogglE
                            mov _tmpDelay,#1
                            or outa,En
                            Call #Delayus         
                            andn outa,En
    TogglE_ret              ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    RS                      long    |< 15
    RW                      long    |< 14
    EN                      long    |< 24
    
    DB4                     long    |< 10
    DB5                     long    |< 11
    DB6                     long    |< 12
    DB7                     long    |< 13
    Led23                   long    |< 23
    Led22                   long    |< 22
    
    port                    long    $100BC00 
    
    CLR                     long    %1111 << 10
    cmd                     long    0
    ndx                     long    0       ' use ndx as an index into the msg array
    
    _tmp                    long    0
    _delayms                long    80_000
    _delayus                long    8
    _tmpDelay               long    0
    
     
    t1                      res     1
    t2                      res     1
    

    delayms has no problem. It is not a problem timing related because 400us are enought
  • kuronekokuroneko Posts: 3,623
    edited 2011-09-03 07:47
    If _delayms is 80k, shouldn't _delayus be 80 (instead of 8)?
  • MazziniMazzini Posts: 58
    edited 2011-09-03 08:17
    Yes. Sry:blank: my fault
  • MazziniMazzini Posts: 58
    edited 2011-09-12 14:01
    Thank to all

    Some days ago I finished my lcd routine.It helped me to learn a bit of pasm ( delay,string,clr bit,uart,Dat section ecc....) :lol:
    Im going to make one for Graphic lcd:tongue:
    I know it isn't so good but any feedback greatly appreciated
    CON 
      _clkmode = xtal1 + pll16x 
      _xinfreq = 5_000_000 
     
    
    PUB Main 
      
    cognew(@entry, @@0)
    repeat ' the spin stops here
    dat       ' separate dat section to show msg is independent
    long
    Message_1         byte    "Hello ",0                                                                                                          
    Message_2         byte    "World!",0                                                                                                          
    Buffer            byte    "      ",0
    
     
    dat org 0
                                                                           
    entry                mov dira,port           'Config Port I/O
                         or  dira,Tx_Mask
                         or  outa,Tx_Mask
    
    'INIT THE LCD
                         mov _tmpDelay,#500
                         Call #Delayms           'Wait for powerUp lcd  about 0.5s
                         Call #lcd_init          'Init Lcd
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'DEMO
    'READ STRING MSG FROM MEMORY AND PRINT IT
    
                         mov  _ndx,#@Message_1
                         add  _ndx,par           'read the address of msg to ndx
                         Call #LcdChar
    
                         mov  _ndx,#@Message_2
                         add  _ndx,par           'read the address of msg to ndx
                         Call #LcdChar
    
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                         andn outa,rs            'Get ready for next string   
                         mov cmd,#$C0            'second line
                         call #LcdDat            'Send command
                         or outa,rs              'DATA enabled
    
      
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'DEMO 
    'TEST division & remainder and print on LCD
                         mov __x,#66       
                         mov __y,#10       
                         Call #Divide               'ret __x
                         mov _tmp,__x
                         andn _tmp,clrW             '_tmp = Integer value
                         shr __x,#15                '__x = remainder
                         mov _tmp2,__x
                         
                         mov number,_tmp            
                         Call #decToAscii    
                         
                         mov  _ndx,#@Buffer
                         add  _ndx,par           'read the address of msg to ndx
                         Call #Lcdchar
                                                    
                         mov number,_tmp2            
                         Call #decToAscii    
                         
                         mov cmd,#"."
                         Call #LcdDat   
                         mov  _ndx,#@Buffer
                         add  _ndx,par           'read the address of msg to ndx
                         Call #Lcdchar
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'DEMO
    'Write custom char at first location and print it on LCD 
                         Call #LcdCgram          'Just test Cgram routine
       
    :uart
                         mov  _ndx,#@Message_1
                         Call #Send_Message
                         mov  _ndx,#$0D
                         call #UART_Transmit   
      
    
    
                         JMP #:uart
    '&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&                     
    'DEMO UART
    Send_Message
                         add     _ndx,par            ' Add the relative address of the message to the address 
    :Get_Byte                                        ' of String_Lookup to find the absolute address
                         rdbyte  cmd,_ndx wz
                  if_z   jmp     Send_Message_ret
                         call    #UART_Transmit
                         add     _ndx,#1
                         jmp     #:Get_Byte
    Send_Message_ret  ret
    
    
    
    UART_Transmit
              or      cmd,#$100            ' Add a stop bit
              shl     cmd,#1               ' Add a start bit
              mov     Bit_Counter,#10
              mov     cnt,Baud
              add     cnt,#16
              add     cnt,cnt
    :Loop
              shr     cmd,#1          wc   ' Shift lsb out of Data into C
              muxc    outa,Tx_Mask               ' Set / clear the Tx_pin depending on C
              waitcnt cnt,Baud
              djnz    Bit_Counter,#:Loop         ' Loop until ten bits sent
    UART_Transmit_ret ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
    
    
    LcdChar
                         or outa,RS
            :loop        rdbyte cmd,_ndx   WZ    'read the character from ndx
            IF_Z         tjz cmd,:done           'if the character is 0, exit the loop 
                       
                         Call #LcdDat            'character is not 0, print it
                         mov _tmpDelay,#50
                         Call #Delayms
    
                         add _ndx, #1            'get the next character address
                         jmp #:loop              'repeat the loop
    
           :done
    LcdChar_ret          ret
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'copy to memory and reverse it
    decToAscii
                         mov _tmp,number         '
            :nDigit
    
                         mov __x,_tmp             'x = number
                         mov __y,#10              'y = 10
                         Call #Divide             'number = number / 10
                         add countTmp,#1          'Count digit 
                         andn __x,clrW            'Clear remainder ( High word)
                         mov _tmp,__x             'copy to var number the new value ( number /=10)
                         tjnz _tmp,#:nDigit
     
                         mov  _ndx,#@Buffer
                         add  _ndx,par           'read the address of msg to ndx
                         add _ndx,countTmp       'start from last location to avoid reverse routine ( max 3 digit ( 3 + NULL) that is an long ) 
                                    
                         mov char,#0
                         wrbyte char,_ndx         'Add NULL Character.After reversed it , NULL will be at last position 
                         sub _ndx,#1
            :loop                     
                         Call #Modulus            'digit = number % 10 
                         mov __x,number           'x = number
                         mov __y,#10              'y = 10
                         Call #Divide             'number = number / 10   
                         andn __x,clrW            'Clear remainder ( High word)
                         mov number,__x           'copy to var number the new value ( number /=10)
                         mov char,digit           'copy digit to char
                         add char,#48             'Add '0' to char. The ascii-characters for numbers start at 48 (for 0) up to 57(for 9)
                         wrbyte char,_ndx         'write to memory
                         sub _ndx,#1              'next location (from 4 to 1)
    
                         tjnz number,#:loop       'if number = 0 Exit
                         mov countTmp,#0
    decToAscii_ret       ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''                                                                         
    Lcd_init
    'reset for 4 Bit mode                                                    
                           mov _tmp,#3              'Send 0x03 three times
            :Again                        
                           mov cmd,#$03             '0x03 for 4bit mode, 0x30 for 8bit 
                           Call #LcdDat             'Send data
    
                           mov _tmpDelay,#5         '5ms delay
                           Call #Delayms
                           djnz _tmp, #:Again       'need to Send 0x03 three times                
      
                           mov cmd,#$02             'last command
                           Call #LcdDat                                      
                           mov _tmpDelay,#5         '5ms delay
                           Call #Delayms
    'Initialization sequence
                            andn outa,RS
                            mov cmd,#$28           '4 bit,2linee,5x7
                            Call #LcdDat
    
                            mov cmd,#$08           'Display OFF
                            Call #LcdDat
    
                            mov cmd,#$0C           'Display ON, cursor & blink off
                            Call #LcdDat
      
                            mov cmd,#$06           'Entry mode
                            Call #LcdDat
    
                            mov cmd,#$01           'Clear Screen
                            Call #LcdDat                   
    
                            mov cmd,#$06           'Entry mode
                            Call #LcdDat
    
                            mov cmd,#$02           'Cursor Home
                            Call #LcdDat
    
                            mov cmd,#$80           'Cursor prima riga 
                            Call #LcdDat                                                                   
    Lcd_init_ret            ret
     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    LcdDat                  'Send MSB aftwerward the LSB
    'MSB                     
    '-----                  
                            mov t2,cmd
                            shr t2,#4
                            shl t2,#10
                            andn outa,CLR
                            OR outa,t2
                            Call #TogglE  
    'LSB
    '-----
                            mov t2,cmd
                            and t2,#$0F
                            shl t2,#10
                            andn outa,CLR
                            OR outa,t2
                            Call #TogglE
                            mov _tmpDelay,#400
                            Call #Delayus         
    LcdDat_ret              ret
    
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    LcdCgram
    'TEST CGRAM
                         andn outa,RS
                         mov cmd,#64     'CGRAM Add first chr
                         Call #LcdDat
                         or outa,RS
                                                    'Draw the custom character
                         mov cmd,                   #%10001
                         Call #LcdDat
                         mov cmd,                   #%11111
                         Call #LcdDat
                         mov cmd,                   #%10001
                         Call #LcdDat
                         mov cmd,                   #%11111
                         Call #LcdDat                      
                         mov cmd,                   #%00100
                         Call #LcdDat
                         mov cmd,                   #%00000
                         Call #LcdDat
                         mov cmd,                   #%00100
                         Call #LcdDat
                         mov cmd,                   #%10001
                         Call #LcdDat
                                      '
                         andn outa,rs            'Get ready for next string   
                         mov cmd,#$C5            'second line
                         call #LcdDat            'Send command
                         or outa,rs
                         mov cmd,#0              'DDRAM Add first chr
                         Call #LcdDat
    LcdCgram_ret         ret                                             
    ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'DELAY US
    Delayus                mov     t2,_delayus      '   
                           add     t2,cnt           'Set the counter = counter +delayus
    
            :_Delay
                           waitcnt t2,_delayus       'Waiting..
                           djnz _tmpDelay,#:_Delay  'every loop is about 1us ( our delay is 1us(micro)*_tmpDelay )
    Delayus_ret            ret
    
    '*************************************************************************************
    'DELAY MS
    Delayms                mov     t2,_delayms         
                           add     t2,cnt           'Set the counter = counter +delayms
    
            :_Delay
                           waitcnt t2,_delayms       'Waiting..
                           djnz _tmpDelay,#:_Delay  'every loop is about 1ms ( our delay is 1ms(mili)*_tmpDelay )
    Delayms_ret            ret                       
    '***************************************************************************************
    TogglE
                            mov _tmpDelay,#1
                            or outa,En
                            Call #Delayus         
                            andn outa,En
    TogglE_ret              ret
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    
              
    Modulus '---------------------------------------------------------- digit = number // 10
    
    'digit = number - (10 * int(number/10))    'Wikipedia
                      mov __x,number           'x = number
                      mov __y,#10              'y = 10
                      Call #Divide             'number = number / 10
                      andn __x,clrW            'Clear remainder ( High word)
                      mov __x1,__x             'multiply __x * 10
                      mov __y1,#10
                      Call #multiply            'ret __y1                                       
                      sub number,__y1
                      mov digit,number          'return result in digit
    Modulus_ret       ret                                    
    
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Divide x[31..0] by y[15..0] (y[16] must be 0) 
    ' on exit, quotient is in x[15..0] and remainder is in x[31..16]     ' Parallax
    ' Propeller Manual  1.1
    divide          shl     __y,#15        'get divisor into y[30..15] 
                    mov     __t,#16        'ready for 16 quotient bits 
            :loop   cmpsub  __x,__y     wc 'y =< x? Subtract it, quotient bit in c 
                    rcl     __x,#1         'rotate c into quotient, shift dividend 
                    djnz    __t,#:loop     'loop until done 
    divide_ret      ret                    'quotient in x[15..0], 
                                           'remainder in x[31..16]
    
    '' Multiply x[15..0] by y[15..0] (y[31..16] must be 0) 
    ' on exit, product in y[31..0] 
    ' 
    multiply        shl     __x1,#16            'get multiplicand into x[31..16] 
                    mov     __t1,#16            'ready for 16 multiplier bits 
                    shr     __y1,#1      wc     'get initial multiplier bit into c 
    :loop  if_c     add     __y1,__x1    wc     'if c set, add multiplicand to product 
                    rcr     __y1,#1      wc     'put next multiplier in c, shift prod. 
                    djnz    __t1,#:loop         'loop until done 
    multiply_ret    ret                         'return with product in y[31..0]                                         
    
     
    RS                      long    |< 15
    pwm                     long    |< 14
    EN                      long    |< 24
    
    DB4                     long    |< 10
    DB5                     long    |< 11
    DB6                     long    |< 12
    DB7                     long    |< 13
    
    Led23                   long    |< 23
    Led22                   long    |< 22
    
    port                    long    $100BC00 
    CLR                     long    %1111 << 10
    clrW                    long    $FFFF << 15
    
    
    _delayms                long    80_000
    _delayus                long    80
    
    Tx_Mask                 long    1<<30
    Baud                    long    694                   ' 694 * 0.0125µs = 115,274 bps
    Temp                    res     1
    Bit_Counter             res     1
    _tmpDelay               res     1
    _ndx                    res     1       ' use ndx as an index into the msg array
    _tmp                    res     1
    _tmp2                   res     1
     
    t2                      res     1
    __x                     res     1
    __y                     res     1
    __t                     res     1
    __x1                    res     1
    __y1                    res     1
    __t1                    res     1
    
    digit                   res     1
    number                  res     1
    cmd                     res     1
    char                    res     1
    countTmp                res     1
                  fit 496 
    
    
Sign In or Register to comment.