Subversion Repositories svn.mios

Rev

Rev 52 | Rev 103 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
53 tk 1
; $Id: mios_iic.inc 53 2008-01-30 22:52:41Z tk $
1 tk 2
;
3
; MIOS IIC 1st layer routines
4
;
5
; ==========================================================================
6
;
7
;  Copyright 1998-2006 Thorsten Klose (tk@midibox.org)
8
;  Licensed for personal non-commercial use only.
9
;  All other rights reserved.
10
;
11
; ==========================================================================
12
 
13
;; IIC Pins for the external EEPROM (BankStick)
14
MIOS_IIC_PORT_SCL    EQU     PORTD
15
MIOS_IIC_TRIS_SCL    EQU     TRISD
16
MIOS_IIC_PIN_SCL     EQU     5
17
MIOS_IIC_PORT_SDA    EQU     PORTA
18
MIOS_IIC_TRIS_SDA    EQU     TRISA
19
MIOS_IIC_PIN_SDA     EQU     4
20
 
21
;; if RA4 is not an open drain driver, set this to 0 (e.g. PIC18F4620)
22
;; in this version, we always disable it to get an identical behaviour
23
#define RA4_IS_OPEN_DRAIN 0
24
 
25
;; --------------------------------------------------------------------------
26
;;  Delay Routines
27
;; --------------------------------------------------------------------------
28
MIOS_IIC_Delay_600ns_Stretch
29
	;; 2 cycles for the call
30
	btfss	MIOS_BOX_CFG1, MIOS_BOX_CFG1_IIC_STRETCH_CLK	; 1/2 for this bit test
31
	return			; 2 cycles for the return
32
 
33
	;; if clock stretching enabled:
34
	bsf	MIOS_IIC_TRIS_SCL, MIOS_IIC_PIN_SCL
35
MIOS_IIC_Delay_600ns_StretchLoop
36
	BRA_IFCLR MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL, ACCESS, MIOS_IIC_Delay_600ns_StretchLoop
37
	bcf	MIOS_IIC_TRIS_SCL, MIOS_IIC_PIN_SCL
38
	return
39
 
40
MIOS_IIC_Delay_600ns
41
	;; 2 cycles for the call
42
	nop		; 1 cycle for the nop
43
	;; 2 cycles for the return
44
	;; one for the following instruction
45
	return
46
 
47
MIOS_IIC_Delay_1300ns
48
	;; 2 cycles for the call
49
	nop
50
	nop
51
	nop
52
	nop
53
	nop
54
	nop
55
	nop
56
	;; 2 cycles for the return
57
	;; one for the following instruction
58
	return
59
 
60
;; --------------------------------------------------------------------------
61
;;  FUNCTION: MIOS_IIC_Start
62
;;  C_DECLARATION: void MIOS_IIC_Start(void)
63
;;  DESCRIPTION: sends the IIC start condition (SCL=1, SDA 1->0)
64
;;  IN:	  -
65
;;  C_IN:  -
66
;;  OUT:  -
67
;;  C_OUT:  -
68
;;  USES: -
69
;;  EXAMPLE:
70
;;      see MIOS_IIC_ByteSend and MIOS_IIC_ByteReceive
71
;;  C_EXAMPLE:
72
;;      see MIOS_IIC_ByteSend and MIOS_IIC_ByteReceive
73
;; --------------------------------------------------------------------------
74
MIOS_IIC_Start
75
	bsf	MIOS_BOX_STAT, MIOS_BOX_STAT_BS_AVAILABLE
76
#if RA4_IS_OPEN_DRAIN == 0
77
	bcf	MIOS_IIC_TRIS_SDA, MIOS_IIC_PIN_SDA	; SDA = output
78
#endif
79
	bsf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA -> 1
80
	bsf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 1
81
	rcall	MIOS_IIC_Delay_600ns_Stretch
82
	bcf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA -> 0
83
	rcall	MIOS_IIC_Delay_600ns
84
	bcf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 0
85
	return
86
 
87
;; --------------------------------------------------------------------------
88
;;  FUNCTION: MIOS_IIC_Stop
89
;;  C_DECLARATION: void MIOS_IIC_Stop(void)
90
;;  DESCRIPTION: sends the IIC stop condition (SCL=0->1, SDA 0->1)
91
;;  IN:	  -
92
;;  C_IN:  -
93
;;  OUT:  -
94
;;  C_OUT:  -
95
;;  USES: -
96
;;  EXAMPLE:
97
;;      see MIOS_IIC_ByteSend and MIOS_IIC_ByteReceive
98
;;  C_EXAMPLE:
99
;;      see MIOS_IIC_ByteSend and MIOS_IIC_ByteReceive
100
;; --------------------------------------------------------------------------
101
MIOS_IIC_Stop
102
	bcf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 0
103
	bcf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA -> 0
104
	rcall	MIOS_IIC_Delay_600ns
105
	bsf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 1
106
	rcall	MIOS_IIC_Delay_600ns_Stretch
107
	bsf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA -> 1
108
	return
109
 
110
;; --------------------------------------------------------------------------
111
;;  Check Ack
112
;; --------------------------------------------------------------------------
113
MIOS_IIC_CheckAck
114
	bsf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA = input
115
#if RA4_IS_OPEN_DRAIN == 0
116
	bsf	MIOS_IIC_TRIS_SDA, MIOS_IIC_PIN_SDA	; SDA = input
117
#endif
118
	nop
119
	nop
120
	bsf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 1
121
	rcall	MIOS_IIC_Delay_600ns_Stretch
122
	btfsc	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA
123
	bcf	MIOS_BOX_STAT, MIOS_BOX_STAT_BS_AVAILABLE ; notify that EEPROM is not available
124
 
125
	bcf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 0
126
	rcall	MIOS_IIC_Delay_1300ns
127
#if RA4_IS_OPEN_DRAIN == 0
128
	bcf	MIOS_IIC_TRIS_SDA, MIOS_IIC_PIN_SDA	; SDA = output
129
#endif
130
 
131
	;; supported since MIOS V1.9: set ZERO flag if NAK received
132
	iorlw	0xff
133
	btfss	MIOS_BOX_STAT, MIOS_BOX_STAT_BS_AVAILABLE
134
	andlw	0x00
135
	return
136
 
137
;; --------------------------------------------------------------------------
138
;;  FUNCTION: MIOS_IIC_NakSend
139
;;  C_DECLARATION: void MIOS_IIC_NakSend(void)
140
;;  DESCRIPTION: sends a NAK (not acknowledge) to the slave(s)
141
;;  IN:	  -
142
;;  C_IN: -
143
;;  OUT:  -
144
;;  C_OUT:  -
145
;;  USES: -
146
;;  EXAMPLE:
147
;;      see MIOS_IIC_ByteSend and MIOS_IIC_ByteReceive
148
;;  C_EXAMPLE:
149
;;      see MIOS_IIC_ByteSend and MIOS_IIC_ByteReceive
150
;; --------------------------------------------------------------------------
151
MIOS_IIC_NakSend
152
	;; currently SCL = 0 and SDA=1
153
	bsf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA -> 1
154
	rgoto	MIOS_IIC_AckSend_Cont
155
 
156
;; --------------------------------------------------------------------------
157
;;  FUNCTION: MIOS_IIC_AckSend
158
;;  C_DECLARATION: void MIOS_IIC_AckSend
159
;;  DESCRIPTION: sends a ACK (acknowledge) to the slave(s)
160
;;  IN:	  -
161
;;  C_IN: -
162
;;  OUT:  -
163
;;  C_OUT:  -
164
;;  USES: -
165
;;  EXAMPLE:
166
;;      see MIOS_IIC_ByteSend and MIOS_IIC_ByteReceive
167
;;  C_EXAMPLE:
168
;;      see MIOS_IIC_ByteSend and MIOS_IIC_ByteReceive
169
;; --------------------------------------------------------------------------
170
MIOS_IIC_AckSend
171
	;; currently SCL = 0 and SDA=1
