35 #if defined(PIOS_INCLUDE_I2C)
37 #include <pios_i2c_priv.h>
39 struct pios_i2c_adapter {
56 #if defined(PIOS_I2C_DIAGNOSTICS)
57 volatile struct pios_i2c_fault_history i2c_adapter_fault_history;
59 volatile uint32_t i2c_evirq_history[I2C_LOG_DEPTH];
60 volatile uint8_t i2c_evirq_history_pointer;
62 volatile uint32_t i2c_erirq_history[I2C_LOG_DEPTH];
63 volatile uint8_t i2c_erirq_history_pointer;
66 volatile uint8_t i2c_state_history_pointer;
69 volatile uint8_t i2c_state_event_history_pointer;
71 volatile uint32_t i2c_fsm_fault_count;
72 volatile uint32_t i2c_bad_event_counter;
73 volatile uint32_t i2c_error_interrupt_counter;
74 volatile uint32_t i2c_nack_counter;
75 volatile uint32_t i2c_timeout_counter;
79 #if defined(PIOS_I2C_DIAGNOSTICS)
81 #define I2C_DIAG(adapter, field, val) \
83 (adapter)->i2c_##field##_history[(adapter)->i2c_##field##_history_pointer] = val; \
84 (adapter)->i2c_##field##_history_pointer = ((adapter)->i2c_##field##_history_pointer + 1) % I2C_LOG_DEPTH; \
87 #define I2C_DIAG_INCR(adapter, field) do { (adapter)->field++; } while (0)
90 #define I2C_DIAG(adapter, field, val) do { (void) (adapter); (void) (val); } while (0)
92 #define I2C_DIAG_INCR(adapter, field) do { (void) (adapter); } while (0)
94 #define i2c_adapter_log_fault(adapter, val) do { (void) (adapter); (void) (val); } while (0)
97 static void i2c_adapter_inject_event(
struct pios_i2c_adapter *i2c_adapter,
enum i2c_adapter_event event,
bool *woken);
99 static bool PIOS_I2C_validate(
struct pios_i2c_adapter *i2c_adapter)
104 static struct pios_i2c_adapter *PIOS_I2C_alloc(
void)
106 struct pios_i2c_adapter *i2c_adapter;
108 i2c_adapter =
PIOS_malloc(
sizeof(
struct pios_i2c_adapter));
110 if (i2c_adapter == NULL)
114 memset(i2c_adapter, 0,
sizeof(*i2c_adapter));
122 static void i2c_adapter_reset_bus(
struct pios_i2c_adapter *i2c_adapter)
124 uint8_t retry_count = 0;
125 uint8_t retry_count_clk = 0;
126 static const uint8_t MAX_I2C_RETRY_COUNT = 10;
129 I2C_DeInit(i2c_adapter->cfg->regs);
132 GPIO_InitTypeDef scl_gpio_init;
133 scl_gpio_init = i2c_adapter->cfg->scl.init;
134 scl_gpio_init.GPIO_Mode = GPIO_Mode_OUT;
135 GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
136 GPIO_Init(i2c_adapter->cfg->scl.gpio, &scl_gpio_init);
138 GPIO_InitTypeDef sda_gpio_init;
139 sda_gpio_init = i2c_adapter->cfg->sda.init;
140 sda_gpio_init.GPIO_Mode = GPIO_Mode_OUT;
141 GPIO_SetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
142 GPIO_Init(i2c_adapter->cfg->sda.gpio, &sda_gpio_init);
149 while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET && (retry_count_clk++ < MAX_I2C_RETRY_COUNT)) {
152 GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
153 while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET && (retry_count++ < MAX_I2C_RETRY_COUNT))
159 GPIO_ResetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
163 GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
168 GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
170 GPIO_ResetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
172 GPIO_ResetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
176 GPIO_SetBits(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin);
177 GPIO_SetBits(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin);
180 while (GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET && (retry_count++ < MAX_I2C_RETRY_COUNT))
185 while (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) != Bit_SET && (retry_count++ < MAX_I2C_RETRY_COUNT))
190 if (i2c_adapter->cfg->remap) {
191 GPIO_PinAFConfig(i2c_adapter->cfg->scl.gpio,
192 __builtin_ctz(i2c_adapter->cfg->scl.init.GPIO_Pin),
193 i2c_adapter->cfg->remap);
194 GPIO_PinAFConfig(i2c_adapter->cfg->sda.gpio,
195 __builtin_ctz(i2c_adapter->cfg->sda.init.GPIO_Pin),
196 i2c_adapter->cfg->remap);
198 GPIO_Init(i2c_adapter->cfg->scl.gpio, (GPIO_InitTypeDef *) & (i2c_adapter->cfg->scl.init));
199 GPIO_Init(i2c_adapter->cfg->sda.gpio, (GPIO_InitTypeDef *) & (i2c_adapter->cfg->sda.init));
202 I2C_DeInit(i2c_adapter->cfg->regs);
205 I2C_Init(i2c_adapter->cfg->regs, (I2C_InitTypeDef *) & (i2c_adapter->cfg->init));
208 I2C_Cmd(i2c_adapter->cfg->regs, ENABLE);
210 #if defined(STM32F30X)
211 if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_BUSY))
212 I2C_SoftwareResetCmd(i2c_adapter->cfg->regs);
213 #elif defined(STM32F4XX)
214 if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_BUSY))
215 I2C_SoftwareResetCmd(i2c_adapter->cfg->regs, ENABLE);
227 bool valid = PIOS_I2C_validate(i2c_adapter);
238 if (GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET ||
239 GPIO_ReadInputDataBit(i2c_adapter->cfg->scl.gpio, i2c_adapter->cfg->scl.init.GPIO_Pin) == Bit_RESET) {
249 static void i2c_adapter_fsm_init(
struct pios_i2c_adapter *i2c_adapter)
251 i2c_adapter_reset_bus(i2c_adapter);
265 struct pios_i2c_adapter *i2c_adapter;
267 i2c_adapter = (
struct pios_i2c_adapter *) PIOS_I2C_alloc();
272 i2c_adapter->cfg =
cfg;
278 i2c_adapter_fsm_init(i2c_adapter);
287 *i2c_id = i2c_adapter;
290 NVIC_Init((NVIC_InitTypeDef *) & (i2c_adapter->cfg->event.init));
291 NVIC_Init((NVIC_InitTypeDef *) & (i2c_adapter->cfg->error.init));
302 bool valid = PIOS_I2C_validate(i2c_adapter);
308 if (
PIOS_Mutex_Lock(i2c_adapter->lock, i2c_adapter->cfg->transfer_timeout_ms) ==
false)
313 i2c_adapter->last_txn = &txn_list[num_txns - 1];
314 i2c_adapter->active_txn = &txn_list[0];
315 i2c_adapter->bus_error =
false;
316 i2c_adapter->nack =
false;
325 bool semaphore_success = (
PIOS_Semaphore_Take(i2c_adapter->sem_ready, i2c_adapter->cfg->transfer_timeout_ms) ==
true);
327 if (!semaphore_success)
328 I2C_DIAG_INCR(i2c_adapter, i2c_timeout_counter);
330 int32_t result = !semaphore_success ? -2 :
331 i2c_adapter->bus_error ? -1 :
332 i2c_adapter->nack ? -3 :
340 #if defined(PIOS_I2C_DIAGNOSTICS)
348 i2c_adapter->i2c_adapter_fault_history.type =
type;
349 for (uint8_t
i = 0;
i < I2C_LOG_DEPTH;
i++) {
350 i2c_adapter->i2c_adapter_fault_history.evirq[
i] =
351 i2c_adapter->i2c_evirq_history[(I2C_LOG_DEPTH + i2c_adapter->i2c_evirq_history_pointer - 1 -
i) % I2C_LOG_DEPTH];
352 i2c_adapter->i2c_adapter_fault_history.erirq[
i] =
353 i2c_adapter->i2c_erirq_history[(I2C_LOG_DEPTH + i2c_adapter->i2c_erirq_history_pointer - 1 -
i) % I2C_LOG_DEPTH];
354 i2c_adapter->i2c_adapter_fault_history.event[
i] =
355 i2c_adapter->i2c_state_event_history[(I2C_LOG_DEPTH + i2c_adapter->i2c_state_event_history_pointer - 1 -
i) % I2C_LOG_DEPTH];
356 i2c_adapter->i2c_adapter_fault_history.state[
i] =
357 i2c_adapter->i2c_state_history[(I2C_LOG_DEPTH + i2c_adapter->i2c_state_history_pointer - 1 -
i) % I2C_LOG_DEPTH];
361 i2c_adapter->i2c_bad_event_counter++;
364 i2c_adapter->i2c_fsm_fault_count++;
367 i2c_adapter->i2c_error_interrupt_counter++;
373 static void go_fsm_fault(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
374 static void go_bus_error(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
375 static void go_stopped(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
376 static void go_starting(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
377 static void go_nack(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
381 static void receive_byte(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
384 *i2c_adapter->active_byte = I2C_ReceiveData(i2c_adapter->cfg->regs);
387 i2c_adapter->active_byte++;
390 static void send_byte(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
393 I2C_SendData(i2c_adapter->cfg->regs, *i2c_adapter->active_byte);
396 i2c_adapter->active_byte++;
400 struct i2c_adapter_transition {
401 void (*entry_fn)(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
405 #if defined(STM32F30X)
406 static void go_transfer_complete(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
416 .entry_fn = go_bus_error,
423 .entry_fn = go_stopped,
431 .entry_fn = go_starting,
433 [I2C_EVENT_TRANSMIT_BUFFER_EMPTY] = I2C_STATE_WRITE_BYTE,
434 [I2C_EVENT_RECEIVER_BUFFER_NOT_EMPTY] = I2C_STATE_READ_BYTE,
440 [I2C_STATE_WRITE_BYTE] = {
441 .entry_fn = send_byte,
443 [I2C_EVENT_TRANSMIT_BUFFER_EMPTY] = I2C_STATE_WRITE_BYTE,
444 [I2C_EVENT_RECEIVER_BUFFER_NOT_EMPTY] = I2C_STATE_READ_BYTE,
451 [I2C_STATE_READ_BYTE] = {
452 .entry_fn = receive_byte,
454 [I2C_EVENT_TRANSMIT_BUFFER_EMPTY] = I2C_STATE_WRITE_BYTE,
455 [I2C_EVENT_RECEIVER_BUFFER_NOT_EMPTY] = I2C_STATE_READ_BYTE,
463 .entry_fn = go_transfer_complete,
477 #elif defined(STM32F4XX)
479 static void prepare_nack(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
480 static void prepare_ack(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
481 static void receive_byte(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
482 static void send_byte(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
483 static void send_address_and_enable_BUF_intr(
struct pios_i2c_adapter *i2c_adapter,
485 static void send_w_address(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
486 static void receive_and_setup_nack(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
487 static void advance_txn_and_start(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
489 static void go_r_last_txn_post_last(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
491 static void go_w_last_txn_post_last(
struct pios_i2c_adapter *i2c_adapter,
bool *woken);
501 .entry_fn = go_bus_error,
513 .entry_fn = go_stopped,
520 .entry_fn = go_starting,
522 [I2C_EVENT_R_MORE_TXN_STARTED] = I2C_STATE_R_MORE_TXN_ADDR,
523 [I2C_EVENT_W_MORE_TXN_STARTED] = I2C_STATE_W_MORE_TXN_ADDR,
524 [I2C_EVENT_R_LAST_TXN_STARTED] = I2C_STATE_R_LAST_TXN_ADDR,
525 [I2C_EVENT_W_LAST_TXN_STARTED] = I2C_STATE_W_LAST_TXN_ADDR,
534 [I2C_STATE_R_MORE_TXN_ADDR] = {
535 .entry_fn = send_address_and_enable_BUF_intr,
537 [I2C_EVENT_ADDR_SENT_LEN_EQ_1] = I2C_STATE_R_MORE_TXN_PRE_ONE,
538 [I2C_EVENT_ADDR_SENT_LEN_EQ_2] = I2C_STATE_R_MORE_TXN_PRE_FIRST,
539 [I2C_EVENT_ADDR_SENT_LEN_GT_2] = I2C_STATE_R_MORE_TXN_PRE_FIRST,
543 [I2C_STATE_R_MORE_TXN_PRE_ONE] = {
544 .entry_fn = prepare_nack,
546 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1] = I2C_STATE_MORE_TXN_POST_LAST,
550 [I2C_STATE_R_MORE_TXN_PRE_FIRST] = {
551 .entry_fn = prepare_ack,
553 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2] = I2C_STATE_R_MORE_TXN_PRE_LAST,
554 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2] = I2C_STATE_R_MORE_TXN_PRE_MIDDLE,
558 [I2C_STATE_R_MORE_TXN_PRE_MIDDLE] = {
559 .entry_fn = receive_byte,
561 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2] = I2C_STATE_R_MORE_TXN_PRE_LAST,
562 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2] = I2C_STATE_R_MORE_TXN_PRE_MIDDLE,
566 [I2C_STATE_R_MORE_TXN_PRE_LAST] = {
567 .entry_fn = receive_and_setup_nack,
569 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1] = I2C_STATE_MORE_TXN_POST_LAST,
577 [I2C_STATE_R_LAST_TXN_ADDR] = {
578 .entry_fn = send_address_and_enable_BUF_intr,
580 [I2C_EVENT_ADDR_SENT_LEN_EQ_1] = I2C_STATE_R_LAST_TXN_PRE_ONE,
581 [I2C_EVENT_ADDR_SENT_LEN_EQ_2] = I2C_STATE_R_LAST_TXN_PRE_FIRST,
582 [I2C_EVENT_ADDR_SENT_LEN_GT_2] = I2C_STATE_R_LAST_TXN_PRE_FIRST,
586 [I2C_STATE_R_LAST_TXN_PRE_ONE] = {
587 .entry_fn = prepare_nack,
589 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1] = I2C_STATE_R_LAST_TXN_POST_LAST,
593 [I2C_STATE_R_LAST_TXN_PRE_FIRST] = {
594 .entry_fn = prepare_ack,
596 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2] = I2C_STATE_R_LAST_TXN_PRE_LAST,
597 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2] = I2C_STATE_R_LAST_TXN_PRE_MIDDLE,
601 [I2C_STATE_R_LAST_TXN_PRE_MIDDLE] = {
602 .entry_fn = receive_byte,
604 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2] = I2C_STATE_R_LAST_TXN_PRE_LAST,
605 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2] = I2C_STATE_R_LAST_TXN_PRE_MIDDLE,
609 [I2C_STATE_R_LAST_TXN_PRE_LAST] = {
610 .entry_fn = receive_and_setup_nack,
612 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1] = I2C_STATE_R_LAST_TXN_POST_LAST,
616 [I2C_STATE_R_LAST_TXN_POST_LAST] = {
617 .entry_fn = go_r_last_txn_post_last,
626 [I2C_STATE_W_MORE_TXN_ADDR] = {
627 .entry_fn = send_w_address,
629 [I2C_EVENT_ADDR_SENT_LEN_EQ_1] = I2C_STATE_W_MORE_TXN_PRE,
630 [I2C_EVENT_ADDR_SENT_LEN_EQ_2] = I2C_STATE_W_MORE_TXN_PRE,
631 [I2C_EVENT_ADDR_SENT_LEN_GT_2] = I2C_STATE_W_MORE_TXN_PRE,
635 [I2C_STATE_W_MORE_TXN_PRE] = {
636 .entry_fn = send_byte,
638 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_0] = I2C_STATE_MORE_TXN_POST_LAST,
639 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1] = I2C_STATE_W_MORE_TXN_PRE,
640 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2] = I2C_STATE_W_MORE_TXN_PRE,
641 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2] = I2C_STATE_W_MORE_TXN_PRE,
647 [I2C_STATE_MORE_TXN_POST_LAST] = {
648 .entry_fn = advance_txn_and_start,
650 [I2C_EVENT_R_MORE_TXN_STARTED] = I2C_STATE_R_MORE_TXN_ADDR,
651 [I2C_EVENT_W_MORE_TXN_STARTED] = I2C_STATE_W_MORE_TXN_ADDR,
652 [I2C_EVENT_R_LAST_TXN_STARTED] = I2C_STATE_R_LAST_TXN_ADDR,
653 [I2C_EVENT_W_LAST_TXN_STARTED] = I2C_STATE_W_LAST_TXN_ADDR,
662 [I2C_STATE_W_LAST_TXN_ADDR] = {
663 .entry_fn = send_w_address,
665 [I2C_EVENT_ADDR_SENT_LEN_EQ_1] = I2C_STATE_W_LAST_TXN_PRE,
666 [I2C_EVENT_ADDR_SENT_LEN_EQ_2] = I2C_STATE_W_LAST_TXN_PRE,
667 [I2C_EVENT_ADDR_SENT_LEN_GT_2] = I2C_STATE_W_LAST_TXN_PRE,
671 [I2C_STATE_W_LAST_TXN_PRE] = {
672 .entry_fn = send_byte,
674 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_0] = I2C_STATE_W_LAST_TXN_POST_LAST,
675 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1] = I2C_STATE_W_LAST_TXN_PRE,
676 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2] = I2C_STATE_W_LAST_TXN_PRE,
677 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2] = I2C_STATE_W_LAST_TXN_PRE,
681 [I2C_STATE_W_LAST_TXN_POST_LAST] = {
682 .entry_fn = go_w_last_txn_post_last,
691 static void i2c_adapter_process_auto(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
696 while (i2c_adapter_transitions[i2c_adapter->state].next_state[
I2C_EVENT_AUTO]) {
697 i2c_adapter->state = i2c_adapter_transitions[i2c_adapter->state].next_state[
I2C_EVENT_AUTO];
700 if (i2c_adapter_transitions[i2c_adapter->state].entry_fn) {
701 i2c_adapter_transitions[i2c_adapter->state].entry_fn(i2c_adapter, woken);
706 static void i2c_adapter_inject_event(
struct pios_i2c_adapter *i2c_adapter,
enum i2c_adapter_event event,
bool *woken)
708 I2C_DIAG(i2c_adapter, state_event, event);
709 I2C_DIAG(i2c_adapter,
state, i2c_adapter->state);
724 i2c_adapter->state = i2c_adapter_transitions[i2c_adapter->state].next_state[event];
727 if (i2c_adapter_transitions[i2c_adapter->state].entry_fn) {
728 i2c_adapter_transitions[i2c_adapter->state].entry_fn(i2c_adapter, woken);
732 i2c_adapter_process_auto(i2c_adapter, woken);
735 static void go_fsm_fault(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
737 #if defined(I2C_HALT_ON_ERRORS)
741 i2c_adapter->bus_error =
true;
743 i2c_adapter_reset_bus(i2c_adapter);
746 static void go_bus_error(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
749 i2c_adapter->bus_error =
true;
751 i2c_adapter_reset_bus(i2c_adapter);
754 static void set_i2c_irqs(
struct pios_i2c_adapter *i2c_adapter, FunctionalState new_state)
756 #if defined(STM32F30X)
757 I2C_ITConfig(i2c_adapter->cfg->regs, I2C_IT_ERRI | I2C_IT_TCI | I2C_IT_NACKI | I2C_IT_RXI | I2C_IT_STOPI | I2C_IT_TXI, new_state);
758 #elif defined(STM32F4XX)
759 I2C_ITConfig(i2c_adapter->cfg->regs, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR, new_state);
763 static void go_nack(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
765 i2c_adapter->nack =
true;
766 set_i2c_irqs(i2c_adapter, DISABLE);
768 I2C_AcknowledgeConfig(i2c_adapter->cfg->regs, DISABLE);
769 I2C_GenerateSTART(i2c_adapter->cfg->regs, DISABLE);
770 I2C_GenerateSTOP(i2c_adapter->cfg->regs, ENABLE);
773 static void go_stopped(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
775 set_i2c_irqs(i2c_adapter, DISABLE);
779 #if defined(I2C_HALT_ON_ERRORS)
785 static void setup_txn_ptrs(
struct pios_i2c_adapter *i2c_adapter)
788 i2c_adapter->active_byte = &(i2c_adapter->active_txn->buf[0]);
789 i2c_adapter->last_byte = &(i2c_adapter->active_txn->buf[i2c_adapter->active_txn->len - 1]);
792 #if defined(STM32F30X)
793 static void go_starting(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
799 setup_txn_ptrs(i2c_adapter);
801 set_i2c_irqs(i2c_adapter, ENABLE);
803 I2C_TransferHandling(
804 i2c_adapter->cfg->regs,
805 (i2c_adapter->active_txn->addr << 1),
806 i2c_adapter->active_txn->len,
807 i2c_adapter->active_txn == i2c_adapter->last_txn ? I2C_AutoEnd_Mode : I2C_SoftEnd_Mode,
808 i2c_adapter->active_txn->rw ==
PIOS_I2C_TXN_WRITE ? I2C_Generate_Start_Write : I2C_Generate_Start_Read);
811 static void go_transfer_complete(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
814 i2c_adapter->active_txn++;
822 bool valid = PIOS_I2C_validate(i2c_adapter);
827 if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_RXNE)) {
829 I2C_DIAG(i2c_adapter, evirq, I2C_FLAG_RXNE);
830 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_RECEIVER_BUFFER_NOT_EMPTY, &woken);
831 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_TXIS)) {
833 I2C_DIAG(i2c_adapter, evirq, I2C_FLAG_TXIS);
834 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSMIT_BUFFER_EMPTY, &woken);
835 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_NACKF)) {
836 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_NACKF);
837 I2C_DIAG(i2c_adapter, evirq, I2C_FLAG_NACKF);
838 I2C_DIAG_INCR(i2c_adapter, i2c_nack_counter);
840 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_TC)) {
841 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_TC);
842 I2C_DIAG(i2c_adapter, evirq, I2C_FLAG_TC);
843 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_COMPLETE, &woken);
844 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_STOPF)) {
845 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_STOPF);
846 I2C_DIAG(i2c_adapter, evirq, I2C_FLAG_STOPF);
858 bool valid = PIOS_I2C_validate(i2c_adapter);
861 if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_BERR)) {
862 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_BERR);
863 I2C_DIAG(i2c_adapter, erirq, I2C_FLAG_BERR);
864 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_ARLO)) {
865 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_ARLO);
866 I2C_DIAG(i2c_adapter, erirq, I2C_FLAG_ARLO);
867 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_OVR)) {
868 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_OVR);
869 I2C_DIAG(i2c_adapter, erirq, I2C_FLAG_OVR);
870 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_PECERR)) {
871 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_PECERR);
872 I2C_DIAG(i2c_adapter, erirq, I2C_FLAG_PECERR);
873 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_TIMEOUT)) {
874 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_TIMEOUT);
875 I2C_DIAG(i2c_adapter, erirq, I2C_FLAG_TIMEOUT);
876 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_ALERT)) {
877 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_ALERT);
878 I2C_DIAG(i2c_adapter, erirq, I2C_FLAG_ALERT);
879 }
else if (I2C_GetFlagStatus(i2c_adapter->cfg->regs, I2C_FLAG_BUSY)) {
880 I2C_ClearFlag(i2c_adapter->cfg->regs, I2C_FLAG_BUSY);
881 I2C_DIAG(i2c_adapter, erirq, I2C_FLAG_BUSY);
893 #elif defined(STM32F4XX)
895 static void go_starting(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
897 setup_txn_ptrs(i2c_adapter);
900 I2C_ITConfig(i2c_adapter->cfg->regs, I2C_IT_EVT | I2C_IT_ERR, ENABLE);
903 I2C_GenerateSTART(i2c_adapter->cfg->regs, ENABLE);
906 static void send_address_and_enable_BUF_intr(
struct pios_i2c_adapter *i2c_adapter,
910 I2C_ITConfig(i2c_adapter->cfg->regs, I2C_IT_BUF, ENABLE);
912 I2C_Send7bitAddress(i2c_adapter->cfg->regs, (i2c_adapter->active_txn->addr) << 1, I2C_Direction_Receiver);
915 static void prepare_nack(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
917 I2C_AcknowledgeConfig(i2c_adapter->cfg->regs, DISABLE);
920 static void prepare_ack(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
922 I2C_AcknowledgeConfig(i2c_adapter->cfg->regs, ENABLE);
925 static void advance_txn_and_start(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
928 I2C_ITConfig(i2c_adapter->cfg->regs, I2C_IT_BUF, DISABLE);
932 (void)I2C_ReceiveData(i2c_adapter->cfg->regs);
934 receive_byte(i2c_adapter, woken);
938 i2c_adapter->active_txn++;
940 setup_txn_ptrs(i2c_adapter);
943 I2C_GenerateSTART(i2c_adapter->cfg->regs, ENABLE);
946 static void send_w_address(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
948 I2C_Send7bitAddress(i2c_adapter->cfg->regs, (i2c_adapter->active_txn->addr) << 1, I2C_Direction_Transmitter);
951 static void receive_and_setup_nack(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
953 receive_byte(i2c_adapter, woken);
956 I2C_AcknowledgeConfig(i2c_adapter->cfg->regs, DISABLE);
962 static void go_r_last_txn_post_last(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
965 I2C_ITConfig(i2c_adapter->cfg->regs, I2C_IT_BUF, DISABLE);
967 receive_byte(i2c_adapter, woken);
970 I2C_GenerateSTOP(i2c_adapter->cfg->regs, ENABLE);
973 i2c_adapter->active_txn++;
980 static void go_w_last_txn_post_last(
struct pios_i2c_adapter *i2c_adapter,
bool *woken)
983 I2C_ITConfig(i2c_adapter->cfg->regs, I2C_IT_BUF, DISABLE);
986 I2C_GenerateSTOP(i2c_adapter->cfg->regs, ENABLE);
989 i2c_adapter->active_txn++;
996 PIOS_Assert(PIOS_I2C_validate(i2c_adapter) ==
true);
1001 uint32_t
event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
1003 I2C_DIAG(i2c_adapter, evirq, event);
1006 case I2C_EVENT_MASTER_MODE_SELECT:
1007 switch (i2c_adapter->active_txn->rw) {
1009 if (i2c_adapter->active_txn == i2c_adapter->last_txn) {
1011 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_R_LAST_TXN_STARTED, &woken);
1014 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_R_MORE_TXN_STARTED, &woken);
1018 if (i2c_adapter->active_txn == i2c_adapter->last_txn) {
1020 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_W_LAST_TXN_STARTED, &woken);
1023 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_W_MORE_TXN_STARTED, &woken);
1028 case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED:
1029 case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED:
1030 switch (i2c_adapter->last_byte - i2c_adapter->active_byte + 1) {
1032 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_ADDR_SENT_LEN_EQ_0, &woken);
1035 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_ADDR_SENT_LEN_EQ_1, &woken);
1038 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_ADDR_SENT_LEN_EQ_2, &woken);
1041 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_ADDR_SENT_LEN_GT_2, &woken);
1045 case I2C_EVENT_MASTER_BYTE_RECEIVED:
1046 case I2C_EVENT_MASTER_BYTE_TRANSMITTED:
1047 switch (i2c_adapter->last_byte - i2c_adapter->active_byte + 1) {
1049 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_EQ_0, &woken);
1052 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_EQ_1, &woken);
1055 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_EQ_2, &woken);
1058 i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_GT_2, &woken);
1062 case I2C_EVENT_MASTER_BYTE_TRANSMITTING:
1079 bool valid = PIOS_I2C_validate(i2c_adapter);
1084 uint32_t
event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
1087 I2C_ClearFlag(i2c_adapter->cfg->regs,
1096 I2C_DIAG(i2c_adapter, erirq, event);
1099 if (event & I2C_FLAG_AF) {
1100 I2C_DIAG_INCR(i2c_adapter, i2c_nack_counter);
1113 #error NoImplForArch
Main PiOS header to include all the compiled in PiOS options.
int32_t PIOS_I2C_CheckClear(pios_i2c_t i2c_id)
#define PIOS_DEBUG_Assert(test)
#define PIOS_IRQ_Epilogue()
void * PIOS_malloc(size_t size)
bool PIOS_Semaphore_Give_FromISR(struct pios_semaphore *sema, bool *woken)
static void go_fsm_fault(struct bl_fsm_context *context)
bool PIOS_Mutex_Unlock(struct pios_mutex *mtx)
struct pios_mutex * PIOS_Mutex_Create(void)
int32_t PIOS_I2C_Init(pios_i2c_t *i2c_id, const char *path)
static struct flyingpicmd_cfg_fa cfg
struct pios_semaphore * PIOS_Semaphore_Create(void)
Creates a binary semaphore.
struct pios_i2c_adapter * pios_i2c_t
void PIOS_I2C_EV_IRQ_Handler(pios_i2c_t i2c_id)
int32_t PIOS_I2C_Transfer(pios_i2c_t i2c_id, const struct pios_i2c_txn txn_list[], uint32_t num_txns)
void PIOS_I2C_ER_IRQ_Handler(pios_i2c_t i2c_id)
static struct pios_mutex * lock
bool PIOS_Semaphore_Take(struct pios_semaphore *sema, uint32_t timeout_ms)
Takes binary semaphore.
#define PIOS_IRQ_Prologue()
#define PIOS_Assert(test)
int32_t PIOS_DELAY_WaituS(uint32_t uS)
bool PIOS_Mutex_Lock(struct pios_mutex *mtx, uint32_t timeout_ms)