2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
5 * @addtogroup PIOS_I2C I2C Functions
6 * @brief STM32F4xx Hardware dependent I2C functionality
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
11 * @brief I2C Enable/Disable routines
12 * @see The GNU Public License (GPL) Version 3
14 *****************************************************************************/
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 3 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 * You should have received a copy of the GNU General Public License along
27 * with this program; if not, write to the Free Software Foundation, Inc.,
28 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 * @note This is very closely related to the F1xx code and should really
38 #ifdef PIOS_INCLUDE_I2C
40 #ifdef PIOS_INCLUDE_FREERTOS
44 #include <pios_i2c_priv.h>
46 enum i2c_adapter_state
{
47 I2C_STATE_FSM_FAULT
= 0, /* Must be zero so undefined transitions land here */
55 I2C_STATE_R_MORE_TXN_ADDR
,
56 I2C_STATE_R_MORE_TXN_PRE_ONE
,
57 I2C_STATE_R_MORE_TXN_PRE_FIRST
,
58 I2C_STATE_R_MORE_TXN_PRE_MIDDLE
,
59 I2C_STATE_R_MORE_TXN_PRE_LAST
,
60 I2C_STATE_R_MORE_TXN_POST_LAST
,
62 I2C_STATE_R_LAST_TXN_ADDR
,
63 I2C_STATE_R_LAST_TXN_PRE_ONE
,
64 I2C_STATE_R_LAST_TXN_PRE_FIRST
,
65 I2C_STATE_R_LAST_TXN_PRE_MIDDLE
,
66 I2C_STATE_R_LAST_TXN_PRE_LAST
,
67 I2C_STATE_R_LAST_TXN_POST_LAST
,
69 I2C_STATE_W_MORE_TXN_ADDR
,
70 I2C_STATE_W_MORE_TXN_MIDDLE
,
71 I2C_STATE_W_MORE_TXN_LAST
,
73 I2C_STATE_W_LAST_TXN_ADDR
,
74 I2C_STATE_W_LAST_TXN_MIDDLE
,
75 I2C_STATE_W_LAST_TXN_LAST
,
79 I2C_STATE_NUM_STATES
/* Must be last */
82 // #define I2C_HALT_ON_ERRORS
84 enum i2c_adapter_event
{
87 I2C_EVENT_STARTED_MORE_TXN_READ
,
88 I2C_EVENT_STARTED_MORE_TXN_WRITE
,
89 I2C_EVENT_STARTED_LAST_TXN_READ
,
90 I2C_EVENT_STARTED_LAST_TXN_WRITE
,
91 I2C_EVENT_ADDR_SENT_LEN_EQ_0
,
92 I2C_EVENT_ADDR_SENT_LEN_EQ_1
,
93 I2C_EVENT_ADDR_SENT_LEN_EQ_2
,
94 I2C_EVENT_ADDR_SENT_LEN_GT_2
,
95 I2C_EVENT_TRANSFER_DONE_LEN_EQ_0
,
96 I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
,
97 I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
,
98 I2C_EVENT_TRANSFER_DONE_LEN_GT_2
,
101 I2C_EVENT_AUTO
, /* FIXME: remove this */
103 I2C_EVENT_NUM_EVENTS
/* Must be last */
106 #if defined(PIOS_I2C_DIAGNOSTICS)
107 static struct pios_i2c_fault_history i2c_adapter_fault_history
;
109 volatile uint32_t i2c_evirq_history
[I2C_LOG_DEPTH
];
110 volatile uint8_t i2c_evirq_history_pointer
= 0;
112 volatile uint32_t i2c_erirq_history
[I2C_LOG_DEPTH
];
113 volatile uint8_t i2c_erirq_history_pointer
= 0;
115 volatile enum i2c_adapter_state i2c_state_history
[I2C_LOG_DEPTH
];
116 volatile uint8_t i2c_state_history_pointer
= 0;
118 volatile enum i2c_adapter_event i2c_state_event_history
[I2C_LOG_DEPTH
];
119 volatile uint8_t i2c_state_event_history_pointer
;
121 static uint8_t i2c_fsm_fault_count
= 0;
122 static uint8_t i2c_bad_event_counter
= 0;
123 static uint8_t i2c_error_interrupt_counter
= 0;
124 static uint8_t i2c_nack_counter
= 0;
125 static uint8_t i2c_timeout_counter
= 0;
128 static void go_fsm_fault(struct pios_i2c_adapter
*i2c_adapter
);
129 static void go_bus_error(struct pios_i2c_adapter
*i2c_adapter
);
130 static void go_stopping(struct pios_i2c_adapter
*i2c_adapter
);
131 static void go_stopped(struct pios_i2c_adapter
*i2c_adapter
);
132 static void go_starting(struct pios_i2c_adapter
*i2c_adapter
);
134 static void go_r_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
);
135 static void go_r_more_txn_pre_one(struct pios_i2c_adapter
*i2c_adapter
);
136 static void go_r_last_txn_pre_one(struct pios_i2c_adapter
*i2c_adapter
);
137 static void go_r_any_txn_pre_first(struct pios_i2c_adapter
*i2c_adapter
);
138 static void go_r_any_txn_pre_middle(struct pios_i2c_adapter
*i2c_adapter
);
139 static void go_r_last_txn_pre_last(struct pios_i2c_adapter
*i2c_adapter
);
140 static void go_r_more_txn_pre_last(struct pios_i2c_adapter
*i2c_adapter
);
141 static void go_r_any_txn_post_last(struct pios_i2c_adapter
*i2c_adapter
);
143 static void go_w_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
);
144 static void go_w_any_txn_middle(struct pios_i2c_adapter
*i2c_adapter
);
145 static void go_w_more_txn_last(struct pios_i2c_adapter
*i2c_adapter
);
146 static void go_w_last_txn_last(struct pios_i2c_adapter
*i2c_adapter
);
148 static void go_nack(struct pios_i2c_adapter
*i2c_adapter
);
150 struct i2c_adapter_transition
{
151 void (*entry_fn
)(struct pios_i2c_adapter
*i2c_adapter
);
152 enum i2c_adapter_state next_state
[I2C_EVENT_NUM_EVENTS
];
155 static void i2c_adapter_process_auto(struct pios_i2c_adapter
*i2c_adapter
);
156 static void i2c_adapter_inject_event(struct pios_i2c_adapter
*i2c_adapter
, enum i2c_adapter_event event
);
157 static void i2c_adapter_fsm_init(struct pios_i2c_adapter
*i2c_adapter
);
158 static bool i2c_adapter_wait_for_stopped(struct pios_i2c_adapter
*i2c_adapter
);
159 static void i2c_adapter_reset_bus(struct pios_i2c_adapter
*i2c_adapter
);
161 static void i2c_adapter_log_fault(enum pios_i2c_error_type type
);
162 static bool i2c_adapter_callback_handler(struct pios_i2c_adapter
*i2c_adapter
, signed portBASE_TYPE
*pxHigherPriorityTaskWoken
);
164 static const struct i2c_adapter_transition i2c_adapter_transitions
[I2C_STATE_NUM_STATES
] = {
165 [I2C_STATE_FSM_FAULT
] = {
166 .entry_fn
= go_fsm_fault
,
168 [I2C_EVENT_AUTO
] = I2C_STATE_STOPPING
,
171 [I2C_STATE_BUS_ERROR
] = {
172 .entry_fn
= go_bus_error
,
174 [I2C_EVENT_AUTO
] = I2C_STATE_STOPPING
,
178 [I2C_STATE_STOPPED
] = {
179 .entry_fn
= go_stopped
,
181 [I2C_EVENT_START
] = I2C_STATE_STARTING
,
182 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
186 [I2C_STATE_STOPPING
] = {
187 .entry_fn
= go_stopping
,
189 [I2C_EVENT_STOPPED
] = I2C_STATE_STOPPED
,
190 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
194 [I2C_STATE_STARTING
] = {
195 .entry_fn
= go_starting
,
197 [I2C_EVENT_STARTED_MORE_TXN_READ
] = I2C_STATE_R_MORE_TXN_ADDR
,
198 [I2C_EVENT_STARTED_MORE_TXN_WRITE
] = I2C_STATE_W_MORE_TXN_ADDR
,
199 [I2C_EVENT_STARTED_LAST_TXN_READ
] = I2C_STATE_R_LAST_TXN_ADDR
,
200 [I2C_EVENT_STARTED_LAST_TXN_WRITE
] = I2C_STATE_W_LAST_TXN_ADDR
,
201 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
202 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
210 [I2C_STATE_R_MORE_TXN_ADDR
] = {
211 .entry_fn
= go_r_any_txn_addr
,
213 [I2C_EVENT_ADDR_SENT_LEN_EQ_1
] = I2C_STATE_R_MORE_TXN_PRE_ONE
,
214 [I2C_EVENT_ADDR_SENT_LEN_EQ_2
] = I2C_STATE_R_MORE_TXN_PRE_FIRST
,
215 [I2C_EVENT_ADDR_SENT_LEN_GT_2
] = I2C_STATE_R_MORE_TXN_PRE_FIRST
,
216 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
220 [I2C_STATE_R_MORE_TXN_PRE_ONE
] = {
221 .entry_fn
= go_r_more_txn_pre_one
,
223 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_R_MORE_TXN_POST_LAST
,
224 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
228 [I2C_STATE_R_MORE_TXN_PRE_FIRST
] = {
229 .entry_fn
= go_r_any_txn_pre_first
,
231 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_R_MORE_TXN_PRE_LAST
,
232 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_R_MORE_TXN_PRE_MIDDLE
,
233 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
237 [I2C_STATE_R_MORE_TXN_PRE_MIDDLE
] = {
238 .entry_fn
= go_r_any_txn_pre_middle
,
240 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_R_MORE_TXN_PRE_LAST
,
241 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_R_MORE_TXN_PRE_MIDDLE
,
242 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
246 [I2C_STATE_R_MORE_TXN_PRE_LAST
] = {
247 .entry_fn
= go_r_more_txn_pre_last
,
249 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_R_MORE_TXN_POST_LAST
,
250 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
254 [I2C_STATE_R_MORE_TXN_POST_LAST
] = {
255 .entry_fn
= go_r_any_txn_post_last
,
257 [I2C_EVENT_AUTO
] = I2C_STATE_STARTING
,
265 [I2C_STATE_R_LAST_TXN_ADDR
] = {
266 .entry_fn
= go_r_any_txn_addr
,
268 [I2C_EVENT_ADDR_SENT_LEN_EQ_1
] = I2C_STATE_R_LAST_TXN_PRE_ONE
,
269 [I2C_EVENT_ADDR_SENT_LEN_EQ_2
] = I2C_STATE_R_LAST_TXN_PRE_FIRST
,
270 [I2C_EVENT_ADDR_SENT_LEN_GT_2
] = I2C_STATE_R_LAST_TXN_PRE_FIRST
,
271 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
275 [I2C_STATE_R_LAST_TXN_PRE_ONE
] = {
276 .entry_fn
= go_r_last_txn_pre_one
,
278 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_R_LAST_TXN_POST_LAST
,
279 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
283 [I2C_STATE_R_LAST_TXN_PRE_FIRST
] = {
284 .entry_fn
= go_r_any_txn_pre_first
,
286 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_R_LAST_TXN_PRE_LAST
,
287 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_R_LAST_TXN_PRE_MIDDLE
,
288 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
292 [I2C_STATE_R_LAST_TXN_PRE_MIDDLE
] = {
293 .entry_fn
= go_r_any_txn_pre_middle
,
295 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_R_LAST_TXN_PRE_LAST
,
296 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_R_LAST_TXN_PRE_MIDDLE
,
297 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
301 [I2C_STATE_R_LAST_TXN_PRE_LAST
] = {
302 .entry_fn
= go_r_last_txn_pre_last
,
304 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_R_LAST_TXN_POST_LAST
,
305 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
309 [I2C_STATE_R_LAST_TXN_POST_LAST
] = {
310 .entry_fn
= go_r_any_txn_post_last
,
312 [I2C_EVENT_AUTO
] = I2C_STATE_STOPPING
,
320 [I2C_STATE_W_MORE_TXN_ADDR
] = {
321 .entry_fn
= go_w_any_txn_addr
,
323 [I2C_EVENT_ADDR_SENT_LEN_EQ_1
] = I2C_STATE_W_MORE_TXN_LAST
,
324 [I2C_EVENT_ADDR_SENT_LEN_EQ_2
] = I2C_STATE_W_MORE_TXN_MIDDLE
,
325 [I2C_EVENT_ADDR_SENT_LEN_GT_2
] = I2C_STATE_W_MORE_TXN_MIDDLE
,
326 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
327 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
331 [I2C_STATE_W_MORE_TXN_MIDDLE
] = {
332 .entry_fn
= go_w_any_txn_middle
,
334 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_W_MORE_TXN_LAST
,
335 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_W_MORE_TXN_MIDDLE
,
336 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_W_MORE_TXN_MIDDLE
,
337 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
338 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
342 [I2C_STATE_W_MORE_TXN_LAST
] = {
343 .entry_fn
= go_w_more_txn_last
,
345 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_0
] = I2C_STATE_STARTING
,
346 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
347 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
355 [I2C_STATE_W_LAST_TXN_ADDR
] = {
356 .entry_fn
= go_w_any_txn_addr
,
358 [I2C_EVENT_ADDR_SENT_LEN_EQ_1
] = I2C_STATE_W_LAST_TXN_LAST
,
359 [I2C_EVENT_ADDR_SENT_LEN_EQ_2
] = I2C_STATE_W_LAST_TXN_MIDDLE
,
360 [I2C_EVENT_ADDR_SENT_LEN_GT_2
] = I2C_STATE_W_LAST_TXN_MIDDLE
,
361 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
362 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
366 [I2C_STATE_W_LAST_TXN_MIDDLE
] = {
367 .entry_fn
= go_w_any_txn_middle
,
369 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_W_LAST_TXN_LAST
,
370 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_W_LAST_TXN_MIDDLE
,
371 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_W_LAST_TXN_MIDDLE
,
372 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
373 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
377 [I2C_STATE_W_LAST_TXN_LAST
] = {
378 .entry_fn
= go_w_last_txn_last
,
380 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_0
] = I2C_STATE_STOPPING
,
381 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
382 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
388 [I2C_EVENT_AUTO
] = I2C_STATE_STOPPING
,
394 static void go_fsm_fault(struct pios_i2c_adapter
*i2c_adapter
)
396 #if defined(I2C_HALT_ON_ERRORS)
397 PIOS_DEBUG_Assert(0);
399 /* Note that this transfer has hit a bus error */
400 i2c_adapter
->bus_error
= true;
402 i2c_adapter_reset_bus(i2c_adapter
);
406 static void go_bus_error(struct pios_i2c_adapter
*i2c_adapter
)
408 /* Note that this transfer has hit a bus error */
409 i2c_adapter
->bus_error
= true;
411 i2c_adapter_reset_bus(i2c_adapter
);
415 static void go_stopping(struct pios_i2c_adapter
*i2c_adapter
)
418 signed portBASE_TYPE pxHigherPriorityTaskWoken
= pdFALSE
;
421 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
423 if (i2c_adapter
->callback
) {
424 i2c_adapter_callback_handler(i2c_adapter
, &pxHigherPriorityTaskWoken
);
427 if (xSemaphoreGiveFromISR(i2c_adapter
->sem_ready
, &pxHigherPriorityTaskWoken
) != pdTRUE
) {
428 #if defined(I2C_HALT_ON_ERRORS)
429 PIOS_DEBUG_Assert(0);
432 #endif /* USE_FREERTOS */
435 portEND_SWITCHING_ISR(pxHigherPriorityTaskWoken
); /* FIXME: is this the right place for this? */
439 static void go_stopped(struct pios_i2c_adapter
*i2c_adapter
)
441 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
442 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, ENABLE
);
446 static void go_starting(struct pios_i2c_adapter
*i2c_adapter
)
448 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
449 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
450 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
452 // check for an empty read/write
453 if (i2c_adapter
->active_txn
->buf
!= NULL
&& i2c_adapter
->active_txn
->len
!= 0) {
455 i2c_adapter
->active_byte
= &(i2c_adapter
->active_txn
->buf
[0]);
456 i2c_adapter
->last_byte
= &(i2c_adapter
->active_txn
->buf
[i2c_adapter
->active_txn
->len
- 1]);
458 // No Data available => Empty read/write
459 i2c_adapter
->last_byte
= NULL
;
460 i2c_adapter
->active_byte
= i2c_adapter
->last_byte
+ 1;
463 I2C_GenerateSTART(i2c_adapter
->cfg
->regs
, ENABLE
);
464 if (i2c_adapter
->active_txn
->rw
== PIOS_I2C_TXN_READ
) {
465 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, ENABLE
);
467 // For write operations, do not enable the IT_BUF events.
468 // The current driver does not act when the TX data register is not full, only when the complete byte is sent.
469 // With the IT_BUF enabled, we constantly get IRQs, See OP-326
470 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_ERR
, ENABLE
);
475 /* Common to 'more' and 'last' transaction */
476 static void go_r_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
)
478 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
479 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
480 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
482 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
->rw
== PIOS_I2C_TXN_READ
);
484 I2C_Send7bitAddress(i2c_adapter
->cfg
->regs
, (i2c_adapter
->active_txn
->addr
) << 1, I2C_Direction_Receiver
);
488 static void go_r_more_txn_pre_one(struct pios_i2c_adapter
*i2c_adapter
)
490 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
491 I2C_GenerateSTART(i2c_adapter
->cfg
->regs
, ENABLE
);
495 static void go_r_last_txn_pre_one(struct pios_i2c_adapter
*i2c_adapter
)
497 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
498 I2C_GenerateSTOP(i2c_adapter
->cfg
->regs
, ENABLE
);
502 /* Common to 'more' and 'last' transaction */
503 static void go_r_any_txn_pre_first(struct pios_i2c_adapter
*i2c_adapter
)
505 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, ENABLE
);
509 /* Common to 'more' and 'last' transaction */
510 static void go_r_any_txn_pre_middle(struct pios_i2c_adapter
*i2c_adapter
)
512 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
513 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
515 *(i2c_adapter
->active_byte
) = I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
517 /* Move to the next byte */
518 i2c_adapter
->active_byte
++;
519 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
523 static void go_r_more_txn_pre_last(struct pios_i2c_adapter
*i2c_adapter
)
525 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
526 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
528 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
530 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
531 I2C_GenerateSTART(i2c_adapter
->cfg
->regs
, ENABLE
);
532 *(i2c_adapter
->active_byte
) = I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
533 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, ENABLE
);
536 /* Move to the next byte */
537 i2c_adapter
->active_byte
++;
538 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
542 static void go_r_last_txn_pre_last(struct pios_i2c_adapter
*i2c_adapter
)
544 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
545 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
547 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
549 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
550 I2C_GenerateSTOP(i2c_adapter
->cfg
->regs
, ENABLE
);
551 *(i2c_adapter
->active_byte
) = I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
552 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, ENABLE
);
555 /* Move to the next byte */
556 i2c_adapter
->active_byte
++;
557 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
561 /* Common to 'more' and 'last' transaction */
562 static void go_r_any_txn_post_last(struct pios_i2c_adapter
*i2c_adapter
)
564 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
565 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
== i2c_adapter
->last_byte
);
566 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
567 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
568 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
570 *(i2c_adapter
->active_byte
) = I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
572 /* Move to the next byte */
573 i2c_adapter
->active_byte
++;
575 /* Move to the next transaction */
576 i2c_adapter
->active_txn
++;
580 /* Common to 'more' and 'last' transaction */
581 static void go_w_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
)
583 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
584 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
585 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
587 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
->rw
== PIOS_I2C_TXN_WRITE
);
589 I2C_Send7bitAddress(i2c_adapter
->cfg
->regs
, (i2c_adapter
->active_txn
->addr
) << 1, I2C_Direction_Transmitter
);
593 static void go_w_any_txn_middle(struct pios_i2c_adapter
*i2c_adapter
)
595 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
596 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
< i2c_adapter
->last_byte
);
597 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
598 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
599 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
601 I2C_SendData(i2c_adapter
->cfg
->regs
, *(i2c_adapter
->active_byte
));
603 /* Move to the next byte */
604 i2c_adapter
->active_byte
++;
605 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
609 static void go_w_more_txn_last(struct pios_i2c_adapter
*i2c_adapter
)
611 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
612 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
== i2c_adapter
->last_byte
);
613 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
614 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
615 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
617 I2C_SendData(i2c_adapter
->cfg
->regs
, *(i2c_adapter
->active_byte
));
619 /* Move to the next byte */
620 i2c_adapter
->active_byte
++;
622 /* Move to the next transaction */
623 i2c_adapter
->active_txn
++;
624 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
628 static void go_w_last_txn_last(struct pios_i2c_adapter
*i2c_adapter
)
630 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
631 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
== i2c_adapter
->last_byte
);
632 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
633 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
634 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
636 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_BUF
, DISABLE
);
637 I2C_SendData(i2c_adapter
->cfg
->regs
, *(i2c_adapter
->active_byte
));
639 // SHOULD MOVE THIS INTO A STOPPING STATE AND SET IT ONLY AFTER THE BYTE WAS SENT
640 I2C_GenerateSTOP(i2c_adapter
->cfg
->regs
, ENABLE
);
642 /* Move to the next byte */
643 i2c_adapter
->active_byte
++;
647 static void go_nack(struct pios_i2c_adapter
*i2c_adapter
)
649 i2c_adapter
->nack
= true;
650 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
651 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
652 I2C_GenerateSTOP(i2c_adapter
->cfg
->regs
, ENABLE
);
656 static void i2c_adapter_inject_event(struct pios_i2c_adapter
*i2c_adapter
, enum i2c_adapter_event event
)
660 #if defined(PIOS_I2C_DIAGNOSTICS)
661 i2c_state_event_history
[i2c_state_event_history_pointer
] = event
;
662 i2c_state_event_history_pointer
= (i2c_state_event_history_pointer
+ 1) % I2C_LOG_DEPTH
;
664 i2c_state_history
[i2c_state_history_pointer
] = i2c_adapter
->curr_state
;
665 i2c_state_history_pointer
= (i2c_state_history_pointer
+ 1) % I2C_LOG_DEPTH
;
667 if (i2c_adapter_transitions
[i2c_adapter
->curr_state
].next_state
[event
] == I2C_STATE_FSM_FAULT
) {
668 i2c_adapter_log_fault(PIOS_I2C_ERROR_FSM
);
672 * Move to the next state
674 * This is done prior to calling the new state's entry function to
675 * guarantee that the entry function never depends on the previous
676 * state. This way, it cannot ever know what the previous state was.
678 i2c_adapter
->curr_state
= i2c_adapter_transitions
[i2c_adapter
->curr_state
].next_state
[event
];
680 /* Call the entry function (if any) for the next state. */
681 if (i2c_adapter_transitions
[i2c_adapter
->curr_state
].entry_fn
) {
682 i2c_adapter_transitions
[i2c_adapter
->curr_state
].entry_fn(i2c_adapter
);
685 /* Process any AUTO transitions in the FSM */
686 i2c_adapter_process_auto(i2c_adapter
);
692 static void i2c_adapter_process_auto(struct pios_i2c_adapter
*i2c_adapter
)
696 while (i2c_adapter_transitions
[i2c_adapter
->curr_state
].next_state
[I2C_EVENT_AUTO
]) {
697 i2c_adapter
->curr_state
= i2c_adapter_transitions
[i2c_adapter
->curr_state
].next_state
[I2C_EVENT_AUTO
];
699 /* Call the entry function (if any) for the next state. */
700 if (i2c_adapter_transitions
[i2c_adapter
->curr_state
].entry_fn
) {
701 i2c_adapter_transitions
[i2c_adapter
->curr_state
].entry_fn(i2c_adapter
);
709 static void i2c_adapter_fsm_init(struct pios_i2c_adapter
*i2c_adapter
)
711 i2c_adapter_reset_bus(i2c_adapter
);
712 i2c_adapter
->curr_state
= I2C_STATE_STOPPED
;
716 static bool i2c_adapter_wait_for_stopped(struct pios_i2c_adapter
*i2c_adapter
)
721 * Wait for the bus to return to the stopped state.
722 * This was pulled out of the FSM due to occasional
723 * failures at this transition which previously resulted
724 * in spinning on this bit in the ISR forever.
726 for (guard
= 1000000; /* FIXME: should use the configured bus timeout */
727 guard
&& (i2c_adapter
->cfg
->regs
->CR1
& I2C_CR1_STOP
); guard
--) {
731 /* We timed out waiting for the stop condition */
739 static void i2c_adapter_reset_bus(struct pios_i2c_adapter
*i2c_adapter
)
741 // retry with wait code from
742 // TauLabs 20150718 - Prevent F3 I2C Init Lockup #1728
744 uint8_t retry_count_clk
;
745 static const uint8_t MAX_I2C_RETRY_COUNT
= 10;
747 /* Reset the I2C block */
748 I2C_DeInit(i2c_adapter
->cfg
->regs
);
750 /* Make sure the bus is free by clocking it until any slaves release the bus. */
751 GPIO_InitTypeDef scl_gpio_init
;
752 scl_gpio_init
= i2c_adapter
->cfg
->scl
.init
;
753 scl_gpio_init
.GPIO_Mode
= GPIO_Mode_OUT
;
754 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
755 GPIO_Init(i2c_adapter
->cfg
->scl
.gpio
, &scl_gpio_init
);
757 GPIO_InitTypeDef sda_gpio_init
;
758 sda_gpio_init
= i2c_adapter
->cfg
->sda
.init
;
759 sda_gpio_init
.GPIO_Mode
= GPIO_Mode_OUT
;
760 GPIO_SetBits(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
);
761 GPIO_Init(i2c_adapter
->cfg
->sda
.gpio
, &sda_gpio_init
);
763 /* Check SDA line to determine if slave is asserting bus and clock out if so, this may */
764 /* have to be repeated (due to futher bus errors) but better than clocking 0xFF into an */
766 // bool sda_hung = GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET;
768 while (GPIO_ReadInputDataBit(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
) == Bit_RESET
&& (retry_count_clk
++ < MAX_I2C_RETRY_COUNT
)) {
770 /* Set clock high and wait for any clock stretching to finish. */
771 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
772 while (GPIO_ReadInputDataBit(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
) == Bit_RESET
&& (retry_count
++ < MAX_I2C_RETRY_COUNT
)) {
773 PIOS_DELAY_WaituS(1);
775 PIOS_DELAY_WaituS(2);
778 GPIO_ResetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
779 PIOS_DELAY_WaituS(2);
781 /* Clock high again */
782 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
783 PIOS_DELAY_WaituS(2);
786 /* Generate a start then stop condition */
787 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
788 PIOS_DELAY_WaituS(2);
789 GPIO_ResetBits(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
);
790 PIOS_DELAY_WaituS(2);
791 GPIO_ResetBits(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
);
792 PIOS_DELAY_WaituS(2);
794 /* Set data and clock high and wait for any clock stretching to finish. */
795 GPIO_SetBits(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
);
796 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
798 while (GPIO_ReadInputDataBit(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
) == Bit_RESET
&& (retry_count
++ < MAX_I2C_RETRY_COUNT
)) {
799 PIOS_DELAY_WaituS(1);
801 /* Wait for data to be high */
803 while (GPIO_ReadInputDataBit(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
) != Bit_SET
&& (retry_count
++ < MAX_I2C_RETRY_COUNT
)) {
804 PIOS_DELAY_WaituS(1);
808 /* Bus signals are guaranteed to be high (ie. free) after this point */
809 /* Initialize the GPIO pins to the peripheral function */
810 if (i2c_adapter
->cfg
->remapSCL
) {
811 GPIO_PinAFConfig(i2c_adapter
->cfg
->scl
.gpio
,
812 __builtin_ctz(i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
),
813 i2c_adapter
->cfg
->remapSCL
);
815 if (i2c_adapter
->cfg
->remapSDA
) {
816 GPIO_PinAFConfig(i2c_adapter
->cfg
->sda
.gpio
,
817 __builtin_ctz(i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
),
818 i2c_adapter
->cfg
->remapSDA
);
820 GPIO_Init(i2c_adapter
->cfg
->scl
.gpio
, (GPIO_InitTypeDef
*)&(i2c_adapter
->cfg
->scl
.init
)); // Struct is const, function signature not
821 GPIO_Init(i2c_adapter
->cfg
->sda
.gpio
, (GPIO_InitTypeDef
*)&(i2c_adapter
->cfg
->sda
.init
));
823 /* Reset the I2C block */
824 I2C_DeInit(i2c_adapter
->cfg
->regs
);
826 /* Initialize the I2C block */
827 I2C_Init(i2c_adapter
->cfg
->regs
, (I2C_InitTypeDef
*)&(i2c_adapter
->cfg
->init
));
829 // for delays during transfer timeouts
830 // one tick correspond to transmission of 1 byte i.e. 9 clock ticks
831 i2c_adapter
->transfer_delay_uS
= 9000000 / (((I2C_InitTypeDef
*)&(i2c_adapter
->cfg
->init
))->I2C_ClockSpeed
);
834 if (i2c_adapter
->cfg
->regs
->SR2
& I2C_FLAG_BUSY
) {
835 /* Reset the I2C block */
836 I2C_SoftwareResetCmd(i2c_adapter
->cfg
->regs
, ENABLE
);
837 I2C_SoftwareResetCmd(i2c_adapter
->cfg
->regs
, DISABLE
);
842 /* Return true if the FSM is in a terminal state */
843 static bool i2c_adapter_fsm_terminated(struct pios_i2c_adapter
*i2c_adapter
)
845 switch (i2c_adapter
->curr_state
) {
846 case I2C_STATE_STOPPING
:
847 case I2C_STATE_STOPPED
:
856 uint32_t i2c_cb_count
= 0;
857 static bool i2c_adapter_callback_handler(struct pios_i2c_adapter
*i2c_adapter
, signed portBASE_TYPE
*pxHigherPriorityTaskWoken
)
859 /* transfer_timeout_ticks is set by PIOS_I2C_Transfer_Callback */
860 /* Spin waiting for the transfer to finish */
861 while (!i2c_adapter_fsm_terminated(i2c_adapter
)) {
862 // sleep 1 byte, as FSM can't be faster
863 // FIXME: clock stretching could make problems, but citing NPX: alsmost no slave device implements clock stretching
864 // three times the expected time should cover clock delay
865 PIOS_DELAY_WaituS(i2c_adapter
->transfer_delay_uS
);
867 i2c_adapter
->transfer_timeout_ticks
--;
868 if (i2c_adapter
->transfer_timeout_ticks
== 0) {
873 if (i2c_adapter_wait_for_stopped(i2c_adapter
)) {
874 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STOPPED
);
876 i2c_adapter_fsm_init(i2c_adapter
);
881 xSemaphoreGiveFromISR(i2c_adapter
->sem_busy
, pxHigherPriorityTaskWoken
);
885 i2c_adapter
->busy
= 0;
887 #endif /* USE_FREERTOS */
890 // Execute user supplied function
891 if (i2c_adapter
->callback(PIOS_I2C_TRANSFER_OK
)) {
892 *pxHigherPriorityTaskWoken
= pdTRUE
;
897 return !i2c_adapter
->bus_error
;
902 * Logs the last N state transitions and N IRQ events due to
904 * \param[in] i2c the adapter number to log an event for
906 void i2c_adapter_log_fault(enum pios_i2c_error_type type
)
908 #if defined(PIOS_I2C_DIAGNOSTICS)
909 i2c_adapter_fault_history
.type
= type
;
910 for (uint8_t i
= 0; i
< I2C_LOG_DEPTH
; i
++) {
911 i2c_adapter_fault_history
.evirq
[i
] =
912 i2c_evirq_history
[(I2C_LOG_DEPTH
+ i2c_evirq_history_pointer
- 1 - i
) % I2C_LOG_DEPTH
];
913 i2c_adapter_fault_history
.erirq
[i
] =
914 i2c_erirq_history
[(I2C_LOG_DEPTH
+ i2c_erirq_history_pointer
- 1 - i
) % I2C_LOG_DEPTH
];
915 i2c_adapter_fault_history
.event
[i
] =
916 i2c_state_event_history
[(I2C_LOG_DEPTH
+ i2c_state_event_history_pointer
- 1 - i
) % I2C_LOG_DEPTH
];
917 i2c_adapter_fault_history
.state
[i
] =
918 i2c_state_history
[(I2C_LOG_DEPTH
+ i2c_state_history_pointer
- 1 - i
) % I2C_LOG_DEPTH
];
921 case PIOS_I2C_ERROR_EVENT
:
922 i2c_bad_event_counter
++;
924 case PIOS_I2C_ERROR_FSM
:
925 i2c_fsm_fault_count
++;
927 case PIOS_I2C_ERROR_INTERRUPT
:
928 i2c_error_interrupt_counter
++;
931 #endif /* if defined(PIOS_I2C_DIAGNOSTICS) */
936 * Logs the last N state transitions and N IRQ events due to
938 * \param[out] data address where to copy the pios_i2c_fault_history structure to
939 * \param[out] counts three uint16 that receive the bad event, fsm, and error irq
942 void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history
*data
, uint8_t *counts
)
944 #if defined(PIOS_I2C_DIAGNOSTICS)
945 memcpy(data
, &i2c_adapter_fault_history
, sizeof(i2c_adapter_fault_history
));
946 counts
[PIOS_I2C_BAD_EVENT_COUNTER
] = i2c_bad_event_counter
;
947 counts
[PIOS_I2C_FSM_FAULT_COUNT
] = i2c_fsm_fault_count
;
948 counts
[PIOS_I2C_ERROR_INTERRUPT_COUNTER
] = i2c_error_interrupt_counter
;
949 counts
[PIOS_I2C_NACK_COUNTER
] = i2c_nack_counter
;
950 counts
[PIOS_I2C_TIMEOUT_COUNTER
] = i2c_timeout_counter
;
952 struct pios_i2c_fault_history i2c_adapter_fault_history
;
953 i2c_adapter_fault_history
.type
= PIOS_I2C_ERROR_EVENT
;
955 memcpy(data
, &i2c_adapter_fault_history
, sizeof(i2c_adapter_fault_history
));
956 memset(counts
, 0, sizeof(*counts
) * PIOS_I2C_ERROR_COUNT_NUMELEM
);
960 static bool PIOS_I2C_validate(struct pios_i2c_adapter
*i2c_adapter
)
962 return i2c_adapter
->magic
== PIOS_I2C_DEV_MAGIC
;
966 #if defined(PIOS_INCLUDE_FREERTOS) && 0
967 static struct pios_i2c_dev
*PIOS_I2C_alloc(void)
969 struct pios_i2c_dev
*i2c_adapter
;
971 i2c_adapter
= (struct pios_i2c_adapter
*)pios_malloc(sizeof(*i2c_adapter
));
976 i2c_adapter
->magic
= PIOS_I2C_DEV_MAGIC
;
980 static struct pios_i2c_adapter pios_i2c_adapters
[PIOS_I2C_MAX_DEVS
];
981 static uint8_t pios_i2c_num_adapters
;
982 static struct pios_i2c_adapter
*PIOS_I2C_alloc(void)
984 struct pios_i2c_adapter
*i2c_adapter
;
986 if (pios_i2c_num_adapters
>= PIOS_I2C_MAX_DEVS
) {
990 i2c_adapter
= &pios_i2c_adapters
[pios_i2c_num_adapters
++];
991 i2c_adapter
->magic
= PIOS_I2C_DEV_MAGIC
;
995 #endif /* if defined(PIOS_INCLUDE_FREERTOS) && 0 */
999 * Initializes IIC driver
1000 * \param[in] mode currently only mode 0 supported
1001 * \return < 0 if initialisation failed
1003 int32_t PIOS_I2C_Init(uint32_t *i2c_id
, const struct pios_i2c_adapter_cfg
*cfg
)
1005 PIOS_DEBUG_Assert(i2c_id
);
1006 PIOS_DEBUG_Assert(cfg
);
1008 struct pios_i2c_adapter
*i2c_adapter
;
1010 i2c_adapter
= (struct pios_i2c_adapter
*)PIOS_I2C_alloc();
1015 /* Bind the configuration to the device instance */
1016 i2c_adapter
->cfg
= cfg
;
1020 * Must be done prior to calling i2c_adapter_fsm_init()
1021 * since the sem_ready mutex is used in the initial state.
1023 vSemaphoreCreateBinary(i2c_adapter
->sem_ready
);
1024 i2c_adapter
->sem_busy
= xSemaphoreCreateMutex();
1026 i2c_adapter
->busy
= 0;
1027 #endif // USE_FREERTOS
1029 /* Initialize the state machine */
1030 i2c_adapter_fsm_init(i2c_adapter
);
1032 *i2c_id
= (uint32_t)i2c_adapter
;
1034 /* Configure and enable I2C interrupts */
1035 NVIC_Init((NVIC_InitTypeDef
*)&(i2c_adapter
->cfg
->event
.init
));
1036 NVIC_Init((NVIC_InitTypeDef
*)&(i2c_adapter
->cfg
->error
.init
));
1046 int32_t PIOS_I2C_Transfer(uint32_t i2c_id
, const struct pios_i2c_txn txn_list
[], uint32_t num_txns
)
1048 struct pios_i2c_adapter
*i2c_adapter
= (struct pios_i2c_adapter
*)i2c_id
;
1050 if (!PIOS_I2C_validate(i2c_adapter
)) {
1051 return PIOS_I2C_TRANSFER_DEVICE_ERROR
;
1054 PIOS_DEBUG_Assert(txn_list
);
1055 PIOS_DEBUG_Assert(num_txns
);
1057 bool semaphore_success
= true;
1061 portTickType timeout
;
1062 timeout
= i2c_adapter
->cfg
->transfer_timeout_ms
/ portTICK_RATE_MS
;
1063 if (xSemaphoreTake(i2c_adapter
->sem_busy
, timeout
) == pdFALSE
) {
1064 return PIOS_I2C_TRANSFER_BUSY
;
1068 if (i2c_adapter
->busy
) {
1070 return PIOS_I2C_TRANSFER_BUSY
;
1072 i2c_adapter
->busy
= 1;
1074 #endif /* USE_FREERTOS */
1076 PIOS_DEBUG_Assert(i2c_adapter
->curr_state
== I2C_STATE_STOPPED
);
1078 i2c_adapter
->first_txn
= &txn_list
[0];
1079 i2c_adapter
->last_txn
= &txn_list
[num_txns
- 1];
1080 i2c_adapter
->active_txn
= i2c_adapter
->first_txn
;
1083 /* Make sure the done/ready semaphore is consumed before we start */
1084 semaphore_success
&= (xSemaphoreTake(i2c_adapter
->sem_ready
, timeout
) == pdTRUE
);
1087 // Estimate bytes of transmission. Per txns: 1 adress byte + length
1088 i2c_adapter
->transfer_timeout_ticks
= num_txns
;
1089 for (uint32_t i
= 0; i
< num_txns
; i
++) {
1090 i2c_adapter
->transfer_timeout_ticks
+= txn_list
[i
].len
;
1092 // timeout if it takes eight times the expected time
1093 i2c_adapter
->transfer_timeout_ticks
<<= 3;
1095 i2c_adapter
->callback
= NULL
;
1096 i2c_adapter
->bus_error
= false;
1097 i2c_adapter
->nack
= false;
1098 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_START
);
1100 /* Wait for the transfer to complete */
1102 semaphore_success
&= (xSemaphoreTake(i2c_adapter
->sem_ready
, timeout
) == pdTRUE
);
1103 xSemaphoreGive(i2c_adapter
->sem_ready
);
1104 #endif /* USE_FREERTOS */
1106 /* Spin waiting for the transfer to finish */
1107 while (!i2c_adapter_fsm_terminated(i2c_adapter
)) {
1108 /* sleep 9 clock ticks (1 byte), because FSM can't be faster than one byte
1109 FIXME: clock stretching could make problems, but citing NPX: alsmost no slave device implements clock stretching
1110 three times the expected time should cover clock delay */
1111 PIOS_DELAY_WaituS(i2c_adapter
->transfer_delay_uS
);
1113 i2c_adapter
->transfer_timeout_ticks
--;
1114 if (i2c_adapter
->transfer_timeout_ticks
== 0) {
1119 if (i2c_adapter_wait_for_stopped(i2c_adapter
)) {
1120 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STOPPED
);
1122 i2c_adapter_fsm_init(i2c_adapter
);
1126 /* Unlock the bus */
1127 xSemaphoreGive(i2c_adapter
->sem_busy
);
1128 if (!semaphore_success
) {
1129 i2c_timeout_counter
++;
1133 i2c_adapter
->busy
= 0;
1135 #endif /* USE_FREERTOS */
1137 return !semaphore_success
? PIOS_I2C_TRANSFER_TIMEOUT
:
1138 i2c_adapter
->bus_error
? PIOS_I2C_TRANSFER_BUS_ERROR
:
1139 i2c_adapter
->nack
? PIOS_I2C_TRANSFER_NACK
:
1140 PIOS_I2C_TRANSFER_OK
;
1143 static int32_t PIOS_I2C_Transfer_Callback_Internal(struct pios_i2c_adapter
*i2c_adapter
, const struct pios_i2c_txn txn_list
[], uint32_t num_txns
, pios_i2c_callback callback
)
1145 PIOS_DEBUG_Assert(i2c_adapter
->curr_state
== I2C_STATE_STOPPED
);
1147 i2c_adapter
->first_txn
= &txn_list
[0];
1148 i2c_adapter
->last_txn
= &txn_list
[num_txns
- 1];
1149 i2c_adapter
->active_txn
= i2c_adapter
->first_txn
;
1150 i2c_adapter
->bus_error
= false;
1151 i2c_adapter
->nack
= false;
1152 i2c_adapter
->callback
= callback
;
1154 // Estimate bytes of transmission. Per txns: 1 adress byte + length
1155 i2c_adapter
->transfer_timeout_ticks
= num_txns
;
1156 for (uint32_t i
= 0; i
< num_txns
; i
++) {
1157 i2c_adapter
->transfer_timeout_ticks
+= txn_list
[i
].len
;
1159 // timeout if it takes eight times the expected time
1160 i2c_adapter
->transfer_timeout_ticks
<<= 3;
1162 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_START
);
1167 int32_t PIOS_I2C_Transfer_Callback(uint32_t i2c_id
, const struct pios_i2c_txn txn_list
[], uint32_t num_txns
, pios_i2c_callback callback
)
1169 struct pios_i2c_adapter
*i2c_adapter
= (struct pios_i2c_adapter
*)i2c_id
;
1171 if (!PIOS_I2C_validate(i2c_adapter
)) {
1175 PIOS_Assert(callback
);
1177 PIOS_DEBUG_Assert(txn_list
);
1178 PIOS_DEBUG_Assert(num_txns
);
1182 portTickType timeout
;
1183 timeout
= i2c_adapter
->cfg
->transfer_timeout_ms
/ portTICK_RATE_MS
;
1184 if (xSemaphoreTake(i2c_adapter
->sem_busy
, timeout
) == pdFALSE
) {
1185 return PIOS_I2C_TRANSFER_BUSY
;
1189 if (i2c_adapter
->busy
) {
1191 return PIOS_I2C_TRANSFER_BUSY
;
1193 i2c_adapter
->busy
= 1;
1195 #endif /* USE_FREERTOS */
1197 return PIOS_I2C_Transfer_Callback_Internal(i2c_adapter
, txn_list
, num_txns
, callback
);
1200 int32_t PIOS_I2C_Transfer_CallbackFromISR(uint32_t i2c_id
, const struct pios_i2c_txn txn_list
[], uint32_t num_txns
, pios_i2c_callback callback
, bool *woken
)
1202 // FIXME: only supports transfer sizes up to 255 bytes
1203 struct pios_i2c_adapter
*i2c_adapter
= (struct pios_i2c_adapter
*)i2c_id
;
1205 bool valid
= PIOS_I2C_validate(i2c_adapter
);
1209 PIOS_DEBUG_Assert(txn_list
);
1210 PIOS_DEBUG_Assert(num_txns
);
1213 signed portBASE_TYPE xHigherPriorityTaskWoken
= pdFALSE
;
1216 bool locked
= xSemaphoreTakeFromISR(i2c_adapter
->sem_busy
, &xHigherPriorityTaskWoken
) == pdTRUE
;
1218 if (xHigherPriorityTaskWoken
== pdTRUE
) {
1223 return PIOS_I2C_TRANSFER_BUSY
;
1227 if (i2c_adapter
->busy
) {
1229 return PIOS_I2C_TRANSFER_BUSY
;
1231 i2c_adapter
->busy
= 1;
1233 #endif /* USE_FREERTOS */
1235 return PIOS_I2C_Transfer_Callback_Internal(i2c_adapter
, txn_list
, num_txns
, callback
);
1238 void PIOS_I2C_EV_IRQ_Handler(uint32_t i2c_id
)
1240 struct pios_i2c_adapter
*i2c_adapter
= (struct pios_i2c_adapter
*)i2c_id
;
1242 if (!PIOS_I2C_validate(i2c_adapter
)) {
1246 uint32_t event
= I2C_GetLastEvent(i2c_adapter
->cfg
->regs
);
1248 #if defined(PIOS_I2C_DIAGNOSTICS)
1249 /* Store event for diagnostics */
1250 i2c_evirq_history
[i2c_evirq_history_pointer
] = event
;
1251 i2c_evirq_history_pointer
= (i2c_evirq_history_pointer
+ 1) % I2C_LOG_DEPTH
;
1254 #define EVENT_MASK 0x000700FF
1255 event
&= EVENT_MASK
;
1257 // This is very poor and inconsistent practice with the FSM since no other
1258 // throw event depends on the current state. However when accelerated (-Os)
1259 // we definitely catch this event twice and there is no clean way to do deal
1260 // with that in the FMS short of a special state for it
1261 if (i2c_adapter
->curr_state
== I2C_STATE_STARTING
&& event
== 0x70084) {
1265 switch (event
) { /* Mask out all the bits we don't care about */
1266 case (I2C_EVENT_MASTER_MODE_SELECT
| 0x40):
1267 /* Unexplained event: EV5 + RxNE : Extraneous Rx. Probably a late NACK from previous read. */
1268 /* Clean up the extra Rx until the root cause is identified and just keep going */
1269 (void)I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
1271 case I2C_EVENT_MASTER_MODE_SELECT
: /* EV5 */
1272 switch (i2c_adapter
->active_txn
->rw
) {
1273 case PIOS_I2C_TXN_READ
:
1274 if (i2c_adapter
->active_txn
== i2c_adapter
->last_txn
) {
1275 /* Final transaction */
1276 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STARTED_LAST_TXN_READ
);
1277 } else if (i2c_adapter
->active_txn
< i2c_adapter
->last_txn
) {
1278 /* More transactions follow */
1279 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STARTED_MORE_TXN_READ
);
1281 PIOS_DEBUG_Assert(0);
1284 case PIOS_I2C_TXN_WRITE
:
1285 if (i2c_adapter
->active_txn
== i2c_adapter
->last_txn
) {
1286 /* Final transaction */
1287 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STARTED_LAST_TXN_WRITE
);
1288 } else if (i2c_adapter
->active_txn
< i2c_adapter
->last_txn
) {
1289 /* More transactions follow */
1290 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STARTED_MORE_TXN_WRITE
);
1292 PIOS_DEBUG_Assert(0);
1296 PIOS_DEBUG_Assert(0);
1300 case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED
: /* EV6 */
1301 case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED
: /* EV6 */
1302 switch (i2c_adapter
->last_byte
- i2c_adapter
->active_byte
+ 1) {
1304 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_ADDR_SENT_LEN_EQ_0
);
1307 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_ADDR_SENT_LEN_EQ_1
);
1310 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_ADDR_SENT_LEN_EQ_2
);
1313 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_ADDR_SENT_LEN_GT_2
);
1317 case 0x80: /* TxE only. TRA + MSL + BUSY have been cleared before we got here. */
1320 static volatile bool halt
= false;
1326 case 0: /* This triggers an FSM fault sometimes, but not having it stops things working */
1327 case 0x40: /* RxNE only. MSL + BUSY have already been cleared by HW. */
1328 case 0x44: /* RxNE + BTF. MSL + BUSY have already been cleared by HW. */
1329 case I2C_EVENT_MASTER_BYTE_RECEIVED
: /* EV7 */
1330 case (I2C_EVENT_MASTER_BYTE_RECEIVED
| 0x4): /* EV7 + BTF */
1331 case I2C_EVENT_MASTER_BYTE_TRANSMITTED
: /* EV8_2 */
1332 case 0x84: /* TxE + BTF. EV8_2 but TRA + MSL + BUSY have already been cleared by HW. */
1333 switch (i2c_adapter
->last_byte
- i2c_adapter
->active_byte
+ 1) {
1335 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_TRANSFER_DONE_LEN_EQ_0
);
1338 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
);
1341 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
);
1344 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_TRANSFER_DONE_LEN_GT_2
);
1348 case I2C_EVENT_MASTER_BYTE_TRANSMITTING
: /* EV8 */
1349 /* Ignore this event and wait for TRANSMITTED in case we can't keep up */
1352 case 0x30084: /* BUSY + MSL + TXE + BFT Occurs between byte transmitted and master mode selected */
1353 case 0x30000: /* BUSY + MSL Need to throw away this spurious event */
1354 case 0x30403 & EVENT_MASK
: /* BUSY + MSL + SB + ADDR Detected this after got a NACK, probably stop bit */
1358 i2c_adapter_log_fault(PIOS_I2C_ERROR_EVENT
);
1359 #if defined(I2C_HALT_ON_ERRORS)
1360 PIOS_DEBUG_Assert(0);
1362 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_BUS_ERROR
);
1371 void PIOS_I2C_ER_IRQ_Handler(uint32_t i2c_id
)
1373 struct pios_i2c_adapter
*i2c_adapter
= (struct pios_i2c_adapter
*)i2c_id
;
1375 if (!PIOS_I2C_validate(i2c_adapter
)) {
1379 uint32_t event
= I2C_GetLastEvent(i2c_adapter
->cfg
->regs
);
1381 #if defined(PIOS_I2C_DIAGNOSTICS)
1382 i2c_erirq_history
[i2c_erirq_history_pointer
] = event
;
1383 i2c_erirq_history_pointer
= (i2c_erirq_history_pointer
+ 1) % 5;
1386 if (event
& I2C_FLAG_AF
) {
1389 I2C_ClearFlag(i2c_adapter
->cfg
->regs
, I2C_FLAG_AF
);
1391 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_NACK
);
1392 } else { /* Mostly bus errors here */
1393 i2c_adapter_log_fault(PIOS_I2C_ERROR_INTERRUPT
);
1395 /* Fail hard on any errors for now */
1396 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_BUS_ERROR
);
1400 #endif /* PIOS_INCLUDE_I2C */