mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-02 10:24:11 +01:00
F2 PiOS I2C: Add a poor man semaphore here in case we start calling I2C
transfers from IRQ. Also catch the double 0x70084 event which was locking up the FSM with -Os enabled. I did this in a cheating way (filtering the event based on state) but it's the cleanest I can see. Hopefully a DMA version of I2C will fix this.
This commit is contained in:
parent
b0e04e5f79
commit
7444337418
@ -889,6 +889,8 @@ int32_t PIOS_I2C_Init(uint32_t * i2c_id, const struct pios_i2c_adapter_cfg * cfg
|
||||
*/
|
||||
vSemaphoreCreateBinary(i2c_adapter->sem_ready);
|
||||
i2c_adapter->sem_busy = xSemaphoreCreateMutex();
|
||||
#else
|
||||
i2c_adapter->busy = 0;
|
||||
#endif // USE_FREERTOS
|
||||
|
||||
/* Initialize the state machine */
|
||||
@ -927,6 +929,17 @@ bool PIOS_I2C_Transfer(uint32_t i2c_id, const struct pios_i2c_txn txn_list[], ui
|
||||
portTickType timeout;
|
||||
timeout = i2c_adapter->cfg->transfer_timeout_ms / portTICK_RATE_MS;
|
||||
semaphore_success &= (xSemaphoreTake(i2c_adapter->sem_busy, timeout) == pdTRUE);
|
||||
#else
|
||||
uint32_t timeout = 0xffff;
|
||||
while(i2c_adapter->busy && --timeout);
|
||||
if(timeout == 0) //timed out
|
||||
return -1;
|
||||
|
||||
PIOS_IRQ_Disable();
|
||||
if(i2c_adapter->busy)
|
||||
return -1;
|
||||
i2c_adapter->busy = 1;
|
||||
PIOS_IRQ_Enable();
|
||||
#endif /* USE_FREERTOS */
|
||||
|
||||
PIOS_DEBUG_Assert(i2c_adapter->curr_state == I2C_STATE_STOPPED);
|
||||
@ -963,6 +976,10 @@ bool PIOS_I2C_Transfer(uint32_t i2c_id, const struct pios_i2c_txn txn_list[], ui
|
||||
xSemaphoreGive(i2c_adapter->sem_busy);
|
||||
if(!semaphore_success)
|
||||
i2c_timeout_counter++;
|
||||
#else
|
||||
PIOS_IRQ_Disable();
|
||||
i2c_adapter->busy = 0;
|
||||
PIOS_IRQ_Enable();
|
||||
#endif /* USE_FREERTOS */
|
||||
|
||||
transfers_successful+= (!i2c_adapter->bus_error) && semaphore_success;
|
||||
@ -988,6 +1005,13 @@ void PIOS_I2C_EV_IRQ_Handler(uint32_t i2c_id)
|
||||
#define EVENT_MASK 0x000700FF
|
||||
event &= EVENT_MASK;
|
||||
|
||||
// This is very poor and inconsistent practice with the FSM since no other
|
||||
// throw event depends on the current state. However when accelerated (-Os)
|
||||
// we definitely catch this event twice and there is no clean way to do deal
|
||||
// with that in the FMS short of a special state for it
|
||||
if(i2c_adapter->curr_state == I2C_STATE_STARTING && event == 0x70084)
|
||||
return;
|
||||
|
||||
|
||||
switch (event) { /* Mask out all the bits we don't care about */
|
||||
case (I2C_EVENT_MASTER_MODE_SELECT | 0x40):
|
||||
|
@ -90,6 +90,8 @@ struct pios_i2c_adapter {
|
||||
#ifdef PIOS_INCLUDE_FREERTOS
|
||||
xSemaphoreHandle sem_busy;
|
||||
xSemaphoreHandle sem_ready;
|
||||
#else
|
||||
uint8_t busy;
|
||||
#endif
|
||||
|
||||
bool bus_error;
|
||||
|
Loading…
Reference in New Issue
Block a user