Shop OBEX P1 Docs P2 Docs Learn Events
Control a 4usec switch in 1-wire — Parallax Forums

Control a 4usec switch in 1-wire

MacTuxLinMacTuxLin Posts: 821
edited 2012-01-11 17:35 in Propeller 1
Hi All,

I need help in understanding PASM. I knew I'll have to touch on this sooner or later (was hoping the latter but), anyway, I need to control a 1-wire device that has a very tight timing requirement. Example:

Logic 1 = Low in 4.34 usec, then a High in 4.34 usec, then a Low in 4.34 usec, then a High in 25.98 usec

I need to set low at 4.34 usec but it seems I can only set either 4 usec or 5 usec? The device spec Min (4.1 usec) & Max (4.5 usec). Do I add 2 or 3 dummy instructions to achieve the 0.34 usec or do something in the _delay routine?

I've made slight changes but I think I have erred in the _newwrite sub-routine.
[SIZE=3][FONT=courier new]
[SIZE=2]cmd_newwrite            rdlong  value, t2               ' get the data byte
                        add     t2, #4                  
                        rdlong  bitCnt, t2 wz           ' get bit count    
          if_z          mov     bitCnt, #1              ' must be 1 to 32
                        max     bitCnt, #32
                        call    #_newwrite              ' write bits and exit
                        jmp     #endCommand


[/SIZE][/FONT][/SIZE][SIZE=2][FONT=courier new]'------------------------------------------------------------------------------[/FONT]
[FONT=courier new]' input:  value         data bits[/FONT]
[FONT=courier new]'         bitCount      number of bits[/FONT]
[FONT=courier new]' output: none[/FONT]
[FONT=courier new]'------------------------------------------------------------------------------[/FONT]

