mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
Update the F1 SPI library to support multiple NSS lines
This commit is contained in:
parent
5fd458426a
commit
aaf1c5dfdd
@ -7,7 +7,7 @@
|
||||
* @{
|
||||
*
|
||||
* @file pios_spi.c
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
||||
* @brief Hardware Abstraction Layer for SPI ports of STM32
|
||||
* @see The GNU Public License (GPL) Version 3
|
||||
* @notes
|
||||
@ -70,6 +70,8 @@ static struct pios_spi_dev * PIOS_SPI_alloc(void)
|
||||
*/
|
||||
int32_t PIOS_SPI_Init(uint32_t * spi_id, const struct pios_spi_cfg * cfg)
|
||||
{
|
||||
uint32_t init_ssel = 0;
|
||||
|
||||
PIOS_Assert(spi_id);
|
||||
PIOS_Assert(cfg);
|
||||
|
||||
@ -100,18 +102,20 @@ int32_t PIOS_SPI_Init(uint32_t * spi_id, const struct pios_spi_cfg * cfg)
|
||||
if (spi_dev->cfg->init.SPI_Mode == SPI_Mode_Master) {
|
||||
/* We're a master in soft NSS mode, make sure we see NSS high at all times. */
|
||||
SPI_NSSInternalSoftwareConfig(spi_dev->cfg->regs, SPI_NSSInternalSoft_Set);
|
||||
/* Since we're driving the SSEL pin in software, ensure that the slave is deselected */
|
||||
GPIO_SetBits(spi_dev->cfg->ssel.gpio, spi_dev->cfg->ssel.init.GPIO_Pin);
|
||||
GPIO_Init(spi_dev->cfg->ssel.gpio, &(spi_dev->cfg->ssel.init));
|
||||
/* Init as many slave selects as the config advertises. */
|
||||
init_ssel = spi_dev->cfg->slave_count;
|
||||
} else {
|
||||
/* We're a slave in soft NSS mode, make sure we see NSS low at all times. */
|
||||
SPI_NSSInternalSoftwareConfig(spi_dev->cfg->regs, SPI_NSSInternalSoft_Reset);
|
||||
}
|
||||
break;
|
||||
case SPI_NSS_Hard:
|
||||
/* only legal for single-slave config */
|
||||
PIOS_Assert(spi_dev->cfg->slave_count == 1);
|
||||
init_ssel = 1;
|
||||
/* FIXME: Should this also call SPI_SSOutputCmd()? */
|
||||
GPIO_Init(spi_dev->cfg->ssel.gpio, &(spi_dev->cfg->ssel.init));
|
||||
break;
|
||||
|
||||
default:
|
||||
PIOS_Assert(0);
|
||||
}
|
||||
@ -120,6 +124,12 @@ int32_t PIOS_SPI_Init(uint32_t * spi_id, const struct pios_spi_cfg * cfg)
|
||||
GPIO_Init(spi_dev->cfg->sclk.gpio, &(spi_dev->cfg->sclk.init));
|
||||
GPIO_Init(spi_dev->cfg->mosi.gpio, &(spi_dev->cfg->mosi.init));
|
||||
GPIO_Init(spi_dev->cfg->miso.gpio, &(spi_dev->cfg->miso.init));
|
||||
for (uint32_t i = 0; i < init_ssel; i++) {
|
||||
/* Since we're driving the SSEL pin in software, ensure that the slave is deselected */
|
||||
/* XXX multi-slave support - maybe have another SPI_NSS_ mode? */
|
||||
GPIO_SetBits(spi_dev->cfg->ssel[i].gpio, spi_dev->cfg->ssel[i].init.GPIO_Pin);
|
||||
GPIO_Init(spi_dev->cfg->ssel[i].gpio, (GPIO_InitTypeDef*)&(spi_dev->cfg->ssel[i].init));
|
||||
}
|
||||
|
||||
/* Enable the associated peripheral clock */
|
||||
switch ((uint32_t) spi_dev->cfg->regs) {
|
||||
@ -252,6 +262,26 @@ int32_t PIOS_SPI_ClaimBus(uint32_t spi_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Claim the SPI bus semaphore from an ISR. Has no timeout.
|
||||
* \param[in] spi SPI number (0 or 1)
|
||||
* \return 0 if no error
|
||||
* \return -1 if timeout before claiming semaphore
|
||||
*/
|
||||
int32_t PIOS_SPI_ClaimBusISR(uint32_t spi_id)
|
||||
{
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
|
||||
|
||||
bool valid = PIOS_SPI_validate(spi_dev);
|
||||
PIOS_Assert(valid)
|
||||
|
||||
if (xQueueGenericReceive(( xQueueHandle ) spi_dev->busy, NULL, 0x0000 , pdFALSE ) != pdTRUE)
|
||||
return -1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the SPI bus semaphore. Calling the SPI functions does not require this
|
||||
* \param[in] spi SPI number (0 or 1)
|
||||
@ -282,17 +312,19 @@ int32_t PIOS_SPI_ReleaseBus(uint32_t spi_id)
|
||||
* \param[in] pin_value 0 or 1
|
||||
* \return 0 if no error
|
||||
*/
|
||||
int32_t PIOS_SPI_RC_PinSet(uint32_t spi_id, uint8_t pin_value)
|
||||
int32_t PIOS_SPI_RC_PinSet(uint32_t spi_id, uint32_t slave_id, uint8_t pin_value)
|
||||
{
|
||||
struct pios_spi_dev * spi_dev = (struct pios_spi_dev *)spi_id;
|
||||
|
||||
bool valid = PIOS_SPI_validate(spi_dev);
|
||||
PIOS_Assert(valid)
|
||||
PIOS_Assert(slave_id <= spi_dev->cfg->slave_count)
|
||||
|
||||
/* XXX multi-slave support? */
|
||||
if (pin_value) {
|
||||
GPIO_SetBits(spi_dev->cfg->ssel.gpio, spi_dev->cfg->ssel.init.GPIO_Pin);
|
||||
GPIO_SetBits(spi_dev->cfg->ssel[slave_id].gpio, spi_dev->cfg->ssel[slave_id].init.GPIO_Pin);
|
||||
} else {
|
||||
GPIO_ResetBits(spi_dev->cfg->ssel.gpio, spi_dev->cfg->ssel.init.GPIO_Pin);
|
||||
GPIO_ResetBits(spi_dev->cfg->ssel[slave_id].gpio, spi_dev->cfg->ssel[slave_id].init.GPIO_Pin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -50,7 +50,7 @@ static bool PIOS_SPI_validate(struct pios_spi_dev * com_dev)
|
||||
return(true);
|
||||
}
|
||||
|
||||
#if defined(PIOS_INCLUDE_FREERTOS) && 0
|
||||
#if defined(PIOS_INCLUDE_FREERTOS)
|
||||
static struct pios_spi_dev * PIOS_SPI_alloc(void)
|
||||
{
|
||||
return (malloc(sizeof(struct pios_spi_dev)));
|
||||
|
@ -44,11 +44,7 @@ typedef enum {
|
||||
|
||||
/* Public Functions */
|
||||
extern int32_t PIOS_SPI_SetClockSpeed(uint32_t spi_id, SPIPrescalerTypeDef spi_prescaler);
|
||||
#if defined(STM32F2XX) || defined(STM32F4XX) /* XXX harmonise these */
|
||||
extern int32_t PIOS_SPI_RC_PinSet(uint32_t spi_id, uint32_t slave_id, uint8_t pin_value);
|
||||
#else
|
||||
extern int32_t PIOS_SPI_RC_PinSet(uint32_t spi_id, uint8_t pin_value);
|
||||
#endif
|
||||
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);
|
||||
|
@ -34,8 +34,6 @@
|
||||
#include <pios.h>
|
||||
#include <pios_stm32.h>
|
||||
|
||||
/* XXX these two should be reconciled - separate for now to avoid breaking other targets */
|
||||
#if defined(STM32F2XX) || defined(STM32F4XX)
|
||||
struct pios_spi_cfg {
|
||||
SPI_TypeDef *regs;
|
||||
uint32_t remap; /* GPIO_Remap_* or GPIO_AF_* */
|
||||
@ -48,18 +46,6 @@ struct pios_spi_cfg {
|
||||
uint32_t slave_count;
|
||||
struct stm32_gpio ssel[];
|
||||
};
|
||||
#else
|
||||
struct pios_spi_cfg {
|
||||
SPI_TypeDef *regs;
|
||||
SPI_InitTypeDef init;
|
||||
bool use_crc;
|
||||
struct stm32_dma dma;
|
||||
struct stm32_gpio ssel;
|
||||
struct stm32_gpio sclk;
|
||||
struct stm32_gpio miso;
|
||||
struct stm32_gpio mosi;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct pios_spi_dev {
|
||||
const struct pios_spi_cfg * cfg;
|
||||
|
Loading…
Reference in New Issue
Block a user