Skip to content

Commit 42c5521

Browse files
authored
Merge pull request #135 from fprwi6labs/i2c_master_it_mode
I2C IT mode
2 parents 30a305f + acc2e60 commit 42c5521

File tree

3 files changed

+144
-64
lines changed

3 files changed

+144
-64
lines changed

Diff for: cores/arduino/stm32/stm32_def.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252

5353
// Here define some compatibility
5454
#ifdef STM32F0xx
55-
#define I2C1_EV_IRQn I2C1_IRQn
5655

5756
#elif defined(STM32F1xx)
5857

@@ -65,8 +64,7 @@
6564
#elif defined(STM32F7xx)
6665

6766
#elif defined(STM32L0xx)
68-
#define I2C1_EV_IRQn I2C1_IRQn
69-
#define I2C2_EV_IRQn I2C2_IRQn
67+
7068
#elif defined(STM32L1xx)
7169

7270
#elif defined(STM32L4xx)

Diff for: cores/arduino/stm32/twi.c

+119-59
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,16 @@
101101
*/
102102

103103
/* Family specific description for I2C */
104-
#define I2C_NUM (5)
104+
#if defined(STM32F7xx) || defined(STM32L4xx)
105+
#define I2C_NUM (4)
106+
#elif defined(STM32F2xx) || defined(STM32F3xx) || defined(STM32F4xx) || defined(STM32L0xx)
107+
#define I2C_NUM (3)
108+
#elif defined(STM32F0xx) || defined(STM32F1xx) || defined(STM32L1xx)
109+
#define I2C_NUM (2)
110+
#else
111+
#error "Unknown Family - unknown I2C_NUM"
112+
#endif
113+
105114
static I2C_HandleTypeDef* i2c_handles[I2C_NUM];
106115

