Home | Projects | Notes > MCU Peripheral Drivers > I2C Driver (stm32f407xx_i2c_driver.h/.c
)
stm32f407xx_i2c_driver.h/.c
)
I2C initialization
Configure the mode (e.g., standard, fast, ...)
Configure the serial clock (SCL) speed (e.g., 25 KHz, 50 KHz, 100 KHz, 200 KHz, 400 KHz, ...)
When using higher frequency, the length of the communication wire must be short.
In STM32F4x I2C peripheral, CR2 and CCR registers are used to control the I2C serial clock settings and other I2C timings like setup time and hold time.
Configure the device address (Applicable only when the device is slave.)
Enable ACKing (For STM32F407xx MCUs, ACKing is disabled by default.)
Configure the rise time (the time it takes for the signal to reach the VCC level from the GND level) for I2C pins (Also called as "slew rate")
All of the above configuration must be done while the I2C peripheral is in DISABLED state. (Check the control register!)
I2C master Tx
Since in I2C, only master can initiate the communication, master Tx/Rx and slave Tx/Rx must be separated.
I2C master Rx
I2C slave Tx
I2C slave Rx
I2C error interrupt handling
I2C event interrupt handling
I2C_SCLSpeed
I2C_DeviceAddress
I2C_ACKControl
I2C automatic ACKing is disabled by default. This item will provide the user the ability to enable/disable ACKing.
I2C_FMDutyCycle
This structure will give the user the ability to configure the duty cycle of the clock when the I2C peripheral is in "fast mode".
Create stm32f407xx_i2c_driver.c
and stm32f407xx_i2c_driver.h
Add I2Cx related details to MCU specific header file
I2C peripheral register definition structure
I2Cx base address macros
I2Cx peripheral definition macros
Macros to enable and disable I2Cx peripheral clock
Bit position definitions of I2C peripheral
stm32f407xx_i2c_driver.h
Path: Project/Drivers/Inc/
xxxxxxxxxx
1401/*******************************************************************************
2 * File : stm32f407xx_i2c_driver.h
3 * Brief : STM32F407xx MCU specific I2C driver header file
4 * Author ; Kyungjae Lee
5 * Date : Jun 09, 2023
6 *
7 * Note : This code includes only the features that are necessary for my
8 * personal projects.
9 * ****************************************************************************/
10
11
12
13
14
15
16/*******************************************************************************
17 * I2Cx peripheral structures
18 ******************************************************************************/
19
20/* I2Cx peripheral configuration structure */
21typedef struct
22{
23 uint32_t I2C_SCLSpeed; /* Available values @I2C_SCLSpeed */
24 uint8_t I2C_DeviceAddress; /* Value will be entered by user */
25 uint8_t I2C_ACKEnable; /* Available values @I2C_ACKEnable */
26 uint8_t I2C_FMDutyCycle; /* Available values @I2C_FMDutyCycle */
27} I2C_Config_TypeDef;
28
29/* I2Cx peripheral handle structure */
30typedef struct
31{
32 I2C_TypeDef *pI2Cx; /* Base address of I2Cx(x:1,2,3) peripheral */
33 I2C_Config_TypeDef I2C_Config;
34 uint8_t *pTxBuffer; /* Application Tx buffer address */
35 uint8_t *pRxBuffer; /* Application Rx buffer address */
36 uint32_t TxLen; /* Number of bytes left to transmit */
37 uint32_t RxLen; /* Number of bytes left to receive */
38 uint8_t TxRxState; /* Available values @I2C_TxRxState */
39 uint8_t DevAddr; /* Slave/device address */
40 uint32_t RxSize; /* Total size of data to receive */
41 uint8_t RepeatedStart; /* Repeated start enable/disable */
42} I2C_Handle_TypeDef;
43
44/**
45 * @I2C_SCLSpeed
46 * Note: Any clock frequency greater than 100 KHz is considered "fast mode".
47 */
48/* 100 KHz */
49/* 200 KHz */
50/* 400 KHz */
51
52/**
53 * @I2C_ACKEnable
54 * Note: ACKing is disabled by default.
55 */
56
57
58
59/**
60 * @I2C_FMDutyCycle (Fm mode duty cycle)
61 */
62
63
64
65/**
66 * I2C_TxRxState (I2C application communication state)
67 * Note: Unlike the SPI communication, I2C communication is half-duplex.
68 * Therefore, only one communication state variable is necessary.
69 */
70
71
72
73
74/**
75 * I2C application event macros
76 */
77
78
79
80
81
82
83
84
85
86
87
88
89/*******************************************************************************
90 * APIs supported by the I2C driver
91 * (See function definitions for more information)
92 ******************************************************************************/
93
94/* Peripheral clock setup */
95void I2C_PeriClockControl(I2C_TypeDef *pI2Cx, uint8_t state);
96
97/**
98 * Init and De-init
99 */
100void I2C_Init(I2C_Handle_TypeDef *pI2CHandle);
101void I2C_DeInit(I2C_TypeDef *pI2Cx); /* Utilize RCC_AHBxRSTR (AHBx peripheral reset register) */
102
103/**
104 * Data send and receive
105 */
106void I2C_MasterTxBlocking(I2C_Handle_TypeDef *pI2CHandle, uint8_t *pTxBuffer, uint8_t len, uint8_t slaveAddr, uint8_t repeatedStartState);
107void I2C_MasterRxBlocking(I2C_Handle_TypeDef *pI2CHandle, uint8_t *pRxBuffer, uint8_t len, uint8_t slaveAddr, uint8_t repeatedStartState);
108uint8_t I2C_MasterTxInterrupt(I2C_Handle_TypeDef *pI2CHandle, uint8_t *pTxBuffer, uint8_t len, uint8_t slaveAddr, uint8_t repeatedStartState);
109uint8_t I2C_MasterRxInterrupt(I2C_Handle_TypeDef *pI2CHandle, uint8_t *pRxBuffer, uint8_t len, uint8_t slaveAddr, uint8_t repeatedStartState);
110void I2C_CloseTx(I2C_Handle_TypeDef *pI2CHandle);
111void I2C_CloseRx(I2C_Handle_TypeDef *pI2CHandle);
112void I2C_SlaveTx(I2C_TypeDef *pI2Cx, uint8_t data);
113uint8_t I2C_SlaveRx(I2C_TypeDef *pI2Cx);
114
115/**
116 * IRQ configuration and ISR handling
117 */
118void I2C_IRQInterruptConfig(uint8_t irqNumber, uint8_t state);
119void I2C_IRQPriorityConfig(uint8_t irqNumber, uint32_t irqPriority);
120void I2C_EV_IRQHandling(I2C_Handle_TypeDef *pI2CHandle);
121void I2C_ER_IRQHandling(I2C_Handle_TypeDef *pI2CHandle);
122
123/**
124 * Other peripheral control APIs
125 */
126void I2C_PeriControl(I2C_TypeDef *pI2Cx, uint8_t state);
127void I2C_ManageACK(I2C_TypeDef *pI2Cx, uint8_t state);
128void I2C_GenerateSTARTCondition(I2C_TypeDef *pI2Cx);
129void I2C_GenerateSTOPCondition(I2C_TypeDef *pI2Cx);
130void I2C_SlaveEnableDisableCallbackEvents(I2C_TypeDef *pI2Cx, uint8_t state);
131
132/**
133 * Application callback functions (Must be implemented by application)
134 * Note: Since the driver does not know in which application this function will
135 * be implemented, it is good idea to give a weak function definition.
136 */
137void I2C_ApplicationEventCallback(I2C_Handle_TypeDef *pI2CHandle, uint8_t appEvent);
138
139
140/* STM32F407XX_I2C_DRIVER_H */
stm32f407xx_i2c_driver.c
Path: Project/Drivers/Src/
xxxxxxxxxx
11001/*******************************************************************************
2 * File : stm32f407xx_i2c_driver.c
3 * Brief : STM32F407xx MCU specific I2C driver source file
4 * Author ; Kyungjae Lee
5 * Date : Jun 09, 2023
6 *
7 * Note : This code includes only the features that are necessary for my
8 * personal projects.
9 * ****************************************************************************/
10
11
12
13/* Declaration of I2C peripheral driver private functions */
14static void I2C_ExecuteAddressPhaseRead(I2C_TypeDef *pI2Cx, uint8_t slaveAddr);
15static void I2C_ExecuteAddressPhaseWrite(I2C_TypeDef *pI2Cx, uint8_t slaveAddr);
16static void I2C_ClearADDRFlag(I2C_Handle_TypeDef *pI2CHandle);
17
18
19/*******************************************************************************
20 * APIs supported by the I2C driver
21 * (See function definitions for more information)
22 ******************************************************************************/
23
24/**
25 * I2C_PeriControl()
26 * Brief : Enables or disables I2C peripheral
27 * Param : @pI2Cx - base address of I2Cx peripheral
28 * @state - ENABLE or DISABLE macro
29 * Retval : None
30 * Note : N/A
31 */
32void I2C_PeriControl(I2C_TypeDef *pI2Cx, uint8_t state)
33{
34 if (state == ENABLE)
35 {
36 pI2Cx->CR1 |= (1 << I2C_CR1_PE);
37 }
38 else
39 {
40 pI2Cx->CR1 &= ~(1 << I2C_CR1_PE);
41 }
42} /* End of I2C_PeriControl */
43
44/**
45 * I2C_PeriClockControl()
46 * Brief : Enable or disable clock for I2C peripheral
47 * Param : @pI2Cx - base address of I2Cx peripheral
48 * Retval : None
49 * Note : N/A
50 */
51void I2C_PeriClockControl(I2C_TypeDef *pI2Cx, uint8_t state)
52{
53 if (state == ENABLE)
54 {
55 if (pI2Cx == I2C1)
56 I2C1_PCLK_EN();
57 else if (pI2Cx == I2C2)
58 I2C2_PCLK_EN();
59 else if (pI2Cx == I2C3)
60 I2C3_PCLK_EN();
61 }
62 else
63 {
64 if (pI2Cx == I2C1)
65 I2C1_PCLK_DI();
66 else if (pI2Cx == I2C2)
67 I2C2_PCLK_DI();
68 else if (pI2Cx == I2C3)
69 I2C3_PCLK_DI();
70 }
71} /* End of I2C_PeriClockControl */
72
73/**
74 * I2C_Init()
75 * Brief : Initializes passed I2C peripheral
76 * Param : @pI2CHandle - pointer to I2C peripheral handle
77 * Retval : None
78 * Note : N/A
79 */
80void I2C_Init(I2C_Handle_TypeDef *pI2CHandle)
81{
82 uint32_t temp = 0;
83
84 /* Enable I2C1 peripheral clock */
85 I2C_PeriClockControl(pI2CHandle->pI2Cx, ENABLE);
86
87 /* Configure I2C_CR1 (Enable ACK) */
88 //temp |= pI2CHandle->I2C_Config.I2C_ACKEnable << I2C_CR1_ACK;
89 //pI2CHandle->pI2Cx->CR1 = temp;
90 // Commented out since ACK bit cannot be set when PE=0. This will be done
91 // in the application.
92 // (Consider moving this logic into 'I2C_PeriControl()' function. )
93
94 /* Configure I2C_CR2 (FREQ[5:0])
95 * The FREQ bits must be configured with the APB clock frequency value (I2C
96 * peripheral connected to APB). The FREQ field is used by the peripheral
97 * to generate data setup and hold times compliant with the I2C
98 * specifications. The minimum allowed frequency is 2 MHz, the maximum
99 * frequency is limited by the maximum APB frequency and cannot exceed
100 * 50 MHz (peripheral intrinsic maximum limit).
101 *
102 * 0b000000: Not allowed
103 * 0b000001: Not allowed
104 * 0b000010: 2 MHz
105 * ...
106 * 0b110010: 50 MHz
107 * Higher than 0b101010: Not allowed
108 */
109 temp = 0;
110 temp |= RCC_GetPCLK1Value() / 1000000; /* e.g., 16 MHz -> 16 */
111 pI2CHandle->pI2Cx->CR2 |= (temp & 0x3F); /* Masking for safety purpose */
112
113 /* Configure OAR1 (Device own address) */
114 temp = 0;
115 temp |= pI2CHandle->I2C_Config.I2C_DeviceAddress << I2C_OAR1_ADD71;
116 /* bit[0] of OAR1 is used only when the own address is of 10-bit long
117 * instead of 7-bit. big[15] of OAR1 determines the length of the
118 * address (7 or 10). 7-bit length by default.
119 */
120 temp |= (0x1 << 14);
121 /* bit[14] should always be kept at 1 by software (Reference manual) */
122 pI2CHandle->pI2Cx->OAR1 |= temp;
123
124 /* Configure CCR (Calaulate CCR) */
125 uint16_t ccrVal = 0;
126 temp = 0;
127
128 if (pI2CHandle->I2C_Config.I2C_SCLSpeed <= I2C_SCL_SPEED_SM)
129 {
130 /* Standard mode (I2C_CCR bit[15] == 0) */
131 ccrVal = RCC_GetPCLK1Value() / (2 * pI2CHandle->I2C_Config.I2C_SCLSpeed);
132 temp |= (ccrVal & 0xFFF); /* 12-bit value */
133 }
134 else
135 {
136 /* Fast mode (I2C_CCR bit[15] == 1) */
137 temp |= (0x1 << I2C_CCR_FS);
138 temp |= (pI2CHandle->I2C_Config.I2C_FMDutyCycle << I2C_CCR_DUTY);
139
140 if (pI2CHandle->I2C_Config.I2C_FMDutyCycle == I2C_FM_DUTY_2)
141 {
142 ccrVal = RCC_GetPCLK1Value() / (3 * pI2CHandle->I2C_Config.I2C_SCLSpeed);
143 }
144 else
145 {
146 ccrVal = RCC_GetPCLK1Value() / (25 * pI2CHandle->I2C_Config.I2C_SCLSpeed);
147 }
148
149 temp |= (ccrVal & 0xFFF); /* 12-bit value */
150 }
151
152 pI2CHandle->pI2Cx->CCR |= temp;
153
154 /* TRISE configuration */
155 if (pI2CHandle->I2C_Config.I2C_SCLSpeed <= I2C_SCL_SPEED_SM)
156 {
157 /* Standard mode */
158 temp = (RCC_GetPCLK1Value() / 1000000U) + 1;
159 }
160 else
161 {
162 /* Fast mode */
163 temp = ((RCC_GetPCLK1Value() * 300U) / 1000000000U) + 1;
164 }
165
166 pI2CHandle->pI2Cx->TRISE = (temp & 0x3F);
167} /* End of I2C_Init */
168
169/**
170 * I2C_DeInit()
171 * Brief : Deinitializes passed I2C peripheral
172 * Param : @pI2Cx - base address of I2Cx peripheral
173 * Retval : None
174 * Note : N/A
175 */
176void I2C_DeInit(I2C_TypeDef *pI2Cx)
177{
178 /* Do nothing */
179} /* End of I2C_DeInit */
180
181/**
182 * I2C_MasterTxBlocking()
183 * Brief : Handles blocking-based I2C transmission
184 * Param : @pI2CHandle - pointer to I2C peripheral handle
185 * @pTxBuffer - address of the Tx buffer
186 * @len - length of the data to transmit
187 * @slaveAddr - slave address
188 * @repeatedStartState - I2C_REPEATED_START_EN or DI
189 * Retval : None
190 * Note : N/A
191 */
192void I2C_MasterTxBlocking(I2C_Handle_TypeDef *pI2CHandle, uint8_t *pTxBuffer, uint8_t len, uint8_t slaveAddr, uint8_t repeatedStartState)
193{
194 /* 1. Generate the START condition */
195 I2C_GenerateSTARTCondition(pI2CHandle->pI2Cx); /* Helper function private to driver */
196
197 /* 2. Confirm that START generation is completed by checking the SB flag in
198 * the SR1
199 * Note: Until SB (Start Bit) gets cleared, SCL will be stretched
200 * (pulled to LOW)
201 * According to the reference manual, SB bit can be cleared by
202 * reading the SR1 register followed by writing the DR register,
203 * or by hardware when PE = 0.
204 */
205 while ( !(pI2CHandle->pI2Cx->SR1 & (0x01 << I2C_SR1_SB)) );
206 /* Reading SR1 register is done here. Writing the DR register will
207 * be done in Step 3.
208 */
209
210 /* 3. Send the address of the slave with r/w bit set to w(0) (total 8 bits)
211 */
212 I2C_ExecuteAddressPhaseWrite(pI2CHandle->pI2Cx, slaveAddr);
213
214 /* 4. Wait until the address phase is completed by checking the ADDR flag
215 * of SR1
216 */
217 while ( !(pI2CHandle->pI2Cx->SR1 & (0x01 << I2C_SR1_ADDR)) );
218
219 /* 5. Clear the ADDR flag according to its software sequence (ADDR bit is
220 * cleared by software reading SR1 register followed by reading SR2, or
221 * by hardware when PE = 0.)
222 * Note: Until ADDR is cleared SCL will be stretched (pulled to LOW)
223 */
224 I2C_ClearADDRFlag(pI2CHandle);
225
226 /* 6. Send the data until @len becomes 0 */
227 while (len > 0)
228 {
229 /* Wait until the TxE is set */
230 while ( !(pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_TxE)) );
231
232 /* Copy @pTxBuffer contents to DR */
233 pI2CHandle->pI2Cx->DR = *pTxBuffer;
234 pTxBuffer++;
235 len--;
236 }
237
238 /* 7. When @len becomes zero wait for TXE=1 and BTF=1 before generating the
239 * STOP condition.
240 * Note: TXE=1, BTF=1, means that both SR and DR are empty and next
241 * transmission should begin when BTF=1 SCL will be stretched
242 * (pulled to LOW)
243 */
244 while ( !(pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_TxE)) );
245
246 while ( !(pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_BTF)) );
247
248
249 /* 8. Generate STOP condition and master does not need to wait for the
250 * completion of stop condition.
251 * Note: generating STOP, automatically clears the BTF.
252 */
253 if (repeatedStartState == I2C_REPEATED_START_DI)
254 {
255 I2C_GenerateSTOPCondition(pI2CHandle->pI2Cx);
256 }
257} /* End of I2C_MasterTxBlocking */
258
259/**
260 * I2C_MasterRxBlocking()
261 * Brief : Handles blocking-based I2C reception
262 * Param : @pI2CHandle - pointer to I2C peripheral handle
263 * @pTxBuffer - address of the Tx buffer
264 * @len - length of the data to transmit
265 * @slaveAddr - slave address
266 * @repeatedStartState - I2C_REPEATED_START_EN or DI
267 * Retval : None
268 * Note : N/A
269 */
270void I2C_MasterRxBlocking(I2C_Handle_TypeDef *pI2CHandle, uint8_t *pRxBuffer, uint8_t len, uint8_t slaveAddr, uint8_t repeatedStartState)
271{
272 /* 1. Generate the START condition */
273 I2C_GenerateSTARTCondition(pI2CHandle->pI2Cx); /* Helper function private to driver */
274
275 /* 2. Confirm that START generation is completed by checking the SB flag in
276 * the SR1
277 * Note: Until SB (Start Bit) gets cleared, SCL will be stretched
278 * (pulled to LOW)
279 * According to the reference manual, SB bit can be cleared by
280 * reading the SR1 register followed by writing the DR register,
281 * or by hardware when PE = 0.
282 */
283 while ( !(pI2CHandle->pI2Cx->SR1 & (0x01 << I2C_SR1_SB)) );
284 /* Reading SR1 register is done here. Writing the DR register will
285 * be done in Step 3.
286 */
287 /* 3. Send the address of the slave with r/w bit set to R(1) (total 8 bits)
288 */
289 I2C_ExecuteAddressPhaseRead(pI2CHandle->pI2Cx, slaveAddr);
290
291 /* 4. Wait until the address phase is completed by checking the ADDR flag
292 * of SR1
293 */
294 while ( !(pI2CHandle->pI2Cx->SR1 & (0x01 << I2C_SR1_ADDR)) );
295
296 /**
297 * 5. Read data from the slave
298 */
299
300 /* 5.1. Read the last byte */
301 if (len == 1)
302 {
303 /* Disable ACK */
304 I2C_ManageACK(pI2CHandle->pI2Cx, I2C_ACK_DISABLE);
305
306 /* Clear the ADDR flag */
307 I2C_ClearADDRFlag(pI2CHandle);
308
309 /* Wait until the RxNE flag is set */
310 while ( !(pI2CHandle->pI2Cx->SR1 & (0x01 << I2C_SR1_RxNE)) );
311
312 /* Generate STOP condition */
313 if (repeatedStartState == I2C_REPEATED_START_DI)
314 {
315 I2C_GenerateSTOPCondition(pI2CHandle->pI2Cx);
316 }
317
318 /* Read data into the Rx buffer */
319 *pRxBuffer = pI2CHandle->pI2Cx->DR;
320 }
321
322 /* 5.2. Read non-last byte */
323 if (len > 1)
324 {
325 /* Clear the ADDR flag */
326 I2C_ClearADDRFlag(pI2CHandle);
327 /* Now, the data reception begins! */
328
329 /* Read the data until @len becomes zero */
330 for (uint32_t i = len; i > 0; i--)
331 {
332 /* Wait until RxNE flag is set */
333 while ( !(pI2CHandle->pI2Cx->SR1 & (0x01 << I2C_SR1_RxNE)) );
334
335 /* Read the second to last byte */
336 if (i == 2)
337 {
338 /* Disable ACK */
339 I2C_ManageACK(pI2CHandle->pI2Cx, I2C_ACK_DISABLE);
340
341 /* Generate STOP condition */
342 if (repeatedStartState == I2C_REPEATED_START_DI)
343 {
344 I2C_GenerateSTOPCondition(pI2CHandle->pI2Cx);
345 }
346 }
347
348 /* Read the data from the DR into Rx buffer */
349 *pRxBuffer = pI2CHandle->pI2Cx->DR;
350
351 /* Increment the buffer address */
352 pRxBuffer++;
353 }
354
355 }
356
357 /* Enable ACK (Before entering this function, ACK was enabled.
358 * Make sure to re-enable ACK to restore the previous condition.) */
359 if (pI2CHandle->I2C_Config.I2C_ACKEnable == I2C_ACK_ENABLE)
360 I2C_ManageACK(pI2CHandle->pI2Cx, I2C_ACK_ENABLE);
361} /* End of I2C_MasterRxBlocking */
362
363/**
364 * I2C_MasterTxInterrupt()
365 * Brief : Handles interrupt-based I2C transmission
366 * Param : @pI2CHandle - pointer to I2C peripheral handle
367 * @pTxBuffer - address of the Tx buffer
368 * @len - length of the data to transmit
369 * @slaveAddr - slave address
370 * @repeatedStartState - I2C_REPEATED_START_EN or DI
371 * Retval : None
372 * Note : N/A
373 */
374uint8_t I2C_MasterTxInterrupt(I2C_Handle_TypeDef *pI2CHandle, uint8_t *pTxBuffer, uint8_t len, uint8_t slaveAddr, uint8_t repeatedStartState)
375{
376 uint8_t busyState = pI2CHandle->TxRxState;
377
378 if ((busyState != I2C_BUSY_IN_TX) && (busyState != I2C_BUSY_IN_RX))
379 {
380 pI2CHandle->pTxBuffer = pTxBuffer;
381 pI2CHandle->TxLen = len;
382 pI2CHandle->TxRxState= I2C_BUSY_IN_TX;
383 pI2CHandle->DevAddr = slaveAddr;
384 pI2CHandle->RepeatedStart = repeatedStartState;
385
386 /* Generate START condition */
387 I2C_GenerateSTARTCondition(pI2CHandle->pI2Cx);
388 /* If successful, SB bit will bet set here */
389
390 /**
391 * Enable all available interrupts by setting the control bits
392 */
393 /* Enable ITBUFEN control bit */
394 pI2CHandle->pI2Cx->CR2 |= (0x1 << I2C_CR2_ITBUFEN);
395 /* Enable ITEVTEN control bit */
396 pI2CHandle->pI2Cx->CR2 |= (0x1 << I2C_CR2_ITEVTEN);
397 /* Enable ITERREN control bit */
398 pI2CHandle->pI2Cx->CR2 |= (0x1 << I2C_CR2_ITERREN);
399 }
400
401 return busyState;
402} /* End of I2C_MasterTxInterrupt */
403
404/**
405 * I2C_MasterRxInterrupt()
406 * Brief : Handles interrupt-based I2C reception
407 * Param : @pI2CHandle - pointer to I2C peripheral handle
408 * @pTxBuffer - address of the Tx buffer
409 * @len - length of the data to transmit
410 * @slaveAddr - slave address
411 * @repeatedStartState - I2C_REPEATED_START_EN or DI
412 * Retval : None
413 * Note : N/A
414 */
415uint8_t I2C_MasterRxInterrupt(I2C_Handle_TypeDef *pI2CHandle, uint8_t *pRxBuffer, uint8_t len, uint8_t slaveAddr, uint8_t repeatedStartState)
416{
417 uint8_t busyState = pI2CHandle->TxRxState;
418
419 if ((busyState != I2C_BUSY_IN_TX) && (busyState != I2C_BUSY_IN_RX))
420 {
421 pI2CHandle->pRxBuffer = pRxBuffer;
422 pI2CHandle->RxLen = len;
423 pI2CHandle->TxRxState= I2C_BUSY_IN_RX;
424 pI2CHandle->RxSize = len;
425 pI2CHandle->DevAddr = slaveAddr;
426 pI2CHandle->RepeatedStart = repeatedStartState;
427
428 /* Generate START condition */
429 I2C_GenerateSTARTCondition(pI2CHandle->pI2Cx);
430 /* If successful, SB bit will bet set here */
431
432 /**
433 * Enable all available interrupts by setting the control bits
434 */
435 /* Enable ITBUFEN control bit */
436 pI2CHandle->pI2Cx->CR2 |= (1 << I2C_CR2_ITBUFEN);
437 /* Enable ITEVTEN control bit */
438 pI2CHandle->pI2Cx->CR2 |= (1 << I2C_CR2_ITEVTEN);
439 /* Enable ITERREN control bit */
440 pI2CHandle->pI2Cx->CR2 |= (1 << I2C_CR2_ITERREN);
441
442 }
443
444 return busyState;
445} /* End of I2C_MasterRxInterrupt */
446
447/**
448 * I2C_SlaveTx()
449 * Brief : Handles transmission of a byte of data upon master's read event
450 * Param : @pI2Cx - base address of I2Cx peripheral
451 * @data - a byte of data to send
452 * Retval : None
453 * Note : N/A
454 */
455void I2C_SlaveTx(I2C_TypeDef *pI2Cx, uint8_t data)
456{
457 pI2Cx->DR = data;
458} /* End of I2C_SlaveTx */
459
460/**
461 * I2C_SlaveRx()
462 * Brief : Handles reception of a byte of data upon master's write event
463 * Param : @pI2Cx - base address of I2Cx peripheral
464 * @state - ENABLE or DISABLE macro
465 * Retval : Received byte of data
466 * Note : N/A
467 */
468uint8_t I2C_SlaveRx(I2C_TypeDef *pI2Cx)
469{
470 return (uint8_t)pI2Cx->DR;
471} /* End of I2C_SlaveRx */
472
473/**
474 * I2C_ManageACK()
475 * Brief : Enables or disables @I2Cx peripheral's ACKing
476 * Param : @pI2Cx - base address of I2Cx peripheral
477 * @state - ENABLE or DISABLE macro
478 * Retval : None
479 * Note : N/A
480 */
481void I2C_ManageACK(I2C_TypeDef *pI2Cx, uint8_t state)
482{
483 if (state == I2C_ACK_ENABLE)
484 {
485 /* Enable ACK */
486 pI2Cx->CR1 |= (0x1 << I2C_CR1_ACK);
487 }
488 else
489 {
490 /* Disable ACK */
491 pI2Cx->CR1 &= ~(0x1 << I2C_CR1_ACK);
492 }
493} /* End of I2C_ManageACK */
494
495/**
496 * I2C_IRQInterruptConfig()
497 * Brief : Enables or disables I2C IRQ interrupts
498 * Param : @irqNumber - IRQ number
499 * @state - ENABLE or DISABLE macro
500 * Retval : None
501 * Note : N/A
502 */
503void I2C_IRQInterruptConfig(uint8_t irqNumber, uint8_t state)
504{
505 if (state == ENABLE)
506 {
507 /* Configure NVIC_ISERx register */
508 if (irqNumber <= 31)
509 *NVIC_ISER0 |= (0x1 << irqNumber);
510 else if (32 <= irqNumber && irqNumber <= 64)
511 *NVIC_ISER1 |= (0x1 << irqNumber % 32);
512 else if (65 <= irqNumber && irqNumber <= 96)
513 *NVIC_ISER2 |= (0x1 << irqNumber % 32);
514 }
515 else
516 {
517 /* Configure NVIC_ICERx register */
518 if (irqNumber <= 31)
519 *NVIC_ICER0 |= (0x1 << irqNumber);
520 else if (32 <= irqNumber && irqNumber <= 64)
521 *NVIC_ICER1 |= (0x1 << irqNumber % 32);
522 else if (65 <= irqNumber && irqNumber <= 96)
523 *NVIC_ICER2 |= (0x1 << irqNumber % 32);
524 }
525} /* End of I2C_IRQInterruptConfig */
526
527/**
528 * I2C_IRQPriorityConfig()
529 * Brief : Configures I2C IRQ interrupt priorities
530 * Param : @irqNumber - IRQ number
531 * @irqPriotity - IRQ priority (Make sure this parameter is of
532 * type uint32_t. Due to the number of bits it
533 * needs to be shifted during the calculation,
534 * declaring it as uint8_t did not do its job.
535 * Retval : None
536 * Note : N/A
537 */
538void I2C_IRQPriorityConfig(uint8_t irqNumber, uint32_t irqPriority)
539{
540 /* Find out the IPR register */
541 uint8_t iprNumber = irqNumber / 4;
542 uint8_t iprSection = irqNumber % 4;
543 uint8_t bitOffset = (iprSection * 8) + (8 - NUM_PRI_BITS_USED);
544 *(NVIC_IPR_BASE + iprNumber) |= (irqPriority << bitOffset);
545} /* End of I2C_IRQPriorityConfig */
546
547/**
548 * I2C_EV_IRQHandling()
549 * Brief : Handles I2C event IRQ (common for both master and slave modes)
550 * Param : @pI2CHandle - pointer to I2C peripheral handle
551 * Retval : None
552 * Note : This function will first decode the event that occurred, and
553 * handle the event accordingly.
554 */
555void I2C_EV_IRQHandling(I2C_Handle_TypeDef *pI2CHandle)
556{
557 uint32_t temp1, temp2, temp3;
558
559 temp1 = pI2CHandle->pI2Cx->CR2 & (0x1 << I2C_CR2_ITEVTEN);
560 temp2 = pI2CHandle->pI2Cx->CR2 & (0x1 << I2C_CR2_ITBUFEN);
561 temp3 = pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_SB);
562
563 /* 1. Handle the interrupt generated by SB event
564 * Note: SB event is available only in master mode. Therefore, this block
565 * will note be executed in slave mode. (For slave, SB bit is always
566 * zero. Meaning that in I2C, slaves cannot start communication.)
567 */
568 if (temp1 && temp3)
569 {
570 /* SB flag is set */
571
572 /* Execute the address phase */
573 if (pI2CHandle->TxRxState == I2C_BUSY_IN_TX)
574 {
575 I2C_ExecuteAddressPhaseWrite(pI2CHandle->pI2Cx, pI2CHandle->DevAddr);
576 }
577 else if (pI2CHandle->TxRxState == I2C_BUSY_IN_RX)
578 {
579 I2C_ExecuteAddressPhaseRead(pI2CHandle->pI2Cx, pI2CHandle->DevAddr);
580 }
581 }
582
583 temp3 = pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_ADDR);
584 /* 2. Handle the interrupt generated by ADDR event
585 * Note: When in master mode - Address is sent
586 * When in slave mode - Address matched with own address
587 */
588 if (temp1 && temp3)
589 {
590 /* ADDR flag is set
591 *
592 * When ADDR flag is set, clock will be stretched and both the master
593 * and slave will be in wait state. So it is important to clear it
594 * according to the logic.
595 */
596 I2C_ClearADDRFlag(pI2CHandle);
597 }
598
599 temp3 = pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_BTF);
600 /* 3. Handle the interrupt generated by BTF event */
601 if (temp1 && temp3)
602 {
603 /* BTF (Byte Transfer Finished) flag is set
604 *
605 * When BTF flag is set:
606 *
607 * 1. If TxE=1 during transmission
608 * - Both SR and DR are empty
609 * - Clock will be stretched
610 * 2. If RxNe=1 during reception
611 * - Both SR and DR are full
612 * - Clock will be stretched
613 */
614 if (pI2CHandle->TxRxState == I2C_BUSY_IN_TX)
615 {
616 /* If TxE=1 */
617 if (pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_TxE))
618 {
619 /**
620 * BTF=1 & TxE=1; Close I2C data transmission
621 */
622
623 /* Check if the Tx length is 0 */
624 if (pI2CHandle->TxLen == 0)
625 {
626 /* 1. Generate STOP condition */
627 if (pI2CHandle->RepeatedStart == I2C_REPEATED_START_DI)
628 {
629 I2C_GenerateSTOPCondition(pI2CHandle->pI2Cx);
630 }
631
632 /* 2. Reset all the members of the handle structure */
633 I2C_CloseTx(pI2CHandle);
634
635 /* 3. Notify the application about transmission complete */
636 I2C_ApplicationEventCallback(pI2CHandle, I2C_EV_TX_CMPLT);
637 }
638 }
639 }
640 else if (pI2CHandle->TxRxState == I2C_BUSY_IN_RX)
641 {
642 /* Do nothing */
643 }
644 }
645
646 temp3 = pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_STOPF);
647 /* 4. Handle the interrupt generated by STOPF event
648 * Note: STOP event detection (STOPF) is available only in slave mode.
649 * (In master mode, STOPF flag will not be set.)
650 * STOPF flag is set by hardware when a STOP condition is detected
651 * on the bus by the slave after an Acknowledgement (ACK=1).
652 * STOPF flag is cleared by software reading the SR1 register
653 * followed by a write in the CR1 register,
654 * or by hardware when PE=0.
655 *
656 */
657 if (temp1 && temp3)
658 {
659 /* STOPF flag is set */
660
661 /* Clear STOPF (i.e., Read SR1, write to CR1)
662 * Note: Reading SR1 is already done in the previous line of code
663 */
664 /* Write to CR1 */
665 pI2CHandle->pI2Cx->CR1 |= 0x0000; /* Write without affecting CR1 */
666
667 /* Notify the application of the STOP detection */
668 I2C_ApplicationEventCallback(pI2CHandle, I2C_EV_STOP);
669 }
670
671 temp3 = pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_TxE);
672 /* 5. Handle the interrupt generated by TxE event */
673 if (temp1 && temp2 && temp3)
674 {
675 /* TxE flag is set, perform the data transmission
676 * Note: This is an indication that DR is empty, and software can
677 * put data into DR in order to send the data byte to the
678 * external world.
679 */
680
681 /* Check for device mode */
682 if (pI2CHandle->pI2Cx->SR2 & (0x1 << I2C_SR2_MSL))
683 {
684 /* Device is master */
685
686 if (pI2CHandle->TxRxState == I2C_BUSY_IN_TX)
687 {
688 if (pI2CHandle->TxLen > 0)
689 {
690 /* 1. Load the data into DR */
691 pI2CHandle->pI2Cx->DR = *(pI2CHandle->pTxBuffer);
692
693 /* 2. Decrement TxLen */
694 pI2CHandle->TxLen--;
695
696 /* 3. Increment the Tx buffer address */
697 pI2CHandle->pTxBuffer++;
698 }
699 }
700 }
701 else
702 {
703 /* Device is slave */
704
705 if (pI2CHandle->pI2Cx->SR2 & (0x1 << I2C_SR2_TRA))
706 {
707 /* Slave in transmitter mode */
708
709 I2C_ApplicationEventCallback(pI2CHandle, I2C_EV_TX);
710 }
711
712 }
713 }
714
715 temp3 = pI2CHandle->pI2Cx->SR1 & (0x1 << I2C_SR1_RxNE);
716 /* 6. Handle the interrupt generated by RxNE event */
717 if (temp1 && temp2 && temp3)
718 {
719 /* RxNE flag is set */
720
721 /* Check for device mode */
722 if (pI2CHandle->pI2Cx->SR2 & (0x1 << I2C_SR2_MSL))
723 {
724 /* Device is master */
725
726 if (pI2CHandle->TxRxState == I2C_BUSY_IN_RX)
727 {
728 /* Perform the data reception */
729
730 if (pI2CHandle->RxSize == 1)
731 {
732 *pI2CHandle->pRxBuffer = pI2CHandle->pI2Cx->DR;
733 pI2CHandle->RxLen--;
734 }
735
736 if (pI2CHandle->RxSize > 1)
737 {
738 if (pI2CHandle->RxLen == 2)
739 {
740 /* Clear the ACK bit */
741 I2C_ManageACK(pI2CHandle->pI2Cx, DISABLE);
742 }
743
744 /* Read DR */
745 *pI2CHandle->pRxBuffer = pI2CHandle->pI2Cx->DR;
746 pI2CHandle->pRxBuffer++;
747 pI2CHandle->RxLen--;
748 }
749
750 if (pI2CHandle->RxLen == 0)
751 {
752 /**
753 * No more data to receive. Close the I2C data reception
754 * and notify the application of the communication termination.
755 */
756
757 /* 1. Generate STOP condition */
758 if (pI2CHandle->RepeatedStart == I2C_REPEATED_START_DI)
759 {
760 I2C_GenerateSTOPCondition(pI2CHandle->pI2Cx);
761 }
762
763 /* 2. Close I2C Rx */
764 I2C_CloseRx(pI2CHandle);
765
766 /* 3. Notify the application */
767 I2C_ApplicationEventCallback(pI2CHandle, I2C_EV_RX_CMPLT);
768 }
769 }
770 }
771 else
772 {
773 /* Device is slave */
774
775 if (!(pI2CHandle->pI2Cx->SR2 & (0x1 << I2C_SR2_TRA)))
776 {
777 /* Slave in transmitter mode */
778
779 I2C_ApplicationEventCallback(pI2CHandle, I2C_EV_RX);
780 }
781 }
782 }
783} /* End of I2C_EV_IRQHandling */
784
785/**
786 * I2C_ER_IRQHandling()
787 * Brief : Handles I2C error IRQ (common for both master and slave modes)
788 * Param : @pI2CHandle - pointer to I2C peripheral handle
789 * Retval : None
790 * Note : N/A
791 */
792void I2C_ER_IRQHandling(I2C_Handle_TypeDef *pI2CHandle)
793{
794 uint32_t temp1, temp2;
795
796 /* Check the status of SR2 ITERREN control bit */
797 temp2 = (pI2CHandle->pI2Cx->CR2) & (0x1 << I2C_CR2_ITERREN);
798
799 /* Check for bus error (BERR) *********************************************/
800
801 temp1 = (pI2CHandle->pI2Cx->SR1) & (0x1 << I2C_SR1_BERR);
802 if (temp1 && temp2)
803 {
804 /**
805 * Handle bus error
806 */
807
808 /* Clear the bus error flag */
809 pI2CHandle->pI2Cx->SR1 &= ~(0x1 << I2C_SR1_BERR);
810
811 /* Notify the application of this error */
812 I2C_ApplicationEventCallback(pI2CHandle, I2C_ERROR_BERR);
813 }
814
815 /* Check for arbitration lost (ARLO) **************************************/
816
817 temp1 = (pI2CHandle->pI2Cx->SR1) & (0x1 << I2C_SR1_ARLO);
818 if (temp1 && temp2)
819 {
820 /**
821 * Handle arbitration lost error
822 */
823
824 /* Clear the arbitration lost error flag */
825 pI2CHandle->pI2Cx->SR1 &= ~(0x1 << I2C_SR1_ARLO);
826
827 /* Notify the application of this error */
828 I2C_ApplicationEventCallback(pI2CHandle, I2C_ERROR_ARLO);
829 }
830
831 /* Check for ACK failure (AF) *********************************************/
832
833 temp1 = (pI2CHandle->pI2Cx->SR1) & (0x1 << I2C_SR1_AF);
834 if (temp1 && temp2)
835 {
836 /**
837 * Handle ACK failure error
838 */
839
840 /* Clear the ACK failure error flag */
841 pI2CHandle->pI2Cx->SR1 &= ~(0x1 << I2C_SR1_AF);
842
843 /* Notify the application of this error */
844 I2C_ApplicationEventCallback(pI2CHandle, I2C_ERROR_AF);
845 }
846
847 /* Check for overrun/underrun (OVR) ***************************************/
848
849 temp1 = (pI2CHandle->pI2Cx->SR1) & (0x1 << I2C_SR1_OVR);
850 if (temp1 && temp2)
851 {
852 /**
853 * Handle overrun/underrun error
854 */
855
856 /* Clear the overrun/underrun error flag */
857 pI2CHandle->pI2Cx->SR1 &= ~(0x1 << I2C_SR1_OVR);
858
859 /* Notify the application of this error */
860 I2C_ApplicationEventCallback(pI2CHandle, I2C_ERROR_OVR);
861 }
862
863 /* Check for timeout error (TIMEOUT) **************************************/
864
865 temp1 = (pI2CHandle->pI2Cx->SR1) & (0x1 << I2C_SR1_TIMEOUT);
866 if (temp1 && temp2)
867 {
868 /**
869 * Handle timeout error
870 */
871
872 /* Clear the timeout error flag */
873 pI2CHandle->pI2Cx->SR1 &= ~(0x1 << I2C_SR1_TIMEOUT);
874
875 /* Notify the application of this error */
876 I2C_ApplicationEventCallback(pI2CHandle, I2C_ERROR_TIMEOUT);
877 }
878} /* End of I2C_ER_IRQHandling */
879
880/**
881 * I2C_CloseTx()
882 * Brief : Handles closing I2C Tx operation
883 * Param : @pI2CHandle - pointer to I2C peripheral handle
884 * Retval : None
885 * Note : N/A
886 */
887void I2C_CloseTx(I2C_Handle_TypeDef *pI2CHandle)
888{
889 /* Disable ITBUFEN control bit */
890 pI2CHandle->pI2Cx->CR2 &= ~(0x1 << I2C_CR2_ITBUFEN);
891
892 /* Disable ITEVTEN control bit */
893 pI2CHandle->pI2Cx->CR2 &= ~(0x1 << I2C_CR2_ITEVTEN);
894
895 /* Reset I2C handle members */
896 pI2CHandle->TxRxState = I2C_READY;
897 pI2CHandle->pTxBuffer = NULL;
898 pI2CHandle->TxLen = 0;
899} /* End of I2C_CloseTx */
900
901/**
902 * I2C_CloseRx()
903 * Brief : Handles closing I2C Rx operation
904 * Param : @pI2CHandle - pointer to I2C peripheral handle
905 * Retval : None
906 * Note : N/A
907 */
908void I2C_CloseRx(I2C_Handle_TypeDef *pI2CHandle)
909{
910 /* Disable ITBUFEN control bit */
911 pI2CHandle->pI2Cx->CR2 &= ~(0x1 << I2C_CR2_ITBUFEN);
912
913 /* Disable ITEVTEN control bit */
914 pI2CHandle->pI2Cx->CR2 &= ~(0x1 << I2C_CR2_ITEVTEN);
915
916 /* Reset I2C handle members */
917 pI2CHandle->TxRxState = I2C_READY;
918 pI2CHandle->pRxBuffer = NULL;
919 pI2CHandle->RxLen = 0;
920 pI2CHandle->RxSize = 0;
921
922 /* Enable ACK */
923 if (pI2CHandle->I2C_Config.I2C_ACKEnable == I2C_ACK_ENABLE)
924 {
925 I2C_ManageACK(pI2CHandle->pI2Cx, ENABLE);
926 }
927} /* End of I2C_CloseRx */
928
929/**
930 * I2C_GenerateSTARTCondition()
931 * Brief : Generates I2C START condition
932 * Param : @pI2Cx - base address of I2Cx peripheral
933 * Retval : None
934 * Note : N/A
935 */
936void I2C_GenerateSTARTCondition(I2C_TypeDef *pI2Cx)
937{
938 pI2Cx->CR1 |= (0x1 << I2C_CR1_START);
939} /* End of I2C_GenerateSTARTCondition */
940
941/**
942 * I2C_GenerateSTOPCondition()
943 * Brief : Generates I2C START condition
944 * Param : @pI2Cx - base address of I2Cx peripheral
945 * Retval : None
946 * Note : N/A
947 */
948void I2C_GenerateSTOPCondition(I2C_TypeDef *pI2Cx)
949{
950 pI2Cx->CR1 |= (0x1 << I2C_CR1_STOP);
951} /* End of I2C_GenerateSTOPCondition */
952
953/**
954 * I2C_SlaveEnableDisableCallbackEvents()
955 * Brief : Enables or disables @pI2Cx's (as a slave) callback events
956 * Param : @pI2Cx - base address of I2Cx peripheral
957 * @state - ENABLE or DISABLE macro
958 * Retval : None
959 * Note : N/A
960 */
961void I2C_SlaveEnableDisableCallbackEvents(I2C_TypeDef *pI2Cx, uint8_t state)
962{
963 if (state == ENABLE)
964 {
965 /**
966 * Enable all available interrupts by setting the control bits
967 */
968 /* Enable ITBUFEN control bit */
969 pI2Cx->CR2 |= (0x1 << I2C_CR2_ITBUFEN);
970 /* Enable ITEVTEN control bit */
971 pI2Cx->CR2 |= (0x1 << I2C_CR2_ITEVTEN);
972 /* Enable ITERREN control bit */
973 pI2Cx->CR2 |= (0x1 << I2C_CR2_ITERREN);
974 }
975 else
976 {
977 /**
978 * Disable all available interrupts by setting the control bits
979 */
980 /* Disable ITBUFEN control bit */
981 pI2Cx->CR2 &= ~(0x1 << I2C_CR2_ITBUFEN);
982 /* Disable ITEVTEN control bit */
983 pI2Cx->CR2 &= ~(0x1 << I2C_CR2_ITEVTEN);
984 /* Disable ITERREN control bit */
985 pI2Cx->CR2 &= ~(0x1 << I2C_CR2_ITERREN);
986 }
987} /* End of I2C_SlaveEnableDisableCallbackEvents */
988
989/**
990 * I2C_ApplicationEventCallback()
991 * Brief : Notifies the application of the event occurred
992 * Param : @pI2CHandle - pointer to I2C handle structure
993 * @appEvent - I2C event occurred
994 * Retval : None
995 * Note : This function must be implemented by the application. Since the driver
996 * does not know in which application this function will be implemented,
997 * the driver defines it as a weak function. The application may override
998 * this function.
999 * If the application does not implement this function, the following
1000 * definition will be executed.
1001 */
1002__WEAK void I2C_ApplicationEventCallback(I2C_Handle_TypeDef *pI2CHandle, uint8_t appEvent)
1003{
1004 /* Implemented in the application */
1005} /* End of I2C_ApplicationEventCallback */
1006
1007
1008/*******************************************************************************
1009 * I2C driver private functions
1010 ******************************************************************************/
1011
1012/**
1013 * I2C_ExecuteAddressPhaseRead()
1014 * Brief : Executes address phase for I2C read operation
1015 * Param : @pI2Cx - base address of I2Cx peripheral
1016 * @slaveAddr - slave address
1017 * Retval : None
1018 * Note : N/A
1019 */
1020static void I2C_ExecuteAddressPhaseRead(I2C_TypeDef *pI2Cx, uint8_t slaveAddr)
1021{
1022 /* Shift 7-bit slave address to left 1 bit position to make room for
1023 * r/w bit. Slave address (1 byte) = 7-bit slave address + r/w bit (1).
1024 */
1025 slaveAddr <<= 1;
1026 slaveAddr |= 1; /* Set bit[0] */
1027 pI2Cx->DR = slaveAddr;
1028} /* End of I2C_ExecuteAddressPhaseRead */
1029
1030/**
1031 * I2C_ExecuteAddressPhaseWrite()
1032 * Brief : Executes address phase for I2C write operation
1033 * Param : @pI2Cx - base address of I2Cx peripheral
1034 * @slaveAddr - slave address
1035 * Retval : None
1036 * Note : N/A
1037 */
1038static void I2C_ExecuteAddressPhaseWrite(I2C_TypeDef *pI2Cx, uint8_t slaveAddr)
1039{
1040 /* Shift 7-bit slave address to left 1 bit position to make room for
1041 * r/w bit. Slave address (1 byte) = 7-bit slave address + r/w bit (0).
1042 */
1043 slaveAddr <<= 1;
1044 slaveAddr &= ~(1); /* Clear bit[0] */
1045 pI2Cx->DR = slaveAddr;
1046} /* End of I2C_ExecuteAddressPhaseWrite */
1047
1048/**
1049 * I2C_ClearADDRFlag()
1050 * Brief : Clears the ADDR bit of I2Cx SR1 register
1051 * Param : @pI2CHandle - pointer to I2C peripheral handle
1052 * Retval : None
1053 * Note : ADDR bit is cleared by software reading SR1 register followed by
1054 * reading SR2, or by hardware when PE = 0.
1055 * This function is a private helper function.
1056 */
1057static void I2C_ClearADDRFlag(I2C_Handle_TypeDef *pI2CHandle)
1058{
1059 uint32_t dummyRead;
1060
1061 /* Check for the device mode */
1062 if (pI2CHandle->pI2Cx->SR2 & (0x1 << I2C_SR2_MSL))
1063 {
1064 /**
1065 * Device is in master mode
1066 */
1067
1068 if (pI2CHandle->TxRxState == I2C_BUSY_IN_RX)
1069 {
1070 if (pI2CHandle->RxSize == 1)
1071 {
1072 /* Disable ACK first */
1073 I2C_ManageACK(pI2CHandle->pI2Cx, DISABLE);
1074
1075 /* Clear ADDR flag (Read SR1, read SR2) */
1076 dummyRead = pI2CHandle->pI2Cx->SR1;
1077 dummyRead = pI2CHandle->pI2Cx->SR2;
1078 (void)dummyRead; /* To suppress 'unused variable' warning */
1079 }
1080 }
1081 else
1082 {
1083 /* Clear ADDR flag (Read SR1, read SR2) */
1084 dummyRead = pI2CHandle->pI2Cx->SR1;
1085 dummyRead = pI2CHandle->pI2Cx->SR2;
1086 (void)dummyRead; /* To suppress 'unused variable' warning */
1087 }
1088 }
1089 else
1090 {
1091 /**
1092 * Device is in slave mode
1093 */
1094
1095 /* Clear ADDR flag (Read SR1, read SR2) */
1096 dummyRead = pI2CHandle->pI2Cx->SR1;
1097 dummyRead = pI2CHandle->pI2Cx->SR2;
1098 (void)dummyRead; /* To suppress 'unused variable' warning */
1099 }
1100} /* End of I2C_ClearADDRFlag */