mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
OP-14 OP-16: I2C Improvements
1) Added nack counter monitoring 2) Made timeout for getting semaphore in I2C user space code use the one from driver and record timeouts. This does not influence timeouts in the non FreeRTOS case 3) Remove case block from the error handler so that all bus errors reset the i2c interface git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2469 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
0e441a20f3
commit
21b4e55029
@ -79,9 +79,11 @@ volatile uint8_t i2c_state_history_pointer = 0;
|
|||||||
volatile enum i2c_adapter_event i2c_state_event_history[I2C_LOG_DEPTH];
|
volatile enum i2c_adapter_event i2c_state_event_history[I2C_LOG_DEPTH];
|
||||||
volatile uint8_t i2c_state_event_history_pointer;
|
volatile uint8_t i2c_state_event_history_pointer;
|
||||||
|
|
||||||
static uint16_t i2c_fsm_fault_count = 0;
|
static uint8_t i2c_fsm_fault_count = 0;
|
||||||
static uint16_t i2c_bad_event_counter = 0;
|
static uint8_t i2c_bad_event_counter = 0;
|
||||||
static uint16_t i2c_error_interrupt_counter = 0;
|
static uint8_t i2c_error_interrupt_counter = 0;
|
||||||
|
static uint8_t i2c_nack_counter = 0;
|
||||||
|
static uint8_t i2c_timeout_counter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void go_fsm_fault(struct pios_i2c_adapter *i2c_adapter);
|
static void go_fsm_fault(struct pios_i2c_adapter *i2c_adapter);
|
||||||
@ -802,13 +804,15 @@ void i2c_adapter_log_fault(enum pios_i2c_error_type type)
|
|||||||
* \param[out] counts three uint16 that receive the bad event, fsm, and error irq
|
* \param[out] counts three uint16 that receive the bad event, fsm, and error irq
|
||||||
* counts
|
* counts
|
||||||
*/
|
*/
|
||||||
void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history * data, uint16_t * counts)
|
void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history * data, uint8_t * counts)
|
||||||
{
|
{
|
||||||
#if defined(PIOS_I2C_DIAGNOSTICS)
|
#if defined(PIOS_I2C_DIAGNOSTICS)
|
||||||
memcpy(data, &i2c_adapter_fault_history, sizeof(i2c_adapter_fault_history));
|
memcpy(data, &i2c_adapter_fault_history, sizeof(i2c_adapter_fault_history));
|
||||||
counts[0] = i2c_bad_event_counter;
|
counts[0] = i2c_bad_event_counter;
|
||||||
counts[1] = i2c_fsm_fault_count;
|
counts[1] = i2c_fsm_fault_count;
|
||||||
counts[2] = i2c_error_interrupt_counter;
|
counts[2] = i2c_error_interrupt_counter;
|
||||||
|
counts[3] = i2c_nack_counter;
|
||||||
|
counts[4] = i2c_timeout_counter;
|
||||||
#else
|
#else
|
||||||
struct pios_i2c_fault_history i2c_adapter_fault_history;
|
struct pios_i2c_fault_history i2c_adapter_fault_history;
|
||||||
i2c_adapter_fault_history.type = PIOS_I2C_ERROR_EVENT;
|
i2c_adapter_fault_history.type = PIOS_I2C_ERROR_EVENT;
|
||||||
@ -871,13 +875,16 @@ bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32
|
|||||||
PIOS_DEBUG_Assert(num_txns);
|
PIOS_DEBUG_Assert(num_txns);
|
||||||
|
|
||||||
struct pios_i2c_adapter *i2c_adapter;
|
struct pios_i2c_adapter *i2c_adapter;
|
||||||
|
bool semaphore_success = true;
|
||||||
|
|
||||||
i2c_adapter = find_i2c_adapter_by_id(i2c);
|
i2c_adapter = find_i2c_adapter_by_id(i2c);
|
||||||
PIOS_DEBUG_Assert(i2c_adapter);
|
PIOS_DEBUG_Assert(i2c_adapter);
|
||||||
|
|
||||||
#ifdef USE_FREERTOS
|
#ifdef USE_FREERTOS
|
||||||
/* Lock the bus */
|
/* Lock the bus */
|
||||||
xSemaphoreTake(i2c_adapter->sem_busy, portMAX_DELAY);
|
portTickType timeout;
|
||||||
|
timeout = i2c_adapter->cfg->transfer_timeout_ms / portTICK_RATE_MS;
|
||||||
|
semaphore_success &= (xSemaphoreTake(i2c_adapter->sem_busy, timeout) == pdTRUE);
|
||||||
#endif /* USE_FREERTOS */
|
#endif /* USE_FREERTOS */
|
||||||
|
|
||||||
PIOS_DEBUG_Assert(i2c_adapter->curr_state == I2C_STATE_STOPPED);
|
PIOS_DEBUG_Assert(i2c_adapter->curr_state == I2C_STATE_STOPPED);
|
||||||
@ -888,7 +895,7 @@ bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32
|
|||||||
|
|
||||||
#ifdef USE_FREERTOS
|
#ifdef USE_FREERTOS
|
||||||
/* Make sure the done/ready semaphore is consumed before we start */
|
/* Make sure the done/ready semaphore is consumed before we start */
|
||||||
xSemaphoreTake(i2c_adapter->sem_ready, portMAX_DELAY);
|
semaphore_success &= (xSemaphoreTake(i2c_adapter->sem_ready, timeout) == pdTRUE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
i2c_adapter->bus_error = false;
|
i2c_adapter->bus_error = false;
|
||||||
@ -896,7 +903,7 @@ bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32
|
|||||||
|
|
||||||
/* Wait for the transfer to complete */
|
/* Wait for the transfer to complete */
|
||||||
#ifdef USE_FREERTOS
|
#ifdef USE_FREERTOS
|
||||||
xSemaphoreTake(i2c_adapter->sem_ready, portMAX_DELAY);
|
semaphore_success &= (xSemaphoreTake(i2c_adapter->sem_ready, timeout) == pdTRUE);
|
||||||
xSemaphoreGive(i2c_adapter->sem_ready);
|
xSemaphoreGive(i2c_adapter->sem_ready);
|
||||||
#endif /* USE_FREERTOS */
|
#endif /* USE_FREERTOS */
|
||||||
|
|
||||||
@ -912,9 +919,11 @@ bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32
|
|||||||
#ifdef USE_FREERTOS
|
#ifdef USE_FREERTOS
|
||||||
/* Unlock the bus */
|
/* Unlock the bus */
|
||||||
xSemaphoreGive(i2c_adapter->sem_busy);
|
xSemaphoreGive(i2c_adapter->sem_busy);
|
||||||
|
if(!semaphore_success)
|
||||||
|
i2c_timeout_counter++;
|
||||||
#endif /* USE_FREERTOS */
|
#endif /* USE_FREERTOS */
|
||||||
|
|
||||||
return (!i2c_adapter->bus_error);
|
return (!i2c_adapter->bus_error) && semaphore_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -1058,29 +1067,8 @@ void PIOS_I2C_ER_IRQ_Handler(uint8_t i2c)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(event) {
|
|
||||||
case 0x70184: /* EV8_2, but system detects own stop byte as erroneous */
|
|
||||||
switch (i2c_adapter->last_byte - i2c_adapter->active_byte + 1) {
|
|
||||||
case 0:
|
|
||||||
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_EQ_0);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_EQ_1);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_EQ_2);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_TRANSFER_DONE_LEN_GT_2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(event & I2C_FLAG_AF) {
|
if(event & I2C_FLAG_AF) {
|
||||||
|
i2c_nack_counter++;
|
||||||
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_NACK);
|
i2c_adapter_inject_event(i2c_adapter, I2C_EVENT_NACK);
|
||||||
} else { /* Mostly bus errors here */
|
} else { /* Mostly bus errors here */
|
||||||
i2c_adapter_log_fault(PIOS_I2C_ERROR_INTERRUPT);
|
i2c_adapter_log_fault(PIOS_I2C_ERROR_INTERRUPT);
|
||||||
|
@ -69,7 +69,7 @@ extern int32_t PIOS_I2C_Init(void);
|
|||||||
extern bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32_t num_txns);
|
extern bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32_t num_txns);
|
||||||
extern void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c);
|
extern void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c);
|
||||||
extern void PIOS_I2C_ER_IRQ_Handler(uint8_t i2c);
|
extern void PIOS_I2C_ER_IRQ_Handler(uint8_t i2c);
|
||||||
extern void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history * data, uint16_t * error_counts);
|
extern void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history * data, uint8_t * error_counts);
|
||||||
|
|
||||||
#endif /* PIOS_I2C_H */
|
#endif /* PIOS_I2C_H */
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
<xml>
|
<xml>
|
||||||
<object name="I2CStats" singleinstance="true" settings="false">
|
<object name="I2CStats" singleinstance="true" settings="false">
|
||||||
<description>Tracks statistics on the I2C bus.</description>
|
<description>Tracks statistics on the I2C bus.</description>
|
||||||
<field name="event_errors" units="" type="uint16" elements="1"/>
|
<field name="event_errors" units="" type="uint8" elements="1"/>
|
||||||
<field name="fsm_errors" units="" type="uint16" elements="1"/>
|
<field name="fsm_errors" units="" type="uint8" elements="1"/>
|
||||||
<field name="irq_errors" units="" type="uint16" elements="1"/>
|
<field name="irq_errors" units="" type="uint8" elements="1"/>
|
||||||
|
<field name="nacks" units="" type="uint8" elements="1"/>
|
||||||
|
<field name="timeouts" units="" type="uint8" elements="1"/>
|
||||||
<field name="last_error_type" units="" type="enum" elements="1" options="EVENT,FSM,INTERRUPT"/>
|
<field name="last_error_type" units="" type="enum" elements="1" options="EVENT,FSM,INTERRUPT"/>
|
||||||
<field name="evirq_log" units="" type="uint32" elements="5"/>
|
<field name="evirq_log" units="" type="uint32" elements="5"/>
|
||||||
<field name="erirq_log" units="" type="uint32" elements="5"/>
|
<field name="erirq_log" units="" type="uint32" elements="5"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user