1 | #include "main.h"
|
2 | #include "i2c.h"
|
3 |
|
4 | //-------------------------------------------
|
5 | // Definition of local constants
|
6 | //-------------------------------------------
|
7 | #define I2C_TIMEOUT (0x1000)
|
8 |
|
9 | //-------------------------------------------
|
10 | // Declaration of local functions
|
11 | //-------------------------------------------
|
12 | static int I2C_check_dev(uint8_t addr);
|
13 | static int I2C_start(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr);
|
14 | static int I2C_restart(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr);
|
15 | static int I2C_stop(I2C_TypeDef* I2Cx);
|
16 | static int I2C_write(I2C_TypeDef* I2Cx, uint8_t data);
|
17 | static int I2C_read_ack(I2C_TypeDef* I2Cx);
|
18 | static int I2C_read_nack(I2C_TypeDef* I2Cx);
|
19 | static int I2C_timeout(char *msg);
|
20 |
|
21 | /*******************************************************************************
|
22 | * Function Name : I2C_BusInit
|
23 | * Description : Configure I2C-Bus
|
24 | * Input : None
|
25 | * Output : None
|
26 | * Return : None
|
27 | * Attention : None
|
28 | *******************************************************************************/
|
29 | void I2C_BusInit(void)
|
30 | {
|
31 | GPIO_InitTypeDef GPIO_InitStructure;
|
32 | I2C_InitTypeDef I2C_InitStructure;
|
33 | //NVIC_InitTypeDef NVIC_InitStructure;
|
34 | //=========================================================================================
|
35 | // Enable GPIO clock
|
36 | //-----------------------------------------------------------------------------------------
|
37 | RCC_AHB1PeriphClockCmd(Open_I2C_SCL_GPIO_CLK, ENABLE);
|
38 |
|
39 | //=========================================================================================
|
40 | // Enable I2C clock
|
41 | //-----------------------------------------------------------------------------------------
|
42 | RCC_APB1PeriphClockCmd(Open_I2C_CLK, ENABLE);
|
43 |
|
44 | //=========================================================================================
|
45 | //GPIO Alternate functions configuration
|
46 | //-----------------------------------------------------------------------------------------
|
47 | GPIO_PinAFConfig(Open_I2C_SCL_GPIO_PORT, Open_I2C_SCL_SOURCE, Open_I2C_SCL_AF);
|
48 | GPIO_PinAFConfig(Open_I2C_SDA_GPIO_PORT, Open_I2C_SDA_SOURCE, Open_I2C_SDA_AF);
|
49 |
|
50 | //=========================================================================================
|
51 | // Configure I2C GPIO
|
52 | //-----------------------------------------------------------------------------------------
|
53 | GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
|
54 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
55 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
56 | GPIO_InitStructure.GPIO_Pin = Open_I2C_SCL_PIN | Open_I2C_SDA_PIN;
|
57 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
58 | GPIO_Init(GPIOB, &GPIO_InitStructure);
|
59 |
|
60 | //=========================================================================================
|
61 | // Configure I2C Controller
|
62 | //-----------------------------------------------------------------------------------------
|
63 | I2C_InitStructure.I2C_ClockSpeed = I2C_SCL_SPEED;
|
64 | I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
|
65 | I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
|
66 | I2C_InitStructure.I2C_OwnAddress1 = I2C_OWN_ADDR;
|
67 | I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
|
68 | I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
|
69 |
|
70 | //=========================================================================================
|
71 | // Enable I2C
|
72 | //-----------------------------------------------------------------------------------------
|
73 | I2C_Cmd(Open_I2C, ENABLE);
|
74 | I2C_Init(Open_I2C, &I2C_InitStructure);
|
75 |
|
76 | //=========================================================================================
|
77 | // Configure the SPI interrupt priority
|
78 | //-----------------------------------------------------------------------------------------
|
79 | /*
|
80 | NVIC_InitStructure.NVIC_IRQChannel = Open_I2C_IRQn;
|
81 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
|
82 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
83 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
84 | NVIC_Init(&NVIC_InitStructure);
|
85 | */
|
86 | }
|
87 |
|
88 | //===============================================================================
|
89 | // I2C_ReadTransfer - initiate a read transfer on the I2C bus
|
90 | //
|
91 | // Initiates a read transfer on the I2C bus.
|
92 | // If a register address is specified (<addressLength> != 0) a write without a stop
|
93 | // condition will be initiated to the device to write the address, before the
|
94 | // read is initiated.
|
95 | // If no address if required (sequential read) <addressLength> is set to 0.
|
96 | //-------------------------------------------------------------------------------
|
97 | // u08 dev_addr I2C device address
|
98 | // u08 *buffer pointer to the buffer to store the read data.
|
99 | // The buffer must be at least 'cnt' bytes long
|
100 | // int cnt number of bytes to read
|
101 | // u32 ptr register address, if required by the I2C-device
|
102 | // u08 ptrlen length of the register address to be written.
|
103 | // Valid values are 0..4
|
104 | //-------------------------------------------------------------------------------
|
105 | int I2C_ReadTransfer(uint8_t dev_addr, uint8_t *buffer, int cnt, uint32_t ptr, uint8_t ptrlen)
|
106 | {
|
107 | int i, rc = OK;
|
108 | //-----------------------------------------------------------------------------
|
109 | // parameter check
|
110 | //-----------------------------------------------------------------------------
|
111 | if ((buffer == 0) || (ptrlen > 4) || ((cnt | ptrlen) == 0))
|
112 | {
|
113 | return I2C_check_dev(dev_addr); // may be used to check if device is responding
|
114 | }
|
115 | //-----------------------------------------------------------------------------
|
116 | // write the register address pointer to the device
|
117 | //-----------------------------------------------------------------------------
|
118 | if (ptrlen > 0)
|
119 | {
|
120 | rc = I2C_start(Open_I2C, dev_addr, I2C_Direction_Transmitter);
|
121 | if (rc == OK)
|
122 | {
|
123 | for (i=1; i<=ptrlen; i++)
|
124 | {
|
125 | rc |= I2C_write(Open_I2C,((ptr >>(8*(ptrlen-i))) & 0xff));
|
126 | }
|
127 | }
|
128 | }
|
129 | //-----------------------------------------------------------------------------
|
130 | // read data from device
|
131 | //-----------------------------------------------------------------------------
|
132 | if ((cnt > 0) && (rc == OK))
|
133 | {
|
134 | if (ptrlen > 0)
|
135 | {
|
136 | rc |= I2C_restart(Open_I2C, dev_addr, I2C_Direction_Receiver);
|
137 | }
|
138 | else
|
139 | {
|
140 | rc |= I2C_start(Open_I2C, dev_addr, I2C_Direction_Receiver);
|
141 | }
|
142 | if (rc == OK)
|
143 | {
|
144 | while (--cnt>0) // while more than one byte to read
|
145 | {
|
146 | *(buffer++) = I2C_read_ack(Open_I2C); // read next databyte from I2C device
|
147 | }
|
148 | *(buffer) = I2C_read_nack(Open_I2C); // read last databyte from I2C device
|
149 | }
|
150 | }
|
151 | //-----------------------------------------------------------------------------
|
152 | I2C_stop(Open_I2C); // stop the transmission
|
153 | return rc;
|
154 | }
|
155 |
|
156 |
|
157 | //===============================================================================
|
158 | // I2C_WriteTransfer r- initiate a write transfer on the I2C bus
|
159 | //
|
160 | // Initiates a write transfer on the I2C bus.
|
161 | // If a register address is supplied it is inserted between the I2C device address
|
162 | // and the data.
|
163 | //-------------------------------------------------------------------------------
|
164 | // u08 dev_addr I2C device address
|
165 | // u08 *buffer pointer to the buffer to store the read data.
|
166 | // The buffer must be at least 'cnt' bytes long
|
167 | // int cnt number of bytes to read
|
168 | // u32 ptr register address, if required by the I2C-device
|
169 | // u08 ptrlen length of the register address to be written.
|
170 | // Valid values are 0..4
|
171 | //-------------------------------------------------------------------------------
|
172 | int I2C_WriteTransferuint8_t dev_addr, uint8_t *buffer, int cnt, uint32_t ptr, uint8_t ptrlen)
|
173 | {
|
174 | int i, rc=OK;
|
175 | //-----------------------------------------------------------------------------
|
176 | // parameter check
|
177 | //-----------------------------------------------------------------------------
|
178 | if ((buffer == 0) || (ptrlen > 4) || ((cnt | ptrlen) == 0))
|
179 | {
|
180 | return I2C_check_dev(dev_addr); // may be used to check if device is responding
|
181 | }
|
182 | //-----------------------------------------------------------------------------
|
183 | rc = I2C_start(Open_I2C, dev_addr, I2C_Direction_Transmitter);
|
184 | if (rc == OK)
|
185 | {
|
186 | //---------------------------------------------------------------------------
|
187 | // write the register address pointer to the device
|
188 | //---------------------------------------------------------------------------
|
189 | if (ptrlen > 0)
|
190 | {
|
191 | for (i=1; i<=ptrlen; i++)
|
192 | {
|
193 | rc |= I2C_write(Open_I2C,((ptr >>(8*(ptrlen-i))) & 0xff));
|
194 | }
|
195 | }
|
196 | //---------------------------------------------------------------------------
|
197 | // write data to the device
|
198 | //---------------------------------------------------------------------------
|
199 | for (i=0; i<cnt; i++)
|
200 | {
|
201 | rc |= I2C_write(Open_I2C,*(buffer++));
|
202 | }
|
203 | }
|
204 | //-----------------------------------------------------------------------------
|
205 | I2C_stop(Open_I2C); // stop the transmission
|
206 | return rc;
|
207 | }
|
208 |
|
209 |
|
210 | //===============================================================================
|
211 | // Check if a device is responding with acknowledge on the given I2C-Bus address
|
212 | //-------------------------------------------------------------------------------
|
213 | static int I2C_check_dev(uint8_t addr)
|
214 | {
|
215 | int timeout;
|
216 | //-----------------------------------------------------------------------------
|
217 | timeout = I2C_TIMEOUT;
|
218 | while(I2C_GetFlagStatus(Open_I2C, I2C_FLAG_BUSY))
|
219 | {
|
220 | if((timeout--)==0) // wait until I2C-Bus is not busy anymore
|
221 | {
|
222 | return ERROR;
|
223 | }
|
224 | }
|
225 | //-----------------------------------------------------------------------------
|
226 | I2C_GenerateSTART(Open_I2C, ENABLE);
|
227 | timeout = I2C_TIMEOUT;
|
228 | while(!I2C_CheckEvent(Open_I2C, I2C_EVENT_MASTER_MODE_SELECT))
|
229 | {
|
230 | if((timeout--)==0) // wait while sending I2C-Bus START condition
|
231 | {
|
232 | I2C_GenerateSTOP(Open_I2C, ENABLE);
|
233 | return ERROR;
|
234 | }
|
235 | }
|
236 | //-----------------------------------------------------------------------------
|
237 | I2C_Send7bitAddress(Open_I2C, addr, I2C_Direction_Transmitter);
|
238 | timeout = I2C_TIMEOUT;
|
239 | while(!I2C_CheckEvent(Open_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
|
240 | {
|
241 | if((timeout--)==0) // wait while sending slave address for write
|
242 | {
|
243 | I2C_GenerateSTOP(Open_I2C, ENABLE);
|
244 | return ERROR;
|
245 | }
|
246 | }
|
247 | //-----------------------------------------------------------------------------
|
248 | I2C_GenerateSTOP(Open_I2C, ENABLE);
|
249 | return OK;
|
250 | }
|
251 |
|
252 | //------------------------------------------------------------------
|
253 | // This function issues a start condition and
|
254 | // transmits the slave address + R/W bit
|
255 | //
|
256 | // Parameters:
|
257 | // I2Cx --> the I2C peripheral e.g. I2C1
|
258 | // addr --> the 7 bit slave address
|
259 | // rdwr --> the tranmission direction can be:
|
260 | // I2C_Direction_Tranmitter for Master transmitter mode
|
261 | // I2C_Direction_Receiver for Master receiver
|
262 | //------------------------------------------------------------------
|
263 | static int I2C_start(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr)
|
264 | {
|
265 | uint32_t timeout = (100 * I2C_TIMEOUT);
|
266 | // wait until I2C1 is not busy anymore
|
267 | while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))
|
268 | {
|
269 | if((timeout--)==0) return I2C_timeout("I2C_start(): bus busy");
|
270 | }
|
271 | // Send I2C1 RESTART condition
|
272 | return I2C_restart(I2Cx, addr, rdwr);
|
273 | }
|
274 |
|
275 | //------------------------------------------------------------------
|
276 | // This function issues a restart condition and
|
277 | // transmits the slave address + R/W bit
|
278 | //
|
279 | // Parameters:
|
280 | // I2Cx --> the I2C peripheral e.g. I2C1
|
281 | // addr --> the 7 bit slave address
|
282 | // rdwr --> the tranmission direction can be:
|
283 | // I2C_Direction_Tranmitter for Master transmitter mode
|
284 | // I2C_Direction_Receiver for Master receiver
|
285 | //------------------------------------------------------------------
|
286 | static int I2C_restart(I2C_TypeDef* I2Cx, uint8_t addr, uint8_t rdwr)
|
287 | {
|
288 | uint32_t timeout = I2C_TIMEOUT;
|
289 | // Send I2C1 START condition
|
290 | I2C_GenerateSTART(I2Cx, ENABLE);
|
291 | // wait for I2C1 EV5 --> Slave has acknowledged start condition
|
292 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
|
293 | {
|
294 | if((timeout--)==0) return I2C_timeout("I2C_start(): start failed");
|
295 | }
|
296 | // Send slave Address for read or write
|
297 | I2C_Send7bitAddress(I2Cx, addr, rdwr);
|
298 | //------------------------------------------------------------------------
|
299 | // wait for I2C1 EV6, check if Slave has acknowledged Master transmitter
|
300 | // or Master receiver mode, depending on the transmission direction
|
301 | //------------------------------------------------------------------------
|
302 | timeout = I2C_TIMEOUT;
|
303 | if (rdwr==I2C_Direction_Transmitter)
|
304 | {
|
305 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
|
306 | {
|
307 | if((timeout--)==0) return I2C_timeout("I2C_start(): no acknowledge");
|
308 | }
|
309 | }
|
310 | else if(rdwr==I2C_Direction_Receiver)
|
311 | {
|
312 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
|
313 | {
|
314 | if((timeout--)==0) return I2C_timeout("I2C_start(): no acknowledge");
|
315 | }
|
316 | }
|
317 | return 0;
|
318 | }
|
319 |
|
320 | //------------------------------------------------------------------
|
321 | // This function transmits one byte to the slave device
|
322 | // Parameters:
|
323 | // I2Cx --> the I2C peripheral e.g. I2C1
|
324 | // data --> the data byte to be transmitted
|
325 | //------------------------------------------------------------------
|
326 | static int I2C_write(I2C_TypeDef* I2Cx, uint8_t data)
|
327 | {
|
328 | uint32_t timeout = I2C_TIMEOUT;
|
329 | I2C_SendData(I2Cx, data);
|
330 | // wait for I2C1 EV8_2 --> byte has been transmitted
|
331 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
|
332 | {
|
333 | if((timeout--)==0) return I2C_timeout("I2C_write(): write byte failed");
|
334 | }
|
335 | return 0;
|
336 | }
|
337 |
|
338 | //------------------------------------------------------------------
|
339 | // This function reads one byte from the slave device
|
340 | // and acknowledges the byte (requests another byte)
|
341 | //------------------------------------------------------------------
|
342 | static int I2C_read_ack(I2C_TypeDef* I2Cx)
|
343 | {
|
344 | uint32_t timeout = I2C_TIMEOUT;
|
345 | // enable acknowledge of recieved data
|
346 | I2C_AcknowledgeConfig(I2Cx, ENABLE);
|
347 | // wait until one byte has been received
|
348 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))
|
349 | {
|
350 | if((timeout--)==0) return I2C_timeout("I2C_read_ack(): read byte failed");
|
351 | }
|
352 | // read data from I2C data register and return data byte
|
353 | return I2C_ReceiveData(I2Cx);
|
354 | }
|
355 |
|
356 | //------------------------------------------------------------------
|
357 | // This function reads one byte from the slave device
|
358 | // and doesn't acknowledge the recieved data
|
359 | //------------------------------------------------------------------
|
360 | static int I2C_read_nack(I2C_TypeDef* I2Cx)
|
361 | {
|
362 | uint32_t timeout = I2C_TIMEOUT;
|
363 | // disabe acknowledge of received data
|
364 | I2C_AcknowledgeConfig(I2Cx, DISABLE);
|
365 | // wait until one byte has been received
|
366 | while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED))
|
367 | {
|
368 | if((timeout--)==0) return I2C_timeout("I2C_read_nack(): read byte failed");
|
369 | }
|
370 | // read data from I2C data register and return data byte
|
371 | return I2C_ReceiveData(I2Cx);
|
372 | }
|
373 |
|
374 | //------------------------------------------------------------------
|
375 | // This funtion issues a stop condition and therefore
|
376 | // releases the bus
|
377 | //------------------------------------------------------------------
|
378 | static int I2C_stop(I2C_TypeDef* I2Cx)
|
379 | {
|
380 | // Send I2C1 STOP Condition
|
381 | I2C_GenerateSTOP(I2Cx, ENABLE);
|
382 | return 0;
|
383 | }
|
384 |
|
385 | static int I2C_timeout(char *msg)
|
386 | {
|
387 | printf("TIMEOUT: %s\n",msg);
|
388 | return -1;
|
389 | }
|
390 |
|
391 | void I2C1_EV_IRQHandler(void)
|
392 | {
|
393 | u32 event;
|
394 | event = I2C_GetLastEvent(I2C2);
|
395 | printf("I2C1_EV_IRQHandler(): Event=0x%08X\n",event);
|
396 | //---------------------------------------------------
|
397 | // todo, if I2C1 ISR mode shall be used
|
398 | //---------------------------------------------------
|
399 | }
|
400 |
|
401 | void I2C2_EV_IRQHandler(void)
|
402 | {
|
403 | u32 event;
|
404 | event = I2C_GetLastEvent(I2C2);
|
405 | printf("I2C2_EV_IRQHandler(): Event=0x%08X\n",event);
|
406 | //---------------------------------------------------
|
407 | // todo, if I2C2 ISR mode shall be used
|
408 | //---------------------------------------------------
|
409 | }
|