Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .include "tn85def.inc" ;usi2i: Tidy up of code. Get enough timing information to speed up.
- ;fixed some problems. The Rx was interfeering with the next tx so I've made the Tx pin (PB1)
- ; an input unless it's actually just about to transmit then it's an output
- ;Working -- test_usiTxT at 19200 (52 /8 19200) see ***
- again:
- ldi r16, low(RAMEND)
- out SPL, r16
- ldi r16,high(RAMEND)
- out SPH, r16
- ;rjmp split62
- ;ldi r17,17
- ;ldi r18,18
- ;ldi r16,$a6
- ;rcall split62
- ;nop
- ;rcall reverseBits
- ;ag1:
- ;rjmp ag1
- ldi r16,$ff
- out DDRB,r16
- out PORTB,r16
- ldi r19,(1<<USIWM0)|(0<<USICS0) ;need this otherwise msb not initially joined to D0
- out USICR,r19
- ;srjmp test_usiTx
- ;rjmp test_usiRx0
- ;rjmp timeAByte
- ;rjmp compare0
- ;rjmp chkBitTime
- rjmp test_usiTxT
- ;rjmp timeAByteT
- ldi r16,$a7 ;!!<--- this works. Comes out as $a6, after reversing and splitiing, on terminal at about 1Hz
- rcall reverseBits
- rcall split62
- rcall SPITransfer_Fast2
- mov r16,r17
- rcall SPITransfer_Fast2
- rjmp here
- ldi r16,$a5
- rcall SPITransfer_Fast2
- ldi r16,$bf
- rcall SPITransfer_Fast2
- ;rcall SPITransfer
- here:
- rcall oneSec
- rcall oneSec
- rcall oneSec
- rjmp again
- ;-----------------------------------
- SPITransfer_Fast2:
- out USIDR,r16
- ;fin2:
- ;rjmp fin2
- ;ldi r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
- ldi r19,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
- ldi r18,8
- upt2:
- ;out USICR,r16 ; MSB
- rcall oneBitTime
- ;rcall oneSec
- ;rjmp upt2
- out USICR,r19
- up3:
- ;rjmp up3
- dec r18
- brne upt2
- ret
- ;---------------------------------------
- halfBitTime: ;better name for this delay. Half of 1/600
- ;myDelay1200:
- ;ldi r21,13 ; 13 works for m328 at 16Mhz
- push r20
- push r21
- ldi r21,7 ;try 7 for tiny85 at 8Hmz
- ldi r20,130 ;r20,21 at 130,7 give 833uS. Good for 600baud at 8Mhz
- starthbt:
- inc r20
- nop
- brne starthbt
- dec r21
- brne starthbt
- pop r21
- pop r20
- ret
- ;--------------------------------------------------
- ;!! rplace this with faster one?
- oneBitTime:
- rcall halfBitTime
- rcall halfBitTime
- ret
- ;---------------------------------
- delay100ms: ;handy; delay for about 0.1 sec = 100 ms
- ;header endif_1,10,"delay100ms"
- ;delay100ms:
- ;.ifdef testing
- ; ldi r16,1
- ;.else
- push r16
- ldi r16,60
- .;endif
- upd100:
- rcall oneBitTime
- dec r16
- brne upd100
- pop r16
- ret ;after about a tenth of a second
- ;------------------------
- oneSec:
- ;jmp finsec ;take out when not simulating
- push r17
- ldi r17,5
- upones:
- rcall delay100ms
- dec r17
- brne upones
- pop r17
- finsec:
- ret
- ;-----------------------------------
- reverseBits: ;r16 gets reversed
- push r17
- push r18
- ldi r18,8
- ;ldi r16,$a6
- ldi r17,0
- uprb:
- lsl r16
- ror r17
- dec r18
- brne uprb
- uprb2:
- mov r16,r17
- pop r18
- pop r17
- ret
- ;-----------------------
- split62: ;split r16 into two bytes, r16 and r17 where r16 contains first 6 bits preceded by
- ; by 10, the last stop bit then start bit. Last two bits go into r17 followed by 6 1's. ie 6 stop bits.
- ;ldi r16,$f0. Wrecks r16,17
- ldi r17,$ff
- clc
- ror r16
- ror r17
- sec
- ror r16
- ror r17
- ret
- rjmp split62
- ;-----------------------------------
- ;!! replace for 600baud
- ;usiTx: ;this is going to be THE tx routine for usi tx. Assume byte to be transferred is in r16
- ldi r17,$fe ;make r1 an output as this stage. Can interfere with Rx
- out DDRB,r17
- rcall reverseBits ;needed
- rcall split62 ;now have (10 + 6lsbs) + (2 msbs + 6Stops) in r116,r17
- rcall SPITransfer_Fast2 ;there's the r16 gone
- mov r16,r17
- rcall SPITransfer_Fast2 ;and the r17.
- ret ;with r16 having been sent via USI Tx
- ;-------------------------------------------
- test_usiTx: ;works at 600baud
- ldi r16,$ab
- rcall usiTx
- ldi r16, $cd
- rcall usiTx
- rcall oneSec
- rjmp test_usiTx
- ;--------------------------------------------------------
- usiRx0: ;try this for usi rx
- ;make PB0 = D0 an input
- ldi r16,$fc
- out DDRB,r16
- ldi r16,$ff
- out PORTB,r16
- out USIDR,r16 ;fill up usidr with only stop bits. Gruadually push them out by inpit bits
- ;ldi r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
- ldi r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
- rcall waitForPin0High
- rcall waitForPin0Low
- rcall halfBitTime ;go to middle of start bit then..
- rcall oneBitTime ;go to middle of first real bit
- ldi r18,8
- ;out USICR,r16 ; MSB
- get1bit:
- out USICR,r17
- rcall oneBitTime
- dec r18
- brne get1bit
- rjmp fin
- out USICR,r16
- out USICR,r17
- out USICR,r16
- out USICR,r17
- out USICR,r16
- out USICR,r17
- out USICR,r16
- out USICR,r17
- out USICR,r16
- out USICR,r17
- out USICR,r16
- out USICR,r17
- out USICR,r16 ; LSB
- out USICR,r17
- fin:
- in r16,USIDR
- rcall reverseBits ;needed
- ret
- ;---------------------
- test_usiRx0:
- rcall usiRx0
- ; rcall oneSec
- ; ldi r17,$fe ;make r1 an output as this stage
- ; out DDRB,r17
- rcall usiTx ;print what we found coming in
- ; rcall oneSec
- rjmp test_usiRx0
- ;--------------------------------
- waitForPin0Low:
- ; ldi zl,0x36
- ; clr zh
- ; ld r16,z
- ;rcall d16
- ; rcall spacecode
- sbic PINB,0
- rjmp waitForPin0Low
- ret ;when pin PB1 goes low
- ;------------------------
- waitForPin0High:
- sbis PINB,0
- rjmp waitForPin0High
- ret ;when pin PB1 goes high
- ;---------------------------------
- setUp:
- CBI DDRB,0 ;clr PORTB1 FOR inPUT
- CBI DDRB,1 ;also make tx an input to avoid false tx's
- clr r17
- clr r18
- clr r19 ;counters
- ;clr r16
- out TCNT0,r17 ;always start with clean count
- ret
- ;----------------------------------------------
- startTim0:
- LDI r16,0b0000_0010 ; 3=/64 4 = /256 SET TIMER PRESCALER TO /1024, 03 is /64
- OUT TCCR0B,r16
- ret ;with timer now started
- ;-----------------------------------------------
- stopTim0:
- LDI r16,0b0000_0000 ;Stop TIMER
- OUT TCCR0B,r16
- ret ;with timer now stopped
- ;-------------------
- timeAByte: ;worked got $75 (occasionally 76 ) in TCNT0. About right for 9 bits at 600 baud.
- rcall setUp
- rcall waitForPin0High
- rcall waitForPin0Low
- rcall startTim0
- rcall waitForPin0High
- rcall stopTim0
- in r16,TCNT0
- rcall usiTx
- rjmp timeAByte
- ;----------------------------------
- compare0: ;trying to see what compares do with timer0
- rcall setUp2
- ldi r16,$50
- out USIDR,r16
- ;here0:
- ;rjmp here0
- rcall startTim0
- hereco:
- nop
- in r16,USISR
- andi r16,$0f
- cpi r16,$08
- brne hereco
- nop ;if here the usi 4-bit clk has clicked 8 times meaning all bits gone
- ; rcall stopTim0
- ldi r16,$ff
- out USIDR,r16
- hereco3:
- in r16,USISR
- andi r16,$0f
- cpi r16,$0f
- brne hereco3
- rcall stopTim0
- ;rcall clrUsiCnt
- rcall oneSec
- rjmp compare0
- rcall setUp2
- ldi r16,$ff
- out USIDR,r16
- rcall startTim0
- hereco2:
- nop
- in r16,USISR
- andi r16,$08
- cpi r16,$0f
- brne hereco2
- nop ;i
- rcall stopTim0
- rcall oneSec
- rjmp compare0
- ret
- ;-----------------
- setUp2:
- CBI DDRB,0 ;clr PORTB0 FOR inPUT
- sbi DDRB,1 ;
- ldi r16,$ff
- out PORTB,r16
- clr r17
- clr r18
- clr r19 ;counters
- ;clr r16
- out TCNT0,r17 ;always start with clean count
- ldi r16,$0c
- out OCR0A,r16 ;put value into compare reg
- ; sbi TCCR0A,WGM01
- ldi r16,$02 ;make compare reset TCNT0
- out TCCR0A,r16
- ldi r19,(1<<USIWM0)|(1<<USICS0) ;keep SPI mode but add Timer0 match overflow as clk source
- out USICR,r19
- rcall clrUsiCnt
- ret
- ;-------
- clrUsiCnt: ;set 4 bit counter, LSnibble of USISR, to 0000
- in r16,USISR
- andi r16, $f0
- out USISR,r16
- ret
- ;----------------------
- ;Note info . Get with below bunch of 0d and occasional 0e
- chkBitTime: ;use timer0 to see actually how long onebittime takes etc
- rcall setup
- rcall startTim0
- rcall oneBitTime1200
- rcall stopTim0
- in r16,TCNT0
- rcall usiTx
- rcall oneSec
- rjmp chkBitTime
- ;--------------------------------
- halfBitTime1200: ;this is half bit time for 1200 baud . Trying r20,21 = 193,4
- push r20
- push r21
- ;ldi r21,4 ;try 7 for tiny85 at 8Hmz
- ;ldi r20,193 ;r20,21 at 130,7 give 833uS. Good for 600baud at 8Mhz
- ldi r21,2
- ldi r20,96 ;r20,21 96,2 should give 2400
- start1200:
- inc r20
- nop
- brne start1200
- dec r21
- brne start1200
- pop r21
- pop r20
- ret
- ;-------------------
- ;--------------------------------------------------
- oneBitTime1200:
- rcall halfBitTime1200
- rcall halfBitTime1200
- ret
- ;---------------------------------
- SPITransfer_Fast1200:
- out USIDR,r16
- ;fin2:
- ;rjmp fin2
- ;ldi r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
- ldi r19,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
- ldi r18,8
- upt12:
- ;out USICR,r16 ; MSB
- rcall oneBitTime1200
- ;rcall oneSec
- ;rjmp upt2
- out USICR,r19
- ;up3:
- ;rjmp up3
- dec r18
- brne upt12
- ret
- ;---------------------------------------
- ;-----------------------------------
- usiTx: ;this is going to be THE tx routine for usi tx. Assume byte to be transferred is in r16
- ldi r17,$fe ;make r1 an output as this stage. Can interfere with Rx
- out DDRB,r17
- rcall reverseBits ;needed
- rcall split62 ;now have (10 + 6lsbs) + (2 msbs + 6Stops) in r116,r17
- rcall SPITransfer_Fast1200 ;there's the r16 gone
- mov r16,r17
- rcall SPITransfer_Fast1200 ;and the r17.
- ret ;with r16 having been sent via USI Tx
- ;-------------------------------------------
- USITransfer_Fast3: ;USES TIMER0:
- out USIDR,r16
- ldi r19,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
- ldi r18,8
- ;rcall startTim0
- LDI r16,0b0000_0010 ; 2=/8 3=/64 4 = /256 5= /1024 SET TIMER PRESCALER TO /1024,
- OUT TCCR0B,r16 ;start tim0
- upt23:
- ;rcall oneBitTime
- rcall clrTCNT0
- rcall waitTilTim0Fin
- out USICR,r19
- dec r18
- brne upt23
- ret
- ;---------------------------------------
- clrTCNT0:
- clr r16
- out TCNT0,r16
- ret
- ;---------------------***--
- waitTilTim0Fin: ;wait til timer 0 counts up to top value
- in r16,TCNT0
- cpi r16,52 ;have we counted up to 13, 1 bit time for 600 , /1024 baud?
- ; 52 with /256 gives 600baund, 26 with /256 should give 1200. Yes, worked. Now
- ;try 13 with same setting to give 2400? Yes, worked. Now change divisor to /64.
- ;With /64 should get 2400 with count to 52. Yes, worked. Now trying same but with 26
- ; to give 4800 baud? Yes, worked at 4800. First time at this speed for bitbang USI.
- ; Now change val from 26 to 13 to give 9600? Yes! Great speed and looks solid. Will keep going.
- ;Now need to change divisor down from 64 to 8.8*13 = 104. Use this with /8. Got 9600 again
- ; this way. Now halve the 104 ( to 52) to double the speed to 19200? Yes!!. The usi is being used to
- ; transfer bytes at 19200. OK, keep going. Now try 26 as TOP with /8 to give 38400?? OK, go first errors.
- ;at 38400. It interpreted 1234 as 1274 so an extra bit got inserted.
- brne waitTilTim0Fin
- ret
- ;-----------------------
- usiTxT: ;uses timer0
- ldi r17,$fe ;make r1 an output as this stage. Can interfere with Rx
- out DDRB,r17
- rcall reverseBits ;needed
- rcall split62 ;now have (10 + 6lsbs) + (2 msbs + 6Stops) in r116,r17
- rcall USITransfer_Fast3 ;there's the r16 gone
- mov r16,r17
- rcall USITransfer_Fast3 ;and the r17.
- LDI r16,0b0000_0000 ;stop timer,
- OUT TCCR0B,r16
- ret ;with r16 having been sent via USI Tx
- ;--------------------------------------
- test_usiTxT: ;worked first time at 600 baud
- ldi r16,$56
- rcall usiTxT
- rcall oneSec
- ldi r16, $78
- rcall usiTxT
- rcall oneSec
- rjmp test_usiTxT
- ;--------------------------------------------------------
- timeAByteT: ;worked got $75 (occasionally 76 ) in TCNT0. About right for 9 bits at 600 baud.
- rcall setUp
- rcall waitForPin0High
- rcall waitForPin0Low
- LDI r16,0b0000_0010 ; 2=/8 3=/64 4 = /256 5= /1024 SET TIMER PRESCALER TO /1024,
- OUT TCCR0B,r16 ;start tim0
- rcall waitForPin0High
- ;rcall stopTim0
- LDI r16,0b0000_0000 ;stop timer,
- OUT TCCR0B,r16
- in r16,TCNT0
- rcall usiTxT
- rcall oneSec
- rjmp timeAByteT ;got 52 for one bit at /8 and 19200. Seems to be limit.Got 26 for 1 bit
- ; at /8 38400. Why can't I tx at this speed?
- ;----------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement