📄 i2c.lst
字号:
ARM COMPILER V2.53, i2c 27/07/06 14:45:57 PAGE 1
ARM COMPILER V2.53, COMPILATION OF MODULE i2c
OBJECT MODULE PLACED IN .\Obj\i2c.obj
COMPILER INVOKED BY: g:\Keil\ARM\BIN\CA.exe i2c.c THUMB INCDIR(..\Common\inc) DEBUG PRINT(.\LST\I2C.LST) TABS(4) OBJECT(
-.\Obj\i2c.obj)
stmt level source
1 /*****************************************************************************
2 * i2c.c: I2C C file for Philips LPC214x Family Microprocessors
3 *
4 * Copyright(C) 2006, Philips Semiconductor
5 * All rights reserved.
6 *
7 * History
8 * 2005.10.01 ver 1.00 Prelimnary version, first Release
9 *
10 *****************************************************************************/
11 #include "LPC214x.h" /* LPC21xx definitions */
12 #include "type.h"
13 #include "irq.h"
14 #include "i2c.h"
15
16 DWORD I2CMasterState = I2C_IDLE;
17 DWORD I2CSlaveState = I2C_IDLE;
18
19 DWORD I2CCmd;
20 DWORD I2CMode;
21
22 BYTE I2CMasterBuffer[BUFSIZE];
23 BYTE I2CSlaveBuffer[BUFSIZE];
24 DWORD I2CCount = 0;
25 DWORD I2CReadLength;
26 DWORD I2CWriteLength;
27
28 DWORD RdIndex = 0;
29 DWORD WrIndex = 0;
30
31 /*
32 From device to device, the I2C communication protocol may vary,
33 in the example below, the protocol uses repeated start to read data from or
34 write to the device:
35 For master read: the sequence is: STA,Addr(W),offset,RE-STA,Addr(w),data...STO
36 for master write: the sequence is: STA,Addr(W),length,RE-STA,Addr(r),data...STO
37 Thus, in state 8, the address is always WRITE. in state 10, the address could
38 be READ or WRITE depending on the I2CCmd.
39 */
40
41 /*****************************************************************************
42 ** Function name: I2C0MasterHandler
43 **
44 ** Descriptions: I2C0 interrupt handler, deal with master mode
45 ** only.
46 **
47 ** parameters: None
48 ** Returned value: None
49 **
50 *****************************************************************************/
51 void I2C0MasterHandler (void) __irq
52 {
53 1 BYTE StatValue;
54 1
55 1 /* this handler deals with master read and master write only */
56 1 StatValue = I20STAT;
57 1 IENABLE; /* handles nested interrupt */
58 1 switch ( StatValue )
ARM COMPILER V2.53, i2c 27/07/06 14:45:57 PAGE 2
59 1 {
60 2 case 0x08: /* A Start condition is issued. */
61 2 I20DAT = I2CMasterBuffer[0];
62 2 I20CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
63 2 I2CMasterState = I2C_STARTED;
64 2 break;
65 2
66 2 case 0x10: /* A repeated started is issued */
67 2 if ( I2CCmd == GET_DEVICE_ID || I2CCmd == GET_TEMPERATURE )
68 2 {
69 3 I20DAT = I2CMasterBuffer[2];
70 3 }
71 2 I20CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
72 2 I2CMasterState = I2C_RESTARTED;
73 2 break;
74 2
75 2 case 0x18: /* Regardless, it's a ACK */
76 2 if ( I2CMasterState == I2C_STARTED )
77 2 {
78 3 I20DAT = I2CMasterBuffer[1+WrIndex];
79 3 WrIndex++;
80 3 I2CMasterState = DATA_ACK;
81 3 }
82 2 I20CONCLR = I2CONCLR_SIC;
83 2 break;
84 2
85 2 case 0x28: /* Data byte has been transmitted, regardless ACK or NACK */
86 2 case 0x30:
87 2 if ( WrIndex != I2CWriteLength )
88 2 {
89 3 I20DAT = I2CMasterBuffer[1+WrIndex]; /* this should be the last one */
90 3 WrIndex++;
91 3 if ( WrIndex != I2CWriteLength )
92 3 {
93 4 I2CMasterState = DATA_ACK;
94 4 }
95 3 else
96 3 {
97 4 I2CMasterState = DATA_NACK;
98 4 if ( I2CReadLength != 0 )
99 4 {
100 5 I20CONSET = I2CONSET_STA; /* Set Repeated-start flag */
101 5 I2CMasterState = I2C_REPEATED_START;
102 5 }
103 4 }
104 3 }
105 2 else
106 2 {
107 3 if ( I2CReadLength != 0 )
108 3 {
109 4 I20CONSET = I2CONSET_STA; /* Set Repeated-start flag */
110 4 I2CMasterState = I2C_REPEATED_START;
111 4 }
112 3 else
113 3 {
114 4 I2CMasterState = DATA_NACK;
115 4 }
116 3 }
117 2 I20CONCLR = I2CONCLR_SIC;
118 2 break;
119 2
120 2 case 0x40: /* Master Receive, SLA_R has been sent */
121 2 I20CONCLR = I2CONCLR_SIC;
122 2 break;
123 2
124 2 case 0x50: /* Data byte has been received, regardless following ACK or NACK */
ARM COMPILER V2.53, i2c 27/07/06 14:45:57 PAGE 3
125 2 case 0x58:
126 2 I2CMasterBuffer[3+RdIndex] = I20DAT;
127 2 RdIndex++;
128 2 if ( RdIndex != I2CReadLength )
129 2 {
130 3 I2CMasterState = DATA_ACK;
131 3 }
132 2 else
133 2 {
134 3 RdIndex = 0;
135 3 I2CMasterState = DATA_NACK;
136 3 }
137 2 I20CONSET = I2CONSET_AA; /* assert ACK after data is received */
138 2 I20CONCLR = I2CONCLR_SIC;
139 2 break;
140 2
141 2 case 0x20: /* regardless, it's a NACK */
142 2 case 0x48:
143 2 I20CONCLR = I2CONCLR_SIC;
144 2 I2CMasterState = DATA_NACK;
145 2 break;
146 2
147 2 case 0x38: /* Arbitration lost, in this example, we don't
148 2 deal with multiple master situation */
149 2 default:
150 2 I20CONCLR = I2CONCLR_SIC;
151 2 break;
152 2 }
153 1 IDISABLE;
154 1 VICVectAddr = 0; /* Acknowledge Interrupt */
155 1 }
156
157 /*****************************************************************************
158 ** Function name: I2CStart
159 **
160 ** Descriptions: Create I2C start condition, a timeout
161 ** value is set if the I2C never gets started,
162 ** and timed out. It's a fatal error.
163 **
164 ** parameters: None
165 ** Returned value: true or false, return false if timed out
166 **
167 *****************************************************************************/
168 DWORD I2CStart( void )
169 {
170 1 DWORD timeout = 0;
171 1 DWORD returnValue = FALSE;
172 1
173 1 /*--- Issue a start condition ---*/
174 1 I20CONSET = I2CONSET_STA; /* Set Start flag */
175 1
176 1 /*--- Wait until START transmitted ---*/
177 1 while( 1 )
178 1 {
179 2 if ( I2CMasterState == I2C_STARTED )
180 2 {
181 3 returnValue = TRUE;
182 3 break;
183 3 }
184 2 if ( timeout >= MAX_TIMEOUT )
185 2 {
186 3 returnValue = FALSE;
187 3 break;
188 3 }
189 2 timeout++;
190 2 }
ARM COMPILER V2.53, i2c 27/07/06 14:45:57 PAGE 4
191 1 return( returnValue );
192 1 }
193
194 /*****************************************************************************
195 ** Function name: I2CStop
196 **
197 ** Descriptions: Set the I2C stop condition, if the routine
198 ** never exit, it's a fatal bus error.
199 **
200 ** parameters: None
201 ** Returned value: true or never return
202 **
203 *****************************************************************************/
204 DWORD I2CStop( void )
205 {
206 1 I20CONSET = I2CONSET_STO; /* Set Stop flag */
207 1 I20CONCLR = I2CONCLR_SIC; /* Clear SI flag */
208 1
209 1 /*--- Wait for STOP detected ---*/
210 1 while( I20CONSET & I2CONSET_STO );
211 1 return TRUE;
212 1 }
213
214 /*****************************************************************************
215 ** Function name: I2CInit
216 **
217 ** Descriptions: Initialize I2C controller
218 **
219 ** parameters: I2c mode is either MASTER or SLAVE
220 ** Returned value: true or false, return false if the I2C
221 ** interrupt handler was not installed correctly
222 **
223 *****************************************************************************/
224 DWORD I2CInit( DWORD I2cMode )
225 {
226 1 PINSEL0 = 0x50; /* set PIO0.2 and PIO0.3 to I2C0 SDA and SCK */
227 1 IODIR0 = 0x0C; /* set port 0.2 and port 0.3 to output, high */
228 1 IOSET0 = 0x0C;
229 1
230 1 /*--- Clear flags ---*/
231 1 I20CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;
232 1
233 1 /*--- Reset registers ---*/
234 1 I20SCLL = I2SCLL_SCLL;
235 1 I20SCLH = I2SCLH_SCLH;
236 1 if ( I2cMode == I2CSLAVE )
237 1 {
238 2 I20ADR = SE95_ADDR;
239 2 }
240 1
241 1 /* Install interrupt handler */
242 1 if ( install_irq( I2C0_INT, (void *)I2C0MasterHandler ) == FALSE )
243 1 {
244 2 return( FALSE );
245 2 }
246 1 I20CONSET = I2CONSET_I2EN;
247 1 return( TRUE );
248 1 }
249
250 /*****************************************************************************
251 ** Function name: I2CEngine
252 **
253 ** Descriptions: The routine to complete a I2C transaction
254 ** from start to stop. All the intermitten
255 ** steps are handled in the interrupt handler.
256 ** Before this routine is called, the read
ARM COMPILER V2.53, i2c 27/07/06 14:45:57 PAGE 5
257 ** length, write length, I2C master buffer,
258 ** and I2C command fields need to be filled.
259 ** see i2cmst.c for more details.
260 **
261 ** parameters: None
262 ** Returned value: true or false, return false only if the
263 ** start condition can never be generated and
264 ** timed out.
265 **
266 *****************************************************************************/
267 DWORD I2CEngine( void )
268 {
269 1 I2CMasterState = I2C_IDLE;
270 1 RdIndex = 0;
271 1 WrIndex = 0;
272 1 if ( I2CStart() != TRUE )
273 1 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -