mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-30 08:24:11 +01:00
f74c6ffdd5
The STM32 I2C block has a number of errata associated with it. These errata are primarily related to timing sensitivities between the peripheral and the interrupt handler. In particular, the correct generation of the stop bit relies on the I2C IRQ running immediately and not being held off for any reason. NOTE: The I2C interrupts must be the highest priority IRQs in the system to ensure correct operation. I2C protocol is now implemented as a formal state machine. See: stm32_i2c_fsm.{dot,jpg} for FSM description. I2C init is now expressed by const initializers in pios_board.c for both OP and AHRS boards. I2C device drivers (ie. bmp085/hmc5843) now pass in const arrays of an unlimited number of bus transfers to be done atomically. The I2C adapter driver now handles all bus-level locking across the list of transactions. Generation of start/restart/stop conditions are handled automatically over the list of transactions. Timeouts have been removed from the API for now. May be added back later. This driver has run error free on both the OP and AHRS boards for up to 48hrs but it still sometimes fails earlier than that on the OP board. There is another possible set of improvements to the driver that could employ the DMA engine for transfers of >= 2bytes. This change would reduce the timing sensitivities between the peripheral and the driver but unfortunately, both the SPI and I2C interfaces share the DMA1 engine. That means only one of these two peripherals can use the DMA engine and right now, SPI between OP and AHRS is already using it. Failures are currently fatal and will lock up the CPU. This allows useful information to be obtained in the failure cases. git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1241 ebee16cc-31ac-478f-84a7-5cbb03baadba
97 lines
2.9 KiB
C
97 lines
2.9 KiB
C
/**
|
|
******************************************************************************
|
|
*
|
|
* @file pios_i2c_priv.h
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
* Parts by Thorsten Klose (tk@midibox.org)
|
|
* @brief I2C private definitions.
|
|
* @see The GNU Public License (GPL) Version 3
|
|
*
|
|
*****************************************************************************/
|
|
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#ifndef PIOS_I2C_PRIV_H
|
|
#define PIOS_I2C_PRIV_H
|
|
|
|
#include <pios.h>
|
|
#include <pios_stm32.h>
|
|
|
|
struct pios_i2c_adapter_cfg {
|
|
I2C_TypeDef * regs;
|
|
I2C_InitTypeDef init;
|
|
|
|
uint32_t transfer_timeout_ms;
|
|
struct stm32_gpio scl;
|
|
struct stm32_gpio sda;
|
|
struct stm32_irq event;
|
|
struct stm32_irq error;
|
|
};
|
|
|
|
enum i2c_adapter_state {
|
|
I2C_STATE_FAULTED = 0, /* Must be zero so undefined transitions land here */
|
|
|
|
I2C_STATE_STOPPED,
|
|
I2C_STATE_STOPPING,
|
|
I2C_STATE_STARTING,
|
|
|
|
I2C_STATE_R_MORE_TXN_ADDR,
|
|
I2C_STATE_R_MORE_TXN_PRE_ONE,
|
|
I2C_STATE_R_MORE_TXN_PRE_FIRST,
|
|
I2C_STATE_R_MORE_TXN_PRE_MIDDLE,
|
|
I2C_STATE_R_MORE_TXN_PRE_LAST,
|
|
I2C_STATE_R_MORE_TXN_POST_LAST,
|
|
|
|
I2C_STATE_R_LAST_TXN_ADDR,
|
|
I2C_STATE_R_LAST_TXN_PRE_ONE,
|
|
I2C_STATE_R_LAST_TXN_PRE_FIRST,
|
|
I2C_STATE_R_LAST_TXN_PRE_MIDDLE,
|
|
I2C_STATE_R_LAST_TXN_PRE_LAST,
|
|
I2C_STATE_R_LAST_TXN_POST_LAST,
|
|
|
|
I2C_STATE_W_MORE_TXN_ADDR,
|
|
I2C_STATE_W_MORE_TXN_MIDDLE,
|
|
I2C_STATE_W_MORE_TXN_LAST,
|
|
|
|
I2C_STATE_W_LAST_TXN_ADDR,
|
|
I2C_STATE_W_LAST_TXN_MIDDLE,
|
|
I2C_STATE_W_LAST_TXN_LAST,
|
|
|
|
I2C_STATE_NUM_STATES /* Must be last */
|
|
};
|
|
|
|
struct pios_i2c_adapter {
|
|
const struct pios_i2c_adapter_cfg * const cfg;
|
|
void (*callback)(uint8_t, uint8_t);
|
|
#ifdef PIOS_INCLUDE_FREERTOS
|
|
xSemaphoreHandle sem_busy;
|
|
xSemaphoreHandle sem_ready;
|
|
#endif
|
|
|
|
enum i2c_adapter_state curr_state;
|
|
const struct pios_i2c_txn * first_txn;
|
|
const struct pios_i2c_txn * active_txn;
|
|
const struct pios_i2c_txn * last_txn;
|
|
|
|
uint8_t * active_byte;
|
|
uint8_t * last_byte;
|
|
};
|
|
|
|
extern struct pios_i2c_adapter pios_i2c_adapters[];
|
|
extern uint8_t pios_i2c_num_adapters;
|
|
|
|
#endif /* PIOS_I2C_PRIV_H */
|