1 | /*************************************************************************/
|
2 | /* CPU-Registerbelegung */
|
3 | /*************************************************************************/
|
4 |
|
5 | #define RXTXI2C R7
|
6 | #define Fehler R8
|
7 | #define DATAI2C R9
|
8 | #define BITI2C R10
|
9 | #define SlaveAdresse R12
|
10 | #define SendeDaten R13
|
11 | #define PointerAdresse R14
|
12 |
|
13 |
|
14 | /*************************************************************************/
|
15 | /* Header-Files */
|
16 | /*************************************************************************/
|
17 |
|
18 | #include "owndef.h"
|
19 |
|
20 | /*************************************************************************/
|
21 | /* in owndef.h werden diese Ersatznamen definiert: */
|
22 | /* */
|
23 | /* #define SDA 0x08 // P4.3 */
|
24 | /* #define SCL 0x10 // P4.4 */
|
25 | /* #define I2C_PORT_OUT P4OUT */
|
26 | /* #define I2C_PORT_IN P4IN */
|
27 | /* #define I2C_PORT_DIR P4DIR */
|
28 | /*************************************************************************/
|
29 |
|
30 | /*************************************************************************/
|
31 | /* Ein Byte lesen für Slaves mit 16-Bit Pointer-Adresse */
|
32 | /* */
|
33 | /* Übergabe-Parameter: SlaveAdresse = Adresse des I²C-Slaves */
|
34 | /* PointerAdresse = Pointer-Register-Wort des I²C- */
|
35 | /* Slaves */
|
36 | /* Rückkehr-Parameter: Daten-Byte vom Slave (R12) */
|
37 | /*************************************************************************/
|
38 |
|
39 | PUBLIC Read_A16_I2C_BYTE
|
40 | RSEG CODE
|
41 |
|
42 | Read_A16_I2C_BYTE
|
43 |
|
44 | push R7 ; Sichern der in C verwendeten
|
45 | ; Register
|
46 | push R8
|
47 | push R9
|
48 | push R10
|
49 |
|
50 | rla.b SlaveAdresse ; Herstellen der Slave-Adresse
|
51 | ; für Übertragung
|
52 |
|
53 | clr.b DATAI2C ; Datenregister löschen
|
54 | clr.b Fehler ; Fehlerstatus zurücksetzen
|
55 | mov.b SlaveAdresse,RXTXI2C ; Slave-Adresse ins RXTX-
|
56 | ; Register laden
|
57 | inc Fehler ; 1 --> kein Slave mit dieser
|
58 | ; Adresse
|
59 | call #I2C_Start ; Senden: START, Slave-Address-
|
60 | ; Byte, Slave Ack prüfen
|
61 |
|
62 | mov.w PointerAdresse,RXTXI2C ; Pointer-Adresse ins RXTX-
|
63 | ; Register laden
|
64 | inc Fehler ; 2 --> kein solches High-
|
65 | ; Register
|
66 | call #I2C_TX_16 ; Senden: 1. Pointer-Address-
|
67 | ; Byte, Slave Ack prüfen
|
68 | inc Fehler ; 3 --> kein solches Low-
|
69 | ; Register
|
70 | call #I2C_TX_16 ; Senden: 2. Pointer-Address-
|
71 | ; Byte, Slave Ack prüfen
|
72 |
|
73 | mov.b SlaveAdresse,RXTXI2C ; Slave-Adresse ins RXTX-
|
74 | ; Register laden
|
75 | bis.b #01h,RXTXI2C ; Slave-Adresse auf "read"
|
76 | ; modifizieren (R/W-setzen)
|
77 | inc Fehler ; 4 --> kein Slave mit dieser
|
78 | ; Adresse
|
79 | call #I2C_Start ; Senden: START, Slave-Address-
|
80 | ; Byte, Slave Ack prüfen
|
81 |
|
82 | call #I2C_RX_8 ; Lesen: Datenbyte
|
83 | call #I2C_RX_NAck_8 ; Senden: No Acknowledge
|
84 | call #I2C_Stop ; Senden: STOP
|
85 | mov.b DATAI2C,R12 ; Gelesenes Byte nach R12
|
86 | ; schieben
|
87 |
|
88 | pop R10 ; Wiederherstellen der
|
89 | pop R9 ; Register für C
|
90 | pop R8
|
91 | pop R7
|
92 |
|
93 | ret ; Rücksprung zu C (ohne Fehler)
|
94 |
|
95 |
|
96 | /*************************************************************************/
|
97 | /* Ein Byte schreiben für Slaves mit 16-Bit Pointer-Adresse */
|
98 | /* */
|
99 | /* Übergabe-Parameter: SlaveAdresse = Adresse des I²C-Slaves */
|
100 | /* PointerAdresse = Pointer-Register-Wort des I²C- */
|
101 | /* Slaves */
|
102 | /* SendeDaten = zu sendendes Daten-Byte */
|
103 | /* Rückkehr-Parameter: 0 --> kein Fehler aufgetreten */
|
104 | /*************************************************************************/
|
105 |
|
106 | PUBLIC Write_A16_I2C_BYTE
|
107 | RSEG CODE
|
108 |
|
109 | Write_A16_I2C_BYTE
|
110 |
|
111 | mov.b 2(SP),SendeDaten ; Übergabeparameter vom Stack
|
112 | ; holen
|
113 |
|
114 | push R7 ; Sichern der in C verwendeten
|
115 | ; Register
|
116 | push R8
|
117 | push R9
|
118 | push R10
|
119 |
|
120 | rla.b SlaveAdresse ; Herstellen der Slave-Adresse
|
121 | ; für Übertragung
|
122 |
|
123 | clr.b DATAI2C ; Datenregister löschen
|
124 | clr.b Fehler ; Fehlerstatus zurücksetzen
|
125 |
|
126 | mov.b SlaveAdresse,RXTXI2C ; Slave-Adresse ins RXTX-
|
127 | ; Register laden
|
128 | inc Fehler ; 1 --> kein Slave mit dieser
|
129 | ; Adresse
|
130 | call #I2C_Start ; Senden: START, Slave-Address-
|
131 | ; Byte, Prüfen von Slave Ack
|
132 |
|
133 | mov.w PointerAdresse,RXTXI2C ; Pointer-Adresse ins RXTX-
|
134 | ; Register laden
|
135 | inc Fehler ; 2 --> kein solches High-
|
136 | ; Register
|
137 | call #I2C_TX_16 ; Senden: 1. Pointer-Register-
|
138 | ; Byte, Prüfen Slave Ack
|
139 | inc Fehler ; 3 --> kein solches Low-
|
140 | ; Register
|
141 | call #I2C_TX_16 ; Senden: 2. Pointer-Register-
|
142 | ; Byte, Prüfen Slave Ack
|
143 |
|
144 | mov.b SendeDaten,RXTXI2C ; zu sendende Datenbyte ins
|
145 | ; RXTX-Register laden
|
146 | inc Fehler ; 4 --> Fehler im Datenbyte
|
147 | call #I2C_TX_8 ; Senden: Datenbyte 1
|
148 | call #I2C_Stop ; Senden: STOP
|
149 | mov.b #0,R12 ; Kein Fehler aufgetreten
|
150 |
|
151 | pop R10 ; Wiederherstellen der
|
152 | pop R9 ; Register für C
|
153 | pop R8
|
154 | pop R7
|
155 |
|
156 | ret ; Rücksprung zu C (ohne Fehler)
|
157 |
|
158 |
|
159 | /*************************************************************************/
|
160 | /* START senden */
|
161 | /* */
|
162 | /* Start: SDA=x, SCL=x */
|
163 | /* Ende: SDA=0, SCL=0 */
|
164 | /*************************************************************************/
|
165 |
|
166 | I2C_Start
|
167 |
|
168 | bic.b #SCL+SDA,&I2C_PORT_DIR ; SCL und SDA auf Eingang
|
169 | ; setzen
|
170 | bic.b #SCL+SDA,&I2C_PORT_OUT ; SCL=0, SDA=0 ins
|
171 | ; Ausgangsregister laden
|
172 | bis.b #SDA,&I2C_PORT_DIR ; SDA=0
|
173 | bis.b #SCL,&I2C_PORT_DIR ; SCL=0
|
174 |
|
175 |
|
176 | /*************************************************************************/
|
177 | /* Ein Byte Daten senden */
|
178 | /* */
|
179 | /* Start: SDA=0, SCL=0 */
|
180 | /* Ende: SDA=0 --> kein Fehler, SDA=1 --> Fehler, SCL=0 */
|
181 | /*************************************************************************/
|
182 |
|
183 | I2C_TX_8
|
184 |
|
185 | mov #08,BITI2C ; Schleifenzähler (Bit-Anzahl)
|
186 |
|
187 | I2C_TX_Bit_8
|
188 |
|
189 | rla.b RXTXI2C ; Daten-Bit -> Carry
|
190 | jc I2C_TX1_8 ; wenn Carry=1, dann Sprung
|
191 |
|
192 | I2C_TX0_8
|
193 |
|
194 | bis.b #SDA,&I2C_PORT_DIR ; SDA=0
|
195 | jmp I2C_TXx_8 ;
|
196 |
|
197 | I2C_TX1_8
|
198 |
|
199 | bic.b #SDA,&I2C_PORT_DIR ; SDA=1
|
200 |
|
201 | I2C_TXx_8
|
202 |
|
203 | bic.b #SCL,&I2C_PORT_DIR ; SCL=1
|
204 | nop ; Verzögerung für I²C-
|
205 | ; Spezifikation
|
206 | nop ;
|
207 | bis.b #SCL,&I2C_PORT_DIR ; SCL=0
|
208 | dec BITI2C ; Schleifenzähler
|
209 | ; dekrementieren
|
210 | jnz I2C_TX_Bit_8 ; Abbruchbedingung
|
211 | bic.b #SDA,&I2C_PORT_DIR ; SDA=1
|
212 |
|
213 | I2C_TX_Ack_8
|
214 |
|
215 | bic.b #SCL,&I2C_PORT_DIR ; SCL=1
|
216 | nop ; Verzögerung für I²C-
|
217 | ; Spezifikation
|
218 | bit.b #SDA,&I2C_PORT_IN ; Slave_NAck --> Carry
|
219 | jc I2C_Error ; Sprung zu Fehlerbehandlung
|
220 | nop ; Verzögerung für I²C-
|
221 | ; Spezifikation
|
222 | bis.b #SCL,&I2C_PORT_DIR ; SCL=0
|
223 | ret ; Rückkehr
|
224 |
|
225 | /*************************************************************************/
|
226 | /* Zwei Bytes Daten senden */
|
227 | /* */
|
228 | /* Start: SDA=0, SCL=0 */
|
229 | /* Ende: SDA=0 --> kein Fehler, SDA=1 --> Fehler, SCL=0 */
|
230 | /*************************************************************************/
|
231 |
|
232 | I2C_TX_16
|
233 |
|
234 | mov #8,BITI2C ; Schleifenzähler (Bit-Anzahl)
|
235 |
|
236 | I2C_TX_Bit_16
|
237 |
|
238 | rla.w RXTXI2C ; Daten-Bit -> Carry
|
239 | jc I2C_TX1_16 ; wenn Carry=1, dann Sprung
|
240 |
|
241 | I2C_TX0_16
|
242 |
|
243 | bis.b #SDA,&I2C_PORT_DIR ; SDA=0
|
244 | jmp I2C_TXx_16 ;
|
245 |
|
246 | I2C_TX1_16
|
247 |
|
248 | bic.b #SDA,&I2C_PORT_DIR ; SDA=1
|
249 |
|
250 | I2C_TXx_16
|
251 |
|
252 | bic.b #SCL,&I2C_PORT_DIR ; SCL=1
|
253 | nop ; Verzögerung für I²C-
|
254 | ; Spezifikation
|
255 | nop ;
|
256 | bis.b #SCL,&I2C_PORT_DIR ; SCL=0
|
257 | dec BITI2C ; Schleifenzähler
|
258 | ; dekrementieren
|
259 | jnz I2C_TX_Bit_16 ; Abbruchbedingung
|
260 | bic.b #SDA,&I2C_PORT_DIR ; SDA=1
|
261 |
|
262 | I2C_TX_Ack_16
|
263 |
|
264 | bic.b #SCL,&I2C_PORT_DIR ; SCL=1
|
265 | nop ; Verzögerung für I²C-
|
266 | ; Spezifikation
|
267 | bit.b #SDA,&I2C_PORT_IN ; Slave_NAck --> Carry
|
268 | jc I2C_Error ; Sprung zu Fehlerbehandlung
|
269 | nop ; Verzögerung für I²C-
|
270 | ; Spezifikation
|
271 | bis.b #SCL,&I2C_PORT_DIR ; SCL=0
|
272 | ret ; Rückkehr
|
273 |
|
274 |
|
275 | /*************************************************************************/
|
276 | /* Ein Byte Daten empfangen */
|
277 | /* */
|
278 | /* Start: SDA=0, SCL=0 */
|
279 | /* Ende: SDA=1, SCL=0 */
|
280 | /*************************************************************************/
|
281 |
|
282 | I2C_RX_8
|
283 |
|
284 | mov.b #08,BITI2C ; Schleifenzähler (Bit-Anzahl)
|
285 |
|
286 | I2C_RX_Bit_8
|
287 |
|
288 | bic.b #SCL,&I2C_PORT_DIR ; SCL=1
|
289 | bit.b #SDA,&I2C_PORT_IN ; Daten-Bit -> Carry
|
290 | rlc.b DATAI2C ; Carry als LSB speichern
|
291 | bis.b #SCL,&I2C_PORT_DIR ; SCL=0
|
292 | dec BITI2C ; Schleifenzähler
|
293 | ; dekrementieren
|
294 | jnz I2C_RX_Bit_8 ; Abbruchbedingung
|
295 | ret ; Rückkehr
|
296 |
|
297 | I2C_RX_Ack_8
|
298 |
|
299 | bis.b #SDA,&I2C_PORT_DIR ; SDA=0, Master Acknowledge
|
300 |
|
301 | I2C_RX_NAck_8
|
302 |
|
303 | bic.b #SCL,&I2C_PORT_DIR ; SCL=1, Master No Acknowledge
|
304 | nop ; Verzögerung für I²C-
|
305 | ; Spezifikation
|
306 | nop ;
|
307 | bis.b #SCL,&I2C_PORT_DIR ; SCL=0
|
308 | bic.b #SDA,&I2C_PORT_DIR ; SDA=1
|
309 | ret ; Rückkehr
|
310 |
|
311 |
|
312 | /*************************************************************************/
|
313 | /* STOP senden */
|
314 | /* */
|
315 | /* Start: SDA=x, SCL=0 */
|
316 | /* Ende: SDA=1, SCL=1 */
|
317 | /*************************************************************************/
|
318 |
|
319 | I2C_Stop
|
320 |
|
321 | bis.b #SDA,&I2C_PORT_DIR ; SDA = 0
|
322 | bic.b #SCL,&I2C_PORT_DIR ; SCL = 1
|
323 | bic.b #SDA,&I2C_PORT_DIR ; SDA = 1
|
324 |
|
325 | I2C_End
|
326 |
|
327 | ret
|
328 |
|
329 |
|
330 | /*************************************************************************/
|
331 | /* Fehlerbehandlung */
|
332 | /* */
|
333 | /* Start: SDA=1, SCL=0 */
|
334 | /* Ende: Rücksprung zu C, Fehler-Code in R12 */
|
335 | /*************************************************************************/
|
336 |
|
337 | I2C_Error
|
338 |
|
339 | mov Fehler,R12 ; Fehler-Code in Rückkehrregister
|
340 | ; laden
|
341 | incd SP ; Stack-Pointer erhöhen, um
|
342 | ; Rückkehradresse zu C zu ändern
|
343 |
|
344 | pop R10 ; Wiederherstellen der Register für C
|
345 | pop R9
|
346 | pop R8
|
347 | pop R7
|
348 | ret ; Rückkehr zu C bei einem Fehler
|
349 | ; (mit Fehler-Code)
|
350 |
|
351 |
|
352 | /*************************************************************************/
|
353 |
|
354 | END
|