24#include "px_stm32cube.h"
31typedef struct px_i2c_per_s
48static bool px_i2c_init_per(I2C_TypeDef * i2c_base_adr,
56 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
61 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C2);
69 i2c_base_adr->CR1 = 0;
71 i2c_base_adr->CR2 = 0;
75 LL_I2C_Enable(i2c_base_adr);
110#if PX_I2C_CFG_I2C1_EN
111 px_i2c_init_per_data(PX_I2C_NR_1, &px_i2c_per_1);
113#if PX_I2C_CFG_I2C2_EN
114 px_i2c_init_per_data(PX_I2C_NR_2, &px_i2c_per_2);
142#if PX_I2C_CFG_I2C1_EN
144 i2c_per = &px_i2c_per_1;
147#if PX_I2C_CFG_I2C2_EN
149 i2c_per = &px_i2c_per_2;
153 PX_LOG_E(
"Invalid peripheral specified");
187 I2C_TypeDef * i2c_base_adr;
194 ||(handle->
i2c_per->open_counter == 0 ) )
217 i2c_base_adr->CR1 = 0;
221#if PX_I2C_CFG_I2C1_EN
223 LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C1);
226#if PX_I2C_CFG_I2C2_EN
228 LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C2);
246 I2C_TypeDef * i2c_base_adr;
247 const uint8_t * data_u8 = (
const uint8_t *)data;
255 ||(handle->
i2c_per->open_counter == 0 ) )
269 if( (nr_of_bytes <= 1)
272 LL_I2C_DisableReloadMode(i2c_base_adr);
276 LL_I2C_EnableReloadMode(i2c_base_adr);
281 LL_I2C_SetTransferSize(i2c_base_adr, 1);
285 LL_I2C_SetTransferSize(i2c_base_adr, 0);
293 if(LL_I2C_IsActiveFlag_BUSY(i2c_base_adr))
295 PX_LOG_E(
"I2C bus is busy with a previous transaction");
302 if(!LL_I2C_IsActiveFlag_BUSY(i2c_base_adr))
309 LL_I2C_SetSlaveAddr(i2c_base_adr, (handle->
slave_adr)<<1);
311 LL_I2C_SetTransferRequest(i2c_base_adr, LL_I2C_REQUEST_WRITE);
313 LL_I2C_GenerateStartCondition(i2c_base_adr);
317 while(!LL_I2C_IsActiveFlag_BUSY(i2c_base_adr)) {;}
320 while(i2c_base_adr->CR2 & I2C_CR2_START) {;}
322 if(LL_I2C_IsActiveFlag_NACK(i2c_base_adr))
325 LL_I2C_ClearFlag_NACK(i2c_base_adr);
327 PX_LOG_W(
"I2C Slave did not ACK SLA+W");
329 while(LL_I2C_IsActiveFlag_BUSY(i2c_base_adr)) {;}
338 if(!LL_I2C_IsActiveFlag_BUSY(i2c_base_adr))
346 i2c_isr = i2c_base_adr->ISR;
348 while((i2c_isr & (I2C_ISR_TXIS | I2C_ISR_NACKF | I2C_ISR_TC | I2C_ISR_TCR | I2C_ISR_BERR)) == 0);
351 if(i2c_isr & I2C_ISR_BERR)
354 LL_I2C_ClearFlag_BERR(i2c_base_adr);
358 while(LL_I2C_IsActiveFlag_BUSY(i2c_base_adr)) {;}
362 if(i2c_isr & I2C_ISR_NACKF)
365 LL_I2C_ClearFlag_NACK(i2c_base_adr);
367 PX_LOG_E(
"I2C Slave did not ACK byte");
369 while(LL_I2C_IsActiveFlag_BUSY(i2c_base_adr)) {;}
373 if(i2c_isr & I2C_ISR_TXIS)
378 LL_I2C_TransmitData8(i2c_base_adr, *data_u8++);
384 if(i2c_isr & I2C_ISR_TC)
394 if(i2c_isr & I2C_ISR_TCR)
403 LL_I2C_SetTransferSize(i2c_base_adr, 1);
411 if(!LL_I2C_IsActiveFlag_BUSY(i2c_base_adr))
417 LL_I2C_GenerateStopCondition(i2c_base_adr);
419 while(!LL_I2C_IsActiveFlag_STOP(i2c_base_adr)) {;}
421 LL_I2C_ClearFlag_STOP(i2c_base_adr);
423 while(LL_I2C_IsActiveFlag_BUSY(i2c_base_adr)) {;}
436 I2C_TypeDef * i2c_base_adr;
437 uint8_t * data_u8 = (uint8_t *)data;
445 ||(handle->
i2c_per->open_counter == 0 ) )
459 if( (nr_of_bytes <= 1)
462 LL_I2C_DisableReloadMode(i2c_base_adr);
466 LL_I2C_EnableReloadMode(i2c_base_adr);
471 LL_I2C_SetTransferSize(i2c_base_adr, 1);
475 LL_I2C_SetTransferSize(i2c_base_adr, 0);
483 if(LL_I2C_IsActiveFlag_BUSY(i2c_base_adr))
485 PX_LOG_E(
"I2C bus is busy with a previous transaction");
492 if(!LL_I2C_IsActiveFlag_BUSY(i2c_base_adr))
499 LL_I2C_SetSlaveAddr(i2c_base_adr, (handle->
slave_adr)<<1);
501 LL_I2C_SetTransferRequest(i2c_base_adr, LL_I2C_REQUEST_READ);
503 LL_I2C_GenerateStartCondition(i2c_base_adr);
506 while(!LL_I2C_IsActiveFlag_BUSY(i2c_base_adr)) {;}
509 while(i2c_base_adr->CR2 & I2C_CR2_START) {;}
511 if(LL_I2C_IsActiveFlag_NACK(i2c_base_adr))
514 LL_I2C_ClearFlag_NACK(i2c_base_adr);
516 PX_LOG_W(
"I2C Slave did not ACK SLA+R");
518 while(LL_I2C_IsActiveFlag_BUSY(i2c_base_adr)) {;}
527 if(!LL_I2C_IsActiveFlag_BUSY(i2c_base_adr))
535 i2c_isr = i2c_base_adr->ISR;
537 while((i2c_isr & (I2C_ISR_RXNE | I2C_ISR_TC | I2C_ISR_TCR | I2C_ISR_NACKF)) == 0);
540 if(i2c_isr & I2C_ISR_RXNE)
545 *data_u8++ = LL_I2C_ReceiveData8(i2c_base_adr);
551 if(i2c_isr & I2C_ISR_NACKF)
554 LL_I2C_ClearFlag_NACK(i2c_base_adr);
558 while(LL_I2C_IsActiveFlag_BUSY(i2c_base_adr)) {;}
562 if(i2c_isr & I2C_ISR_TC)
572 if(i2c_isr & I2C_ISR_TCR)
575 if( (nr_of_bytes == 1)
578 LL_I2C_DisableReloadMode(i2c_base_adr);
588 LL_I2C_SetTransferSize(i2c_base_adr, 1);
596 if(!LL_I2C_IsActiveFlag_BUSY(i2c_base_adr))
602 LL_I2C_GenerateStopCondition(i2c_base_adr);
604 while(!LL_I2C_IsActiveFlag_STOP(i2c_base_adr)) {;}
606 LL_I2C_ClearFlag_STOP(i2c_base_adr);
608 while(LL_I2C_IsActiveFlag_BUSY(i2c_base_adr)) {;}
623 ||(handle->
i2c_per->open_counter == 0 ) )
#define NULL
NULL pointer.
#define PX_LOG_NAME(name)
Macro to declare a log name string once for each file to reduce code size.
#define PX_LOG_W(format,...)
Macro to display a formatted WARNING message.
#define PX_LOG_E(format,...)
Macro to display a formatted ERROR message.
#define PX_LOG_ASSERT(expression)
Macro that will test an expression, and block indefinitely if false.
uint8_t slave_adr
7-bit I2C slave address
struct px_i2c_per_s * i2c_per
I2C peripheral data.
#define PX_I2C_FLAG_START
Begin I2C transaction with a START condition.
#define PX_I2C_CFG_TIMINGR
I2C peripheral timing register value Calculated using STM32CubeMX graphical tool:
bool px_i2c_close(px_i2c_handle_t *handle)
Close specified handle.
void px_i2c_init(void)
Initialise I2C driver.
bool px_i2c_open(px_i2c_handle_t *handle, px_i2c_nr_t i2c_nr, uint8_t slave_adr)
Open I2C slave handle.
px_i2c_nr_t
Specify I2C peripheral.
bool px_i2c_rd(px_i2c_handle_t *handle, void *data, size_t nr_of_bytes, uint8_t flags)
Perform an I2C read transaction with an I2C slave.
#define PX_I2C_FLAG_END
Signal END of current I2C transaction for REP_START to follow.
#define PX_I2C_FLAG_REP_START
Begin I2C transaction with a REPEATED START condition.
#define PX_I2C_FLAG_STOP
Finish I2C transaction with a STOP condition.
void px_i2c_change_slave_adr(px_i2c_handle_t *handle, uint8_t slave_adr)
Change I2C slave address.
bool px_i2c_wr(px_i2c_handle_t *handle, const void *data, size_t nr_of_bytes, uint8_t flags)
Perform an I2C write transaction with an I2C slave.
Define I2C handle for a slave.
Definition of data for each I2C peripheral.
I2C_TypeDef * i2c_base_adr
I2C peripheral base register address.
px_i2c_nr_t i2c_nr
Peripheral.
uint8_t open_counter
Number of open handles referencing peripheral.