172
	bcf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA -> 0
173
MIOS_IIC_AckSend_Cont
174
#if RA4_IS_OPEN_DRAIN == 0
175
	bcf	MIOS_IIC_TRIS_SDA, MIOS_IIC_PIN_SDA	; SDA = output
176
#endif
177
	nop						; wait > 100 ns
178
	bsf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 1
179
	rcall	MIOS_IIC_Delay_600ns_Stretch
180
	bcf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 0
181
	rgoto	MIOS_IIC_Delay_1300ns
182
 
183
;; --------------------------------------------------------------------------
184
;;  FUNCTION: MIOS_IIC_ByteSend
185
;;  C_DECLARATION: void MIOS_IIC_ByteSend(unsigned char b)
186
;;  DESCRIPTION: sends a byte over the IIC bus and checks for acknowledge.<BR>
187
;;  If the slave didn't send an acknowledge, the (MIOS_BOX_STAT_)BS_AVAILABLE
188
;;  flag in MIOS_BOX_STAT will be cleared.
189
;;  IN:	  byte which should be sent in WREG
190
;;  C_IN: byte which should be sent in <b>
191
;;  OUT:  WREG==0x00 if NAK has been received, otherwise != 0x00
192
;;        due to compatibility reasons, MIOS_BOX_STAT.MIOS_BOX_STAT_BS_AVAILABLE set so long ACK is received
193
;;  C_OUT:  returns 0x00 if NAK has been received, otherwise != 0x00
194
;;        due to compatibility reasons, mios_box_stat.BS_AVAILABLE is set so long ACK is received
195
;;  USES: BSR
196
;;  EXAMPLE:
197
;;
198
;;	;; send 0x34, 0x56, 0x78 to the IIC slave with ID 0x12
199
;;
200
;;	call	MIOS_IIC_Start		; start IIC
201
;;	movlw	0x12			; send device address
202
;;	call	MIOS_IIC_ByteSend	; bit #0 cleared to notify a write!!!
203
;;	movlw	0x34			; send first data byte
204
;;	call	MIOS_IIC_ByteSend
205
;;	movlw	0x56			; send second data byte
206
;;	call	MIOS_IIC_ByteSend
207
;;	movlw	0x78			; send third data byte
208
;;	call	MIOS_IIC_ByteSend
209
;;	call	MIOS_IIC_Stop		; stop IIC
210
;;
211
;;  For more details about the IIC protocol (officially called I2C), see
212
;;     http://www.semiconductors.philips.com/buses/i2c/
213
;;
214
;;  An enhanced example with retry can be
215
;;  found at the MBHP_IIC_MIDI page
216
;;  C_EXAMPLE:
217
;;
218
;;	// send 0x34, 0x56, 0x78 to the IIC slave with ID 0x12
219
;;
220
;;	MIOS_IIC_Start();		// start IIC
221
;;	MIOS_IIC_ByteSend(0x12);	// send device address
222
;;	                            	// bit #0 cleared to notify a write!!!
223
;;	MIOS_IIC_ByteSend(0x34);	// send first data byte
224
;;	MIOS_IIC_ByteSend(0x56);	// send second data byte
225
;;	MIOS_IIC_ByteSend(0x78);	// send third data byte
226
;;	MIOS_IIC_Stop();		// stop IIC
227
;;
228
;;  For more details about the IIC protocol (officially called I2C), see
229
;;     http://www.semiconductors.philips.com/buses/i2c/
230
;;
231
;;  An enhanced example with retry on NAK's can be
232
;;  found at the MBHP_IIC_MIDI page
233
;; --------------------------------------------------------------------------
234
MIOS_IIC_ByteSend
235
	SET_BSR	MIOS_IIC_BUFFER
236
	movwf	MIOS_IIC_BUFFER, BANKED		; store value
237
	movlw	0x08				; loop 8 times
238
	movwf	MIOS_IIC_CTR, BANKED
239
MIOS_IIC_ByteSendLoop
240
	btfsc	MIOS_IIC_BUFFER, 7, BANKED
