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