107116
/**
@@ -142,7 +151,6 @@ void i2c_init(i2c_t *obj)
142151
*/
143152
void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, uint32_t ownAddress, uint8_t master)
144153
{
145-
UNUSED(master);
146154
if(obj == NULL)
147155
return;
148156

@@ -170,53 +178,56 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
170178
#if defined I2C1_BASE
171179
// Enable I2C1 clock if not done
172180
if (obj->i2c == I2C1) {
173-
__HAL_RCC_I2C1_CLK_ENABLE();
174-
__HAL_RCC_I2C1_FORCE_RESET();
175-
__HAL_RCC_I2C1_RELEASE_RESET();
176-
obj->irq = I2C1_EV_IRQn;
177-
#ifdef STM32F1xx
178-
obj->irqER = I2C1_ER_IRQn;
179-
#endif
180-
i2c_handles[0] = handle;
181+
__HAL_RCC_I2C1_CLK_ENABLE();
182+
__HAL_RCC_I2C1_FORCE_RESET();
183+
__HAL_RCC_I2C1_RELEASE_RESET();
184+
185+
obj->irq = I2C1_EV_IRQn;
186+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
187+
obj->irqER = I2C1_ER_IRQn;
188+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
189+
i2c_handles[0] = handle;
181190
}
182-
#endif
191+
#endif // I2C1_BASE
183192
#if defined I2C2_BASE
184193
// Enable I2C2 clock if not done
185194
if (obj->i2c == I2C2) {
186-
__HAL_RCC_I2C2_CLK_ENABLE();
187-
__HAL_RCC_I2C2_FORCE_RESET();
188-
__HAL_RCC_I2C2_RELEASE_RESET();
189-
#ifdef STM32F0xx
190-
obj->irq = I2C2_IRQn;
191-
#else
192-
obj->irq = I2C2_EV_IRQn;
193-
#ifdef STM32F1xx
194-
obj->irqER = I2C2_ER_IRQn;
195-
#endif
196-
#endif
197-
i2c_handles[1] = handle;
195+
__HAL_RCC_I2C2_CLK_ENABLE();
196+
__HAL_RCC_I2C2_FORCE_RESET();
197+
__HAL_RCC_I2C2_RELEASE_RESET();
198+
obj->irq = I2C2_EV_IRQn;
199+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
200+
obj->irqER = I2C2_ER_IRQn;
201+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
202+
i2c_handles[1] = handle;
198203
}
199-
#endif
204+
#endif // I2C2_BASE
200205
#if defined I2C3_BASE
201206
// Enable I2C3 clock if not done
202207
if (obj->i2c == I2C3) {
203-
__HAL_RCC_I2C3_CLK_ENABLE();
204-
__HAL_RCC_I2C3_FORCE_RESET();
205-
__HAL_RCC_I2C3_RELEASE_RESET();
206-
obj->irq = I2C3_EV_IRQn;
207-
i2c_handles[2] = handle;
208+
__HAL_RCC_I2C3_CLK_ENABLE();
209+
__HAL_RCC_I2C3_FORCE_RESET();
210+
__HAL_RCC_I2C3_RELEASE_RESET();
211+
obj->irq = I2C3_EV_IRQn;
212+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
213+
obj->irqER = I2C3_ER_IRQn;
214+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
215+
i2c_handles[2] = handle;
208216
}
209-
#endif
217+
#endif // I2C3_BASE
210218
#if defined I2C4_BASE
211-
// Enable I2C3 clock if not done
219+
// Enable I2C4 clock if not done
212220
if (obj->i2c == I2C4) {
213-
__HAL_RCC_I2C4_CLK_ENABLE();
214-
__HAL_RCC_I2C4_FORCE_RESET();
215-
__HAL_RCC_I2C4_RELEASE_RESET();
216-
obj->irq = I2C4_EV_IRQn;
217-
i2c_handles[3] = handle;
221+
__HAL_RCC_I2C4_CLK_ENABLE();
222+
__HAL_RCC_I2C4_FORCE_RESET();
223+
__HAL_RCC_I2C4_RELEASE_RESET();
224+
obj->irq = I2C4_EV_IRQn;
225+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
226+
obj->irqER = I2C4_ER_IRQn;
227+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
228+
i2c_handles[3] = handle;
218229
}
219-
#endif
230+
#endif // I2C4_BASE
220231

221232
//SCL
222233
port = set_GPIO_Port_Clock(STM_PORT(obj->scl));
@@ -250,7 +261,7 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
250261
handle->Init.Timing = timing;
251262
#else
252263
handle->Init.ClockSpeed = timing;
253-
handle->Init.DutyCycle = I2C_DUTYCYCLE_2;//16_9;
264+
handle->Init.DutyCycle = I2C_DUTYCYCLE_2;
254265
#endif
255266
handle->Init.OwnAddress1 = ownAddress;
256267
handle->Init.OwnAddress2 = 0xFF;
@@ -261,17 +272,17 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
261272

262273
handle->State = HAL_I2C_STATE_RESET;
263274

264-
if(master == 0) {
265-
HAL_NVIC_SetPriority(obj->irq, 0, 1);
266-
HAL_NVIC_EnableIRQ(obj->irq);
267-
#ifdef STM32F1xx
268-
HAL_NVIC_SetPriority(obj->irqER, 0, 1);
269-
HAL_NVIC_EnableIRQ(obj->irqER);
270-
#endif
271-
}
275+
HAL_NVIC_SetPriority(obj->irq, 0, 1);
276+
HAL_NVIC_EnableIRQ(obj->irq);
277+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
278+
HAL_NVIC_SetPriority(obj->irqER, 0, 1);
279+
HAL_NVIC_EnableIRQ(obj->irqER);
280+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
272281

273282
// Init the I2C
274283
HAL_I2C_Init(handle);
284+
285+
obj->isMaster = master;
275286
}
276287

277288
/**
@@ -282,9 +293,9 @@ void i2c_custom_init(i2c_t *obj, i2c_timing_e timing, uint32_t addressingMode, u
282293
void i2c_deinit(i2c_t *obj)
283294
{
284295
HAL_NVIC_DisableIRQ(obj->irq);
285-
#ifdef STM32F1xx
296+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
286297
HAL_NVIC_DisableIRQ(obj->irqER);
287-
#endif
298+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
288299
HAL_I2C_DeInit(&(obj->handle));
289300
}
290301

@@ -341,17 +352,20 @@ i2c_status_e i2c_master_write(i2c_t *obj, uint8_t dev_address,
341352

342353
{
343354
i2c_status_e ret = I2C_ERROR;
344-
HAL_StatusTypeDef status = HAL_OK;
355+
uint32_t tickstart = HAL_GetTick();
345356

346-
// Check the communication status
347-
status = HAL_I2C_Master_Transmit(&(obj->handle), dev_address, data, size, I2C_TIMEOUT_TICK);
348-
349-
if(status == HAL_OK)
357+
if(HAL_I2C_Master_Transmit_IT(&(obj->handle), dev_address, data, size) == HAL_OK){
350358
ret = I2C_OK;
351-
else if(status == HAL_TIMEOUT)
352-
ret = I2C_TIMEOUT;
353-
else
354-
ret = I2C_ERROR;
359+
// wait for transfer completion
360+
while((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY)
361+
&& (ret == I2C_OK)){
362+
if((HAL_GetTick() - tickstart) > I2C_TIMEOUT_TICK) {
363+
ret = I2C_TIMEOUT;
364+
} else if(HAL_I2C_GetError(&(obj->handle)) != HAL_I2C_ERROR_NONE) {
365+
ret = I2C_ERROR;
366+
}
367+
}
368+
}
355369

356370
return ret;
357371
}
@@ -385,9 +399,19 @@ void i2c_slave_write_IT(i2c_t *obj, uint8_t *data, uint8_t size)
385399
i2c_status_e i2c_master_read(i2c_t *obj, uint8_t dev_address, uint8_t *data, uint8_t size)
386400
{
387401
i2c_status_e ret = I2C_ERROR;
402+
uint32_t tickstart = HAL_GetTick();
388403

389-
if(HAL_I2C_Master_Receive(&(obj->handle), dev_address, data, size, I2C_TIMEOUT_TICK) == HAL_OK) {
404+
if(HAL_I2C_Master_Receive_IT(&(obj->handle), dev_address, data, size) == HAL_OK) {
390405
ret = I2C_OK;
406+
// wait for transfer completion
407+
while((HAL_I2C_GetState(&(obj->handle)) != HAL_I2C_STATE_READY)
408+
&& (ret == I2C_OK)){
409+
if((HAL_GetTick() - tickstart) > I2C_TIMEOUT_TICK) {
410+
ret = I2C_TIMEOUT;
411+
} else if(HAL_I2C_GetError(&(obj->handle)) != HAL_I2C_ERROR_NONE) {
412+
ret = I2C_ERROR;
413+
}
414+
}
391415
}
392416

393417
return ret;
@@ -506,15 +530,24 @@ void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
506530

507531
/**
508532
* @brief I2C error callback.
533+
* @note In master mode, the callback is not used because the error is reported
534+
* to the Arduino API from i2c_master_write() and i2c_master_read().
535+
* In slave mode, there is no mechanism in Arduino API to report an error
536+
* so the error callback forces the slave to listen again.
509537
* @param hi2c Pointer to a I2C_HandleTypeDef structure that contains
510538
* the configuration information for the specified I2C.
511539
* @retval None
512540
*/
513541
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
514542
{
515-
HAL_I2C_EnableListen_IT(hi2c);
543+
i2c_t *obj = get_i2c_obj(hi2c);
544+
545+
if(obj->isMaster == 0) {
546+
HAL_I2C_EnableListen_IT(hi2c);
547+
}
516548
}
517549