[FONT=courier new]_writeByte              mov     bitCnt, #8              ' write an 8-bit byte[/FONT]
[FONT=courier new]
[/FONT]
[/SIZE][SIZE=2][FONT=courier new]_newwrite                  andn    outa, dataMask          ' set data low for 4 usec[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        or      dira, dataMask[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        mov     t1, #4[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        call    #_delay[/FONT][/SIZE]
[SIZE=2][FONT=courier new]
[/FONT][/SIZE]
[SIZE=2]
[/SIZE][SIZE=2][FONT=courier new]                        ror     value, #1 wc            ' check next bit[/FONT][/SIZE]
[SIZE=2][FONT=courier new]          if_c          andn    dira, dataMask          ' if 1, set data to high Z[/FONT][/SIZE]
[SIZE=2][FONT=courier new]
[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        mov     t1, #4                 ' hold for 4 usec[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        call    #_delay[/FONT][/SIZE]
[SIZE=2]
[/SIZE][SIZE=2][FONT=courier new]                        andn    outa, dataMask          ' set data low for 4 usec[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        or      dira, dataMask[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        mov     t1, #4[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        call    #_delay[/FONT][/SIZE]

[SIZE=2][FONT=courier new]                        andn    dira, dataMask          ' set data to high again 25 usec[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        mov     t1, #25[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        call    #_delay[/FONT][/SIZE]
[SIZE=2][FONT=courier new]
[/FONT][/SIZE]
[SIZE=2][FONT=courier new]                        djnz    bitCnt, #_newwrite         ' repeat for all bits[/FONT][/SIZE]


[SIZE=2][FONT=courier new]_writeByte_ret[/FONT]
[FONT=courier new]_write_ret              ret[/FONT]
[FONT=courier new]


'------------------------------------------------------------------------------[/FONT]
[FONT=courier new]' input:  t1            number of usec to delay (must be multiple of 4)[/FONT]
[FONT=courier new]' output: none[/FONT]
[FONT=courier new]'------------------------------------------------------------------------------[/FONT]
[FONT=courier new]
_delay                 shr     t1, #2 wz               ' divide delay count by 4[/FONT]
[FONT=courier new]          if_z          mov     t1, #1                  ' ensure at least one delay[/FONT]
[FONT=courier new]                        mov     t2, delay4usec          ' get initial delay[/FONT]
[FONT=courier new]                        add     t2, cnt[/FONT]
[FONT=courier new]                        sub     t2, #41                 ' adjust for call overhead[/FONT]
[FONT=courier new]
[/FONT]
[FONT=courier new]:wait                   waitcnt t2, delay4usec          ' wait for 4 usec[/FONT]
[FONT=courier new]                        djnz    t1, #:wait              ' loop while delay count > 0[/FONT]
[FONT=courier new]_delay_ret              ret[/FONT]

[/SIZE]

I'm using the 1-wire object from OBEX

Thanks a lot!

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2012-01-11 03:20
    Why do you have a loop in _delay? You only need a loop in case you want to wait longer than ~51seconds.

    You would simply create some delay-values for your different timings like

    delay4_34us long 347
    delay28_98us long 2078

    At the beginning of your signal-sequence you would store cnt into another variable and after you set the signal to a level simply call the waitcnt with the right time:

    mov waittime, cnt
    add waittime, delay4_34us

    andn outa, dataMask
    or dira, dataMask
    waitcnt waittime, delay4_34us ' this is the timing for the next wait
    ...


    ' this has to be at the very end of your PASM-dat section
    waittime res 1


    The call of a subroutine is not needed and the subroutine is wasting more memory than just having some constants for the timing.
  • MacTuxLinMacTuxLin Posts: 821
    edited 2012-01-11 05:25
    Thank you MagIO2. I've changed the code, could you please take a look again?
    _writeByte              mov     bitCnt, #8              ' write an 8-bit byte
    
    _newwrite               mov     waittime, cnt
                            add     waittime, delay4_34us
                            andn    outa, dataMask          ' set data low for 4.34 usec
                            or      dira, dataMask
                            waitcnt waittime, delay4_34us
    
    
                            ror     value, #1 wc            ' check next bit
              if_c          mov     waittime, cnt
                            add     waittime, delay4_34us
                            andn    dira, dataMask          ' if 1, set data to high for 4.34 usec
                            waitcnt waittime, delay4_34us
    
    
                            mov     waittime, cnt
                            add     waittime, delay
                            andn    outa, dataMask          ' set data low again for 4.34 usec
                            or      dira, dataMask
                            waitcnt waittime, delay4_34us
    
    
                            mov     waittime, cnt
                            add     waittime, delay
                            andn    dira, dataMask          ' set data high 25.98 usec
                            waitcnt waittime, delay28_98us
    
    
                            djnz    bitCnt, #_newwrite      ' repeat for all bits
    _writeByte_ret
    _write_ret              ret
    
    
    
    
    delay4_34us             long    347
    delay28_98us            long    2078
    
    
    
    
    bitCnt                  res     1                       ' bit counter
    dataMask                res     1                       ' data pin mask
    waittime                res     1
    
    
    
  • JonnyMacJonnyMac Posts: 9,198
    edited 2012-01-11 06:34
    Is the device a Dallas/Maxim 1-Wire device? If yes, it should conform to the 1-Wire specification which Cam's object, too. I've also written a PASM driver for 1-Wire which uses timing values I received directly from a Dallas/Maxim engineer. It's another approach that may help you with your project.
  • MacTuxLinMacTuxLin Posts: 821
    edited 2012-01-11 07:34
    Thank you Jon. Unfortunately, its not a Dallas/Maxim chip but I'll use your code as reference as well. I'm reading the datasheet & I guess its never a better time than now to seriously learn PASM.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-01-11 08:34
    That is not exactly what I meant. You should read the manual entry for waitcnt. Waitcnt already is doing the calculation of the next waittime. So, you don't have to read cnt again and add delay4_34 again. Just read cnt at the beginning and sum up on that initial waittime.

    I'm pretty sure johns code will show you this way. (can't check it on the smartphone to make sure)
  • MacTuxLinMacTuxLin Posts: 821
    edited 2012-01-11 17:35
    Thank you. (slap my head) I re-look my code again this morning & it looks bad. I'll continue with Jon's code. Thanks.
    _writeByte              mov     bitCnt, #8              ' write an 8-bit byte
    
    _newwrite               mov     waittime, cnt
                            andn    outa, dataMask          ' set data low for 4.34 usec
                            or      dira, dataMask
                            waitcnt waittime, delay_4_34us
    
    
                            ror     value, #1 wc            ' check next bit
              if_c          mov     waittime, cnt           ' if 1, set data to high for 4.34 usec
                            andn    dira, dataMask          
                            waitcnt waittime, delay_4_34us
    
    
                            mov     waittime, cnt
                            andn    outa, dataMask          ' set data low again for 4.34 usec
                            or      dira, dataMask
                            waitcnt waittime, delay_4_34us
    
    
                            mov     waittime, cnt
                            andn    dira, dataMask          ' set data high 25.98 usec
                            waitcnt waittime, delay_28_98us
    
    
                            djnz    bitCnt, #_newwrite      ' repeat for all bits
    _writeByte_ret
    _write_ret              ret
    
    
    
Sign In or Register to comment.