1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

hwinit: Convert SPI drivers to dynamic init

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2772 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
stac 2011-02-12 22:19:50 +00:00 committed by stac
parent 841b0d3d6d
commit 3fda65c5d3
24 changed files with 251 additions and 238 deletions

View File

@ -547,6 +547,8 @@ int main()
uint32_t counter_val = 0;
ahrs_algorithm = AHRSSETTINGS_ALGORITHM_SIMPLE;
reset_values();
PIOS_Board_Init();
#if defined(PIOS_INCLUDE_HMC5843) && defined(PIOS_INCLUDE_I2C)
@ -555,9 +557,6 @@ int main()
PIOS_HMC5843_ReadID(mag_data.id);
#endif
reset_values();
AhrsInitComms();
while(!AhrsLinkReady()) {
AhrsPoll();
}

View File

@ -137,21 +137,11 @@ static const struct pios_spi_cfg pios_spi_op_cfg = {
},
};
/*
* Board specific number of devices.
*/
struct pios_spi_dev pios_spi_devs[] = {
{
.cfg = &pios_spi_op_cfg,
},
};
uint8_t pios_spi_num_devices = NELEMENTS(pios_spi_devs);
uint32_t pios_spi_op_id;
void PIOS_SPI_op_irq_handler(void)
{
/* Call into the generic code to handle the IRQ for this specific device */
PIOS_SPI_IRQ_Handler(PIOS_SPI_OP);
PIOS_SPI_IRQ_Handler(pios_spi_op_id);
}
#endif /* PIOS_INCLUDE_SPI */
@ -440,4 +430,16 @@ void PIOS_Board_Init(void) {
PIOS_HMC5843_Init();
#endif
#if defined(PIOS_INCLUDE_SPI)
#include "ahrs_spi_comm.h"
AhrsInitComms();
/* Set up the SPI interface to the OP board */
if (PIOS_SPI_Init(&pios_spi_op_id, &pios_spi_op_cfg)) {
PIOS_DEBUG_Assert(0);
}
AhrsConnect(pios_spi_op_id);
#endif
}

View File

