33 #include <libopencm3/stm32/rcc.h>
34 #include <libopencm3/stm32/gpio.h>
35 #include <libopencm3/cm3/nvic.h>
36 #include <libopencm3/cm3/scb.h>
52 #define I2C_SR1_ERR_MASK (I2C_SR1_SMBALERT | \
62 #define BIT_X_IS_SET_IN_REG(X,REG) (((REG) & (X)) == (X))
71 #define __I2C_REG_CRITICAL_ZONE_START __disable_irq();
72 #define __I2C_REG_CRITICAL_ZONE_STOP __enable_irq();
75 #ifndef NVIC_I2C_IRQ_PRIO
76 #define NVIC_I2C1_IRQ_PRIO 0
77 #define NVIC_I2C2_IRQ_PRIO 0
78 #define NVIC_I2C3_IRQ_PRIO 0
80 #define NVIC_I2C1_IRQ_PRIO NVIC_I2C_IRQ_PRIO
81 #define NVIC_I2C2_IRQ_PRIO NVIC_I2C_IRQ_PRIO
82 #define NVIC_I2C3_IRQ_PRIO NVIC_I2C_IRQ_PRIO
85 #if USE_I2C1 || USE_I2C2 || USE_I2C3
87 static void i2c_setup_gpio(
uint32_t i2c)
94 GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN,
102 GPIO_CNF_OUTPUT_ALTFN_OPENDRAIN,
111 #elif defined(STM32F4)
113 #define I2C1_GPIO_AF GPIO_AF4
117 #define I2C2_GPIO_AF GPIO_AF4
120 #ifndef I2C3_GPIO_SCL_AF
121 #define I2C3_GPIO_SCL_AF GPIO_AF4
123 #ifndef I2C3_GPIO_SDA_AF
124 #define I2C3_GPIO_SDA_AF GPIO_AF4
127 static void i2c_setup_gpio(
uint32_t i2c)
135 gpio_set_output_options(
GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ,
145 gpio_set_output_options(
I2C2_GPIO_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ,
189 i2c_enable_interrupt(i2c, I2C_CR2_ITERREN);
190 i2c_enable_interrupt(i2c, I2C_CR2_ITEVTEN);
191 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
194 i2c_nack_current(i2c);
195 i2c_disable_ack(i2c);
197 i2c_peripheral_enable(i2c);
228 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
237 uint16_t SR2 __attribute__((unused)) = I2C_SR2(i2c);
244 i2c_send_data(i2c, trans->
buf[0]);
245 if (trans->
len_w > 1) {
246 i2c_send_data(i2c, trans->
buf[1]);
255 i2c_enable_interrupt(i2c, I2C_CR2_ITBUFEN);
264 i2c_send_data(i2c, trans->
buf[periph->
idx_buf]);
270 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
299 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
308 i2c_nack_current(i2c);
309 i2c_disable_ack(i2c);
315 uint16_t SR2 __attribute__((unused)) = I2C_SR2(i2c);
324 i2c_enable_interrupt(i2c, I2C_CR2_ITBUFEN);
331 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
332 trans->
buf[0] = I2C_DR(i2c);
359 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
376 uint16_t SR2 __attribute__((unused)) = I2C_SR2(i2c);
379 i2c_disable_ack(i2c);
382 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
401 trans->
buf[0] = I2C_DR(i2c);
402 trans->
buf[1] = I2C_DR(i2c);
424 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
426 i2c_nack_current(i2c);
441 i2c_enable_interrupt(i2c, I2C_CR2_ITBUFEN);
446 uint16_t SR2 __attribute__((unused)) = I2C_SR2(i2c);
462 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
465 trans->
buf[periph->
idx_buf] = i2c_get_data(i2c);
476 i2c_enable_interrupt(i2c, I2C_CR2_ITBUFEN);
481 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
493 i2c_disable_ack(i2c);
496 trans->
buf[periph->
idx_buf] = i2c_get_data(i2c);
511 trans->
buf[periph->
idx_buf] = i2c_get_data(i2c);
516 i2c_enable_interrupt(i2c, I2C_CR2_ITBUFEN);
569 i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN);
580 i2c_send_data(i2c, 0x00);
585 uint16_t SR2 __attribute__((unused)) = I2C_SR2(i2c);
590 uint8_t dummy __attribute__((unused)) = i2c_get_data(i2c);
591 i2c_send_data(i2c, 0x00);
742 switch (trans->
len_r) {
784 i2c_send_data(i2c, 0x00);
795 i2c_send_data(i2c, 0x00);
838 #error "The STM32 doesn't have I2C0, use I2C1 or I2C2"
844 #ifndef I2C1_CLOCK_SPEED
845 #define I2C1_CLOCK_SPEED 200000
851 void i2c1_hw_init(
void)
857 i2c1.reg_addr = (
void *)
I2C1;
858 i2c1.init_struct = NULL;
859 i2c1.errors = &i2c1_errors;
870 nvic_enable_irq(NVIC_I2C1_EV_IRQ);
874 nvic_enable_irq(NVIC_I2C1_ER_IRQ);
878 rcc_periph_clock_enable(RCC_I2C1);
880 i2c_setup_gpio(
I2C1);
882 rcc_periph_reset_pulse(RST_I2C1);
885 i2c_peripheral_enable(
I2C1);
887 i2c_set_own_7bit_slave_address(
I2C1, 0);
890 i2c_enable_interrupt(
I2C1, I2C_CR2_ITERREN);
895 void i2c1_ev_isr(
void)
898 i2c_disable_interrupt(i2c, I2C_CR2_ITERREN);
901 i2c_enable_interrupt(i2c, I2C_CR2_ITERREN);
904 void i2c1_er_isr(
void)
907 i2c_disable_interrupt(i2c, I2C_CR2_ITEVTEN);
910 i2c_enable_interrupt(i2c, I2C_CR2_ITEVTEN);
918 #ifndef I2C2_CLOCK_SPEED
919 #define I2C2_CLOCK_SPEED 300000
925 void i2c2_hw_init(
void)
931 i2c2.reg_addr = (
void *)I2C2;
932 i2c2.init_struct = NULL;
933 i2c2.errors = &i2c2_errors;
944 nvic_enable_irq(NVIC_I2C2_EV_IRQ);
948 nvic_enable_irq(NVIC_I2C2_ER_IRQ);
952 rcc_periph_clock_enable(RCC_I2C2);
955 i2c_setup_gpio(I2C2);
957 rcc_periph_reset_pulse(RST_I2C2);
960 i2c_peripheral_enable(I2C2);
962 i2c_set_own_7bit_slave_address(I2C2, 0);
965 i2c_enable_interrupt(I2C2, I2C_CR2_ITERREN);
970 void i2c2_ev_isr(
void)
973 i2c_disable_interrupt(i2c, I2C_CR2_ITERREN);
976 i2c_enable_interrupt(i2c, I2C_CR2_ITERREN);
979 void i2c2_er_isr(
void)
982 i2c_disable_interrupt(i2c, I2C_CR2_ITEVTEN);
985 i2c_enable_interrupt(i2c, I2C_CR2_ITEVTEN);
991 #if USE_I2C3 && defined STM32F4
994 #ifndef I2C3_CLOCK_SPEED
995 #define I2C3_CLOCK_SPEED 300000
1001 void i2c3_hw_init(
void)
1007 i2c3.reg_addr = (
void *)I2C3;
1008 i2c3.init_struct = NULL;
1009 i2c3.errors = &i2c3_errors;
1020 nvic_enable_irq(NVIC_I2C3_EV_IRQ);
1024 nvic_enable_irq(NVIC_I2C3_ER_IRQ);
1028 rcc_periph_clock_enable(RCC_I2C3);
1031 i2c_setup_gpio(I2C3);
1033 rcc_periph_reset_pulse(RST_I2C3);
1036 i2c_peripheral_enable(I2C3);
1038 i2c_set_own_7bit_slave_address(I2C3, 0);
1041 i2c_enable_interrupt(I2C3, I2C_CR2_ITERREN);
1046 void i2c3_ev_isr(
void)
1049 i2c_disable_interrupt(i2c, I2C_CR2_ITERREN);
1052 i2c_enable_interrupt(i2c, I2C_CR2_ITERREN);
1055 void i2c3_er_isr(
void)
1058 i2c_disable_interrupt(i2c, I2C_CR2_ITEVTEN);
1061 i2c_enable_interrupt(i2c, I2C_CR2_ITEVTEN);
1075 volatile int devider;
1076 volatile int risetime;
1097 if (bitrate < 3000) {
1104 devider = (rcc_apb1_frequency / 2000) / (bitrate / 1000);
1112 if (devider >= 4095) {
1117 risetime = 1000000 / (bitrate / 1000) / 6 / 28;
1119 if (risetime < 10) {
1124 if (risetime >= 31) {
1133 i2c_peripheral_disable(i2c);
1137 i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_36MHZ);
1139 i2c_set_clock_frequency(i2c, I2C_CR2_FREQ_42MHZ);
1143 i2c_set_ccr(i2c, devider);
1145 i2c_set_trise(i2c, risetime);
1148 i2c_peripheral_enable(i2c);
1155 #define WD_DELAY 20 // number of ticks with 2ms - 40ms delay before resetting the bus
1156 #define WD_RECOVERY_TICKS 18 // number of generated SCL clocking pulses
1158 #if USE_I2C1 || USE_I2C2 || USE_I2C3
1159 static inline void i2c_scl_set(
uint32_t i2c)
1178 static inline void i2c_scl_toggle(
uint32_t i2c)
1197 static inline bool i2c_sda_get(
uint32_t i2c)
1218 static void i2c_wd_check(
struct i2c_periph *periph)
1225 i2c_disable_interrupt(i2c, I2C_CR2_ITEVTEN);
1226 i2c_disable_interrupt(i2c, I2C_CR2_ITERREN);
1233 trans = periph->
trans[i];
1237 i2c_peripheral_disable(i2c);
1260 if (i2c_sda_get(i2c)) {
1263 i2c_scl_toggle(i2c);
1268 i2c_setup_gpio(i2c);
1272 i2c_peripheral_enable(i2c);
1273 i2c_set_own_7bit_slave_address(i2c, 0);
1274 i2c_enable_interrupt(i2c, I2C_CR2_ITERREN);
1314 i2c_wd_check(&i2c1);
1318 i2c_wd_check(&i2c2);
1321 i2c_wd_check(&i2c3);
1337 if (temp >= I2C_TRANSACTION_QUEUE_LEN) { temp = 0; }
volatile uint16_t arb_lost_cnt
#define I2C_TRANSACTION_QUEUE_LEN
I2C transaction queue length.
#define I2C3_GPIO_PORT_SCL
volatile uint16_t miss_start_stop_cnt
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
uint16_t len_r
Number of bytes to read/receive.
static void __enable_irq(void)
transaction successfully finished by I2C driver
static bool i2c_idle(struct i2c_periph *p)
Check if I2C bus is idle.
static void i2c_irq(struct i2c_periph *periph)
Some architecture independent helper functions for GPIOs.
transmit and receive transaction
uint8_t trans_extract_idx
static void __disable_irq(void)
volatile uint16_t queue_full_cnt
#define BIT_X_IS_SET_IN_REG(X, REG)
struct i2c_errors * errors
#define __I2C_REG_CRITICAL_ZONE_STOP
static enum STMI2CSubTransactionStatus stmi2c_readmany(uint32_t i2c, struct i2c_periph *periph, struct i2c_transaction *trans)
void gpio_setup_output(ioportid_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as outputs.
volatile uint32_t er_irq_cnt
static void gpio_toggle(ioportid_t port, uint16_t pin)
Toggle a gpio output to low level.
#define I2C3_GPIO_PORT_SDA
void gpio_enable_clock(uint32_t port)
Enable the relevant clock.
#define __I2C_REG_CRITICAL_ZONE_START
uint8_t len_w
Number of bytes to write/transmit.
#define NVIC_I2C1_IRQ_PRIO
#define ZEROS_ERR_COUNTER(_i2c_err)
static enum STMI2CSubTransactionStatus stmi2c_read2(uint32_t i2c, struct i2c_periph *periph, struct i2c_transaction *trans)
Architecture independent timing functions.
static void i2c_error(struct i2c_periph *periph)
static bool i2c_stm32_idle(struct i2c_periph *periph)
struct i2c_transaction * trans[I2C_TRANSACTION_QUEUE_LEN]
static void i2c_stm32_setbitrate(struct i2c_periph *periph, int bitrate)
volatile uint16_t over_under_cnt
static enum STMI2CSubTransactionStatus stmi2c_read1(uint32_t i2c, struct i2c_periph *periph, struct i2c_transaction *trans)
I2C transaction structure.
enum I2CTransactionStatus status
Transaction status.
#define NVIC_I2C2_IRQ_PRIO
volatile uint16_t unexpected_event_cnt
uint8_t slave_addr
Slave address.
static uint8_t gpio_get(ioportid_t port, uint16_t pin)
Get level of a gpio.
STMI2CSubTransactionStatus
#define NVIC_I2C3_IRQ_PRIO
static bool i2c_stm32_submit(struct i2c_periph *periph, struct i2c_transaction *t)
transmit only transaction
volatile int16_t watchdog
volatile uint32_t last_unexpected_event
static void i2c_setbitrate(struct i2c_periph *p, int bitrate)
Set I2C bitrate.
static enum STMI2CSubTransactionStatus stmi2c_send(uint32_t i2c, struct i2c_periph *periph, struct i2c_transaction *trans)
volatile uint16_t wd_reset_cnt
volatile uint16_t smbus_alert_cnt
#define WD_RECOVERY_TICKS
void i2c_event(void)
i2c_event() function
enum I2CTransactionType type
Transaction type.
#define I2C1_CLOCK_SPEED
I2C defines.
#define SysTimeTimerStart(_t)
volatile uint16_t pec_recep_cnt
void gpio_setup_input(ioportid_t port, uint16_t gpios)
Setup one or more pins of the given GPIO port as inputs.
static void PPRZ_I2C_SEND_START(struct i2c_periph *periph)
static void gpio_set(ioportid_t port, uint16_t pin)
Set a gpio output to high level.
transaction is pending in queue
static void stmi2c_clear_pending_interrupts(uint32_t i2c)
static void PPRZ_I2C_SEND_STOP(uint32_t i2c)
volatile uint16_t ack_fail_cnt
volatile uint16_t timeout_tlow_cnt
Architecture independent I2C (Inter-Integrated Circuit Bus) API.