241
	bsf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA -> 1
242
	btfss	MIOS_IIC_BUFFER, 7, BANKED
243
	bcf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA -> 0
244
	nop						; relax
245
	nop
246
	bsf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 1
247
	rcall	MIOS_IIC_Delay_600ns_Stretch
248
	bcf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 0
249
							; (wait > 1.3 us)
250
	rcall	MIOS_IIC_Delay_600ns
251
	rlf	MIOS_IIC_BUFFER, F, BANKED		; shift left value
252
	decfsz	MIOS_IIC_CTR, F, BANKED			; loop
253
	rgoto	MIOS_IIC_ByteSendLoop
254
 
255
	rgoto	MIOS_IIC_CheckAck		; check the acknowledge
256
 
257
;; --------------------------------------------------------------------------
258
;;  FUNCTION: MIOS_IIC_ByteReceive
259
;;  C_DECLARATION: unsigned char MIOS_IIC_ByteReceive(void)
260
;;  DESCRIPTION: receives a byte from a IIC slave.
261
;;  IN:	  -
262
;;  C_IN:  -
263
;;  OUT: received byte in WREG
264
;;  C_OUT: received byte in WREG
265
;;  USES: BSR
266
;;  EXAMPLE:
267
;;
268
;;	;; receive three bytes from the IIC slave with ID 0x12
269
;;
270
;;	rcall	MIOS_IIC_Start		; start IIC
271
;;	movlw	0x12 | 1		; send device address -
272
;;	call	MIOS_IIC_ByteSend	;    set bit #0 to notify a read!!!
273
;;	;; don't continue if IIC device not available
274
;;	BRA_IFCLR MIOS_BOX_STAT, MIOS_BOX_STAT_BS_AVAILABLE, ACCESS, ReadFailed
275
;;
276
;;	call	MIOS_IIC_ByteReceive	; read first byte
277
;;      movwf   TMP1			; save it in TMP1
278
;;	call	MIOS_IIC_AckSend	; send acknowledge
279
;;	call	MIOS_IIC_ByteReceive	; read second byte
280
;;      movwf   TMP2			; save it in TMP2
281
;;	call	MIOS_IIC_AckSend	; send acknowledge
282
;;	call	MIOS_IIC_ByteReceive	; read third byte
283
;;      movwf   TMP3			; save it in TMP3
284
;;  ReadFailed:
285
;;	call	MIOS_IIC_NakSend	; send disacknowledge!!!
286
;;	call	MIOS_IIC_Stop		; stop IIC
287
;;
288
;;  For more details about the IIC protocol (officially called I2C), see
289
;;     http://www.semiconductors.philips.com/buses/i2c/
290
;;  C_EXAMPLE:
291
;;
292
;;	// receive three bytes from the IIC slave with ID 0x12
293
;;
294
;;	MIOS_IIC_Start();		// start IIC
295
;;	MIOS_IIC_ByteSend(0x12 | 1);	// send device address -
296
;;	                            	//    set bit #0 to notify a read!!!
297
;;	// don't continue if IIC device not available
298
;;	if( MIOS_BOX_STAT.BS_AVAILABLE ) {
299
;;	  b0 = MIOS_IIC_ByteReceive;	// read first byte
300
;;	  MIOS_IIC_AckSend();		// send acknowledge
301
;;	  b1 = MIOS_IIC_ByteReceive;	// read second byte
302
;;	  MIOS_IIC_AckSend();		// send acknowledge
303
;;	  b2 = MIOS_IIC_ByteReceive;	// read third byte
304
;;	}
305
;;	MIOS_IIC_NakSend();		// send disacknowledge!!!
306
;;	MIOS_IIC_Stop();		// stop IIC
307
;;
308
;;  For more details about the IIC protocol (officially called I2C), see
309
;;     http://www.semiconductors.philips.com/buses/i2c/
310
;; --------------------------------------------------------------------------
311
MIOS_IIC_ByteReceive
312
	SET_BSR	MIOS_IIC_BUFFER
