Advertisement
prjbrook

usi_2i.asm Tx using usi works at 19200!

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