mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-19 09:54:15 +01:00
hwinit: Convert I2C driver to dynamic init
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2773 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
3fda65c5d3
commit
66a9d53d0a
@ -265,6 +265,7 @@ void PIOS_USART_aux_irq_handler(void)
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
|
||||
#if defined(PIOS_INCLUDE_I2C)
|
||||
|
||||
#include <pios_i2c_priv.h>
|
||||
|
||||
/*
|
||||
@ -327,27 +328,17 @@ const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Board specific number of devices.
|
||||
*/
|
||||
struct pios_i2c_adapter pios_i2c_adapters[] = {
|
||||
{
|
||||
.cfg = &pios_i2c_main_adapter_cfg,
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t pios_i2c_num_adapters = NELEMENTS(pios_i2c_adapters);
|
||||
|
||||
uint32_t pios_i2c_main_adapter_id;
|
||||
void PIOS_I2C_main_adapter_ev_irq_handler(void)
|
||||
{
|
||||
/* Call into the generic code to handle the IRQ for this specific device */
|
||||
PIOS_I2C_EV_IRQ_Handler(PIOS_I2C_MAIN_ADAPTER);
|
||||
PIOS_I2C_EV_IRQ_Handler(pios_i2c_main_adapter_id);
|
||||
}
|
||||
|
||||
void PIOS_I2C_main_adapter_er_irq_handler(void)
|
||||
{
|
||||
/* Call into the generic code to handle the IRQ for this specific device */
|
||||
PIOS_I2C_ER_IRQ_Handler(PIOS_I2C_MAIN_ADAPTER);
|
||||
PIOS_I2C_ER_IRQ_Handler(pios_i2c_main_adapter_id);
|
||||
}
|
||||
|
||||
#endif /* PIOS_INCLUDE_I2C */
|
||||
@ -426,7 +417,9 @@ void PIOS_Board_Init(void) {
|
||||
|
||||
#if defined(PIOS_INCLUDE_HMC5843) && defined(PIOS_INCLUDE_I2C)
|
||||
/* Magnetic sensor system */
|
||||
PIOS_I2C_Init();
|
||||
if (PIOS_I2C_Init(&pios_i2c_main_adapter_id, &pios_i2c_main_adapter_cfg)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
}
|
||||
PIOS_HMC5843_Init();
|
||||
#endif
|
||||
|
||||
|
@ -28,7 +28,6 @@
|
||||
*/
|
||||
|
||||
#include <pios.h>
|
||||
#include <pios_i2c_priv.h>
|
||||
#include <openpilot.h>
|
||||
#include <uavobjectsinit.h>
|
||||
|
||||
@ -580,6 +579,10 @@ void PIOS_TIM4_irq_handler()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_I2C)
|
||||
|
||||
#include <pios_i2c_priv.h>
|
||||
|
||||
/*
|
||||
* I2C Adapters
|
||||
*/
|
||||
@ -638,29 +641,21 @@ const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Board specific number of devices.
|
||||
*/
|
||||
struct pios_i2c_adapter pios_i2c_adapters[] = {
|
||||
{
|
||||
.cfg = &pios_i2c_main_adapter_cfg,
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t pios_i2c_num_adapters = NELEMENTS(pios_i2c_adapters);
|
||||
|
||||
uint32_t pios_i2c_main_adapter_id;
|
||||
void PIOS_I2C_main_adapter_ev_irq_handler(void)
|
||||
{
|
||||
/* Call into the generic code to handle the IRQ for this specific device */
|
||||
PIOS_I2C_EV_IRQ_Handler(PIOS_I2C_MAIN_ADAPTER);
|
||||
PIOS_I2C_EV_IRQ_Handler(pios_i2c_main_adapter_id);
|
||||
}
|
||||
|
||||
void PIOS_I2C_main_adapter_er_irq_handler(void)
|
||||
{
|
||||
/* Call into the generic code to handle the IRQ for this specific device */
|
||||
PIOS_I2C_ER_IRQ_Handler(PIOS_I2C_MAIN_ADAPTER);
|
||||
PIOS_I2C_ER_IRQ_Handler(pios_i2c_main_adapter_id);
|
||||
}
|
||||
|
||||
#endif /* PIOS_INCLUDE_I2C */
|
||||
|
||||
extern const struct pios_com_driver pios_usb_com_driver;
|
||||
|
||||
uint32_t pios_com_telem_rf_id;
|
||||
@ -740,7 +735,12 @@ void PIOS_Board_Init(void) {
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
#endif
|
||||
PIOS_I2C_Init();
|
||||
|
||||
#if defined(PIOS_INCLUDE_I2C)
|
||||
if (PIOS_I2C_Init(&pios_i2c_main_adapter_id, &pios_i2c_main_adapter_cfg)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_I2C */
|
||||
PIOS_IAP_Init();
|
||||
PIOS_WDG_Init();
|
||||
}
|
||||
|
@ -28,13 +28,11 @@
|
||||
*/
|
||||
|
||||
#include <pios.h>
|
||||
#include <pios_i2c_priv.h>
|
||||
#include <openpilot.h>
|
||||
#include <uavobjectsinit.h>
|
||||
|
||||
#if defined(PIOS_INCLUDE_SPI)
|
||||
|
||||
|
||||
#include <pios_spi_priv.h>
|
||||
|
||||
/* MicroSD Interface
|
||||
@ -764,6 +762,10 @@ void PIOS_TIM5_irq_handler()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PIOS_INCLUDE_I2C)
|
||||
|
||||
#include <pios_i2c_priv.h>
|
||||
|
||||
/*
|
||||
* I2C Adapters
|
||||
*/
|
||||
@ -822,29 +824,21 @@ const struct pios_i2c_adapter_cfg pios_i2c_main_adapter_cfg = {
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Board specific number of devices.
|
||||
*/
|
||||
struct pios_i2c_adapter pios_i2c_adapters[] = {
|
||||
{
|
||||
.cfg = &pios_i2c_main_adapter_cfg,
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t pios_i2c_num_adapters = NELEMENTS(pios_i2c_adapters);
|
||||
|
||||
uint32_t pios_i2c_main_adapter_id;
|
||||
void PIOS_I2C_main_adapter_ev_irq_handler(void)
|
||||
{
|
||||
/* Call into the generic code to handle the IRQ for this specific device */
|
||||
PIOS_I2C_EV_IRQ_Handler(PIOS_I2C_MAIN_ADAPTER);
|
||||
PIOS_I2C_EV_IRQ_Handler(pios_i2c_main_adapter_id);
|
||||
}
|
||||
|
||||
void PIOS_I2C_main_adapter_er_irq_handler(void)
|
||||
{
|
||||
/* Call into the generic code to handle the IRQ for this specific device */
|
||||
PIOS_I2C_ER_IRQ_Handler(PIOS_I2C_MAIN_ADAPTER);
|
||||
PIOS_I2C_ER_IRQ_Handler(pios_i2c_main_adapter_id);
|
||||
}
|
||||
|
||||
#endif /* PIOS_INCLUDE_I2C */
|
||||
|
||||
#if defined(PIOS_ENABLE_DEBUG_PINS)
|
||||
|
||||
static const struct stm32_gpio pios_debug_pins[] = {
|
||||
@ -1019,7 +1013,12 @@ void PIOS_Board_Init(void) {
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_COM */
|
||||
#endif /* PIOS_INCLUDE_USB_HID */
|
||||
PIOS_I2C_Init();
|
||||
|
||||
#if defined(PIOS_INCLUDE_I2C)
|
||||
if (PIOS_I2C_Init(&pios_i2c_main_adapter_id, &pios_i2c_main_adapter_cfg)) {
|
||||
PIOS_DEBUG_Assert(0);
|
||||
}
|
||||
#endif /* PIOS_INCLUDE_I2C */
|
||||
PIOS_IAP_Init();
|
||||
PIOS_WDG_Init();
|
||||
}
|
||||
|
@ -125,7 +125,9 @@ TIM8 | | | |
|
||||
// PIOS_I2C
|
||||
// See also pios_board.c
|
||||
//------------------------
|
||||
#define PIOS_I2C_MAIN_ADAPTER 0
|
||||
#define PIOS_I2C_MAX_DEVS 1
|
||||
extern uint32_t pios_i2c_main_adapter_id;
|
||||
#define PIOS_I2C_MAIN_ADAPTER (pios_i2c_main_adapter_id)
|
||||
|
||||
//-------------------------
|
||||
// SPI
|
||||
|
@ -137,7 +137,9 @@ TIM4 | RC In 1 | Servo 3 | Servo 2 | Servo 1
|
||||
// PIOS_I2C
|
||||
// See also pios_board.c
|
||||
//------------------------
|
||||
#define PIOS_I2C_MAIN_ADAPTER 0
|
||||
#define PIOS_I2C_MAX_DEVS 1
|
||||
extern uint32_t pios_i2c_main_adapter_id;
|
||||
#define PIOS_I2C_MAIN_ADAPTER (pios_i2c_main_adapter_id)
|
||||
|
||||
//-------------------------
|
||||
// SPI
|
||||
|
@ -131,7 +131,9 @@ TIM8 | Servo 5 | Servo 6 | Servo 7 | Servo 8
|
||||
// PIOS_I2C
|
||||
// See also pios_board.c
|
||||
//------------------------
|
||||
#define PIOS_I2C_MAIN_ADAPTER 0
|
||||
#define PIOS_I2C_MAX_DEVS 1
|
||||
extern uint32_t pios_i2c_main_adapter_id;
|
||||
#define PIOS_I2C_MAIN_ADAPTER (pios_i2c_main_adapter_id)
|
||||
|
||||
//------------------------
|
||||
// PIOS_BMP085
|
||||
|
@ -740,17 +740,6 @@ static void i2c_adapter_reset_bus(struct pios_i2c_adapter *i2c_adapter)
|
||||
|
||||
#include <pios_i2c_priv.h>
|
||||
|
||||
static struct pios_i2c_adapter *find_i2c_adapter_by_id(uint8_t adapter)
|
||||
{
|
||||
if (adapter >= pios_i2c_num_adapters) {
|
||||
/* Undefined I2C adapter for this board (see pios_board.c) */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get a handle for the device configuration */
|
||||
return &(pios_i2c_adapters[adapter]);
|
||||
}
|
||||
|
||||
/* Return true if the FSM is in a terminal state */
|
||||
static bool i2c_adapter_fsm_terminated(struct pios_i2c_adapter *i2c_adapter)
|
||||
{
|
||||
@ -822,64 +811,108 @@ void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history * data, uint8_t * cou
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool PIOS_I2C_validate(struct pios_i2c_adapter * i2c_adapter)
|
||||
{
|
||||
return (i2c_adapter->magic == PIOS_I2C_DEV_MAGIC);
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS) && 0
|
||||
static struct pios_i2c_dev * PIOS_I2C_alloc(void)
|
||||
{
|
||||
struct pios_i2c_dev * i2c_adapter;
|
||||
|
||||
i2c_adapter = (struct pios_i2c_adapter *)malloc(sizeof(*i2c_adapter));
|
||||
if (!i2c_adapter) return(NULL);
|
||||
|
||||
i2c_adapter->magic = PIOS_I2C_DEV_MAGIC;
|
||||
return(i2c_adapter);
|
||||
}
|
||||
#else
|
||||
static struct pios_i2c_adapter pios_i2c_adapters[PIOS_I2C_MAX_DEVS];
|
||||
static uint8_t pios_i2c_num_adapters;
|
||||
static struct pios_i2c_adapter * PIOS_I2C_alloc(void)
|
||||
{
|
||||
struct pios_i2c_adapter * i2c_adapter;
|
||||
|
||||
if (pios_i2c_num_adapters >= PIOS_I2C_MAX_DEVS) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
i2c_adapter = &pios_i2c_adapters[pios_i2c_num_adapters++];
|
||||
i2c_adapter->magic = PIOS_I2C_DEV_MAGIC;
|
||||
|
||||
return (i2c_adapter);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Initializes IIC driver
|
||||
* \param[in] mode currently only mode 0 supported
|
||||
* \return < 0 if initialisation failed
|
||||
*/
|
||||
int32_t PIOS_I2C_Init(void)
|
||||
int32_t PIOS_I2C_Init(uint32_t * i2c_id, const struct pios_i2c_adapter_cfg * cfg)
|
||||
{
|
||||
struct pios_i2c_adapter *i2c_adapter;
|
||||
PIOS_DEBUG_Assert(i2c_id);
|
||||
PIOS_DEBUG_Assert(cfg);
|
||||
|
||||
for (uint8_t i = 0; i < pios_i2c_num_adapters; i++) {
|
||||
/* Get a handle for the device configuration */
|
||||
i2c_adapter = find_i2c_adapter_by_id(i);
|
||||
PIOS_DEBUG_Assert(i2c_adapter);
|
||||
struct pios_i2c_adapter * i2c_adapter;
|
||||
|
||||
i2c_adapter = (struct pios_i2c_adapter *) PIOS_I2C_alloc();
|
||||
if (!i2c_adapter) goto out_fail;
|
||||
|
||||
/* Bind the configuration to the device instance */
|
||||
i2c_adapter->cfg = cfg;
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
/*
|
||||
* Must be done prior to calling i2c_adapter_fsm_init()
|
||||
* since the sem_ready mutex is used in the initial state.
|
||||
*/
|
||||
vSemaphoreCreateBinary(i2c_adapter->sem_ready);
|
||||
i2c_adapter->sem_busy = xSemaphoreCreateMutex();
|
||||
/*
|
||||
* Must be done prior to calling i2c_adapter_fsm_init()
|
||||
* since the sem_ready mutex is used in the initial state.
|
||||
*/
|
||||
vSemaphoreCreateBinary(i2c_adapter->sem_ready);
|
||||
i2c_adapter->sem_busy = xSemaphoreCreateMutex();
|
||||
#endif // USE_FREERTOS
|
||||
|
||||
/* Enable the associated peripheral clock */
|
||||
switch ((uint32_t) i2c_adapter->cfg->regs) {
|
||||
case (uint32_t) I2C1:
|
||||
/* Enable I2C peripheral clock (APB1 == slow speed) */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
|
||||
break;
|
||||
case (uint32_t) I2C2:
|
||||
/* Enable I2C peripheral clock (APB1 == slow speed) */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Initialize the state machine */
|
||||
i2c_adapter_fsm_init(i2c_adapter);
|
||||
|
||||
/* Configure and enable I2C interrupts */
|
||||
NVIC_Init(&(i2c_adapter->cfg->event.init));
|
||||
NVIC_Init(&(i2c_adapter->cfg->error.init));
|
||||
/* Enable the associated peripheral clock */
|
||||
switch ((uint32_t) i2c_adapter->cfg->regs) {
|
||||
case (uint32_t) I2C1:
|
||||
/* Enable I2C peripheral clock (APB1 == slow speed) */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
|
||||
break;
|
||||
case (uint32_t) I2C2:
|
||||
/* Enable I2C peripheral clock (APB1 == slow speed) */
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Initialize the state machine */
|
||||
i2c_adapter_fsm_init(i2c_adapter);
|
||||
|
||||
*i2c_id = (uint32_t)i2c_adapter;
|
||||
|
||||
/* Configure and enable I2C interrupts */
|
||||
NVIC_Init(&(i2c_adapter->cfg->event.init));
|
||||
NVIC_Init(&(i2c_adapter->cfg->error.init));
|
||||
|
||||
/* No error */
|
||||
return 0;
|
||||
|
||||
out_fail:
|
||||
return(-1);
|
||||
}
|
||||
|
||||
bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32_t num_txns)
|
||||
bool PIOS_I2C_Transfer(uint32_t i2c_id, const struct pios_i2c_txn txn_list[], uint32_t num_txns)
|
||||
{
|
||||
struct pios_i2c_adapter * i2c_adapter = (struct pios_i2c_adapter *)i2c_id;
|
||||
|
||||
bool valid = PIOS_I2C_validate(i2c_adapter);
|
||||
PIOS_Assert(valid)
|
||||
|
||||
PIOS_DEBUG_Assert(txn_list);
|
||||
PIOS_DEBUG_Assert(num_txns);
|
||||
|
||||
struct pios_i2c_adapter *i2c_adapter;
|
||||
bool semaphore_success = true;
|
||||
|
||||
i2c_adapter = find_i2c_adapter_by_id(i2c);
|
||||
PIOS_DEBUG_Assert(i2c_adapter);
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
/* Lock the bus */
|
||||
portTickType timeout;
|
||||
@ -928,14 +961,13 @@ bool PIOS_I2C_Transfer(uint8_t i2c, const struct pios_i2c_txn txn_list[], uint32
|
||||
|
||||
#endif
|
||||
|
||||
void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c)
|
||||
void PIOS_I2C_EV_IRQ_Handler(uint32_t i2c_id)
|
||||
{
|
||||
struct pios_i2c_adapter *i2c_adapter;
|
||||
|
||||
|
||||
i2c_adapter = find_i2c_adapter_by_id(i2c);
|
||||
PIOS_DEBUG_Assert(i2c_adapter);
|
||||
|
||||
struct pios_i2c_adapter * i2c_adapter = (struct pios_i2c_adapter *)i2c_id;
|
||||
|
||||
bool valid = PIOS_I2C_validate(i2c_adapter);
|
||||
PIOS_Assert(valid)
|
||||
|
||||
uint32_t event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
|
||||
|
||||
#if defined(PIOS_I2C_DIAGNOSTICS)
|
||||
@ -1052,14 +1084,14 @@ skip_event:
|
||||
}
|
||||
|
||||
|
||||
void PIOS_I2C_ER_IRQ_Handler(uint8_t i2c)
|
||||
void PIOS_I2C_ER_IRQ_Handler(uint32_t i2c_id)
|
||||
{
|
||||
struct pios_i2c_adapter *i2c_adapter;
|
||||
struct pios_i2c_adapter * i2c_adapter = (struct pios_i2c_adapter *)i2c_id;
|
||||
|
||||
i2c_adapter = find_i2c_adapter_by_id(i2c);
|
||||
PIOS_DEBUG_Assert(i2c_adapter);
|
||||
|
||||
#if defined(PIOS_I2C_DIAGNOSTICS)
|
||||
bool valid = PIOS_I2C_validate(i2c_adapter);
|
||||
PIOS_Assert(valid)
|
||||
|
||||
#if defined(PIOS_I2C_DIAGNOSTICS)
|
||||
uint32_t event = I2C_GetLastEvent(i2c_adapter->cfg->regs);
|
||||
|
||||
i2c_erirq_history[i2c_erirq_history_pointer] = event;
|
||||
|
@ -65,10 +65,9 @@ struct pios_i2c_fault_history {
|
||||
};
|
||||
|
||||
/* Public Functions */
|
||||
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 void PIOS_I2C_EV_IRQ_Handler(uint8_t i2c);
|
||||
extern void PIOS_I2C_ER_IRQ_Handler(uint8_t i2c);
|
||||
extern bool PIOS_I2C_Transfer(uint32_t i2c_id, const struct pios_i2c_txn txn_list[], uint32_t num_txns);
|
||||
extern void PIOS_I2C_EV_IRQ_Handler(uint32_t i2c_id);
|
||||
extern void PIOS_I2C_ER_IRQ_Handler(uint32_t i2c_id);
|
||||
extern void PIOS_I2C_GetDiagnostics(struct pios_i2c_fault_history * data, uint8_t * error_counts);
|
||||
|
||||
#endif /* PIOS_I2C_H */
|
||||
|
@ -78,8 +78,13 @@ enum i2c_adapter_state {
|
||||
I2C_STATE_NUM_STATES /* Must be last */
|
||||
};
|
||||
|
||||
enum pios_i2c_adapter_magic {
|
||||
PIOS_I2C_DEV_MAGIC = 0xa9a9b8b8,
|
||||
};
|
||||
|
||||
struct pios_i2c_adapter {
|
||||
const struct pios_i2c_adapter_cfg *const cfg;
|
||||
enum pios_i2c_adapter_magic magic;
|
||||
const struct pios_i2c_adapter_cfg * cfg;
|
||||
void (*callback) (uint8_t, uint8_t);
|
||||
#ifdef PIOS_INCLUDE_FREERTOS
|
||||
xSemaphoreHandle sem_busy;
|
||||
@ -97,7 +102,6 @@ struct pios_i2c_adapter {
|
||||
uint8_t *last_byte;
|
||||
};
|
||||
|
||||
extern struct pios_i2c_adapter pios_i2c_adapters[];
|
||||
extern uint8_t pios_i2c_num_adapters;
|
||||
int32_t PIOS_I2C_Init(uint32_t * i2c_id, const struct pios_i2c_adapter_cfg * cfg);
|
||||
|
||||
#endif /* PIOS_I2C_PRIV_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user