313
	clrf	MIOS_IIC_BUFFER, BANKED
314
	bsf	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA	; SDA = input
315
#if RA4_IS_OPEN_DRAIN == 0
316
	bsf	MIOS_IIC_TRIS_SDA, MIOS_IIC_PIN_SDA		; SDA = input
317
#endif
318
 
319
	movlw	0x08					; loop 8 times
320
	movwf	MIOS_IIC_CTR, BANKED
321
MIOS_IIC_ByteReceiveLoop
322
	nop						; relax
323
	nop
324
	bsf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 1
325
	rcall	MIOS_IIC_Delay_600ns_Stretch
326
 
327
	rlf	MIOS_IIC_BUFFER, F, BANKED		; shift left buffer
328
	bcf	MIOS_IIC_BUFFER, 0, BANKED		; copy status of SDA into rightmost bit
329
	btfsc	MIOS_IIC_PORT_SDA, MIOS_IIC_PIN_SDA
330
	bsf	MIOS_IIC_BUFFER, 0, BANKED
331
 
332
	bcf	MIOS_IIC_PORT_SCL, MIOS_IIC_PIN_SCL	; SCL -> 0
333
							; (wait > 1.3 us)
334
	rcall	MIOS_IIC_Delay_600ns
335
	decfsz	MIOS_IIC_CTR, F, BANKED			; loop
336
	rgoto	MIOS_IIC_ByteReceiveLoop
337
 
338
	movf	MIOS_IIC_BUFFER, W, BANKED		; now copy the received value into W
339
 
340
	return
341
 
342
;; --------------------------------------------------------------------------
343
;;  FUNCTION: MIOS_IIC_CtrlSet
344
;;  C_DECLARATION: void MIOS_IIC_CtrlSet(unsigned char ctrl)
345
;;  DESCRIPTION: enables the "clock stretching" like specified in
346
;;  the IIC specification http://www.semiconductors.philips.com/buses/i2c/
347
;;  which is required for some IIC slaves which cannot service the bus
348
;;  immediately on a request.
349
;;  NOTE: if enabled, you have to add a 1k pull-up resistor to the SCL line (Pin #22 of the PIC)
350
;;  IN:	  WREG = 0x00: clock stretching disabled
351
;;        WREG = 0x01: clock stretching enabled
352
;;  C_IN: <ctrl> = 0x00: clock stretching disabled
353
;;        <ctrl> = 0x01: clock stretching enabled
354
;;  OUT:  -
355
;;  USES: -
356
;;  EXAMPLE:
357
;;	;; enable clock stretching
358
;;	movlw   0x01
359
;;	call    MIOS_IIC_CtrlSet
360
;;  C_EXAMPLE:
361
;;	// enable clock stretching
362
;;	MIOS_IIC_CtrlSet(0x01);
363
;; --------------------------------------------------------------------------
364
MIOS_IIC_CtrlSet
365
	bcf	MIOS_BOX_CFG1, MIOS_BOX_CFG1_IIC_STRETCH_CLK
366
	btfsc	WREG, 0
367
	bsf	MIOS_BOX_CFG1, MIOS_BOX_CFG1_IIC_STRETCH_CLK
368
	return
369
 
370
;; --------------------------------------------------------------------------
371
;;  FUNCTION: MIOS_IIC_CtrlGet
372
;;  C_DECLARATION: unsigned char MIOS_IIC_CtrlGet(void)
373
;;  DESCRIPTION: returns the IIC control status
374
;;  IN:  -
375
;;  C_IN:  -
376
;;  OUT:  WREG[0]: clock stretching enabled
377
;;  C_OUT:  bit 0 if return value: clock stretching enabled
378
;;  USES: -
379
;; --------------------------------------------------------------------------
380
MIOS_IIC_CtrlGet
381
	movlw	0x00
382
	btfsc	MIOS_BOX_CFG1, MIOS_BOX_CFG1_IIC_STRETCH_CLK
383
	movlw	0x01
384
	andlw	0xff		; fix STATUS
385
	return