-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathi2c.inc
225 lines (130 loc) · 3.59 KB
/
i2c.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
;
; i2c.inc
;
;
; AtariVox EEPROM Driver
;
; By Alex Herbert, 2004
;
; Debug Constantss
I2C_DEBUGCOLORS equ 0 ; set no non-zero to display timing colours
; I/O Constants
I2C_SDA_MASK equ $04
I2C_SCL_MASK equ $08
; Debug Macros
mac I2C_DEBUGCOL
if I2C_DEBUGCOLORS
lda #{1}
sta COLUBK
endif
endm
; Signalling Macros
mac I2C_SCL_0
lda #$00
sta SWCHA
endm
mac I2C_SCL_1
lda #I2C_SCL_MASK
sta SWCHA
endm
mac I2C_SDA_IN
lda #I2C_SCL_MASK
sta SWACNT
endm
mac I2C_SDA_OUT
lda #I2C_SCL_MASK|I2C_SDA_MASK
sta SWACNT
endm
mac I2C_START
I2C_SCL_1
I2C_SDA_OUT
endm
mac I2C_STOP
I2C_SCL_0
I2C_SDA_OUT
I2C_SCL_1
; return port to input mode
lda #$00
sta SWACNT
endm
mac I2C_TXBIT
I2C_SCL_0
lda #$01
rol
asl
asl
sta SWACNT ; SDA = !C
I2C_SCL_1
endm
mac I2C_TXACK
I2C_SCL_0
I2C_SDA_OUT
I2C_SCL_1
endm
mac I2C_TXNACK
I2C_SCL_0
I2C_SDA_IN
I2C_SCL_1
endm
mac I2C_RXBIT
I2C_SCL_0
I2C_SDA_IN
I2C_SCL_1
lda SWCHA
lsr
lsr
lsr ; C = SDA
endm
mac I2C_RXACK
I2C_RXBIT
endm
; Subroutine Macros
mac I2C_SUBS
i2c_startread
I2C_DEBUGCOL $5e
clv ; use V to flag if previous byte needs ACK
I2C_START ; start signal
lda #%10100001 ; eeprom read command
bvc i2c_txbyte ; transmit
i2c_startwrite
I2C_DEBUGCOL $8e
I2C_START ; start signal
lda #%10100000 ; eeprom write command
i2c_txbyte
eor #$ff ; invert data byte
sta {1} ; store in scratchpad
I2C_DEBUGCOL $86
ldy #$08 ; loop counter
i2c_txbyteloop
asl {1} ; shift next bit into C
I2C_TXBIT ; transmit
dey
bne i2c_txbyteloop
I2C_RXACK ; receive acknowledge bit
I2C_DEBUGCOL $00
rts
i2c_rxbyte
I2C_DEBUGCOL $56
ldy #$08 ; loop counter
bvc i2c_rxskipack ; previous byte needs acknowledge?
I2C_TXACK ; transmit acknowledge bit
i2c_rxbyteloop
I2C_RXBIT ; receive bit in C
rol {1} ; rotate into scratchpad
dey
bne i2c_rxbyteloop
I2C_DEBUGCOL $00
lda {1} ; get received byte from scratchpad
rts
i2c_rxskipack
bit .vbit ; set V - next byte(s) require acknowledge
.vbit bvs i2c_rxbyteloop
i2c_stopread
bvc i2c_stopwrite
I2C_TXNACK ; transmit no-acknowledge
i2c_stopwrite
I2C_DEBUGCOL $0a
I2C_STOP ; stop signal
I2C_DEBUGCOL $02
rts
endm