550+
#if defined(I2C1_BASE)
518551
/**
519552
* @brief This function handles I2C1 interrupt.
520553
* @param None
@@ -524,8 +557,12 @@ void I2C1_EV_IRQHandler(void)
524557
{
525558
I2C_HandleTypeDef * handle = i2c_handles[0];
526559
HAL_I2C_EV_IRQHandler(handle);
560+
#if defined(STM32F0xx) || defined(STM32L0xx)
561+
HAL_I2C_ER_IRQHandler(handle);
562+
#endif // defined(STM32F0xx) || defined(STM32L0xx)
527563
}
528564

565+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
529566
/**
530567
* @brief This function handles I2C1 interrupt.
531568
* @param None
@@ -536,7 +573,10 @@ void I2C1_ER_IRQHandler(void)
536573
I2C_HandleTypeDef * handle = i2c_handles[0];
537574
HAL_I2C_ER_IRQHandler(handle);
538575
}
576+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
577+
#endif // I2C1_BASE
539578

579+
#if defined(I2C2_BASE)
540580
/**
541581
* @brief This function handles I2C2 interrupt.
542582
* @param None
@@ -546,8 +586,12 @@ void I2C2_EV_IRQHandler(void)
546586
{
547587
I2C_HandleTypeDef * handle = i2c_handles[1];
548588
HAL_I2C_EV_IRQHandler(handle);
589+
#if defined(STM32F0xx) || defined(STM32L0xx)
590+
HAL_I2C_ER_IRQHandler(handle);
591+
#endif // defined(STM32F0xx) || defined(STM32L0xx)
549592
}
550593

594+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
551595
/**
552596
* @brief This function handles I2C2 interrupt.
553597
* @param None
@@ -558,7 +602,10 @@ void I2C2_ER_IRQHandler(void)
558602
I2C_HandleTypeDef * handle = i2c_handles[1];
559603
HAL_I2C_ER_IRQHandler(handle);
560604
}
605+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
606+
#endif // I2C2_BASE
561607

608+
#if defined(I2C3_BASE)
562609
/**
563610
* @brief This function handles I2C3 interrupt.
564611
* @param None
@@ -568,8 +615,12 @@ void I2C3_EV_IRQHandler(void)
568615
{
569616
I2C_HandleTypeDef * handle = i2c_handles[2];
570617
HAL_I2C_EV_IRQHandler(handle);
618+
#if defined(STM32F0xx) || defined(STM32L0xx)
619+
HAL_I2C_ER_IRQHandler(handle);
620+
#endif // defined(STM32F0xx) || defined(STM32L0xx)
571621
}
572622

623+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
573624
/**
574625
* @brief This function handles I2C3 interrupt.
575626
* @param None
@@ -580,7 +631,10 @@ void I2C3_ER_IRQHandler(void)
580631
I2C_HandleTypeDef * handle = i2c_handles[2];
581632
HAL_I2C_ER_IRQHandler(handle);
582633
}
634+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
635+
#endif // I2C3_BASE
583636

637+
#if defined(I2C4_BASE)
584638
/**
585639
* @brief This function handles I2C4 interrupt.
586640
* @param None
@@ -590,8 +644,12 @@ void I2C4_EV_IRQHandler(void)
590644
{
591645
I2C_HandleTypeDef * handle = i2c_handles[3];
592646
HAL_I2C_EV_IRQHandler(handle);
647+
#if defined(STM32F0xx) || defined(STM32L0xx)
648+
HAL_I2C_ER_IRQHandler(handle);
649+
#endif // defined(STM32F0xx) || defined(STM32L0xx)
593650
}
594651

652+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
595653
/**
596654
* @brief This function handles I2C4 interrupt.
597655
* @param None
@@ -602,6 +660,8 @@ void I2C4_ER_IRQHandler(void)
602660
I2C_HandleTypeDef * handle = i2c_handles[3];
603661
HAL_I2C_ER_IRQHandler(handle);
604662
}
663+
#endif // !defined(STM32F0xx) && !defined(STM32L0xx)
664+
#endif // I2C4_BASE
605665

606666
/**
607667
* @}

Diff for: cores/arduino/stm32/twi.h

+24-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,29 @@
5252
/* offsetof is a gcc built-in function, this is the manual implementation */
5353
#define OFFSETOF(type, member) ((uint32_t) (&(((type *)(0))->member)))
5454

55+
/* I2C Tx/Rx buffer size */
5556
#define I2C_TXRX_BUFFER_SIZE 32
5657

58+
/* Redefinition of IRQ for F0 & L0 family */
59+
#if defined(STM32F0xx) || defined(STM32L0xx)
60+
#if defined(I2C1_BASE)
61+
#define I2C1_EV_IRQn I2C1_IRQn
62+
#define I2C1_EV_IRQHandler I2C1_IRQHandler
63+
#endif // defined(I2C1_BASE)
64+
#if defined(I2C2_BASE)
65+
#define I2C2_EV_IRQn I2C2_IRQn
66+
#define I2C2_EV_IRQHandler I2C2_IRQHandler
67+
#endif // defined(I2C2_BASE)
68+
#if defined(I2C3_BASE)
69+
#define I2C3_EV_IRQn I2C3_IRQn
70+
#define I2C3_EV_IRQHandler I2C3_IRQHandler
71+
#endif // defined(I2C3_BASE)
72+
#if defined(I2C4_BASE)
73+
#define I2C4_EV_IRQn I2C4_IRQn
74+
#define I2C4_EV_IRQHandler I2C4_IRQHandler
75+
#endif // defined(I2C4_BASE)-
76+
#endif // defined(STM32F0xx) || defined(STM32L0xx)
77+
5778
typedef struct i2c_s i2c_t;
5879

5980
struct i2c_s {
@@ -67,10 +88,11 @@ struct i2c_s {
6788
PinName sda;
6889
PinName scl;
6990
IRQn_Type irq;
70-
#ifdef STM32F1xx
91+
#if !defined(STM32F0xx) && !defined(STM32L0xx)
7192
IRQn_Type irqER;
72-
#endif
93+
#endif //!defined(STM32F0xx) && !defined(STM32L0xx)
7394
uint8_t slaveMode;
95+
uint8_t isMaster;
7496
void (*i2c_onSlaveReceive)(uint8_t *, int);
7597
void (*i2c_onSlaveTransmit)(void);
7698
uint8_t i2cTxRxBuffer[I2C_TXRX_BUFFER_SIZE];

0 commit comments

Comments
 (0)