prjbrook

usi2k.asm Got usi rx,tx going at 9600.

Oct 25th, 2014
372
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.80 KB | None | 0 0
  1. .include "tn85def.inc" ;usi2k: Got tx via usi going up to 19200. Now try rx.
  2. ;OK, usiRxT: is working well at 600 baud 13 /1024 600. Going to try faster speeds.
  3. again:
  4. ldi r16, low(RAMEND)
  5. out SPL, r16
  6. ldi r16,high(RAMEND)
  7. out SPH, r16
  8. ;rjmp split62
  9. ;ldi r17,17
  10. ;ldi r18,18
  11. ;ldi r16,$a6
  12. ;rcall split62
  13. ;nop
  14. ;rcall reverseBits
  15. ;ag1:
  16. ;rjmp ag1
  17. top:
  18. ldi r16,$ff
  19. out DDRB,r16
  20. out PORTB,r16
  21. ldi r19,(1<<USIWM0)|(0<<USICS0) ;need this otherwise msb not initially joined to D0
  22. out USICR,r19
  23. ;srjmp test_usiTx
  24. ;rjmp test_usiRx0
  25. ;rjmp timeAByte
  26. ;rjmp compare0
  27. ;rjmp chkBitTime
  28. ;rjmp test_usiTxT
  29. ;rjmp timeAByteT
  30. rjmp test_usiRxT
  31. ;rjmp testPB3
  32.  
  33. ldi r16,$a7 ;!!<--- this works. Comes out as $a6, after reversing and splitiing, on terminal at about 1Hz
  34. rcall reverseBits
  35. rcall split62
  36. rcall SPITransfer_Fast2
  37. mov r16,r17
  38. rcall SPITransfer_Fast2
  39. rjmp here
  40.  
  41.  
  42.  
  43. ldi r16,$a5
  44. rcall SPITransfer_Fast2
  45. ldi r16,$bf
  46. rcall SPITransfer_Fast2
  47.  
  48. ;rcall SPITransfer
  49. here:
  50. rcall oneSec
  51. rcall oneSec
  52. rcall oneSec
  53. rjmp again
  54.  
  55.  
  56.  
  57. ;-----------------------------------
  58. SPITransfer_Fast2:
  59. out USIDR,r16
  60. ;fin2:
  61. ;rjmp fin2
  62. ;ldi r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
  63. ldi r19,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
  64. ldi r18,8
  65. upt2:
  66. ;out USICR,r16 ; MSB
  67. rcall oneBitTime
  68. ;rcall oneSec
  69. ;rjmp upt2
  70. out USICR,r19
  71. up3:
  72. ;rjmp up3
  73. dec r18
  74. brne upt2
  75.  
  76. ret
  77. ;---------------------------------------
  78.  
  79. halfBitTime: ;better name for this delay. Half of 1/600
  80. ;myDelay1200:
  81. ;ldi r21,13 ; 13 works for m328 at 16Mhz
  82. push r20
  83. push r21
  84. ldi r21,7 ;try 7 for tiny85 at 8Hmz
  85. ldi r20,130 ;r20,21 at 130,7 give 833uS. Good for 600baud at 8Mhz
  86. starthbt:
  87. inc r20
  88. nop
  89. brne starthbt
  90. dec r21
  91. brne starthbt
  92. pop r21
  93. pop r20
  94. ret
  95. ;--------------------------------------------------
  96. ;!! rplace this with faster one?
  97. oneBitTime:
  98. rcall halfBitTime
  99. rcall halfBitTime
  100. ret
  101. ;---------------------------------
  102. delay100ms: ;handy; delay for about 0.1 sec = 100 ms
  103. ;header endif_1,10,"delay100ms"
  104. ;delay100ms:
  105. ;.ifdef testing
  106. ; ldi r16,1
  107. ;.else
  108. push r16
  109. ldi r16,60
  110. .;endif
  111. upd100:
  112. rcall oneBitTime
  113. dec r16
  114. brne upd100
  115. pop r16
  116. ret ;after about a tenth of a second
  117. ;------------------------
  118. oneSec:
  119. ;jmp finsec ;take out when not simulating
  120. push r17
  121. ldi r17,5
  122. upones:
  123. rcall delay100ms
  124. dec r17
  125. brne upones
  126. pop r17
  127. finsec:
  128. ret
  129. ;-----------------------------------
  130. reverseBits: ;r16 gets reversed
  131. push r17
  132. push r18
  133. ldi r18,8
  134. ;ldi r16,$a6
  135. ldi r17,0
  136. uprb:
  137.  
  138. lsl r16
  139. ror r17
  140. dec r18
  141. brne uprb
  142. uprb2:
  143. mov r16,r17
  144. pop r18
  145. pop r17
  146. ret
  147. ;-----------------------
  148. split62: ;split r16 into two bytes, r16 and r17 where r16 contains first 6 bits preceded by
  149. ; by 10, the last stop bit then start bit. Last two bits go into r17 followed by 6 1's. ie 6 stop bits.
  150. ;ldi r16,$f0. Wrecks r16,17
  151. ldi r17,$ff
  152. clc
  153. ror r16
  154. ror r17
  155. sec
  156. ror r16
  157. ror r17
  158. ret
  159. rjmp split62
  160. ;-----------------------------------
  161. ;!! replace for 600baud
  162. ;usiTx: ;this is going to be THE tx routine for usi tx. Assume byte to be transferred is in r16
  163. ldi r17,$fe ;make r1 an output as this stage. Can interfere with Rx
  164. out DDRB,r17
  165.  
  166. rcall reverseBits ;needed
  167. rcall split62 ;now have (10 + 6lsbs) + (2 msbs + 6Stops) in r116,r17
  168. rcall SPITransfer_Fast2 ;there's the r16 gone
  169. mov r16,r17
  170. rcall SPITransfer_Fast2 ;and the r17.
  171. ret ;with r16 having been sent via USI Tx
  172. ;-------------------------------------------
  173. test_usiTx: ;works at 600baud
  174. ldi r16,$ab
  175. rcall usiTx
  176. ldi r16, $cd
  177. rcall usiTx
  178. rcall oneSec
  179. rjmp test_usiTx
  180. ;--------------------------------------------------------
  181.  
  182.  
  183. usiRx0: ;try this for usi rx
  184. ;make PB0 = D0 an input
  185. ldi r16,$fc
  186. out DDRB,r16
  187. ldi r16,$ff
  188. out PORTB,r16
  189. out USIDR,r16 ;fill up usidr with only stop bits. Gruadually push them out by inpit bits
  190. ;ldi r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
  191.  
  192. ldi r17,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
  193.  
  194. rcall waitForPin0High
  195. rcall waitForPin0Low
  196. rcall halfBitTime ;go to middle of start bit then..
  197. rcall oneBitTime ;go to middle of first real bit
  198. ldi r18,8
  199. ;out USICR,r16 ; MSB
  200. get1bit:
  201. out USICR,r17
  202. rcall oneBitTime
  203. dec r18
  204. brne get1bit
  205. rjmp fin
  206.  
  207. out USICR,r16
  208. out USICR,r17
  209. out USICR,r16
  210. out USICR,r17
  211. out USICR,r16
  212. out USICR,r17
  213. out USICR,r16
  214. out USICR,r17
  215. out USICR,r16
  216. out USICR,r17
  217. out USICR,r16
  218. out USICR,r17
  219. out USICR,r16 ; LSB
  220. out USICR,r17
  221. fin:
  222. in r16,USIDR
  223. rcall reverseBits ;needed
  224.  
  225. ret
  226. ;---------------------
  227. test_usiRx0:
  228. rcall usiRx0
  229. ; rcall oneSec
  230. ; ldi r17,$fe ;make r1 an output as this stage
  231. ; out DDRB,r17
  232. rcall usiTx ;print what we found coming in
  233. ; rcall oneSec
  234. rjmp test_usiRx0
  235. ;--------------------------------
  236. waitForPin0Low:
  237. ; ldi zl,0x36
  238. ; clr zh
  239. ; ld r16,z
  240. ;rcall d16
  241. ; rcall spacecode
  242. sbic PINB,0
  243. rjmp waitForPin0Low
  244. ret ;when pin PB1 goes low
  245. ;------------------------
  246.  
  247. waitForPin0High:
  248. sbis PINB,0
  249. rjmp waitForPin0High
  250. ret ;when pin PB1 goes high
  251. ;---------------------------------
  252. setUp:
  253. CBI DDRB,0 ;clr PORTB1 FOR inPUT
  254. CBI DDRB,1 ;also make tx an input to avoid false tx's
  255. clr r17
  256. clr r18
  257. clr r19 ;counters
  258. ;clr r16
  259. out TCNT0,r17 ;always start with clean count
  260. ret
  261. ;----------------------------------------------
  262. startTim0:
  263. LDI r16,0b0000_0010 ; 3=/64 4 = /256 SET TIMER PRESCALER TO /1024, 03 is /64
  264. OUT TCCR0B,r16
  265. ret ;with timer now started
  266. ;-----------------------------------------------
  267. stopTim0:
  268. LDI r16,0b0000_0000 ;Stop TIMER
  269. OUT TCCR0B,r16
  270. ret ;with timer now stopped
  271. ;-------------------
  272. timeAByte: ;worked got $75 (occasionally 76 ) in TCNT0. About right for 9 bits at 600 baud.
  273. rcall setUp
  274. rcall waitForPin0High
  275. rcall waitForPin0Low
  276. rcall startTim0
  277. rcall waitForPin0High
  278. rcall stopTim0
  279. in r16,TCNT0
  280. rcall usiTx
  281. rjmp timeAByte
  282. ;----------------------------------
  283. compare0: ;trying to see what compares do with timer0
  284. rcall setUp2
  285. ldi r16,$50
  286. out USIDR,r16
  287. ;here0:
  288. ;rjmp here0
  289. rcall startTim0
  290.  
  291. hereco:
  292. nop
  293. in r16,USISR
  294. andi r16,$0f
  295. cpi r16,$08
  296. brne hereco
  297. nop ;if here the usi 4-bit clk has clicked 8 times meaning all bits gone
  298. ; rcall stopTim0
  299. ldi r16,$ff
  300. out USIDR,r16
  301. hereco3:
  302. in r16,USISR
  303. andi r16,$0f
  304. cpi r16,$0f
  305. brne hereco3
  306. rcall stopTim0
  307.  
  308.  
  309.  
  310.  
  311. ;rcall clrUsiCnt
  312. rcall oneSec
  313. rjmp compare0
  314.  
  315. rcall setUp2
  316. ldi r16,$ff
  317. out USIDR,r16
  318. rcall startTim0
  319.  
  320.  
  321. hereco2:
  322. nop
  323. in r16,USISR
  324. andi r16,$08
  325. cpi r16,$0f
  326. brne hereco2
  327. nop ;i
  328. rcall stopTim0
  329.  
  330. rcall oneSec
  331. rjmp compare0
  332. ret
  333. ;-----------------
  334. setUp2:
  335. CBI DDRB,0 ;clr PORTB0 FOR inPUT
  336. sbi DDRB,1 ;
  337. ldi r16,$ff
  338. out PORTB,r16
  339. clr r17
  340. clr r18
  341. clr r19 ;counters
  342. ;clr r16
  343.  
  344. out TCNT0,r17 ;always start with clean count
  345. ldi r16,$0c
  346. out OCR0A,r16 ;put value into compare reg
  347. ; sbi TCCR0A,WGM01
  348. ldi r16,$02 ;make compare reset TCNT0
  349. out TCCR0A,r16
  350. ldi r19,(1<<USIWM0)|(1<<USICS0) ;keep SPI mode but add Timer0 match overflow as clk source
  351. out USICR,r19
  352. rcall clrUsiCnt
  353. ret
  354. ;-------
  355. clrUsiCnt: ;set 4 bit counter, LSnibble of USISR, to 0000
  356. in r16,USISR
  357. andi r16, $f0
  358. out USISR,r16
  359. ret
  360. ;----------------------
  361. ;Note info . Get with below bunch of 0d and occasional 0e
  362. chkBitTime: ;use timer0 to see actually how long onebittime takes etc
  363. rcall setup
  364. rcall startTim0
  365. rcall oneBitTime1200
  366. rcall stopTim0
  367. in r16,TCNT0
  368. rcall usiTx
  369. rcall oneSec
  370. rjmp chkBitTime
  371. ;--------------------------------
  372. halfBitTime1200: ;this is half bit time for 1200 baud . Trying r20,21 = 193,4
  373. push r20
  374. push r21
  375. ;ldi r21,4 ;try 7 for tiny85 at 8Hmz
  376. ;ldi r20,193 ;r20,21 at 130,7 give 833uS. Good for 600baud at 8Mhz
  377. ldi r21,2
  378. ldi r20,96 ;r20,21 96,2 should give 2400
  379. start1200:
  380. inc r20
  381. nop
  382. brne start1200
  383. dec r21
  384. brne start1200
  385. pop r21
  386. pop r20
  387. ret
  388. ;-------------------
  389. ;--------------------------------------------------
  390. oneBitTime1200:
  391. rcall halfBitTime1200
  392. rcall halfBitTime1200
  393. ret
  394. ;---------------------------------
  395.  
  396. SPITransfer_Fast1200:
  397. out USIDR,r16
  398. ;fin2:
  399. ;rjmp fin2
  400. ;ldi r16,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)
  401. ldi r19,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
  402. ldi r18,8
  403. upt12:
  404. ;out USICR,r16 ; MSB
  405. rcall oneBitTime1200
  406. ;rcall oneSec
  407. ;rjmp upt2
  408. out USICR,r19
  409. ;up3:
  410. ;rjmp up3
  411. dec r18
  412. brne upt12
  413.  
  414. ret
  415. ;---------------------------------------
  416.  
  417.  
  418.  
  419. ;-----------------------------------
  420. usiTx: ;this is going to be THE tx routine for usi tx. Assume byte to be transferred is in r16
  421. ldi r17,$fe ;make r1 an output as this stage. Can interfere with Rx
  422. out DDRB,r17
  423.  
  424. rcall reverseBits ;needed
  425. rcall split62 ;now have (10 + 6lsbs) + (2 msbs + 6Stops) in r116,r17
  426. rcall SPITransfer_Fast1200 ;there's the r16 gone
  427. mov r16,r17
  428. rcall SPITransfer_Fast1200 ;and the r17.
  429. ret ;with r16 having been sent via USI Tx
  430. ;-------------------------------------------
  431. USITransfer_Fast3: ;USES TIMER0:
  432. out USIDR,r16
  433. ldi r19,(1<<USIWM0)|(0<<USICS0)|(1<<USITC)|(1<<USICLK)
  434. ldi r18,8
  435. ;rcall startTim0
  436. LDI r16,0b0000_0010 ; 2=/8 3=/64 4 = /256 5= /1024 2=/8 SET TIMER PRESCALER TO /1024,
  437. OUT TCCR0B,r16 ;start tim0
  438.  
  439. upt23:
  440. ;rcall oneBitTime
  441. rcall clrTCNT0
  442. rcall waitTilTim0Fin
  443. out USICR,r19
  444. dec r18
  445. brne upt23
  446.  
  447. ret
  448. ;---------------------------------------
  449. clrTCNT0:
  450. clr r16
  451. out TCNT0,r16
  452. ret
  453. ;---------------------***--
  454. waitTilTim0Fin: ;wait til timer 0 counts up to top value
  455. in r16,TCNT0
  456. cpi r16,26 ;have we counted up to 13, 1 bit time for 600 , /1024 baud?
  457. ; 52 with /256 gives 600baund, 26 with /256 should give 1200. Yes, worked. Now
  458. ;try 13 with same setting to give 2400? Yes, worked. Now change divisor to /64.
  459. ;With /64 should get 2400 with count to 52. Yes, worked. Now trying same but with 26
  460. ; to give 4800 baud? Yes, worked at 4800. First time at this speed for bitbang USI.
  461. ; Now change val from 26 to 13 to give 9600? Yes! Great speed and looks solid. Will keep going.
  462. ;Now need to change divisor down from 64 to 8.8*13 = 104. Use this with /8. Got 9600 again
  463. ; this way. Now halve the 104 ( to 52) to double the speed to 19200? Yes!!. The usi is being used to
  464. ; transfer bytes at 19200. OK, keep going. Now try 26 as TOP with /8 to give 38400?? OK, go first errors.
  465. ;at 38400. It interpreted 1234 as 1274 so an extra bit got inserted.
  466. brne waitTilTim0Fin
  467. ret
  468. ;-----------------------
  469. waitHalfBit: ;wait til timer 0 counts to half above
  470. rcall clrTCNT0 ;this took 2 days to insert.
  471.  
  472. rcall startTim0
  473. whb:
  474. in r16,TCNT0
  475. cpi r16,26/2
  476. brne whb
  477. rcall stopTim0
  478. ret ;used during start bit rx
  479. ;-----------------------------------------------------
  480. usiTxT: ;uses timer0. Byte to be sent is in r16
  481. ldi r17,$ff ;make r1 an output as this stage. Can interfere with Rx
  482. out DDRB,r17
  483. ;ldi r16,$78 ;!!
  484. rcall reverseBits ;needed
  485. rcall split62 ;now have (10 + 6lsbs) + (2 msbs + 6Stops) in r116,r17
  486. rcall USITransfer_Fast3 ;there's the r16 gone
  487. mov r16,r17
  488. rcall USITransfer_Fast3 ;and the r17.
  489. LDI r16,0b0000_0000 ;stop timer,
  490. OUT TCCR0B,r16
  491.  
  492. ret ;with r16 having been sent via USI Tx
  493. ;--------------------------------------
  494. test_usiTxT: ;worked first time at 600 baud
  495. ldi r16,$56
  496.  
  497. rcall usiTxT
  498. rcall oneSec
  499. ldi r16, $78
  500. rcall usiTxT
  501. rcall oneSec
  502. rjmp test_usiTxT
  503. ;--------------------------------------------------------
  504. timeAByteT: ;worked got $75 (occasionally 76 ) in TCNT0. About right for 9 bits at 600 baud.
  505. rcall setUp
  506. rcall waitForPin0High
  507. rcall waitForPin0Low
  508. LDI r16,0b0000_0011 ;3=/64 2=/8 4 = /256 5= /1024 SET TIMER PRESCALER TO /1024,
  509. OUT TCCR0B,r16 ;start tim0
  510.  
  511. rcall waitForPin0High
  512. ;rcall stopTim0
  513. LDI r16,0b0000_0000 ;stop timer,
  514. OUT TCCR0B,r16
  515.  
  516. in r16,TCNT0
  517. rcall usiTxT
  518. rcall oneSec
  519. rjmp timeAByteT ;got 52 for one bit at /8 and 19200. Seems to be limit.Got 26 for 1 bit
  520. ; at /8 38400. Why can't I tx at this speed?
  521. ;----------------------
  522. usiRxT: ;input a byte serially via PB0 using usi
  523. ldi r16,$fc
  524. out DDRB,r16 ;make both Tx,Rx inputs to stop interference
  525. rcall waitForPin0High
  526. rcall waitForPin0Low2
  527. ;rcall clrPB3
  528. rcall waitHalfBit
  529.  
  530.  
  531. ldi r16,$ff
  532. out PORTB,r16 ;fill usi data reg with 1's so no start bits come out while shifting
  533. rcall USITransfer_Fast3 ;do 8 shifts into usidr from PB0. Emerge with byte in usidr
  534.  
  535. in r16,USIDR
  536. rcall reverseBits ;needed
  537.  
  538. ;rcall usiTxT
  539. rcall usiTxT ;display byte. (Back to front?)
  540. ret
  541. ;------------------------
  542. test_usiRxT: ;worked at 13 /1024 600. Try now 52 /256 600? OK.
  543. ;Now try 26 /256 1200? Yes, worked.
  544. ;Now try 13 /256 2400? Yes, but can't do a string because of rx tx rx tx ...
  545. ;Now try 52 /64 2400? Yes, worked.
  546. ;Now try 26 /64 4800? No, problems. Fixed problem. needed TCNT0 rset each startbit. Yes,worked.
  547. ;Now 26Oct14 11:51am Try 13 /64 9600? Worked!
  548. ;Now try 104 /8 9600? Yes, worked.
  549. ;Now try 52 /8 19200? Yes, worked.
  550. ;Now try 26 /8 38400? No, problems. Maybe just a Tx problem at this speed above. Anyway, this is
  551. ; fast enough at this stage (ie 19200). Let's wind it back to 9600 just to be on the safe side
  552. ; and make it equiv to Arduino serial i/o in normal configs. The nest task then is to integrate all the usi
  553. ; serial tx,rx into main forth85 program and throw out, or put elsewhere, the bit banged
  554. ; 600 baud serial stuff. Step one, pare down the code in this file to one Tx and one Rx routine.
  555. ;sbi DDRB,3
  556. ;rcall setPB3
  557.  
  558. rcall usiRxT
  559. ;rcall oneSec
  560. ;ldi r16,$57
  561.  
  562. ;rcall usiTxT
  563. ;rjmp top
  564. rjmp test_usiRxT
  565. ;------------------
  566. setPB3:
  567. sbi PORTB,3
  568. ret
  569. clrPB3:
  570. cbi PORTB,3
  571. ret
  572.  
  573. testPB3:
  574. sbi DDRB,3
  575. rcall setPB3
  576. rcall oneSec
  577. rcall clrPB3
  578. rcall oneSec
  579. rjmp testPB3
  580.  
  581. ;-----------------------
  582. waitForPin0Low2:
  583. ; ldi zl,0x36
  584. ; clr zh
  585. ; ld r16,z
  586. ;rcall d16
  587. ; rcall spacecode
  588. sbic PINB,0
  589. rjmp waitForPin0Low
  590. ret ;when pin PB1 goes low
Advertisement
Add Comment
Please, Sign In to add comment