-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathi2c_v2.2.inc
executable file
·172 lines (136 loc) · 5.18 KB
/
i2c_v2.2.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
;
; i2c_v2.2.inc
;
;
; AtariVox EEPROM Driver
;
; By Alex Herbert, 2004
;
; Optimisations by Thomas Jentzsch, 2006/2008
;
; I/O Constants
I2C_SDA_MASK equ $04
I2C_SCL_MASK equ $08
; 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
lda #(I2C_SCL_MASK|I2C_SDA_MASK)*2 ; 2 I2C_SCL_MASK
sta SWCHA ; 4
; I2C_SDA_OUT
lsr ; 2 I2C_SCL_MASK|I2C_SDA_MASK
sta SWACNT ; 4
; total: 12 cycles
ENDM
MAC I2C_TXBIT
; I2C_SCL_0
lda #%0011 ; 2
sta SWCHA ; 4
; set bit
adc #%1000 ; 2
sta SWACNT ; 4 SDA = !C (a = %1000 / %1100)
; I2C_SCL_1
lda #I2C_SCL_MASK ; 2
sta SWCHA ; 4
; total: 18 cycles
ENDM
MAC I2C_TXNACK
; I2C_SCL_0
lda #I2C_SCL_MASK*2 ; 2 $00
sta SWCHA ; 4
; I2C_SDA_IN
lsr ; 2 I2C_SCL_MASK
sta SWACNT ; 4
; I2C_SCL_1
nop ; 2 required for timing!
sta SWCHA ; 4 I2C_SCL_MASK
; total: 18 cycles
ENDM
; Subroutine Macros
MAC I2C_SUBS
i2c_startread
; use V to flag if previous byte needs ACK
ldy #%10100001 ; 2 eeprom read command
.byte $2c ; 2
i2c_startwrite
ldy #%10100000 ; 2 eeprom write command
I2C_START ;12 start signal (clears V flag)
tya ; 2 = 16
i2c_txbyte
eor #$ff ; 2 invert data byte
sec ; 2
rol ; 2 = 6 shift loop bit into a
i2c_txbyteloop
tay ; 2
I2C_TXBIT ;18 transmit
tya ; 2
asl ; 2 shift next bit into C
bne i2c_txbyteloop ; 2³= 26/27
; receive acknowledge bit
beq i2c_rxbit ;43 = 43
; i2c_txbyte: 264 cycles
;-------------------------------------------------------------------------------
i2c_rxbyte
bvc i2c_rxskipack ; 2³ previous byte needs acknowledge?
jsr i2c_txack ;24 transmit acknowledge bit
i2c_rxskipack
bit i2c_rxbyte ; 4 set V - next byte(s) require acknowledge
lda #1 ; 2
i2c_rxbyteloop
tay ; 2 = 2
i2c_rxbit: ; receive bit in C
I2C_TXNACK ;18 = 18
lda SWCHA ; 4
lsr ; 2
lsr ; 2
lsr ; 2 = 10 C = SDA
tya ; 2
rol ; 2 rotate into Y
bcc i2c_rxbyteloop ; 2³= 6/7
; received byte in A
rts ; 6 = 6
; i2c_rxbit: 40 cycles
; i2c_rxbyte: 310/333 cycles
;-------------------------------------------------------------------------------
i2c_stopread
bvc i2c_stopwrite ; 2³
ldy #$80 ; 2
jsr i2c_rxbit ;46 transmit no-acknowledge
i2c_stopwrite
jsr i2c_txack ;30
; return port to input mode
lda #0 ; 2 0
sta SWACNT ; 4
rts ; 6 = 12
; i2c_stopread: 45/92
; i2c_stopwrite: 42
;-------------------------------------------------------------------------------
i2c_txack
; I2C_SCL_0
lda #0 ; 2 $00
sta SWCHA ; 4
; I2C_SDA_OUT
lda #(I2C_SCL_MASK|I2C_SDA_MASK) ; 2 I2C_SCL_MASK|I2C_SDA_MASK
sta SWACNT ; 4
; I2C_SCL_1
asl ; 2 I2C_SCL_MASK
sta SWCHA ; 4
rts ; 6
; total: 24 cycles
;-------------------------------------------------------------------------------
ENDM