Control a 4usec switch in 1-wire
MacTuxLin
Posts: 821
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.
I'm using the 1-wire object from OBEX
Thanks a lot!
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!
spin
38K
Comments
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.
I'm pretty sure johns code will show you this way. (can't check it on the smartphone to make sure)