2 ******************************************************************************
3 * @addtogroup PIOS PIOS Core hardware abstraction layer
5 * @addtogroup PIOS_I2C I2C Functions
6 * @brief STM32 Hardware dependent I2C functionality
10 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
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
33 #ifdef PIOS_INCLUDE_I2C
35 #if defined(PIOS_INCLUDE_FREERTOS)
39 #include <pios_i2c_priv.h>
41 // #define I2C_HALT_ON_ERRORS
43 enum i2c_adapter_event
{
46 I2C_EVENT_STARTED_MORE_TXN_READ
,
47 I2C_EVENT_STARTED_MORE_TXN_WRITE
,
48 I2C_EVENT_STARTED_LAST_TXN_READ
,
49 I2C_EVENT_STARTED_LAST_TXN_WRITE
,
50 I2C_EVENT_ADDR_SENT_LEN_EQ_0
,
51 I2C_EVENT_ADDR_SENT_LEN_EQ_1
,
52 I2C_EVENT_ADDR_SENT_LEN_EQ_2
,
53 I2C_EVENT_ADDR_SENT_LEN_GT_2
,
54 I2C_EVENT_TRANSFER_DONE_LEN_EQ_0
,
55 I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
,
56 I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
,
57 I2C_EVENT_TRANSFER_DONE_LEN_GT_2
,
60 I2C_EVENT_AUTO
, /* FIXME: remove this */
62 I2C_EVENT_NUM_EVENTS
/* Must be last */
65 #if defined(PIOS_I2C_DIAGNOSTICS)
66 static struct pios_i2c_fault_history i2c_adapter_fault_history
;
68 volatile uint32_t i2c_evirq_history
[I2C_LOG_DEPTH
];
69 volatile uint8_t i2c_evirq_history_pointer
= 0;
71 volatile uint32_t i2c_erirq_history
[I2C_LOG_DEPTH
];
72 volatile uint8_t i2c_erirq_history_pointer
= 0;
74 volatile enum i2c_adapter_state i2c_state_history
[I2C_LOG_DEPTH
];
75 volatile uint8_t i2c_state_history_pointer
= 0;
77 volatile enum i2c_adapter_event i2c_state_event_history
[I2C_LOG_DEPTH
];
78 volatile uint8_t i2c_state_event_history_pointer
;
80 static uint8_t i2c_fsm_fault_count
= 0;
81 static uint8_t i2c_bad_event_counter
= 0;
82 static uint8_t i2c_error_interrupt_counter
= 0;
83 static uint8_t i2c_nack_counter
= 0;
84 static uint8_t i2c_timeout_counter
= 0;
87 static void go_fsm_fault(struct pios_i2c_adapter
*i2c_adapter
);
88 static void go_bus_error(struct pios_i2c_adapter
*i2c_adapter
);
89 static void go_stopping(struct pios_i2c_adapter
*i2c_adapter
);
90 static void go_stopped(struct pios_i2c_adapter
*i2c_adapter
);
91 static void go_starting(struct pios_i2c_adapter
*i2c_adapter
);
92 static void go_r_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
);
93 static void go_r_more_txn_pre_one(struct pios_i2c_adapter
*i2c_adapter
);
94 static void go_r_any_txn_pre_first(struct pios_i2c_adapter
*i2c_adapter
);
95 static void go_r_any_txn_pre_middle(struct pios_i2c_adapter
*i2c_adapter
);
96 static void go_r_more_txn_pre_last(struct pios_i2c_adapter
*i2c_adapter
);
97 static void go_r_any_txn_post_last(struct pios_i2c_adapter
*i2c_adapter
);
99 static void go_r_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
);
100 static void go_r_last_txn_pre_one(struct pios_i2c_adapter
*i2c_adapter
);
101 static void go_r_any_txn_pre_first(struct pios_i2c_adapter
*i2c_adapter
);
102 static void go_r_any_txn_pre_middle(struct pios_i2c_adapter
*i2c_adapter
);
103 static void go_r_last_txn_pre_last(struct pios_i2c_adapter
*i2c_adapter
);
104 static void go_r_any_txn_post_last(struct pios_i2c_adapter
*i2c_adapter
);
106 static void go_w_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
);
107 static void go_w_any_txn_middle(struct pios_i2c_adapter
*i2c_adapter
);
108 static void go_w_more_txn_last(struct pios_i2c_adapter
*i2c_adapter
);
110 static void go_w_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
);
111 static void go_w_any_txn_middle(struct pios_i2c_adapter
*i2c_adapter
);
112 static void go_w_last_txn_last(struct pios_i2c_adapter
*i2c_adapter
);
114 static void go_nack(struct pios_i2c_adapter
*i2c_adapter
);
116 struct i2c_adapter_transition
{
117 void (*entry_fn
)(struct pios_i2c_adapter
*i2c_adapter
);
118 enum i2c_adapter_state next_state
[I2C_EVENT_NUM_EVENTS
];
121 static void i2c_adapter_process_auto(struct pios_i2c_adapter
*i2c_adapter
);
122 static void i2c_adapter_inject_event(struct pios_i2c_adapter
*i2c_adapter
, enum i2c_adapter_event event
);
123 static void i2c_adapter_fsm_init(struct pios_i2c_adapter
*i2c_adapter
);
124 static bool i2c_adapter_wait_for_stopped(struct pios_i2c_adapter
*i2c_adapter
);
125 static void i2c_adapter_reset_bus(struct pios_i2c_adapter
*i2c_adapter
);
127 static void i2c_adapter_log_fault(enum pios_i2c_error_type type
);
129 static const struct i2c_adapter_transition i2c_adapter_transitions
[I2C_STATE_NUM_STATES
] = {
130 [I2C_STATE_FSM_FAULT
] = {
131 .entry_fn
= go_fsm_fault
,
133 [I2C_EVENT_AUTO
] = I2C_STATE_STOPPING
,
136 [I2C_STATE_BUS_ERROR
] = {
137 .entry_fn
= go_bus_error
,
139 [I2C_EVENT_AUTO
] = I2C_STATE_STOPPING
,
143 [I2C_STATE_STOPPED
] = {
144 .entry_fn
= go_stopped
,
146 [I2C_EVENT_START
] = I2C_STATE_STARTING
,
147 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
151 [I2C_STATE_STOPPING
] = {
152 .entry_fn
= go_stopping
,
154 [I2C_EVENT_STOPPED
] = I2C_STATE_STOPPED
,
155 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
159 [I2C_STATE_STARTING
] = {
160 .entry_fn
= go_starting
,
162 [I2C_EVENT_STARTED_MORE_TXN_READ
] = I2C_STATE_R_MORE_TXN_ADDR
,
163 [I2C_EVENT_STARTED_MORE_TXN_WRITE
] = I2C_STATE_W_MORE_TXN_ADDR
,
164 [I2C_EVENT_STARTED_LAST_TXN_READ
] = I2C_STATE_R_LAST_TXN_ADDR
,
165 [I2C_EVENT_STARTED_LAST_TXN_WRITE
] = I2C_STATE_W_LAST_TXN_ADDR
,
166 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
167 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
175 [I2C_STATE_R_MORE_TXN_ADDR
] = {
176 .entry_fn
= go_r_any_txn_addr
,
178 [I2C_EVENT_ADDR_SENT_LEN_EQ_1
] = I2C_STATE_R_MORE_TXN_PRE_ONE
,
179 [I2C_EVENT_ADDR_SENT_LEN_EQ_2
] = I2C_STATE_R_MORE_TXN_PRE_FIRST
,
180 [I2C_EVENT_ADDR_SENT_LEN_GT_2
] = I2C_STATE_R_MORE_TXN_PRE_FIRST
,
181 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
185 [I2C_STATE_R_MORE_TXN_PRE_ONE
] = {
186 .entry_fn
= go_r_more_txn_pre_one
,
188 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_R_MORE_TXN_POST_LAST
,
189 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
193 [I2C_STATE_R_MORE_TXN_PRE_FIRST
] = {
194 .entry_fn
= go_r_any_txn_pre_first
,
196 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_R_MORE_TXN_PRE_LAST
,
197 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_R_MORE_TXN_PRE_MIDDLE
,
198 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
202 [I2C_STATE_R_MORE_TXN_PRE_MIDDLE
] = {
203 .entry_fn
= go_r_any_txn_pre_middle
,
205 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_R_MORE_TXN_PRE_LAST
,
206 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_R_MORE_TXN_PRE_MIDDLE
,
207 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
211 [I2C_STATE_R_MORE_TXN_PRE_LAST
] = {
212 .entry_fn
= go_r_more_txn_pre_last
,
214 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_R_MORE_TXN_POST_LAST
,
215 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
219 [I2C_STATE_R_MORE_TXN_POST_LAST
] = {
220 .entry_fn
= go_r_any_txn_post_last
,
222 [I2C_EVENT_AUTO
] = I2C_STATE_STARTING
,
230 [I2C_STATE_R_LAST_TXN_ADDR
] = {
231 .entry_fn
= go_r_any_txn_addr
,
233 [I2C_EVENT_ADDR_SENT_LEN_EQ_1
] = I2C_STATE_R_LAST_TXN_PRE_ONE
,
234 [I2C_EVENT_ADDR_SENT_LEN_EQ_2
] = I2C_STATE_R_LAST_TXN_PRE_FIRST
,
235 [I2C_EVENT_ADDR_SENT_LEN_GT_2
] = I2C_STATE_R_LAST_TXN_PRE_FIRST
,
236 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
240 [I2C_STATE_R_LAST_TXN_PRE_ONE
] = {
241 .entry_fn
= go_r_last_txn_pre_one
,
243 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_R_LAST_TXN_POST_LAST
,
244 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
248 [I2C_STATE_R_LAST_TXN_PRE_FIRST
] = {
249 .entry_fn
= go_r_any_txn_pre_first
,
251 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_R_LAST_TXN_PRE_LAST
,
252 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_R_LAST_TXN_PRE_MIDDLE
,
253 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
257 [I2C_STATE_R_LAST_TXN_PRE_MIDDLE
] = {
258 .entry_fn
= go_r_any_txn_pre_middle
,
260 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_R_LAST_TXN_PRE_LAST
,
261 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_R_LAST_TXN_PRE_MIDDLE
,
262 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
266 [I2C_STATE_R_LAST_TXN_PRE_LAST
] = {
267 .entry_fn
= go_r_last_txn_pre_last
,
269 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_R_LAST_TXN_POST_LAST
,
270 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
274 [I2C_STATE_R_LAST_TXN_POST_LAST
] = {
275 .entry_fn
= go_r_any_txn_post_last
,
277 [I2C_EVENT_AUTO
] = I2C_STATE_STOPPING
,
285 [I2C_STATE_W_MORE_TXN_ADDR
] = {
286 .entry_fn
= go_w_any_txn_addr
,
288 [I2C_EVENT_ADDR_SENT_LEN_EQ_1
] = I2C_STATE_W_MORE_TXN_LAST
,
289 [I2C_EVENT_ADDR_SENT_LEN_EQ_2
] = I2C_STATE_W_MORE_TXN_MIDDLE
,
290 [I2C_EVENT_ADDR_SENT_LEN_GT_2
] = I2C_STATE_W_MORE_TXN_MIDDLE
,
291 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
292 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
296 [I2C_STATE_W_MORE_TXN_MIDDLE
] = {
297 .entry_fn
= go_w_any_txn_middle
,
299 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_W_MORE_TXN_LAST
,
300 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_W_MORE_TXN_MIDDLE
,
301 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_W_MORE_TXN_MIDDLE
,
302 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
303 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
307 [I2C_STATE_W_MORE_TXN_LAST
] = {
308 .entry_fn
= go_w_more_txn_last
,
310 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_0
] = I2C_STATE_STARTING
,
311 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
312 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
320 [I2C_STATE_W_LAST_TXN_ADDR
] = {
321 .entry_fn
= go_w_any_txn_addr
,
323 [I2C_EVENT_ADDR_SENT_LEN_EQ_1
] = I2C_STATE_W_LAST_TXN_LAST
,
324 [I2C_EVENT_ADDR_SENT_LEN_EQ_2
] = I2C_STATE_W_LAST_TXN_MIDDLE
,
325 [I2C_EVENT_ADDR_SENT_LEN_GT_2
] = I2C_STATE_W_LAST_TXN_MIDDLE
,
326 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
327 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
331 [I2C_STATE_W_LAST_TXN_MIDDLE
] = {
332 .entry_fn
= go_w_any_txn_middle
,
334 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
] = I2C_STATE_W_LAST_TXN_LAST
,
335 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
] = I2C_STATE_W_LAST_TXN_MIDDLE
,
336 [I2C_EVENT_TRANSFER_DONE_LEN_GT_2
] = I2C_STATE_W_LAST_TXN_MIDDLE
,
337 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
338 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
342 [I2C_STATE_W_LAST_TXN_LAST
] = {
343 .entry_fn
= go_w_last_txn_last
,
345 [I2C_EVENT_TRANSFER_DONE_LEN_EQ_0
] = I2C_STATE_STOPPING
,
346 [I2C_EVENT_NACK
] = I2C_STATE_NACK
,
347 [I2C_EVENT_BUS_ERROR
] = I2C_STATE_BUS_ERROR
,
353 [I2C_EVENT_AUTO
] = I2C_STATE_STOPPING
,
358 static void go_fsm_fault(struct pios_i2c_adapter
*i2c_adapter
)
360 #if defined(I2C_HALT_ON_ERRORS)
361 PIOS_DEBUG_Assert(0);
363 /* Note that this transfer has hit a bus error */
364 i2c_adapter
->bus_error
= true;
366 i2c_adapter_reset_bus(i2c_adapter
);
369 static void go_bus_error(struct pios_i2c_adapter
*i2c_adapter
)
371 /* Note that this transfer has hit a bus error */
372 i2c_adapter
->bus_error
= true;
374 i2c_adapter_reset_bus(i2c_adapter
);
377 static void go_stopping(struct pios_i2c_adapter
*i2c_adapter
)
380 signed portBASE_TYPE pxHigherPriorityTaskWoken
= pdFALSE
;
383 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
386 if (xSemaphoreGiveFromISR(i2c_adapter
->sem_ready
, &pxHigherPriorityTaskWoken
) != pdTRUE
) {
387 #if defined(I2C_HALT_ON_ERRORS)
388 PIOS_DEBUG_Assert(0);
391 portEND_SWITCHING_ISR(pxHigherPriorityTaskWoken
); /* FIXME: is this the right place for this? */
392 #endif /* USE_FREERTOS */
395 static void go_stopped(struct pios_i2c_adapter
*i2c_adapter
)
397 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
398 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, ENABLE
);
401 static void go_starting(struct pios_i2c_adapter
*i2c_adapter
)
403 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
404 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
405 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
407 // check for an empty read/write
408 if (i2c_adapter
->active_txn
->buf
!= NULL
&& i2c_adapter
->active_txn
->len
!= 0) {
410 i2c_adapter
->active_byte
= &(i2c_adapter
->active_txn
->buf
[0]);
411 i2c_adapter
->last_byte
= &(i2c_adapter
->active_txn
->buf
[i2c_adapter
->active_txn
->len
- 1]);
413 // No Data available => Empty read/write
414 i2c_adapter
->last_byte
= NULL
;
415 i2c_adapter
->active_byte
= i2c_adapter
->last_byte
+ 1;
419 I2C_GenerateSTART(i2c_adapter
->cfg
->regs
, ENABLE
);
420 if (i2c_adapter
->active_txn
->rw
== PIOS_I2C_TXN_READ
) {
421 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, ENABLE
);
423 // For write operations, do not enable the IT_BUF events.
424 // The current driver does not act when the TX data register is not full, only when the complete byte is sent.
425 // With the IT_BUF enabled, we constantly get IRQs, See OP-326
426 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_ERR
, ENABLE
);
430 /* Common to 'more' and 'last' transaction */
431 static void go_r_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
)
433 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
434 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
435 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
437 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
->rw
== PIOS_I2C_TXN_READ
);
439 I2C_Send7bitAddress(i2c_adapter
->cfg
->regs
, (i2c_adapter
->active_txn
->addr
) << 1, I2C_Direction_Receiver
);
442 static void go_r_more_txn_pre_one(struct pios_i2c_adapter
*i2c_adapter
)
444 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
445 I2C_GenerateSTART(i2c_adapter
->cfg
->regs
, ENABLE
);
448 static void go_r_last_txn_pre_one(struct pios_i2c_adapter
*i2c_adapter
)
450 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
451 I2C_GenerateSTOP(i2c_adapter
->cfg
->regs
, ENABLE
);
454 /* Common to 'more' and 'last' transaction */
455 static void go_r_any_txn_pre_first(struct pios_i2c_adapter
*i2c_adapter
)
457 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, ENABLE
);
460 /* Common to 'more' and 'last' transaction */
461 static void go_r_any_txn_pre_middle(struct pios_i2c_adapter
*i2c_adapter
)
463 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
464 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
466 *(i2c_adapter
->active_byte
) = I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
468 /* Move to the next byte */
469 i2c_adapter
->active_byte
++;
470 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
473 static void go_r_more_txn_pre_last(struct pios_i2c_adapter
*i2c_adapter
)
475 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
476 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
478 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
480 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
481 I2C_GenerateSTART(i2c_adapter
->cfg
->regs
, ENABLE
);
482 *(i2c_adapter
->active_byte
) = I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
483 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, ENABLE
);
486 /* Move to the next byte */
487 i2c_adapter
->active_byte
++;
488 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
491 static void go_r_last_txn_pre_last(struct pios_i2c_adapter
*i2c_adapter
)
493 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
494 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
496 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
498 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
499 I2C_GenerateSTOP(i2c_adapter
->cfg
->regs
, ENABLE
);
500 *(i2c_adapter
->active_byte
) = I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
501 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, ENABLE
);
504 /* Move to the next byte */
505 i2c_adapter
->active_byte
++;
506 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
509 /* Common to 'more' and 'last' transaction */
510 static void go_r_any_txn_post_last(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
);
514 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
515 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
516 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
518 *(i2c_adapter
->active_byte
) = I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
520 /* Move to the next byte */
521 i2c_adapter
->active_byte
++;
523 /* Move to the next transaction */
524 i2c_adapter
->active_txn
++;
527 /* Common to 'more' and 'last' transaction */
528 static void go_w_any_txn_addr(struct pios_i2c_adapter
*i2c_adapter
)
530 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
531 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
532 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
534 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
->rw
== PIOS_I2C_TXN_WRITE
);
536 I2C_Send7bitAddress(i2c_adapter
->cfg
->regs
, (i2c_adapter
->active_txn
->addr
) << 1, I2C_Direction_Transmitter
);
539 static void go_w_any_txn_middle(struct pios_i2c_adapter
*i2c_adapter
)
541 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
542 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
< i2c_adapter
->last_byte
);
543 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
544 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
545 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
547 I2C_SendData(i2c_adapter
->cfg
->regs
, *(i2c_adapter
->active_byte
));
549 /* Move to the next byte */
550 i2c_adapter
->active_byte
++;
551 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
<= i2c_adapter
->last_byte
);
554 static void go_w_more_txn_last(struct pios_i2c_adapter
*i2c_adapter
)
556 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
557 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
== i2c_adapter
->last_byte
);
558 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
559 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
560 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
562 I2C_SendData(i2c_adapter
->cfg
->regs
, *(i2c_adapter
->active_byte
));
564 /* Move to the next byte */
565 i2c_adapter
->active_byte
++;
567 /* Move to the next transaction */
568 i2c_adapter
->active_txn
++;
569 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
572 static void go_w_last_txn_last(struct pios_i2c_adapter
*i2c_adapter
)
574 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
);
575 PIOS_DEBUG_Assert(i2c_adapter
->active_byte
== i2c_adapter
->last_byte
);
576 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
);
577 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
>= i2c_adapter
->first_txn
);
578 PIOS_DEBUG_Assert(i2c_adapter
->active_txn
<= i2c_adapter
->last_txn
);
580 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_BUF
, DISABLE
);
581 I2C_SendData(i2c_adapter
->cfg
->regs
, *(i2c_adapter
->active_byte
));
583 // SHOULD MOVE THIS INTO A STOPPING STATE AND SET IT ONLY AFTER THE BYTE WAS SENT
584 I2C_GenerateSTOP(i2c_adapter
->cfg
->regs
, ENABLE
);
586 /* Move to the next byte */
587 i2c_adapter
->active_byte
++;
590 static void go_nack(struct pios_i2c_adapter
*i2c_adapter
)
592 I2C_ITConfig(i2c_adapter
->cfg
->regs
, I2C_IT_EVT
| I2C_IT_BUF
| I2C_IT_ERR
, DISABLE
);
593 I2C_AcknowledgeConfig(i2c_adapter
->cfg
->regs
, DISABLE
);
594 I2C_GenerateSTOP(i2c_adapter
->cfg
->regs
, ENABLE
);
597 static void i2c_adapter_inject_event(struct pios_i2c_adapter
*i2c_adapter
, enum i2c_adapter_event event
)
601 #if defined(PIOS_I2C_DIAGNOSTICS)
602 i2c_state_event_history
[i2c_state_event_history_pointer
] = event
;
603 i2c_state_event_history_pointer
= (i2c_state_event_history_pointer
+ 1) % I2C_LOG_DEPTH
;
605 i2c_state_history
[i2c_state_history_pointer
] = i2c_adapter
->curr_state
;
606 i2c_state_history_pointer
= (i2c_state_history_pointer
+ 1) % I2C_LOG_DEPTH
;
608 if (i2c_adapter_transitions
[i2c_adapter
->curr_state
].next_state
[event
] == I2C_STATE_FSM_FAULT
) {
609 i2c_adapter_log_fault(PIOS_I2C_ERROR_FSM
);
613 * Move to the next state
615 * This is done prior to calling the new state's entry function to
616 * guarantee that the entry function never depends on the previous
617 * state. This way, it cannot ever know what the previous state was.
619 i2c_adapter
->curr_state
= i2c_adapter_transitions
[i2c_adapter
->curr_state
].next_state
[event
];
621 /* Call the entry function (if any) for the next state. */
622 if (i2c_adapter_transitions
[i2c_adapter
->curr_state
].entry_fn
) {
623 i2c_adapter_transitions
[i2c_adapter
->curr_state
].entry_fn(i2c_adapter
);
626 /* Process any AUTO transitions in the FSM */
627 i2c_adapter_process_auto(i2c_adapter
);
632 static void i2c_adapter_process_auto(struct pios_i2c_adapter
*i2c_adapter
)
635 while (i2c_adapter_transitions
[i2c_adapter
->curr_state
].next_state
[I2C_EVENT_AUTO
]) {
636 i2c_adapter
->curr_state
= i2c_adapter_transitions
[i2c_adapter
->curr_state
].next_state
[I2C_EVENT_AUTO
];
638 /* Call the entry function (if any) for the next state. */
639 if (i2c_adapter_transitions
[i2c_adapter
->curr_state
].entry_fn
) {
640 i2c_adapter_transitions
[i2c_adapter
->curr_state
].entry_fn(i2c_adapter
);
647 static void i2c_adapter_fsm_init(struct pios_i2c_adapter
*i2c_adapter
)
649 i2c_adapter_reset_bus(i2c_adapter
);
650 i2c_adapter
->curr_state
= I2C_STATE_STOPPED
;
653 static bool i2c_adapter_wait_for_stopped(struct pios_i2c_adapter
*i2c_adapter
)
658 * Wait for the bus to return to the stopped state.
659 * This was pulled out of the FSM due to occasional
660 * failures at this transition which previously resulted
661 * in spinning on this bit in the ISR forever.
663 #define I2C_CR1_STOP_REQUESTED 0x0200
664 for (guard
= 1000000; /* FIXME: should use the configured bus timeout */
665 guard
&& (i2c_adapter
->cfg
->regs
->CR1
& I2C_CR1_STOP_REQUESTED
); guard
--) {
669 /* We timed out waiting for the stop condition */
676 static void i2c_adapter_reset_bus(struct pios_i2c_adapter
*i2c_adapter
)
678 /* Reset the I2C block */
679 I2C_DeInit(i2c_adapter
->cfg
->regs
);
681 /* Make sure the bus is free by clocking it until any slaves release the bus. */
682 GPIO_InitTypeDef scl_gpio_init
;
683 scl_gpio_init
= i2c_adapter
->cfg
->scl
.init
;
684 scl_gpio_init
.GPIO_Mode
= GPIO_Mode_Out_OD
;
685 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
686 GPIO_Init(i2c_adapter
->cfg
->scl
.gpio
, &scl_gpio_init
);
688 GPIO_InitTypeDef sda_gpio_init
;
689 sda_gpio_init
= i2c_adapter
->cfg
->sda
.init
;
690 sda_gpio_init
.GPIO_Mode
= GPIO_Mode_Out_OD
;
691 GPIO_SetBits(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
);
692 GPIO_Init(i2c_adapter
->cfg
->sda
.gpio
, &sda_gpio_init
);
694 /* Check SDA line to determine if slave is asserting bus and clock out if so, this may */
695 /* have to be repeated (due to futher bus errors) but better than clocking 0xFF into an */
697 // bool sda_hung = GPIO_ReadInputDataBit(i2c_adapter->cfg->sda.gpio, i2c_adapter->cfg->sda.init.GPIO_Pin) == Bit_RESET;
698 while (GPIO_ReadInputDataBit(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
) == Bit_RESET
) {
699 /* Set clock high and wait for any clock stretching to finish. */
700 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
701 while (GPIO_ReadInputDataBit(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
) == Bit_RESET
) {
704 PIOS_DELAY_WaituS(2);
707 GPIO_ResetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
708 PIOS_DELAY_WaituS(2);
710 /* Clock high again */
711 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
712 PIOS_DELAY_WaituS(2);
715 /* Generate a start then stop condition */
716 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
717 PIOS_DELAY_WaituS(2);
718 GPIO_ResetBits(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
);
719 PIOS_DELAY_WaituS(2);
720 GPIO_ResetBits(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
);
721 PIOS_DELAY_WaituS(2);
723 /* Set data and clock high and wait for any clock stretching to finish. */
724 GPIO_SetBits(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
);
725 GPIO_SetBits(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
);
726 while (GPIO_ReadInputDataBit(i2c_adapter
->cfg
->scl
.gpio
, i2c_adapter
->cfg
->scl
.init
.GPIO_Pin
) == Bit_RESET
) {
729 /* Wait for data to be high */
730 while (GPIO_ReadInputDataBit(i2c_adapter
->cfg
->sda
.gpio
, i2c_adapter
->cfg
->sda
.init
.GPIO_Pin
) != Bit_SET
) {
735 /* Bus signals are guaranteed to be high (ie. free) after this point */
736 /* Initialize the GPIO pins to the peripheral function */
737 GPIO_Init(i2c_adapter
->cfg
->scl
.gpio
, &(i2c_adapter
->cfg
->scl
.init
));
738 GPIO_Init(i2c_adapter
->cfg
->sda
.gpio
, &(i2c_adapter
->cfg
->sda
.init
));
740 /* Reset the I2C block */
741 I2C_DeInit(i2c_adapter
->cfg
->regs
);
743 /* Initialize the I2C block */
744 I2C_Init(i2c_adapter
->cfg
->regs
, &(i2c_adapter
->cfg
->init
));
746 #define I2C_BUSY 0x20
747 if (i2c_adapter
->cfg
->regs
->SR2
& I2C_BUSY
) {
748 /* Reset the I2C block */
749 I2C_SoftwareResetCmd(i2c_adapter
->cfg
->regs
, ENABLE
);
750 I2C_SoftwareResetCmd(i2c_adapter
->cfg
->regs
, DISABLE
);
754 #include <pios_i2c_priv.h>
756 /* Return true if the FSM is in a terminal state */
757 static bool i2c_adapter_fsm_terminated(struct pios_i2c_adapter
*i2c_adapter
)
759 switch (i2c_adapter
->curr_state
) {
760 case I2C_STATE_STOPPING
:
761 case I2C_STATE_STOPPED
:
770 * Logs the last N state transitions and N IRQ events due to
772 * \param[in] i2c the adapter number to log an event for
774 void i2c_adapter_log_fault(enum pios_i2c_error_type type
)
776 #if defined(PIOS_I2C_DIAGNOSTICS)
777 i2c_adapter_fault_history
.type
= type
;
778 for (uint8_t i
= 0; i
< I2C_LOG_DEPTH
; i
++) {
779 i2c_adapter_fault_history
.evirq
[i
] =
780 i2c_evirq_history
[(I2C_LOG_DEPTH
+ i2c_evirq_history_pointer
- 1 - i
) % I2C_LOG_DEPTH
];
781 i2c_adapter_fault_history
.erirq
[i
] =
782 i2c_erirq_history
[(I2C_LOG_DEPTH
+ i2c_erirq_history_pointer
- 1 - i
) % I2C_LOG_DEPTH
];
783 i2c_adapter_fault_history
.event
[i
] =
784 i2c_state_event_history
[(I2C_LOG_DEPTH
+ i2c_state_event_history_pointer
- 1 - i
) % I2C_LOG_DEPTH
];
785 i2c_adapter_fault_history
.state
[i
] =
786 i2c_state_history
[(I2C_LOG_DEPTH
+ i2c_state_history_pointer
- 1 - i
) % I2C_LOG_DEPTH
];
789 case PIOS_I2C_ERROR_EVENT
:
790 i2c_bad_event_counter
++;
792 case PIOS_I2C_ERROR_FSM
:
793 i2c_fsm_fault_count
++;
795 case PIOS_I2C_ERROR_INTERRUPT
:
796 i2c_error_interrupt_counter
++;
799 #endif /* if defined(PIOS_I2C_DIAGNOSTICS) */
804 * Logs the last N state transitions and N IRQ events due to
806 * \param[out] data address where to copy the pios_i2c_fault_history structure to
807 * \param[out] counts three uint16 that receive the bad event, fsm, and error irq
810 void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history
*data
, uint8_t *counts
)
812 #if defined(PIOS_I2C_DIAGNOSTICS)
813 memcpy(data
, &i2c_adapter_fault_history
, sizeof(i2c_adapter_fault_history
));
814 counts
[0] = i2c_bad_event_counter
;
815 counts
[1] = i2c_fsm_fault_count
;
816 counts
[2] = i2c_error_interrupt_counter
;
817 counts
[3] = i2c_nack_counter
;
818 counts
[4] = i2c_timeout_counter
;
820 struct pios_i2c_fault_history i2c_adapter_fault_history
;
821 i2c_adapter_fault_history
.type
= PIOS_I2C_ERROR_EVENT
;
823 memcpy(data
, &i2c_adapter_fault_history
, sizeof(i2c_adapter_fault_history
));
824 counts
[0] = counts
[1] = counts
[2] = 0;
828 static bool PIOS_I2C_validate(struct pios_i2c_adapter
*i2c_adapter
)
830 return i2c_adapter
->magic
== PIOS_I2C_DEV_MAGIC
;
833 #if defined(PIOS_INCLUDE_FREERTOS)
834 static struct pios_i2c_adapter
*PIOS_I2C_alloc(void)
836 struct pios_i2c_adapter
*i2c_adapter
;
838 i2c_adapter
= (struct pios_i2c_adapter
*)pios_malloc(sizeof(*i2c_adapter
));
843 i2c_adapter
->magic
= PIOS_I2C_DEV_MAGIC
;
847 static struct pios_i2c_adapter pios_i2c_adapters
[PIOS_I2C_MAX_DEVS
];
848 static uint8_t pios_i2c_num_adapters
;
849 static struct pios_i2c_adapter
*PIOS_I2C_alloc(void)
851 struct pios_i2c_adapter
*i2c_adapter
;
853 if (pios_i2c_num_adapters
>= PIOS_I2C_MAX_DEVS
) {
857 i2c_adapter
= &pios_i2c_adapters
[pios_i2c_num_adapters
++];
858 i2c_adapter
->magic
= PIOS_I2C_DEV_MAGIC
;
862 #endif /* if defined(PIOS_INCLUDE_FREERTOS) */
866 * Initializes IIC driver
867 * \param[in] mode currently only mode 0 supported
868 * \return < 0 if initialisation failed
870 int32_t PIOS_I2C_Init(uint32_t *i2c_id
, const struct pios_i2c_adapter_cfg
*cfg
)
872 PIOS_DEBUG_Assert(i2c_id
);
873 PIOS_DEBUG_Assert(cfg
);
875 struct pios_i2c_adapter
*i2c_adapter
;
877 i2c_adapter
= (struct pios_i2c_adapter
*)PIOS_I2C_alloc();
882 /* Bind the configuration to the device instance */
883 i2c_adapter
->cfg
= cfg
;
887 * Must be done prior to calling i2c_adapter_fsm_init()
888 * since the sem_ready mutex is used in the initial state.
890 vSemaphoreCreateBinary(i2c_adapter
->sem_ready
);
891 i2c_adapter
->sem_busy
= xSemaphoreCreateMutex();
892 #endif // USE_FREERTOS
894 /* Enable the associated peripheral clock */
895 switch ((uint32_t)i2c_adapter
->cfg
->regs
) {
897 /* Enable I2C peripheral clock (APB1 == slow speed) */
898 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1
, ENABLE
);
901 /* Enable I2C peripheral clock (APB1 == slow speed) */
902 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2
, ENABLE
);
906 if (i2c_adapter
->cfg
->remap
) {
907 GPIO_PinRemapConfig(i2c_adapter
->cfg
->remap
, ENABLE
);
910 /* Initialize the state machine */
911 i2c_adapter_fsm_init(i2c_adapter
);
913 *i2c_id
= (uint32_t)i2c_adapter
;
915 /* Configure and enable I2C interrupts */
916 NVIC_Init(&(i2c_adapter
->cfg
->event
.init
));
917 NVIC_Init(&(i2c_adapter
->cfg
->error
.init
));
927 * @brief Perform a series of I2C transactions
928 * @returns 0 if success or error code
929 * @retval -1 for failed transaction
930 * @retval -2 for failure to get semaphore
932 int32_t PIOS_I2C_Transfer(uint32_t i2c_id
, const struct pios_i2c_txn txn_list
[], uint32_t num_txns
)
934 struct pios_i2c_adapter
*i2c_adapter
= (struct pios_i2c_adapter
*)i2c_id
;
936 if (!PIOS_I2C_validate(i2c_adapter
)) {
940 PIOS_DEBUG_Assert(txn_list
);
941 PIOS_DEBUG_Assert(num_txns
);
943 bool semaphore_success
= true;
947 portTickType timeout
;
948 timeout
= i2c_adapter
->cfg
->transfer_timeout_ms
/ portTICK_RATE_MS
;
949 if (xSemaphoreTake(i2c_adapter
->sem_busy
, timeout
) == pdFALSE
) {
953 uint32_t timeout
= 0xfff;
954 while (i2c_adapter
->busy
&& --timeout
) {
957 if (timeout
== 0) { // timed out
962 if (i2c_adapter
->busy
) {
965 i2c_adapter
->busy
= 1;
967 #endif /* USE_FREERTOS */
969 PIOS_DEBUG_Assert(i2c_adapter
->curr_state
== I2C_STATE_STOPPED
);
971 i2c_adapter
->first_txn
= &txn_list
[0];
972 i2c_adapter
->last_txn
= &txn_list
[num_txns
- 1];
973 i2c_adapter
->active_txn
= i2c_adapter
->first_txn
;
976 /* Make sure the done/ready semaphore is consumed before we start */
977 semaphore_success
&= (xSemaphoreTake(i2c_adapter
->sem_ready
, timeout
) == pdTRUE
);
980 // Estimate bytes of transmission. Per txns: 1 adress byte + length
981 i2c_adapter
->transfer_timeout_ticks
= num_txns
;
982 for (uint32_t i
= 0; i
< num_txns
; i
++) {
983 i2c_adapter
->transfer_timeout_ticks
+= txn_list
[i
].len
;
985 // timeout if it takes eight times the expected time
986 i2c_adapter
->transfer_timeout_ticks
<<= 3;
988 i2c_adapter
->bus_error
= false;
989 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_START
);
991 /* Wait for the transfer to complete */
993 semaphore_success
&= (xSemaphoreTake(i2c_adapter
->sem_ready
, timeout
) == pdTRUE
);
994 xSemaphoreGive(i2c_adapter
->sem_ready
);
997 i2c_adapter
->busy
= 0;
999 #endif /* USE_FREERTOS */
1001 /* Spin waiting for the transfer to finish */
1002 while (!i2c_adapter_fsm_terminated(i2c_adapter
)) {
1003 /* sleep 9 clock ticks (1 byte), because FSM can't be faster than one byte
1004 FIXME: clock streching could make problems, but citing NPX: alsmost no slave device implements clock stretching
1005 three times the expected time should cover clock delay */
1006 PIOS_DELAY_WaituS(i2c_adapter
->transfer_delay_uS
);
1008 i2c_adapter
->transfer_timeout_ticks
--;
1009 if (i2c_adapter
->transfer_timeout_ticks
== 0) {
1014 if (i2c_adapter_wait_for_stopped(i2c_adapter
)) {
1015 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STOPPED
);
1017 i2c_adapter_fsm_init(i2c_adapter
);
1021 /* Unlock the bus */
1022 xSemaphoreGive(i2c_adapter
->sem_busy
);
1023 if (!semaphore_success
) {
1024 i2c_timeout_counter
++;
1026 #endif /* USE_FREERTOS */
1028 return !semaphore_success
? -2 :
1029 i2c_adapter
->bus_error
? -1 :
1034 void PIOS_I2C_EV_IRQ_Handler(uint32_t i2c_id
)
1036 struct pios_i2c_adapter
*i2c_adapter
= (struct pios_i2c_adapter
*)i2c_id
;
1038 if (!PIOS_I2C_validate(i2c_adapter
)) {
1042 uint32_t event
= I2C_GetLastEvent(i2c_adapter
->cfg
->regs
);
1044 #if defined(PIOS_I2C_DIAGNOSTICS)
1045 /* Store event for diagnostics */
1046 i2c_evirq_history
[i2c_evirq_history_pointer
] = event
;
1047 i2c_evirq_history_pointer
= (i2c_evirq_history_pointer
+ 1) % I2C_LOG_DEPTH
;
1050 #define EVENT_MASK 0x000700FF
1051 event
&= EVENT_MASK
;
1054 switch (event
) { /* Mask out all the bits we don't care about */
1055 case (I2C_EVENT_MASTER_MODE_SELECT
| 0x40):
1056 /* Unexplained event: EV5 + RxNE : Extraneous Rx. Probably a late NACK from previous read. */
1057 /* Clean up the extra Rx until the root cause is identified and just keep going */
1058 (void)I2C_ReceiveData(i2c_adapter
->cfg
->regs
);
1060 case I2C_EVENT_MASTER_MODE_SELECT
: /* EV5 */
1061 switch (i2c_adapter
->active_txn
->rw
) {
1062 case PIOS_I2C_TXN_READ
:
1063 if (i2c_adapter
->active_txn
== i2c_adapter
->last_txn
) {
1064 /* Final transaction */
1065 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STARTED_LAST_TXN_READ
);
1066 } else if (i2c_adapter
->active_txn
< i2c_adapter
->last_txn
) {
1067 /* More transactions follow */
1068 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STARTED_MORE_TXN_READ
);
1070 PIOS_DEBUG_Assert(0);
1073 case PIOS_I2C_TXN_WRITE
:
1074 if (i2c_adapter
->active_txn
== i2c_adapter
->last_txn
) {
1075 /* Final transaction */
1076 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STARTED_LAST_TXN_WRITE
);
1077 } else if (i2c_adapter
->active_txn
< i2c_adapter
->last_txn
) {
1078 /* More transactions follow */
1079 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_STARTED_MORE_TXN_WRITE
);
1081 PIOS_DEBUG_Assert(0);
1085 PIOS_DEBUG_Assert(0);
1089 case I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED
: /* EV6 */
1090 case I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED
: /* EV6 */
1091 switch (i2c_adapter
->last_byte
- i2c_adapter
->active_byte
+ 1) {
1093 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_ADDR_SENT_LEN_EQ_0
);
1096 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_ADDR_SENT_LEN_EQ_1
);
1099 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_ADDR_SENT_LEN_EQ_2
);
1102 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_ADDR_SENT_LEN_GT_2
);
1106 case 0x80: /* TxE only. TRA + MSL + BUSY have been cleared before we got here. */
1109 static volatile bool halt
= FALSE
;
1115 case 0: /* This triggers an FSM fault sometimes, but not having it stops things working */
1116 case 0x40: /* RxNE only. MSL + BUSY have already been cleared by HW. */
1117 case 0x44: /* RxNE + BTF. MSL + BUSY have already been cleared by HW. */
1118 case I2C_EVENT_MASTER_BYTE_RECEIVED
: /* EV7 */
1119 case (I2C_EVENT_MASTER_BYTE_RECEIVED
| 0x4): /* EV7 + BTF */
1120 case I2C_EVENT_MASTER_BYTE_TRANSMITTED
: /* EV8_2 */
1121 case 0x84: /* TxE + BTF. EV8_2 but TRA + MSL + BUSY have already been cleared by HW. */
1122 switch (i2c_adapter
->last_byte
- i2c_adapter
->active_byte
+ 1) {
1124 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_TRANSFER_DONE_LEN_EQ_0
);
1127 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_TRANSFER_DONE_LEN_EQ_1
);
1130 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_TRANSFER_DONE_LEN_EQ_2
);
1133 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_TRANSFER_DONE_LEN_GT_2
);
1137 case I2C_EVENT_MASTER_BYTE_TRANSMITTING
: /* EV8 */
1138 /* Ignore this event and wait for TRANSMITTED in case we can't keep up */
1141 case 0x30084: /* Occurs between byte tranmistted and master mode selected */
1142 case 0x30000: /* Need to throw away this spurious event */
1143 case 0x30403 & EVENT_MASK
: /* Detected this after got a NACK, probably stop bit */
1147 i2c_adapter_log_fault(PIOS_I2C_ERROR_EVENT
);
1148 #if defined(I2C_HALT_ON_ERRORS)
1149 PIOS_DEBUG_Assert(0);
1151 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_BUS_ERROR
);
1160 void PIOS_I2C_ER_IRQ_Handler(uint32_t i2c_id
)
1162 struct pios_i2c_adapter
*i2c_adapter
= (struct pios_i2c_adapter
*)i2c_id
;
1164 if (!PIOS_I2C_validate(i2c_adapter
)) {
1169 #if defined(PIOS_I2C_DIAGNOSTICS)
1170 uint32_t event
= I2C_GetLastEvent(i2c_adapter
->cfg
->regs
);
1172 i2c_erirq_history
[i2c_erirq_history_pointer
] = event
;
1173 i2c_erirq_history_pointer
= (i2c_erirq_history_pointer
+ 1) % 5;
1177 if (event
& I2C_FLAG_AF
) {
1180 I2C_ClearFlag(i2c_adapter
->cfg
->regs
, I2C_FLAG_AF
);
1182 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_NACK
);
1183 } else { /* Mostly bus errors here */
1184 i2c_adapter_log_fault(PIOS_I2C_ERROR_INTERRUPT
);
1186 /* Fail hard on any errors for now */
1187 i2c_adapter_inject_event(i2c_adapter
, I2C_EVENT_BUS_ERROR
);
1191 #endif /* PIOS_INCLUDE_I2C */