GCC Code Coverage Report


Directory: src/drv/
File: src/drv/i2c/src/i2c_driver.c
Date: 2024-01-25 15:03:18
Exec Total Coverage
Lines: 0 260 0.0%
Branches: 0 174 0.0%

Line Branch Exec Source
1 /********************************************************************************************************//**
2 * @file i2c_driver.c
3 *
4 * @brief File containing the APIs for configuring the I2C peripheral.
5 *
6 * Public Functions:
7 * - void I2C_Init(I2C_Handle_t* pI2C_Handle)
8 * - void I2C_DeInit(I2C_RegDef_t* pI2Cx)
9 * - void I2C_PerClkCtrl(I2C_RegDef_t* pI2Cx, uint8_t en_or_di)
10 * - void I2C_MasterSendData(I2C_Handle_t* pI2C_Handle,
11 * uint8_t* pTxBuffer,
12 * uint32_t len,
13 * uint8_t slave_addr,
14 * sr_t sr)
15 * - void I2C_MasterReceiveData(I2C_Handle_t* pI2C_Handle,
16 * uint8_t* pRxBuffer,
17 * uint8_t len,
18 * uint8_t slave_addr,
19 * sr_t sr)
20 * - uint8_t I2C_MasterSendDataIT(I2C_Handle_t* pI2C_Handle,
21 * uint8_t* pTxBuffer,
22 * uint32_t len,
23 * uint8_t slave_addr,
24 * sr_t sr)
25 * - uint8_t I2C_MasterReceiveDataIT(I2C_Handle_t* pI2C_Handle,
26 * uint8_t* pRxBuffer,
27 * uint8_t len,
28 * uint8_t slave_addr,
29 * sr_t sr)
30 * - void I2C_SlaveSendData(I2C_RegDef_t* pI2Cx, uint8_t data)
31 * - uint8_t I2C_SlaveReceiveData(I2C_RegDef_t* pI2Cx)
32 * - void I2C_EV_IRQHandling(I2C_Handle_t* pI2C_Handle)
33 * - void I2C_ER_IRQHandling(I2C_Handle_t* pI2C_Handle)
34 * - void I2C_Enable(I2C_RegDef_t* pI2Cx, uint8_t en_or_di)
35 * - uint8_t I2C_GetFlagStatus(I2C_RegDef_t* pI2Cx, uint32_t flagname)
36 * - void I2C_GenerateStopCondition(I2C_RegDef_t* pI2Cx)
37 * - void I2C_ManageAcking(I2C_RegDef_t* pI2Cx, uint8_t en_or_di)
38 * - void I2C_SlaveEnCallbackEvents(I2C_RegDef_t* pI2Cx, uint8_t en_or_di)
39 * - void I2C_CloseReceiveData(I2C_Handle_t* pI2C_Handle)
40 * - void I2C_CloseSendData(I2C_Handle_t* pI2C_Handle)
41 * - void I2C_ApplicationEventCallback(I2C_Handle_t* pI2C_Handle, uint8_t app_event)
42 *
43 * @note
44 * For further information about functions refer to the corresponding header file.
45 **/
46
47 #include <stdint.h>
48 #include <stddef.h>
49 #include "stm32f446xx.h"
50 #include "i2c_driver.h"
51 #include "rcc_driver.h"
52
53 /***********************************************************************************************************/
54 /* Static Function Prototypes */
55 /***********************************************************************************************************/
56
57 /**
58 * @brief Function to generate the start condition for transmission.
59 * @param[in] pI2Cx the base address of the I2Cx peripheral.
60 * @return void.
61 */
62 static void I2C_GenerateStartCondition(I2C_RegDef_t* pI2Cx);
63
64 /**
65 * @brief Function to set address of the slave for transmission.
66 * @param[in] pI2Cx the base address of the I2Cx peripheral.
67 * @param[in] slave_addr address of the slave.
68 * @param[in] rw selection to read or write.
69 * @return void.
70 */
71 static void I2C_ExecuteAddressPhase(I2C_RegDef_t* pI2Cx, uint8_t slave_addr, rw_t rw);
72
73 /**
74 * @brief Function to clear address flag.
75 * @param[in] pI2C_Handle handle structure for the I2C peripheral.
76 * @return void.
77 */
78 static void I2C_ClearADDRFlag(I2C_Handle_t* pI2C_Handle);
79
80 /**
81 * @brief Function to manage transmission in handle interrupt.
82 * @param[in] pI2C_Handle handle structure for the I2C peripheral.
83 * @return void.
84 */
85 static void I2C_MasterHandleTXEInterrupt(I2C_Handle_t* pI2C_Handle);
86
87 /**
88 * @brief Function to manage reception in handle interrupt.
89 * @param[in] pI2C_Handle handle structure for the I2C peripheral.
90 * @return void.
91 */
92 static void I2C_MasterHandleRXNEInterrupt(I2C_Handle_t* pI2C_Handle);
93
94 /***********************************************************************************************************/
95 /* Public API Definitions */
96 /***********************************************************************************************************/
97
98 void I2C_Init(I2C_Handle_t* pI2C_Handle){
99
100 uint32_t temp = 0;
101 uint16_t ccr_value = 0;
102
103 /* Enable the peripheral clock */
104 I2C_PerClkCtrl(pI2C_Handle->pI2Cx, ENABLE);
105
106 /* ACK control bit */
107 temp |= (pI2C_Handle->I2C_Config.I2C_ACKControl << I2C_CR1_ACK);
108 pI2C_Handle->pI2Cx->CR1 = temp;
109
110 /* FREQ field of CR2 */
111 temp = 0;
112 temp |= RCC_GetPCLK1Value()/1000000U;
113 pI2C_Handle->pI2Cx->CR2 = temp & 0x3F;
114
115 /* Device own address */
116 temp = 0;
117 temp |= (pI2C_Handle->I2C_Config.I2C_DeviceAddress << 1);
118 temp |= (1 << 14);
119 pI2C_Handle->pI2Cx->OAR1 = temp;
120
121 /* CCR */
122 temp = 0;
123 if(pI2C_Handle->I2C_Config.I2C_SCLSpeed <= I2C_SCL_SPEED_SM){
124 /* standard mode */
125 ccr_value = RCC_GetPCLK1Value()/(2*pI2C_Handle->I2C_Config.I2C_SCLSpeed);
126 temp |= (ccr_value & 0xFFF);
127 }
128 else{
129 /* fast mode */
130 temp |= (1 << I2C_CCR_FS);
131 temp |= (pI2C_Handle->I2C_Config.I2C_FMDutyCycle << I2C_CCR_DUTY);
132 if(pI2C_Handle->I2C_Config.I2C_FMDutyCycle == I2C_FM_DUTY_2){
133 ccr_value = RCC_GetPCLK1Value()/(3*pI2C_Handle->I2C_Config.I2C_SCLSpeed);
134 }
135 else{
136 ccr_value = RCC_GetPCLK1Value()/(25*pI2C_Handle->I2C_Config.I2C_SCLSpeed);
137 }
138 temp |= (ccr_value & 0xFFF);
139 }
140 pI2C_Handle->pI2Cx->CCR = temp;
141
142 /* TRISE configuration */
143 if(pI2C_Handle->I2C_Config.I2C_SCLSpeed <= I2C_SCL_SPEED_SM){
144 /* standard mode */
145 temp = (RCC_GetPCLK1Value()/1000000U) + 1;
146 }
147 else{
148 /* fast mode */
149 temp = ((RCC_GetPCLK1Value()*300)/1000000000U) + 1;
150 }
151 pI2C_Handle->pI2Cx->TRISE = (temp & 0x3F);
152 }
153
154 void I2C_DeInit(I2C_RegDef_t* pI2Cx){
155
156 if(pI2Cx == I2C1){
157 I2C1_REG_RESET();
158 }
159 else if(pI2Cx == I2C2){
160 I2C2_REG_RESET();
161 }
162 else if(pI2Cx == I2C3){
163 I2C3_REG_RESET();
164 }
165 else{
166 /* do nothing */
167 }
168 }
169
170 void I2C_PerClkCtrl(I2C_RegDef_t* pI2Cx, uint8_t en_or_di){
171
172 if(en_or_di == ENABLE){
173 if(pI2Cx == I2C1){
174 I2C1_PCLK_EN();
175 }
176 else if(pI2Cx == I2C2){
177 I2C2_PCLK_EN();
178 }
179 else if(pI2Cx == I2C3){
180 I2C3_PCLK_EN();
181 }
182 else{
183 /* do nothing */
184 }
185 }
186 else{
187 if(pI2Cx == I2C1){
188 I2C1_PCLK_DI();
189 }
190 else if(pI2Cx == I2C2){
191 I2C2_PCLK_DI();
192 }
193 else if(pI2Cx == I2C3){
194 I2C3_PCLK_DI();
195 }
196 else{
197 /* do nothing */
198 }
199 }
200 }
201
202 void I2C_MasterSendData(I2C_Handle_t* pI2C_Handle,
203 uint8_t* pTxBuffer,
204 uint32_t len,
205 uint8_t slave_addr, sr_t sr){
206
207 /* Generate start condition */
208 I2C_GenerateStartCondition(pI2C_Handle->pI2Cx);
209
210 /* Check SB flag in SR1 */
211 /* Note: until SB is cleared SCL will be stretched (pulled to LOW) */
212 while(!I2C_GetFlagStatus(pI2C_Handle->pI2Cx, I2C_FLAG_SB));
213
214 /* Send address of the slave with r/w bit set to w(0) (total 8 bits) */
215 I2C_ExecuteAddressPhase(pI2C_Handle->pI2Cx, slave_addr, WRITE);
216
217 /* Confirm address phase is completed by checking the ADDR flag in SR1 */
218 while(!I2C_GetFlagStatus(pI2C_Handle->pI2Cx, I2C_FLAG_ADDR));
219
220 /* Clear the ADDR flag */
221 /* Note: until ADDR is cleared SCL will be stretched (pulled in LOW) */
222 I2C_ClearADDRFlag(pI2C_Handle);
223
224 /* Send data until len becomes 0 */
225 while(len > 0){
226 while(!I2C_GetFlagStatus(pI2C_Handle->pI2Cx, I2C_FLAG_TXE));
227 pI2C_Handle->pI2Cx->DR = *pTxBuffer;
228 pTxBuffer++;
229 len--;
230 }
231
232 /* Wait for TXE=1 and BTF=1 before generating STOP condition */
233 /* Note: TXE=1, BTF=1, means that both SR and DR are empty and next transmission should begin */
234 /* when BTF=1 SCL will be stretched (pulled to LOW) */
235 while(!I2C_GetFlagStatus(pI2C_Handle->pI2Cx, I2C_FLAG_TXE));
236 while(!I2C_GetFlagStatus(pI2C_Handle->pI2Cx, I2C_FLAG_BTF));
237
238 /* Generate STOP condition */
239 /* Note: generating STOP, automatically clears the BTF */
240 if(sr == I2C_DISABLE_SR){
241 I2C_GenerateStopCondition(pI2C_Handle->pI2Cx);
242 }
243 }
244
245 void I2C_MasterReceiveData(I2C_Handle_t* pI2C_Handle,
246 uint8_t* pRxBuffer,
247 uint8_t len,
248 uint8_t slave_addr,
249 sr_t sr){
250
251 uint32_t i = 0;
252
253 /* Generate start condition */
254 I2C_GenerateStartCondition(pI2C_Handle->pI2Cx);
255
256 /* Check SB flag in SR1 */
257 /* Note: until SB is cleared SCL will be stretched (pulled to LOW) */
258 while(!I2C_GetFlagStatus(pI2C_Handle->pI2Cx, I2C_FLAG_SB));
259
260 /* Send address of the slave with r/w bit set to R(1) (total 8 bits) */
261 I2C_ExecuteAddressPhase(pI2C_Handle->pI2Cx, slave_addr, READ);
262
263 /* Wait until address phase is completed by checking the ADDR flag in SR1 */
264 while(!I2C_GetFlagStatus(pI2C_Handle->pI2Cx, I2C_FLAG_ADDR));
265
266 /* Procedure to read only 1 byte from slave */
267 if(len == 1){
268 /* Disable Acking */
269 I2C_ManageAcking(pI2C_Handle->pI2Cx, I2C_ACK_DISABLE);
270
271 /* Clear ADDR flag */
272 I2C_ClearADDRFlag(pI2C_Handle);
273
274 /* Wait until RXNE=1 */
275 while(!I2C_GetFlagStatus(pI2C_Handle->pI2Cx, I2C_FLAG_RXNE));
276
277 /* Generate stop condition */
278 if(sr == I2C_DISABLE_SR){
279 I2C_GenerateStopCondition(pI2C_Handle->pI2Cx);
280 }
281
282 /* Read data into buffer */
283 *pRxBuffer = pI2C_Handle->pI2Cx->DR;
284 }
285
286 /* Procedure to read data from slave when len > 1 */
287 if(len > 1){
288 /* Clear ADDR flag */
289 I2C_ClearADDRFlag(pI2C_Handle);
290
291 /* Read datas until len becomes zero */
292 for(i = len; i > 0; i--){
293 /* Wait until RXNE becomes 1 */
294 while(!I2C_GetFlagStatus(pI2C_Handle->pI2Cx, I2C_FLAG_RXNE));
295
296 if(i == 2){ /* If last 2 bytes are remaining */
297 /* Disable Acking */
298 I2C_ManageAcking(pI2C_Handle->pI2Cx, I2C_ACK_DISABLE);
299
300 /* Generate stop condition */
301 if(sr == I2C_DISABLE_SR){
302 I2C_GenerateStopCondition(pI2C_Handle->pI2Cx);
303 }
304 }
305 /* Read the data from data register into the buffer */
306 *pRxBuffer = pI2C_Handle->pI2Cx->DR;
307
308 /* Increment the buffer address */
309 pRxBuffer++;
310 }
311 }
312
313 /* Re-enable Acking */
314 if(pI2C_Handle->I2C_Config.I2C_ACKControl == I2C_ACK_ENABLE){
315 I2C_ManageAcking(pI2C_Handle->pI2Cx, I2C_ACK_ENABLE);
316 }
317 }
318
319 uint8_t I2C_MasterSendDataIT(I2C_Handle_t* pI2C_Handle,
320 uint8_t* pTxBuffer,
321 uint32_t len,
322 uint8_t slave_addr,
323 sr_t sr){
324
325 uint8_t busystate = pI2C_Handle->TxRxState;
326
327 if((busystate != I2C_BUSY_IN_TX) && (busystate != I2C_BUSY_IN_RX)){
328 pI2C_Handle->pTxBuffer = pTxBuffer;
329 pI2C_Handle->TxLen = len;
330 pI2C_Handle->TxRxState = I2C_BUSY_IN_TX;
331 pI2C_Handle->DevAddr = slave_addr;
332 pI2C_Handle->Sr = sr;
333
334 /* Generate START condition */
335 I2C_GenerateStartCondition(pI2C_Handle->pI2Cx);
336
337 /* Enable ITBUFEN control bit */
338 pI2C_Handle->pI2Cx->CR2 |= (1 << I2C_CR2_ITBUFEN);
339
340 /* Enable ITEVTEN control bit */
341 pI2C_Handle->pI2Cx->CR2 |= (1 << I2C_CR2_ITEVTEN);
342
343 /* Enable ITERREN control bit */
344 pI2C_Handle->pI2Cx->CR2 |= (1 << I2C_CR2_ITERREN);
345 }
346
347 return busystate;
348 }
349
350 uint8_t I2C_MasterReceiveDataIT(I2C_Handle_t* pI2C_Handle,
351 uint8_t* pRxBuffer,
352 uint8_t len,
353 uint8_t slave_addr,
354 sr_t sr){
355
356 uint8_t busystate = pI2C_Handle->TxRxState;
357
358 if((busystate != I2C_BUSY_IN_TX) && (busystate != I2C_BUSY_IN_RX)){
359 pI2C_Handle->pRxBuffer = pRxBuffer;
360 pI2C_Handle->RxLen = len;
361 pI2C_Handle->TxRxState = I2C_BUSY_IN_RX;
362 pI2C_Handle->RxSize = len;
363 pI2C_Handle->DevAddr = slave_addr;
364 pI2C_Handle->Sr = sr;
365
366 /* Generate START condition */
367 I2C_GenerateStartCondition(pI2C_Handle->pI2Cx);
368
369 /* Enable ITBUFEN control bit */
370 pI2C_Handle->pI2Cx->CR2 |= (1 << I2C_CR2_ITBUFEN);
371
372 /* Enable ITEVTEN control bit */
373 pI2C_Handle->pI2Cx->CR2 |= (1 << I2C_CR2_ITEVTEN);
374
375 /* Enable ITERREN control bit */
376 pI2C_Handle->pI2Cx->CR2 |= (1 << I2C_CR2_ITERREN);
377 }
378
379 return busystate;
380 }
381
382 void I2C_SlaveSendData(I2C_RegDef_t* pI2Cx, uint8_t data){
383
384 pI2Cx->DR = data;
385 }
386
387 uint8_t I2C_SlaveReceiveData(I2C_RegDef_t* pI2Cx){
388
389 return pI2Cx->DR;
390 }
391
392 void I2C_EV_IRQHandling(I2C_Handle_t* pI2C_Handle){
393
394 /* Interrupt handling for both master and slave mode of a device */
395 uint32_t temp1, temp2, temp3;
396
397 temp1 = pI2C_Handle->pI2Cx->CR2 & (1 << I2C_CR2_ITEVTEN);
398 temp2 = pI2C_Handle->pI2Cx->CR2 & (1 << I2C_CR2_ITBUFEN);
399 temp3 = pI2C_Handle->pI2Cx->SR1 & (1 << I2C_SR1_SB);
400
401 /* Handle for interrupt generated by SB event */
402 /* Note: SB flag is only applicable in master mode */
403 if(temp1 && temp3){
404 /* SB flag is set */
405 if(pI2C_Handle->TxRxState == I2C_BUSY_IN_TX){
406 I2C_ExecuteAddressPhase(pI2C_Handle->pI2Cx, pI2C_Handle->DevAddr, WRITE);
407 }
408 else if(pI2C_Handle->TxRxState == I2C_BUSY_IN_RX){
409 I2C_ExecuteAddressPhase(pI2C_Handle->pI2Cx, pI2C_Handle->DevAddr, READ);
410 }
411 else{
412 /* do nothing */
413 }
414 }
415
416 temp3 = pI2C_Handle->pI2Cx->SR1 & (1 << I2C_SR1_ADDR);
417 /* Handle for interrupt generated by ADDR event */
418 /* Note: when master mode address is sent */
419 /* when slave mode address matched with own address */
420 if(temp1 && temp3){
421 /* ADDR flag is set */
422 I2C_ClearADDRFlag(pI2C_Handle);
423 }
424
425 temp3 = pI2C_Handle->pI2Cx->SR1 & (1 << I2C_SR1_BTF);
426 /* Handle for interrupt generated by BTF (Byte Transfer Finished) event */
427 if(temp1 && temp3){
428 /* BTF flag is set */
429 if(pI2C_Handle->TxRxState == I2C_BUSY_IN_TX){
430 /* Make sure that TXE is also set */
431 if(pI2C_Handle->pI2Cx->SR1 & (1 << I2C_SR1_TXE)){
432 /* BTF, TXE = 1 */
433 if(pI2C_Handle->TxLen == 0){
434 /* Generate the STOP condition */
435 if(pI2C_Handle->Sr == I2C_DISABLE_SR)
436 I2C_GenerateStopCondition(pI2C_Handle->pI2Cx);
437
438 /* Reset all the member elements of the handle structure */
439 I2C_CloseSendData(pI2C_Handle);
440
441 /* Notify the application about transmission complete */
442 I2C_ApplicationEventCallback(pI2C_Handle, I2C_EVENT_TX_CMPLT);
443 }
444 }
445 }
446 else if(pI2C_Handle->TxRxState == I2C_BUSY_IN_RX){
447 /* do nothing */
448 }
449 else{
450 /* do nothing */
451 }
452 }
453
454 temp3 = pI2C_Handle->pI2Cx->SR1 & (1 << I2C_SR1_STOPF);
455 /* Handle for interrupt generated by STOPF event */
456 /* Note: stop detection flag is applicable only in slave mode */
457 if(temp1 && temp3){
458 /* STOPF flag is set */
459 /* Clear the STOP: read SR1, write to CR1 */
460 pI2C_Handle->pI2Cx->CR1 |= 0x0000;
461 /* Notify the application that STOP is detected */
462 I2C_ApplicationEventCallback(pI2C_Handle, I2C_EVENT_STOP);
463 }
464
465 temp3 = pI2C_Handle->pI2Cx->SR1 & (1 << I2C_SR1_TXE);
466 /* Handle for interrupt generated by TXE event */
467 if(temp1 && temp2 && temp3){
468 /* Check for device mode */
469 if(pI2C_Handle->pI2Cx->SR2 & (1 << I2C_SR2_MSL)){
470 /* The device is master */
471 /* TXE flag is set */
472 if(pI2C_Handle->TxRxState == I2C_BUSY_IN_TX)
473 I2C_MasterHandleTXEInterrupt(pI2C_Handle);
474 }
475 else{
476 /* The device is slave */
477 /* Check slave is in transmitter mode */
478 if(pI2C_Handle->pI2Cx->SR2 & (1 << I2C_SR2_TRA))
479 I2C_ApplicationEventCallback(pI2C_Handle, I2C_EVENT_DATA_REQ);
480 }
481 }
482
483 temp3 = pI2C_Handle->pI2Cx->SR1 & (1 << I2C_SR1_RXNE);
484 /* Handle for interrupt generated by RXNE event */
485 if(temp1 && temp2 && temp3){
486 /* Check for device mode */
487 if(pI2C_Handle->pI2Cx->SR2 & (1 << I2C_SR2_MSL)){
488 /* The device is master */
489 /* RXNE flag is set */
490 if(pI2C_Handle->TxRxState == I2C_BUSY_IN_RX)
491 I2C_MasterHandleRXNEInterrupt(pI2C_Handle);
492 }
493 else{
494 /* The device is slave */
495 /* Check slave is in receiver mode */
496 if(!(pI2C_Handle->pI2Cx->SR2 & (1 << I2C_SR2_TRA)))
497 I2C_ApplicationEventCallback(pI2C_Handle, I2C_EVENT_DATA_RCV);
498 }
499 }
500 }
501
502 void I2C_ER_IRQHandling(I2C_Handle_t* pI2C_Handle){
503
504 uint32_t temp1, temp2;
505
506 temp2 = (pI2C_Handle->pI2Cx->CR2) & (1 << I2C_CR2_ITERREN);
507
508 /* Check for bus error */
509 temp1 = (pI2C_Handle->pI2Cx->SR1) & (1 << I2C_SR1_BERR);
510 if(temp1 && temp2){
511 /* Clear the bus error flag */
512 pI2C_Handle->pI2Cx->SR1 &= ~(1 << I2C_SR1_BERR);
513
514 /*Notify application about the error */
515 I2C_ApplicationEventCallback(pI2C_Handle, I2C_ERROR_BERR);
516 }
517
518 /* Check for arbitration lost error */
519 temp1 = (pI2C_Handle->pI2Cx->SR1) & (1 << I2C_SR1_ARLO);
520 if(temp1 && temp2){
521 /* Clear arbitration lost error flag */
522 pI2C_Handle->pI2Cx->SR1 &= ~(1 << I2C_SR1_ARLO);
523
524 /* Notify application about the error */
525 I2C_ApplicationEventCallback(pI2C_Handle, I2C_ERROR_ARLO);
526 }
527
528 /* Check for ACK failure */
529 temp1 = (pI2C_Handle->pI2Cx->SR1) & (1 << I2C_SR1_AF);
530 if(temp1 && temp2){
531 /* Clear ACK error flag */
532 pI2C_Handle->pI2Cx->SR1 &= ~(1 << I2C_SR1_AF);
533
534 /* Notify application about the error */
535 I2C_ApplicationEventCallback(pI2C_Handle, I2C_ERROR_AF);
536 }
537
538 /* Check for overrun / underrun error */
539 temp1 = (pI2C_Handle->pI2Cx->SR1) & (1 << I2C_SR1_OVR);
540 if(temp1 && temp2){
541 /* Clear the overrun / underrun error flag */
542 pI2C_Handle->pI2Cx->SR1 &= ~(1 << I2C_SR1_OVR);
543
544 /* Notify application about the error */
545 I2C_ApplicationEventCallback(pI2C_Handle, I2C_ERROR_OVR);
546 }
547
548 /* Check for time out error */
549 temp1 = (pI2C_Handle->pI2Cx->SR1) & (1 << I2C_SR1_TIMEOUT);
550 if(temp1 && temp2){
551 /* Clear the time out error flag */
552 pI2C_Handle->pI2Cx->SR1 &= ~(1 << I2C_SR1_TIMEOUT);
553
554 /* Notify application about the error */
555 I2C_ApplicationEventCallback(pI2C_Handle, I2C_ERROR_TIMEOUT);
556 }
557 }
558
559 void I2C_Enable(I2C_RegDef_t* pI2Cx, uint8_t en_or_di){
560
561 if(en_or_di == ENABLE){
562 pI2Cx->CR1 |= (1 << I2C_CR1_PE);
563 }
564 else{
565 pI2Cx->CR1 &= ~(1 << I2C_CR1_PE);
566 }
567 }
568
569 uint8_t I2C_GetFlagStatus(I2C_RegDef_t* pI2Cx, uint32_t flagname){
570
571 if(pI2Cx->SR1 & flagname){
572 return FLAG_SET;
573 }
574 return FLAG_RESET;
575 }
576
577 void I2C_GenerateStopCondition(I2C_RegDef_t* pI2Cx){
578
579 pI2Cx->CR1 |= (1 << I2C_CR1_STOP);
580 }
581
582 void I2C_ManageAcking(I2C_RegDef_t* pI2Cx, uint8_t en_or_di){
583
584 if(en_or_di == I2C_ACK_ENABLE){
585 /* enable the ack */
586 pI2Cx->CR1 |= (1 << I2C_CR1_ACK);
587 }
588 else{
589 /* disable the ack */
590 pI2Cx->CR1 &= ~(1 << I2C_CR1_ACK);
591 }
592 }
593
594 void I2C_SlaveEnCallbackEvents(I2C_RegDef_t* pI2Cx, uint8_t en_or_di){
595
596 if(en_or_di == ENABLE){
597 pI2Cx->CR2 |= (1 << I2C_CR2_ITEVTEN);
598 pI2Cx->CR2 |= (1 << I2C_CR2_ITBUFEN);
599 pI2Cx->CR2 |= (1 << I2C_CR2_ITERREN);
600 }
601 else{
602 pI2Cx->CR2 &= ~(1 << I2C_CR2_ITEVTEN);
603 pI2Cx->CR2 &= ~(1 << I2C_CR2_ITBUFEN);
604 pI2Cx->CR2 &= ~(1 << I2C_CR2_ITERREN);
605 }
606 }
607
608 void I2C_CloseReceiveData(I2C_Handle_t* pI2C_Handle){
609 /* Disable ITBUFEN control bit */
610 pI2C_Handle->pI2Cx->CR2 &= ~(1 << I2C_CR2_ITBUFEN);
611
612 /* Disable ITEVTEN control bit */
613 pI2C_Handle->pI2Cx->CR2 &= ~(1 << I2C_CR2_ITEVTEN);
614
615 pI2C_Handle->TxRxState = I2C_READY;
616 pI2C_Handle->pRxBuffer = NULL;
617 pI2C_Handle->RxLen = 0;
618 pI2C_Handle->RxSize = 0;
619
620 if(pI2C_Handle->I2C_Config.I2C_ACKControl == I2C_ACK_ENABLE){
621 I2C_ManageAcking(pI2C_Handle->pI2Cx, ENABLE);
622 }
623 }
624
625 void I2C_CloseSendData(I2C_Handle_t* pI2C_Handle){
626 /* Disable ITBUFEN control bit */
627 pI2C_Handle->pI2Cx->CR2 &= ~(1 << I2C_CR2_ITBUFEN);
628
629 /* Disable ITEVTEN control bit */
630 pI2C_Handle->pI2Cx->CR2 &= ~(1 << I2C_CR2_ITEVTEN);
631
632 pI2C_Handle->TxRxState = I2C_READY;
633 pI2C_Handle->pTxBuffer = NULL;
634 pI2C_Handle->TxLen = 0;
635 }
636
637 __attribute__((weak)) void I2C_ApplicationEventCallback(I2C_Handle_t* pI2C_Handle, uint8_t app_event){
638
639 /* This is a weak implementation. The application may override this function */
640 (void)pI2C_Handle;
641 (void)app_event;
642 }
643
644 /***********************************************************************************************************/
645 /* Static Function Definitions */
646 /***********************************************************************************************************/
647
648 static void I2C_GenerateStartCondition(I2C_RegDef_t* pI2Cx){
649
650 pI2Cx->CR1 |= (1 << I2C_CR1_START);
651 }
652
653 static void I2C_ExecuteAddressPhase(I2C_RegDef_t* pI2Cx, uint8_t slave_addr, rw_t rw){
654
655 slave_addr = slave_addr << 1;
656 if(rw == WRITE){
657 slave_addr &= ~(1); /* slave_addr is slave address + r/w bit = 0 */
658 }
659 else if(rw == READ){
660 slave_addr |= 1; /* slave_addr is slave address + r/w bit = 1 */
661 }
662 else{
663 /* do nothing */
664 }
665 pI2Cx->DR = slave_addr;
666 }
667
668 static void I2C_ClearADDRFlag(I2C_Handle_t* pI2C_Handle){
669
670 uint32_t dummy_read;
671
672 /* Check for device mode */
673 if(pI2C_Handle->pI2Cx->SR2 & (1 << I2C_SR2_MSL)){
674 /* Master mode */
675 if(pI2C_Handle->TxRxState == I2C_BUSY_IN_RX){
676 if(pI2C_Handle->RxSize == 1){
677 /* Disable ACK */
678 I2C_ManageAcking(pI2C_Handle->pI2Cx, DISABLE);
679
680 /* Clear ADDR flag (read SR1, read SR2 */
681 dummy_read = pI2C_Handle->pI2Cx->SR1;
682 dummy_read = pI2C_Handle->pI2Cx->SR2;
683 (void)dummy_read;
684 }
685 }
686 else{
687 /* Clear ADDR flag (read SR1, read SR2 */
688 dummy_read = pI2C_Handle->pI2Cx->SR1;
689 dummy_read = pI2C_Handle->pI2Cx->SR2;
690 (void)dummy_read;
691 }
692 }
693 else{
694 /* Slave mode */
695 /* Clear ADDR flag (read SR1, read SR2 */
696 dummy_read = pI2C_Handle->pI2Cx->SR1;
697 dummy_read = pI2C_Handle->pI2Cx->SR2;
698 (void)dummy_read;
699 }
700 }
701
702 static void I2C_MasterHandleTXEInterrupt(I2C_Handle_t* pI2C_Handle){
703
704 if(pI2C_Handle->TxLen > 0){
705 /* Load the data into DR */
706 pI2C_Handle->pI2Cx->DR = *(pI2C_Handle->pTxBuffer);
707
708 /* Decrement the TxLen */
709 pI2C_Handle->TxLen--;
710
711 /* Increment the buffer address */
712 pI2C_Handle->pTxBuffer++;
713 }
714 }
715
716 static void I2C_MasterHandleRXNEInterrupt(I2C_Handle_t* pI2C_Handle){
717
718 if(pI2C_Handle->RxSize == 1){
719 *pI2C_Handle->pRxBuffer = pI2C_Handle->pI2Cx->DR;
720 pI2C_Handle->RxLen--;
721 }
722
723 if(pI2C_Handle->RxSize > 1){
724 if(pI2C_Handle->RxLen == 2){
725 /* Clear ACK */
726 I2C_ManageAcking(pI2C_Handle->pI2Cx, DISABLE);
727 }
728 /* Read DR */
729 *pI2C_Handle->pRxBuffer = pI2C_Handle->pI2Cx->DR;
730 pI2C_Handle->pRxBuffer++;
731 pI2C_Handle->RxLen--;
732 }
733
734 if(pI2C_Handle->RxLen == 0){
735 /* Close I2C data reception and notify the application */
736 /* Generate the STOP condition */
737 if(pI2C_Handle->Sr == I2C_DISABLE_SR)
738 I2C_GenerateStopCondition(pI2C_Handle->pI2Cx);
739
740 /* Close the I2C RX */
741 I2C_CloseReceiveData(pI2C_Handle);
742
743 /* Notify the application */
744 I2C_ApplicationEventCallback(pI2C_Handle, I2C_EVENT_RX_CMPLT);
745 }
746 }
747