@ -29,21 +29,21 @@
#include "ahrs_spi_program.h"
#include "pios_spi.h"
PROGERR TransferPacket(AhrsProgramPacket *txBuf, AhrsProgramPacket *rxBuf);
PROGERR TransferPacket(uint32_t spi_id, AhrsProgramPacket *txBuf, AhrsProgramPacket *rxBuf);
#define MAX_CONNECT_TRIES 500 //half a second
bool AhrsProgramConnect(void)
bool AhrsProgramConnect(uint32_t spi_id)
{
AhrsProgramPacket rxBuf;
AhrsProgramPacket txBuf;
memset(&rxBuf, 0, sizeof(AhrsProgramPacket));
memcpy(&txBuf,SPI_PROGRAM_REQUEST,SPI_PROGRAM_REQUEST_LENGTH);
for(int ct = 0; ct < MAX_CONNECT_TRIES; ct++) {
PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 0);
uint32_t res = PIOS_SPI_TransferBlock(PIOS_OPAHRS_SPI, (uint8_t *) &txBuf,
PIOS_SPI_RC_PinSet(spi_id, 0);
uint32_t res = PIOS_SPI_TransferBlock(spi_id, (uint8_t *) &txBuf,
(uint8_t *) & rxBuf, SPI_PROGRAM_REQUEST_LENGTH +1, NULL);
PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 1);
PIOS_SPI_RC_PinSet(spi_id, 1);
if(res == 0 && memcmp(&rxBuf, SPI_PROGRAM_ACK, SPI_PROGRAM_REQUEST_LENGTH) == 0) {
return (true);
}
@ -54,7 +54,7 @@ bool AhrsProgramConnect(void)
}
PROGERR AhrsProgramWrite(uint32_t address, void * data, uint32_t size)
PROGERR AhrsProgramWrite(uint32_t spi_id, uint32_t address, void * data, uint32_t size)
{
AhrsProgramPacket rxBuf;
AhrsProgramPacket txBuf;
@ -63,14 +63,14 @@ PROGERR AhrsProgramWrite(uint32_t address, void * data, uint32_t size)
txBuf.size = size;
txBuf.type = PROGRAM_WRITE;
txBuf.address = address;
PROGERR ret = TransferPacket(&txBuf, &rxBuf);
PROGERR ret = TransferPacket(spi_id, &txBuf, &rxBuf);
if(ret != PROGRAM_ERR_OK) {
return(ret);
}
return(PROGRAM_ERR_OK);
}
PROGERR AhrsProgramRead(uint32_t address, void * data, uint32_t size)
PROGERR AhrsProgramRead(uint32_t spi_id, uint32_t address, void * data, uint32_t size)
{
AhrsProgramPacket rxBuf;
AhrsProgramPacket txBuf;
@ -78,7 +78,7 @@ PROGERR AhrsProgramRead(uint32_t address, void * data, uint32_t size)
txBuf.size = size;
txBuf.type = PROGRAM_READ;
txBuf.address = address;
PROGERR ret = TransferPacket(&txBuf, &rxBuf);
PROGERR ret = TransferPacket(spi_id, &txBuf, &rxBuf);
if(ret != PROGRAM_ERR_OK) {
return(ret);
}
@ -86,14 +86,14 @@ PROGERR AhrsProgramRead(uint32_t address, void * data, uint32_t size)
return(PROGRAM_ERR_OK);
}
PROGERR AhrsProgramReboot(void)
PROGERR AhrsProgramReboot(uint32_t spi_id)
{
AhrsProgramPacket rxBuf;
AhrsProgramPacket txBuf;
memset(&rxBuf, 0, sizeof(AhrsProgramPacket));
txBuf.type = PROGRAM_REBOOT;
memcpy(txBuf.data,REBOOT_CONFIRMATION,REBOOT_CONFIRMATION_LENGTH);
PROGERR ret = TransferPacket(&txBuf, &rxBuf);
PROGERR ret = TransferPacket(spi_id, &txBuf, &rxBuf);
//If AHRS has rebooted we will get comms errors
if(ret == PROGRAM_ERR_LINK) {
return(PROGRAM_ERR_OK);
@ -101,7 +101,7 @@ PROGERR AhrsProgramReboot(void)
return(PROGRAM_ERR_FUNCTION);
}
PROGERR TransferPacket(AhrsProgramPacket *txBuf, AhrsProgramPacket *rxBuf)
PROGERR TransferPacket(uint32_t spi_id, AhrsProgramPacket *txBuf, AhrsProgramPacket *rxBuf)
{
static uint32_t pktId = 0;
pktId++;
@ -109,10 +109,10 @@ PROGERR TransferPacket(AhrsProgramPacket *txBuf, AhrsProgramPacket *rxBuf)
txBuf->crc = GenerateCRC(txBuf);
int ct = 0;
for(; ct < MAX_CONNECT_TRIES; ct++) {
PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 0);
uint32_t res = PIOS_SPI_TransferBlock(PIOS_OPAHRS_SPI, (uint8_t *) txBuf,
PIOS_SPI_RC_PinSet(spi_id, 0);
uint32_t res = PIOS_SPI_TransferBlock(spi_id, (uint8_t *) txBuf,
(uint8_t *) rxBuf, sizeof(AhrsProgramPacket), NULL);
PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 1);
PIOS_SPI_RC_PinSet(spi_id, 1);
if(res == 0) {
if(rxBuf->type != PROGRAM_NULL &&
rxBuf->crc == GenerateCRC(rxBuf) &&

View File

@ -47,7 +47,7 @@ static void ProcessPacket();
//Number of crc failures to allow before giving up
#define PROGRAM_PACKET_TRIES 4
void AhrsProgramReceive(void)
void AhrsProgramReceive(uint32_t spi_id)
{
done = false;
memset(&txBuf,0,sizeof(AhrsProgramPacket));
@ -55,9 +55,9 @@ void AhrsProgramReceive(void)
int count = PROGRAM_PACKET_TRIES;
while(1) {
WAIT_IF_RECEIVING();
while((PIOS_SPI_Busy(PIOS_SPI_OP) != 0)){};
while((PIOS_SPI_Busy(spi_id) != 0)){};
memset(&rxBuf,'a',sizeof(AhrsProgramPacket));
int32_t res = PIOS_SPI_TransferBlock(PIOS_SPI_OP, NULL, (uint8_t*) &rxBuf,
int32_t res = PIOS_SPI_TransferBlock(spi_id, NULL, (uint8_t*) &rxBuf,
SPI_PROGRAM_REQUEST_LENGTH + 1, NULL);
if(res == 0 &&
@ -77,14 +77,14 @@ void AhrsProgramReceive(void)
//send ack
memcpy(&txBuf,SPI_PROGRAM_ACK,SPI_PROGRAM_REQUEST_LENGTH);
WAIT_IF_RECEIVING();
while(0 != PIOS_SPI_TransferBlock(PIOS_SPI_OP,(uint8_t*) &txBuf, NULL,
while(0 != PIOS_SPI_TransferBlock(spi_id,(uint8_t*) &txBuf, NULL,
SPI_PROGRAM_REQUEST_LENGTH + 1, NULL)) {};
txBuf.type = PROGRAM_NULL;
while(!done) {
WAIT_IF_RECEIVING();
if(0 == PIOS_SPI_TransferBlock(PIOS_SPI_OP,(uint8_t*) &txBuf,
if(0 == PIOS_SPI_TransferBlock(spi_id,(uint8_t*) &txBuf,
(uint8_t*) &rxBuf, sizeof(AhrsProgramPacket), NULL)) {
uint32_t crc = GenerateCRC(&rxBuf);

View File

@ -36,29 +36,27 @@ typedef enum {PROGRAM_ERR_OK, //OK
/** Connect to AHRS and request programming mode
* returns: false if failed.
*/
bool AhrsProgramConnect(void);
bool AhrsProgramConnect(uint32_t spi_id);
/** Write data to AHRS
* size must be between 1 and SPI_MAX_PROGRAM_DATA_SIZE
* returns: error status
*/
PROGERR AhrsProgramWrite(uint32_t address, void * data, uint32_t size);
PROGERR AhrsProgramWrite(uint32_t spi_id, uint32_t address, void * data, uint32_t size);
/** Read data from AHRS
* size must be between 1 and SPI_MAX_PROGRAM_DATA_SIZE
* returns: error status
*/
PROGERR AhrsProgramRead(uint32_t address, void * data, uint32_t size);
PROGERR AhrsProgramRead(uint32_t spi_id, uint32_t address, void * data, uint32_t size);
/** reboot AHRS
* returns: error status
*/
PROGERR AhrsProgramReboot(void);
PROGERR AhrsProgramReboot(uint32_t spi_id);
//TODO: Implement programming protocol

View File

@ -31,5 +31,5 @@
* If so, it will program the FLASH then return
* If not it just returns.
*/
void AhrsProgramReceive(void);
void AhrsProgramReceive(uint32_t spi_id);
#endif //AHRS_PROGRAM_SLAVE_H

View File

@ -28,19 +28,23 @@
*/
#include <pios.h>
#include <pios_spi_priv.h>
#include <pios_i2c_priv.h>
#include <openpilot.h>
#include <uavobjectsinit.h>
#if defined(PIOS_INCLUDE_SPI)
#include <pios_spi_priv.h>
/* Flash/Accel Interface
*
* NOTE: Leave this declared as const data so that it ends up in the
* .rodata section (ie. Flash) rather than in the .bss section (RAM).
*/
void PIOS_SPI_ahrs_irq_handler(void);
void DMA1_Channel4_IRQHandler() __attribute__ ((alias ("PIOS_SPI_ahrs_irq_handler")));
void DMA1_Channel5_IRQHandler() __attribute__ ((alias ("PIOS_SPI_ahrs_irq_handler")));
void PIOS_SPI_flash_accel_irq_handler(void);
void DMA1_Channel4_IRQHandler() __attribute__ ((alias ("PIOS_SPI_flash_accel_irq_handler")));
void DMA1_Channel5_IRQHandler() __attribute__ ((alias ("PIOS_SPI_flash_accel_irq_handler")));
const struct pios_spi_cfg pios_spi_flash_accel_cfg = {
.regs = SPI2,
.init = {
@ -59,7 +63,7 @@ const struct pios_spi_cfg pios_spi_flash_accel_cfg = {
.ahb_clk = RCC_AHBPeriph_DMA1,
.irq = {
.handler = PIOS_SPI_ahrs_irq_handler,
.handler = PIOS_SPI_flash_accel_irq_handler,
.flags = (DMA1_FLAG_TC4 | DMA1_FLAG_TE4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4),
.init = {
.NVIC_IRQChannel = DMA1_Channel4_IRQn,
@ -132,23 +136,15 @@ const struct pios_spi_cfg pios_spi_flash_accel_cfg = {
},
};
/*
* Board specific number of devices.
*/
struct pios_spi_dev pios_spi_devs[] = {
{
.cfg = &pios_spi_flash_accel_cfg,
},
};
uint8_t pios_spi_num_devices = NELEMENTS(pios_spi_devs);
void PIOS_SPI_ahrs_irq_handler(void)
static uint32_t pios_spi_flash_accel_id;
void PIOS_SPI_flash_accel_irq_handler(void)
{
/* Call into the generic code to handle the IRQ for this specific device */
// PIOS_SPI_IRQ_Handler(PIOS_OPAHRS_SPI);
PIOS_SPI_IRQ_Handler(pios_spi_flash_accel_id);
}
#endif /* PIOS_INCLUDE_SPI */
/*
* ADC system
*/
@ -682,9 +678,13 @@ void PIOS_Board_Init(void) {
/* Delay system */
PIOS_DELAY_Init();
/* SPI Init */
PIOS_SPI_Init();
PIOS_Flash_W25X_Init();
/* Set up the SPI interface to the serial flash */
if (PIOS_SPI_Init(&pios_spi_flash_accel_id, &pios_spi_flash_accel_cfg)) {
PIOS_DEBUG_Assert(0);
}
PIOS_Flash_W25X_Init(pios_spi_flash_accel_id);
PIOS_ADXL345_Attach(pios_spi_flash_accel_id);
#if defined(PIOS_INCLUDE_SPEKTRUM)
/* SPEKTRUM init must come before comms */

View File

@ -140,10 +140,14 @@ void AhrsInitComms(void)
memset(&readyObjects, 0, sizeof(bool) * MAX_AHRS_OBJECTS);
txPacket.command = COMMS_NULL;
rxPacket.command = COMMS_NULL;
}
#ifdef IN_AHRS
PIOS_SPI_Init();
#else
static uint32_t opahrs_spi_id;
void AhrsConnect(uint32_t spi_id)
{
/* Bind this comms layer to the appropriate SPI id */
opahrs_spi_id = spi_id;
#ifndef IN_AHRS
/* Comms already init in OP code */
for (int ct = 0; ct < MAX_AHRS_OBJECTS; ct++) {
AhrsObjHandle hdl = AhrsFromIndex(ct);
@ -152,7 +156,6 @@ void AhrsInitComms(void)
}
}
#endif
}
int32_t AhrsSetData(AhrsObjHandle obj, const void *dataIn)
@ -310,7 +313,7 @@ AhrsCommStatus AhrsGetStatus()
static void CommsCallback(uint8_t crc_ok, uint8_t crc_val)
{
#ifndef IN_AHRS
PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 1); //signal the end of the transfer
PIOS_SPI_RC_PinSet(opahrs_spi_id, 1); //signal the end of the transfer
#endif
txPacket.command = COMMS_NULL; //we must send something so default to null
@ -356,7 +359,7 @@ static void CommsCallback(uint8_t crc_ok, uint8_t crc_val)
If PIOS_SPI_TransferBlock() fails for any reason, comms will stop working.
In that case, AhrsPoll() should kick start things again.
*/
PIOS_SPI_TransferBlock(PIOS_SPI_OP, (uint8_t *) & txPacket, (uint8_t *) & rxPacket, sizeof(CommsDataPacket), &CommsCallback);
PIOS_SPI_TransferBlock(opahrs_spi_id, (uint8_t *) & txPacket, (uint8_t *) & rxPacket, sizeof(CommsDataPacket), &CommsCallback);
#endif
}
@ -378,23 +381,22 @@ static void PollEvents(void)
}
}
#ifdef IN_AHRS
void AhrsPoll()
{
if(programReceive)
{
AhrsProgramReceive();
AhrsProgramReceive(opahrs_spi_id);
programReceive = false;
}
PollEvents();
if (PIOS_SPI_Busy(PIOS_SPI_OP) != 0) { //Everything is working correctly
if (PIOS_SPI_Busy(opahrs_spi_id) != 0) { //Everything is working correctly
return;
}
txPacket.status.kickStarts++;
//comms have broken down - try kick starting it.
txPacket.command = COMMS_NULL; //we must send something so default to null
PIOS_SPI_TransferBlock(PIOS_SPI_OP, (uint8_t *) & txPacket, (uint8_t *) & rxPacket, sizeof(CommsDataPacket), &CommsCallback);
PIOS_SPI_TransferBlock(opahrs_spi_id, (uint8_t *) & txPacket, (uint8_t *) & rxPacket, sizeof(CommsDataPacket), &CommsCallback);
}
bool AhrsLinkReady(void)
@ -437,9 +439,9 @@ void AhrsSendObjects(void)
void SendPacket(void)
{
PIOS_SPI_RC_PinSet(PIOS_OPAHRS_SPI, 0);
PIOS_SPI_RC_PinSet(opahrs_spi_id, 0);
//no point checking if this failed. There isn't much we could do about it if it did fail
PIOS_SPI_TransferBlock(PIOS_OPAHRS_SPI, (uint8_t *) & txPacket, (uint8_t *) & rxPacket, sizeof(CommsDataPacket), &CommsCallback);
PIOS_SPI_TransferBlock(opahrs_spi_id, (uint8_t *) & txPacket, (uint8_t *) & rxPacket, sizeof(CommsDataPacket), &CommsCallback);
}
static void AhrsUpdatedCb(AhrsObjHandle handle)

View File

@ -24,8 +24,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef AHRSCOMMS_H_INCLUDED
#define AHRSCOMMS_H_INCLUDED
#ifndef AHRS_SPI_COMM_H_INCLUDED
#define AHRS_SPI_COMM_H_INCLUDED
#ifdef IN_AHRS //AHRS only
#include <stdint.h>
@ -87,6 +87,10 @@ AhrsSendObjects()
*/
void AhrsInitComms(void);
/** Connect Comms to a specific SPI interface instance.
*/
void AhrsConnect(uint32_t spi_id);
/** AHRS version of UAVObject xxxSetData.
Returns: 0 if ok, -1 if an error
*/
@ -129,4 +133,4 @@ void AhrsSendObjects(void);
#endif
#endif //#ifndef AHRSCOMMS_H_INCLUDED
#endif //#ifndef AHRS_SPI_COMM_H_INCLUDED

View File

@ -71,8 +71,6 @@ static void ahrscommsTask(void *parameters);
*/
int32_t AHRSCommsInitialize(void)
{
AhrsInitComms();
// Start main task
xTaskCreate(ahrscommsTask, (signed char *)"AHRSComms", STACK_SIZE, NULL, TASK_PRIORITY, &taskHandle);
TaskMonitorAdd(TASKINFO_RUNNING_AHRSCOMMS, taskHandle);

View File

@ -28,11 +28,15 @@
*/
#include <pios.h>
#include <pios_spi_priv.h>
#include <pios_i2c_priv.h>
#include <openpilot.h>
#include <uavobjectsinit.h>
#if defined(PIOS_INCLUDE_SPI)
#include <pios_spi_priv.h>
/* MicroSD Interface
*
* NOTE: Leave this declared as const data so that it ends up in the
@ -230,32 +234,22 @@ const struct pios_spi_cfg pios_spi_ahrs_cfg = {
},
};
/*
* Board specific number of devices.
*/
struct pios_spi_dev pios_spi_devs[] = {
{
.cfg = &pios_spi_sdcard_cfg,
},
{
.cfg = &pios_spi_ahrs_cfg,
},
};
uint8_t pios_spi_num_devices = NELEMENTS(pios_spi_devs);
static uint32_t pios_spi_sdcard_id;
void PIOS_SPI_sdcard_irq_handler(void)
{
/* Call into the generic code to handle the IRQ for this specific device */
PIOS_SPI_IRQ_Handler(PIOS_SDCARD_SPI);
PIOS_SPI_IRQ_Handler(pios_spi_sdcard_id);
}
uint32_t pios_spi_ahrs_id;
void PIOS_SPI_ahrs_irq_handler(void)
{
/* Call into the generic code to handle the IRQ for this specific device */
PIOS_SPI_IRQ_Handler(PIOS_OPAHRS_SPI);
PIOS_SPI_IRQ_Handler(pios_spi_ahrs_id);
}
#endif /* PIOS_INCLUDE_SPI */
/*
* ADC system
*/
@ -938,6 +932,8 @@ uint32_t pios_com_gps_id;
uint32_t pios_com_aux_id;
uint32_t pios_com_spektrum_id;
#include "ahrs_spi_comm.h"
/**
* PIOS_Board_Init()
* initializes all the core subsystems on this specific hardware
@ -951,12 +947,17 @@ void PIOS_Board_Init(void) {
/* Delay system */
PIOS_DELAY_Init();
/* SPI Init */
PIOS_SPI_Init();
#if defined(PIOS_INCLUDE_SPI)
/* Set up the SPI interface to the SD card */
if (PIOS_SPI_Init(&pios_spi_sdcard_id, &pios_spi_sdcard_cfg)) {
PIOS_DEBUG_Assert(0);
}
/* Enable and mount the SDCard */
PIOS_SDCARD_Init();
PIOS_SDCARD_Init(pios_spi_sdcard_id);
PIOS_SDCARD_MountFS(0);
#endif /* PIOS_INCLUDE_SPI */
#if defined(PIOS_INCLUDE_SPEKTRUM)
/* SPEKTRUM init must come before comms */
PIOS_SPEKTRUM_Init();
@ -972,6 +973,17 @@ void PIOS_Board_Init(void) {
/* Initialize the task monitor library */
TaskMonitorInitialize();
/* Prepare the AHRS Comms upper layer protocol */
AhrsInitComms();
/* Set up the SPI interface to the AHRS */
if (PIOS_SPI_Init(&pios_spi_ahrs_id, &pios_spi_ahrs_cfg)) {
PIOS_DEBUG_Assert(0);
}
/* Bind the AHRS comms layer to the AHRS SPI link */
AhrsConnect(pios_spi_ahrs_id);
/* Initialize the PiOS library */
#if defined(PIOS_INCLUDE_COM)
if (PIOS_USART_Init(&pios_usart_telem_rf_id, &pios_usart_telem_cfg)) {

View File

@ -132,7 +132,7 @@ TIM8 | | | |
//
// See also pios_board.c
//-------------------------
#define PIOS_SPI_OP 0
#define PIOS_SPI_MAX_DEVS 1
//-------------------------
// PIOS_USART

View File

@ -144,8 +144,7 @@ TIM4 | RC In 1 | Servo 3 | Servo 2 | Servo 1
//
// See also pios_board.c
//-------------------------
#define PIOS_SPI_FLASH 0
#define PIOS_SPI_ACCEL 0
#define PIOS_SPI_MAX_DEVS 2
//-------------------------
// PIOS_USART

View File

@ -157,12 +157,13 @@ TIM8 | | | |
#define STOPWATCH_TIMER TIM4
// *****************************************************************
// SPI
//
//------------------------
// PIOS_SPI
// See also pios_board.c
#define PIOS_SPI_PORT 0
//------------------------
#define PIOS_SPI_MAX_DEVS 1
extern uint32_t pios_spi_port_id;
#define PIOS_SPI_PORT (pios_spi_port_id)
//-------------------------
// PIOS_USART

View File

@ -121,6 +121,12 @@ TIM8 | Servo 5 | Servo 6 | Servo 7 | Servo 8
#define PIOS_LED_PINS { PIOS_LED_LED1_GPIO_PIN, PIOS_LED_LED2_GPIO_PIN }
#define PIOS_LED_CLKS { PIOS_LED_LED1_GPIO_CLK, PIOS_LED_LED2_GPIO_CLK }
//------------------------
// PIOS_SPI
// See also pios_board.c
//------------------------
#define PIOS_SPI_MAX_DEVS 2
//------------------------
// PIOS_I2C
// See also pios_board.c
@ -182,14 +188,6 @@ extern uint32_t pios_com_spektrum_id;
#define PIOS_COM_SPEKTRUM (pios_com_spektrum_id)
#endif
//-------------------------
// SPI
//
// See also pios_board.c
//-------------------------
#define PIOS_SDCARD_SPI 0
#define PIOS_OPAHRS_SPI 1
//-------------------------
// Delay Timer
//-------------------------

View File

@ -9,6 +9,8 @@
#include "pios.h"
static uint32_t PIOS_SPI_ACCEL;
/**
* @brief Claim the SPI bus for the accel communications and select this chip
*/
@ -74,10 +76,18 @@ void PIOS_ADXL345_SetMeasure(uint8_t enable)
PIOS_ADXL345_ReleaseBus();
}
/**
* @brief Connect to the correct SPI bus
*/
void PIOS_ADXL345_Attach(uint32_t spi_id)
{
PIOS_SPI_ACCEL = spi_id;
}
/**
* @brief Initialize with good default settings
*/
void PIOS_ADXL345_Init()
void PIOS_ADXL345_Init()
{
PIOS_ADXL345_ReleaseBus();
PIOS_ADXL345_SelectRate(ADXL_RATE_3200);
@ -107,4 +117,4 @@ uint8_t PIOS_ADXL345_Read(struct pios_adxl345_data * data)
data->z = rec[5] + (rec[6] << 8);
return rec[8] & 0x7F; // return number of remaining entries
}
}

View File

@ -39,6 +39,8 @@ static void PIOS_Flash_W25X_ReleaseBus();
static uint8_t PIOS_Flash_W25X_WriteEnable();
static uint8_t PIOS_Flash_W25X_Busy() ;
static uint32_t PIOS_SPI_FLASH;
/**
* @brief Claim the SPI bus for flash use and assert CS pin
* @return 0 for sucess, -1 for failure to get semaphore
@ -84,8 +86,10 @@ static uint8_t PIOS_Flash_W25X_WriteEnable()
/**
* @brief Initialize the flash device and enable write access
*/
int8_t PIOS_Flash_W25X_Init()
int8_t PIOS_Flash_W25X_Init(uint32_t spi_id)
{
PIOS_SPI_FLASH = spi_id;
PIOS_GPIO_Enable(PIOS_FLASH_CS_PIN);
device_type = PIOS_Flash_W25X_ReadID();
return 0;
@ -233,4 +237,4 @@ int8_t PIOS_Flash_W25X_ReadData(uint32_t addr, uint8_t * data, uint16_t len)
PIOS_Flash_W25X_ReleaseBus();
return 0;
}
}

View File

@ -90,18 +90,20 @@ uint8_t PIOS_SDCARD_Sector[SECTOR_SIZE];
static uint8_t CardType;
static int32_t sdcard_mounted;
static uint32_t PIOS_SDCARD_SPI;
/**
* Initialises SPI pins and peripheral to access MMC/SD Card
* \param[in] mode currently only mode 0 supported
* \return < 0 if initialisation failed
*/
int32_t PIOS_SDCARD_Init(void)
int32_t PIOS_SDCARD_Init(uint32_t spi_id)
{
SDCARD_MUTEX_TAKE;
sdcard_mounted = 0;
//PIOS_SPI_Init(PIOS_SDCARD_SPI);
PIOS_SDCARD_SPI = spi_id;
/* Init SPI port for slow frequency access (ca. 0.3 MBit/s) */
PIOS_SPI_SetClockSpeed(PIOS_SDCARD_SPI, PIOS_SPI_PRESCALER_256);

View File

@ -40,32 +40,48 @@
#include <pios_spi_priv.h>
static struct pios_spi_dev *find_spi_dev_by_id(uint8_t spi)
static bool PIOS_SPI_validate(struct pios_spi_dev * com_dev)
{
if (spi >= pios_spi_num_devices) {
/* Undefined SPI port for this board (see pios_board.c) */
return NULL;
/* Should check device magic here */
return(true);
}
#if defined(PIOS_INCLUDE_FREERTOS) && 0
static struct pios_spi_dev * PIOS_SPI_alloc(void)
{
return (malloc(sizeof(struct pios_spi_dev)));
}
#else
static struct pios_spi_dev pios_spi_devs[PIOS_SPI_MAX_DEVS];
static uint8_t pios_spi_num_devs;
static struct pios_spi_dev * PIOS_SPI_alloc(void)
{
if (pios_spi_num_devs >= PIOS_SPI_MAX_DEVS) {
return (NULL);
}
/* Get a handle for the device configuration */
return &(pios_spi_devs[spi]);
return (&pios_spi_devs[pios_spi_num_devs++]);
}
#endif
/**
* Initialises SPI pins
* \param[in] mode currently only mode 0 supported
* \return < 0 if initialisation failed
*/
int32_t PIOS_SPI_Init(void)
int32_t PIOS_SPI_Init(uint32_t * spi_id, const struct pios_spi_cfg * cfg)
{
struct pios_spi_dev *spi_dev;
uint8_t i;
PIOS_Assert(spi_id);
PIOS_Assert(cfg);
for (i = 0; i < pios_spi_num_devices; i++) {
/* Get a handle for the device configuration */
spi_dev = find_spi_dev_by_id(i);
PIOS_DEBUG_Assert(spi_dev);
struct pios_spi_dev * spi_dev;
spi_dev = (struct pios_spi_dev *) PIOS_SPI_alloc();
if (!spi_dev) goto out_fail;
/* Bind the configuration to the device instance */
spi_dev->cfg = cfg;
#if defined(PIOS_INCLUDE_FREERTOS)
vSemaphoreCreateBinary(spi_dev->busy);
xSemaphoreGive(spi_dev->busy);
@ -96,7 +112,7 @@ int32_t PIOS_SPI_Init(void)
GPIO_Init(spi_dev->cfg->ssel.gpio, &(spi_dev->cfg->ssel.init));
break;
default:
PIOS_DEBUG_Assert(0);
PIOS_Assert(0);
}
/* Initialize the GPIO pins */
@ -149,9 +165,12 @@ int32_t PIOS_SPI_Init(void)
/* Configure DMA interrupt */
NVIC_Init(&(spi_dev->cfg->dma.irq.init));
}
return 0;
*spi_id = (uint32_t)spi_dev;
return(0);
out_fail:
return(-1);
}
/**
@ -171,21 +190,16 @@ int32_t PIOS_SPI_Init(void)
* </UL>
* \return 0 if no error
* \return -1 if disabled SPI port selected
* \return -2 if unsupported SPI port selected
* \return -3 if invalid spi_prescaler selected
*/
int32_t PIOS_SPI_SetClockSpeed(uint8_t spi, SPIPrescalerTypeDef spi_prescaler)
int32_t PIOS_SPI_SetClockSpeed(uint32_t spi_id, SPIPrescalerTypeDef spi_prescaler)
{
struct pios_spi_dev *spi_dev;
SPI_InitTypeDef SPI_InitStructure;
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
/* Get a handle for the device configuration */
spi_dev = find_spi_dev_by_id(spi);
bool valid = PIOS_SPI_validate(spi_dev);
PIOS_Assert(valid)
if (!spi_dev) {
/* Undefined SPI port for this board (see pios_board.c) */
return -2;
}
SPI_InitTypeDef SPI_InitStructure;
if (spi_prescaler >= 8) {
/* Invalid prescaler selected */
@ -201,7 +215,7 @@ int32_t PIOS_SPI_SetClockSpeed(uint8_t spi, SPIPrescalerTypeDef spi_prescaler)
/* Write back the new configuration */
SPI_Init(spi_dev->cfg->regs, &SPI_InitStructure);
PIOS_SPI_TransferByte(spi, 0xFF);
PIOS_SPI_TransferByte(spi_id, 0xFF);
return 0;
}
@ -211,13 +225,14 @@ int32_t PIOS_SPI_SetClockSpeed(uint8_t spi, SPIPrescalerTypeDef spi_prescaler)
* \return 0 if no error
* \return -1 if timeout before claiming semaphore
*/
int8_t PIOS_SPI_ClaimBus(uint8_t spi)
int32_t PIOS_SPI_ClaimBus(uint32_t spi_id)
{
#if defined(PIOS_INCLUDE_FREERTOS)
struct pios_spi_dev *spi_dev;
/* Get a handle for the device configuration */
spi_dev = find_spi_dev_by_id(spi);
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
bool valid = PIOS_SPI_validate(spi_dev);
PIOS_Assert(valid)
if (xSemaphoreTake(spi_dev->busy, 0xffff) != pdTRUE)
return -1;
#endif
@ -229,14 +244,14 @@ int8_t PIOS_SPI_ClaimBus(uint8_t spi)
* \param[in] spi SPI number (0 or 1)
* \return 0 if no error
*/
int8_t PIOS_SPI_ReleaseBus(uint8_t spi)
int32_t PIOS_SPI_ReleaseBus(uint32_t spi_id)
{
#if defined(PIOS_INCLUDE_FREERTOS)
struct pios_spi_dev *spi_dev;
/* Get a handle for the device configuration */
spi_dev = find_spi_dev_by_id(spi);
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
bool valid = PIOS_SPI_validate(spi_dev);
PIOS_Assert(valid)
xSemaphoreGive(spi_dev->busy);
#endif
return 0;
@ -247,20 +262,13 @@ int8_t PIOS_SPI_ReleaseBus(uint8_t spi)
* \param[in] spi SPI number (0 or 1)
* \param[in] pin_value 0 or 1
* \return 0 if no error
* \return -1 if disabled SPI port selected
* \return -2 if unsupported SPI port selected
*/
int32_t PIOS_SPI_RC_PinSet(uint8_t spi, uint8_t pin_value)
int32_t PIOS_SPI_RC_PinSet(uint32_t spi_id, uint8_t pin_value)
{
struct pios_spi_dev *spi_dev;
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
/* Get a handle for the device configuration */
spi_dev = find_spi_dev_by_id(spi);
if (!spi_dev) {
/* Undefined SPI port for this board (see pios_board.c) */
return -2;
}
bool valid = PIOS_SPI_validate(spi_dev);
PIOS_Assert(valid)
if (pin_value) {
GPIO_SetBits(spi_dev->cfg->ssel.gpio, spi_dev->cfg->ssel.init.GPIO_Pin);
@ -276,17 +284,17 @@ int32_t PIOS_SPI_RC_PinSet(uint8_t spi, uint8_t pin_value)
* \param[in] spi SPI number (0 or 1)
* \param[in] b the byte which should be transfered
*/
int32_t PIOS_SPI_TransferByte(uint8_t spi, uint8_t b)
int32_t PIOS_SPI_TransferByte(uint32_t spi_id, uint8_t b)
{
struct pios_spi_dev *spi_dev;
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
bool valid = PIOS_SPI_validate(spi_dev);
PIOS_Assert(valid)
uint8_t dummy;
uint8_t rx_byte;
/* Get a handle for the device configuration */
spi_dev = find_spi_dev_by_id(spi);
PIOS_DEBUG_Assert(spi_dev);
/*
/*
* Procedure taken from STM32F10xxx Reference Manual section 23.3.5
*/
@ -326,21 +334,16 @@ int32_t PIOS_SPI_TransferByte(uint8_t spi, uint8_t b)
* block until the transfer is finished.
* \return >= 0 if no error during transfer
* \return -1 if disabled SPI port selected
* \return -2 if unsupported SPI port selected
* \return -3 if function has been called during an ongoing DMA transfer
*/
int32_t PIOS_SPI_TransferBlock(uint8_t spi, const uint8_t * send_buffer, uint8_t * receive_buffer, uint16_t len, void *callback)
int32_t PIOS_SPI_TransferBlock(uint32_t spi_id, const uint8_t *send_buffer, uint8_t *receive_buffer, uint16_t len, void *callback)
{
struct pios_spi_dev *spi_dev;
DMA_InitTypeDef dma_init;
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
/* Get a handle for the device configuration */
spi_dev = find_spi_dev_by_id(spi);
bool valid = PIOS_SPI_validate(spi_dev);
PIOS_Assert(valid)
if (!spi_dev) {
/* Undefined SPI port for this board (see pios_board.c) */
return -2;
}
DMA_InitTypeDef dma_init;
/* Exit if ongoing transfer */
if (DMA_GetCurrDataCounter(spi_dev->cfg->dma.rx.channel)) {
@ -371,7 +374,7 @@ int32_t PIOS_SPI_TransferBlock(uint8_t spi, const uint8_t * send_buffer, uint8_t
} else {
/* Disable memory addr. increment - bytes written into dummy buffer */
spi_dev->rx_dummy_byte = 0xFF;
dma_init.DMA_MemoryBaseAddr = (uint32_t) & spi_dev->rx_dummy_byte;
dma_init.DMA_MemoryBaseAddr = (uint32_t) &spi_dev->rx_dummy_byte;
dma_init.DMA_MemoryInc = DMA_MemoryInc_Disable;
}
if (spi_dev->cfg->use_crc) {
@ -396,7 +399,7 @@ int32_t PIOS_SPI_TransferBlock(uint8_t spi, const uint8_t * send_buffer, uint8_t
} else {
/* Disable memory addr. increment - bytes written into dummy buffer */
spi_dev->tx_dummy_byte = 0xFF;
dma_init.DMA_MemoryBaseAddr = (uint32_t) & spi_dev->tx_dummy_byte;
dma_init.DMA_MemoryBaseAddr = (uint32_t) &spi_dev->tx_dummy_byte;
dma_init.DMA_MemoryInc = DMA_MemoryInc_Disable;
}
@ -438,13 +441,13 @@ int32_t PIOS_SPI_TransferBlock(uint8_t spi, const uint8_t * send_buffer, uint8_t
}
/* Wait until all bytes have been transmitted/received */
while (DMA_GetCurrDataCounter(spi_dev->cfg->dma.rx.channel)) ;
while (DMA_GetCurrDataCounter(spi_dev->cfg->dma.rx.channel));
/* Wait for the final bytes of the transfer to complete, including CRC byte(s). */
while (!(SPI_I2S_GetFlagStatus(spi_dev->cfg->regs, SPI_I2S_FLAG_TXE))) ;
while (!(SPI_I2S_GetFlagStatus(spi_dev->cfg->regs, SPI_I2S_FLAG_TXE)));
/* Wait for the final bytes of the transfer to complete, including CRC byte(s). */
while (SPI_I2S_GetFlagStatus(spi_dev->cfg->regs, SPI_I2S_FLAG_BSY)) ;
while (SPI_I2S_GetFlagStatus(spi_dev->cfg->regs, SPI_I2S_FLAG_BSY));
/* Check the CRC on the transfer if enabled. */
if (spi_dev->cfg->use_crc) {
@ -466,17 +469,12 @@ int32_t PIOS_SPI_TransferBlock(uint8_t spi, const uint8_t * send_buffer, uint8_t
* \return -2 if unsupported SPI port selected
* \return -3 if function has been called during an ongoing DMA transfer
*/
int32_t PIOS_SPI_Busy(uint8_t spi)
int32_t PIOS_SPI_Busy(uint32_t spi_id)
{
struct pios_spi_dev * spi_dev;
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
/* Get a handle for the device configuration */
spi_dev = find_spi_dev_by_id(spi);
if (!spi_dev) {
/* Undefined SPI port for this board (see pios_board.c) */
return -2;
}
bool valid = PIOS_SPI_validate(spi_dev);
PIOS_Assert(valid)
/* DMA buffer has data or SPI transmit register not empty or SPI is busy*/
if (DMA_GetCurrDataCounter(spi_dev->cfg->dma.rx.channel) ||
@ -490,15 +488,12 @@ int32_t PIOS_SPI_Busy(uint8_t spi)
}
void PIOS_SPI_IRQ_Handler(uint8_t spi)
void PIOS_SPI_IRQ_Handler(uint32_t spi_id)
{
struct pios_spi_dev *spi_dev;
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
spi_dev = find_spi_dev_by_id(spi);
PIOS_DEBUG_Assert(spi_dev);
bool valid = PIOS_SPI_validate(spi_dev);
PIOS_Assert(valid)
DMA_ClearFlag(spi_dev->cfg->dma.irq.flags);

View File

@ -49,7 +49,8 @@ struct pios_adxl345_data {
void PIOS_ADXL345_SelectRate(uint8_t rate);
void PIOS_ADXL345_SetRange(uint8_t range);
void PIOS_ADXL345_FifoDepth(uint8_t depth);
void PIOS_ADXL345_Attach(uint32_t spi_id);
void PIOS_ADXL345_Init();
uint8_t PIOS_ADXL345_Read(struct pios_adxl345_data * data);
#endif
#endif

View File

@ -92,7 +92,7 @@ extern VOLINFO PIOS_SDCARD_VolInfo;
extern uint8_t PIOS_SDCARD_Sector[SECTOR_SIZE];
/* Prototypes */
extern int32_t PIOS_SDCARD_Init(void);
extern int32_t PIOS_SDCARD_Init(uint32_t spi_id);
extern int32_t PIOS_SDCARD_PowerOn(void);
extern int32_t PIOS_SDCARD_PowerOff(void);
extern int32_t PIOS_SDCARD_CheckAvailable(uint8_t was_available);

View File

@ -44,15 +44,14 @@ typedef enum {
} SPIPrescalerTypeDef;
/* Public Functions */
extern int32_t PIOS_SPI_Init(void);
extern int32_t PIOS_SPI_SetClockSpeed(uint8_t spi, SPIPrescalerTypeDef spi_prescaler);
extern int32_t PIOS_SPI_RC_PinSet(uint8_t spi, uint8_t pin_value);
extern int32_t PIOS_SPI_TransferByte(uint8_t spi, uint8_t b);
extern int32_t PIOS_SPI_TransferBlock(uint8_t spi, const uint8_t * send_buffer, uint8_t * receive_buffer, uint16_t len, void *callback);
extern int32_t PIOS_SPI_Busy(uint8_t spi);
extern void PIOS_SPI_IRQ_Handler(uint8_t spi);
extern int8_t PIOS_SPI_ClaimBus(uint8_t spi);
extern int8_t PIOS_SPI_ReleaseBus(uint8_t spi);
extern int32_t PIOS_SPI_SetClockSpeed(uint32_t spi_id, SPIPrescalerTypeDef spi_prescaler);
extern int32_t PIOS_SPI_RC_PinSet(uint32_t spi_id, uint8_t pin_value);
extern int32_t PIOS_SPI_TransferByte(uint32_t spi_id, uint8_t b);
extern int32_t PIOS_SPI_TransferBlock(uint32_t spi_id, const uint8_t *send_buffer, uint8_t *receive_buffer, uint16_t len, void *callback);
extern int32_t PIOS_SPI_Busy(uint32_t spi_id);
extern int32_t PIOS_SPI_ClaimBus(uint32_t spi_id);
extern int32_t PIOS_SPI_ReleaseBus(uint32_t spi_id);
extern void PIOS_SPI_IRQ_Handler(uint32_t spi_id);
#endif /* PIOS_SPI_H */

View File

@ -47,7 +47,7 @@ struct pios_spi_cfg {
};
struct pios_spi_dev {
const struct pios_spi_cfg *const cfg;
const struct pios_spi_cfg * cfg;
void (*callback) (uint8_t, uint8_t);
uint8_t tx_dummy_byte;
uint8_t rx_dummy_byte;
@ -56,9 +56,7 @@ struct pios_spi_dev {
#endif
};
extern struct pios_spi_dev pios_spi_devs[];
extern uint8_t pios_spi_num_devices;
extern int32_t PIOS_SPI_Init(uint32_t * spi_id, const struct pios_spi_cfg * cfg);
#endif /* PIOS_SPI_PRIV_H */
/**

View File

@ -173,22 +173,11 @@ static const struct pios_spi_cfg pios_spi_port_cfg =
},
};
/*
* Board specific number of devices.
*/
struct pios_spi_dev pios_spi_devs[] =
{
{
.cfg = &pios_spi_port_cfg,
},
};
uint8_t pios_spi_num_devices = NELEMENTS(pios_spi_devs);
uint32_t pios_spi_port_id;
void PIOS_SPI_port_irq_handler(void)
{
/* Call into the generic code to handle the IRQ for this specific device */
PIOS_SPI_IRQ_Handler(PIOS_SPI_PORT);
PIOS_SPI_IRQ_Handler(pios_spi_port_id);
}
#endif /* PIOS_INCLUDE_SPI */
@ -365,5 +354,7 @@ void PIOS_Board_Init(void) {
// PIOS_ADC_Init();
// SPI link to master
PIOS_SPI_Init();
if (PIOS_SPI_Init(&pios_spi_port_id, &pios_spi_port_cfg)) {
PIOS_DEBUG_Assert(0);
}
}