Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
4.8KB

  1. ; *** EEPROM write ***
  2. ; Listen to UART expecting tty-escaped "pingpong" (from tools/) communication.
  3. ;
  4. ; Each of those received bytes is written to the EEPROM, starting at addr 0.
  5. ; that byte is then re-read and sent back to the UART, tty-escaped.
  6. ;
  7. ; Addr selection is done through 2 chained '164, data in/out is done directly
  8. ; with PD7:2 for bits 7:2 and PB1:0 for bits 1:0 (PD1 and PD0 are used for
  9. ; UART).
  10. ;
  11. ; *** Timing, matching and CE ***
  12. ;
  13. ; A lot of trial-and-errors went into those NOPs being place to give time for
  14. ; latching. All these timing are well, well above maximums given in the specs,
  15. ; but when I wasn't going well, well above those specs, I was experiencing
  16. ; read/write errors. It seems we live in an imperfect world!
  17. ;
  18. ; I'm also not sure, in "writedata", whether toggling CE along with WE is
  19. ; actually needed, but until I did, I was experiencing random write failures.
  20. ; So, we end up with this...
  21. ;
  22. ; *** Register Usage ***
  23. ;
  24. ; r0: holds whether last received char was tty-escaped (0 = no, 1=yes)
  25. ; r16: generic tmp
  26. ; r17: generic tmp
  27. ; r20: Byte to send to the "data" SR. Wired to D0-D7.
  28. ; r21: "high" byte, to send to the "addr" SR. Wired to A8-15
  29. ; r22: "low" byte, to send to the "addr" SR. Wired to A0-7
  30. ; r23: tmp value to use for sending to the "addr" SR
  31. .include "m328Pdef.inc"
  32. ; *** Pins ***
  33. .equ SRCP = PORTB2
  34. .equ SRDS = PORTB1
  35. .equ FLWE = PORTB3
  36. .equ FLOE = PORTB4
  37. .equ FLCE = PORTB5 ; WARNING: same as LED
  38. ; *** Consts ***
  39. .equ BAUD_PRESCALE = 103 ; 9600 bauds at 16mhz
  40. rjmp main
  41. ; *** Code ***
  42. ; Waits until a char is read, then put it in R20
  43. ; Perform TTY-escape transparently.
  44. uartrd:
  45. lds r16, UCSR0A
  46. sbrs r16, RXC0 ; RXC0 is set? skip rjmp and fetch char.
  47. rjmp uartrd
  48. lds r20, UDR0
  49. ; is this the escape char?
  50. cpi r20, 0x20
  51. brne uartrd_0
  52. ; escape char
  53. ; We "pong" the escape right away.
  54. rcall uartwr
  55. inc r0
  56. rjmp uartrd
  57. uartrd_0:
  58. ; should we escape?
  59. tst r0
  60. breq uartrd_1
  61. ; yes
  62. andi r20, 0x7f
  63. uartrd_1:
  64. ret
  65. ; Sends char in r20 to UART
  66. ; Perform TTY-escape transparently.
  67. uartwr:
  68. lds r16, UCSR0A
  69. sbrs r16, UDRE0 ; wait until send buffer is empty
  70. rjmp uartwr
  71. ; should we escape?
  72. tst r0
  73. breq uartwr_0
  74. ; we need to escape
  75. ori r20, 0x80
  76. clr r0
  77. uartwr_0:
  78. sts UDR0, r20
  79. ret
  80. ; send r23 to addr shift register.
  81. ; We send highest bits first so that Q7 is the MSB and Q0 is the LSB
  82. sendaddr:
  83. ldi r16, 8 ; we will loop 8 times
  84. cbi PORTB, SRDS
  85. sbrc r23, 7 ; if latest bit isn't cleared, set SER_DP high
  86. sbi PORTB, SRDS
  87. ; toggle SRCP, not waiting between pulses. The CD74AC164 at 5V has a
  88. ; 5.9ns CP min pulse width. We can't match that at 16mhz. No need to
  89. ; wait.
  90. cbi PORTB, SRCP
  91. sbi PORTB, SRCP
  92. lsl r23 ; shift our data left
  93. dec r16
  94. brne sendaddr+1 ; not zero yet? loop! (+1 to avoid reset)
  95. ret
  96. ; send r20 to EEPROM's I/O7:0 through PD7:2 and PB1:0
  97. writedata:
  98. cbi PORTB, FLCE
  99. ; addr is latched on WE falling edge
  100. cbi PORTB, FLWE
  101. ; send bits 7:2
  102. mov r16, r20
  103. andi r16, 0xfc
  104. in r17, PORTD
  105. andi r17, 0x03
  106. or r16, r17
  107. out PORTD, r16
  108. ; send bits 1:0
  109. mov r16, r20
  110. andi r16, 0x03
  111. in r17, PORTB
  112. andi r17, 0xfc
  113. or r16, r17
  114. out PORTB, r16
  115. ; data is latched on rising edge
  116. sbi PORTB, FLWE
  117. sbi PORTB, FLCE
  118. nop ; Give the AT28 time to latch
  119. nop
  120. nop
  121. ret
  122. ; push r20 to the rom and increase the memory counter
  123. nextaddr:
  124. ; first, set up addr
  125. mov r23, r21
  126. rcall sendaddr
  127. mov r23, r22
  128. rcall sendaddr
  129. inc r22
  130. brne nextaddr_0 ; no overflow? skip
  131. inc r21
  132. nextaddr_0:
  133. ret
  134. ; wait until I/O7 stops toggling
  135. waitio7:
  136. cbi PORTB, FLCE
  137. cbi PORTB, FLOE
  138. nop ; Give the AT28 time to latch
  139. nop
  140. nop
  141. in r16, PIND
  142. sbi PORTB, FLOE
  143. sbi PORTB, FLCE
  144. andi r16, 0xfc
  145. cbi PORTB, FLCE
  146. cbi PORTB, FLOE
  147. nop ; Give the AT28 time to latch
  148. nop
  149. nop
  150. in r17, PIND
  151. sbi PORTB, FLOE
  152. sbi PORTB, FLCE
  153. andi r17, 0xfc
  154. cp r16, r17
  155. brne waitio7
  156. ret
  157. ; read EEPROM's I/O7:0 through PD7:2 and PB1:0 into r20
  158. readdata:
  159. cbi PORTB, FLCE
  160. cbi PORTB, FLOE
  161. nop ; Give the AT28 time to latch
  162. nop
  163. nop
  164. ; read bits 7:2
  165. in r20, PIND
  166. andi r20, 0xfc
  167. ; read bits 1:0
  168. in r16, PINB
  169. andi r16, 0x03
  170. or r20, r16
  171. sbi PORTB, FLOE
  172. sbi PORTB, FLCE
  173. ret
  174. ; Set PD7:2 and PB1:0 to output
  175. ioout:
  176. ldi r16, 0xfc ; PD7:2
  177. out DDRD, r16
  178. ldi r16, 0x3f ; PB5:0 (CP, WE, OE and CE too)
  179. out DDRB, r16
  180. ret
  181. ; Set PD7:2 and PB1:0 to input
  182. ioin:
  183. ldi r16, 0x03 ; PD7:2
  184. out DDRD, r16
  185. ldi r16, 0x3c ; PB1:0
  186. out DDRB, r16
  187. ret
  188. main:
  189. ldi r16, low(RAMEND)
  190. out SPL, r16
  191. ldi r16, high(RAMEND)
  192. out SPH, r16
  193. sbi PORTB, FLWE
  194. sbi PORTB, FLOE
  195. sbi PORTB, FLCE
  196. ; Clear counters and flags
  197. clr r0
  198. clr r21
  199. clr r22
  200. ; Setup UART
  201. ldi R16, low(BAUD_PRESCALE)
  202. sts UBRR0L, r16
  203. ldi r16, high(BAUD_PRESCALE)
  204. sts UBRR0H, r16
  205. ldi r16, (1<<RXEN0) | (1<<TXEN0)
  206. sts UCSR0B, r16
  207. loop:
  208. rcall uartrd
  209. rcall ioout
  210. rcall nextaddr
  211. rcall writedata
  212. rcall ioin
  213. rcall waitio7
  214. rcall readdata
  215. rcall uartwr
  216. rjmp loop