mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-30 08:24:11 +01:00
98822bff98
Since the i2c bus is bidirectional, there are certain states (eg. part way through a read) where the slave device is in control of driving the SDA line. On a cold start (power on), the slave devices are all quiescent and will not drive the bus. However, on a warm start (eg. watchdog or jtag restart), it is possible that as the CPU boots, the slave device may be holding the SDA line low. This is a bus busy condition and will prevent the I2C bus master in the CPU from being able to seize the bus during init. The fix for this is to clock the i2c bus sufficiently to ensure that the the slave device finishes its transaction and releases the bus. Once the slave has released the bus, the bus master can properly initialize and assert a STOP condition on the bus. git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1349 ebee16cc-31ac-478f-84a7-5cbb03baadba
100 lines
3.0 KiB
C
100 lines
3.0 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>
|
|
#include <stdbool.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
|
|
|
|
bool bus_needed_reset;
|
|
|
|
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 */
|