git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1258 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
5ccb308ed8
commit
43f9fd4180
|
@ -25,7 +25,7 @@
|
|||
#include "at91lib/aic.h"
|
||||
|
||||
/*
|
||||
* FIQ Handler weak symbol defined in vectors.s.
|
||||
* FIQ Handler weak symbol defined in vectors.s.
|
||||
*/
|
||||
void FiqHandler(void);
|
||||
|
||||
|
@ -123,6 +123,7 @@ void hwinit1(void) {
|
|||
* Default AIC setup, the device drivers will modify it as needed.
|
||||
*/
|
||||
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
|
||||
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
|
||||
AT91C_BASE_AIC->AIC_SVR[0] = (AT91_REG)FiqHandler;
|
||||
for (i = 1; i < 31; i++) {
|
||||
AT91C_BASE_AIC->AIC_SVR[i] = (AT91_REG)NULL;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "at91lib/aic.h"
|
||||
|
||||
/*
|
||||
* FIQ Handler weak symbol defined in vectors.s.
|
||||
* FIQ Handler weak symbol defined in vectors.s.
|
||||
*/
|
||||
void FiqHandler(void);
|
||||
|
||||
|
@ -124,6 +124,7 @@ void hwinit1(void) {
|
|||
* Default AIC setup, the device drivers will modify it as needed.
|
||||
*/
|
||||
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
|
||||
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
|
||||
AT91C_BASE_AIC->AIC_SVR[0] = (AT91_REG)FiqHandler;
|
||||
for (i = 1; i < 31; i++) {
|
||||
AT91C_BASE_AIC->AIC_SVR[i] = (AT91_REG)NULL;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
|
||||
/*
|
||||
* FIQ Handler weak symbol defined in vectors.s.
|
||||
* FIQ Handler weak symbol defined in vectors.s.
|
||||
*/
|
||||
void FiqHandler(void);
|
||||
|
||||
|
@ -125,6 +125,7 @@ void hwinit1(void) {
|
|||
* Default AIC setup, the device drivers will modify it as needed.
|
||||
*/
|
||||
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
|
||||
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
|
||||
AT91C_BASE_AIC->AIC_SVR[0] = (AT91_REG)FiqHandler;
|
||||
for (i = 1; i < 31; i++) {
|
||||
AT91C_BASE_AIC->AIC_SVR[i] = (AT91_REG)NULL;
|
||||
|
|
42
os/io/io.dox
42
os/io/io.dox
|
@ -116,7 +116,7 @@
|
|||
|
||||
/**
|
||||
* @defgroup SERIAL Serial Driver
|
||||
* @brief Generic Serial Drivers.
|
||||
* @brief Generic Serial Driver.
|
||||
* @details This module implements a generic full duplex serial driver. The
|
||||
* driver implements a @p SerialDriver interface and uses I/O Queues for
|
||||
* communication between the upper and the lower driver. Event flags are used
|
||||
|
@ -136,6 +136,46 @@
|
|||
* @ingroup SERIAL
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup SPI SPI Driver
|
||||
* @brief Generic SPI Driver.
|
||||
* @details This module implements a generic SPI driver. The driver implements
|
||||
* a state machine internally:
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
uninit [label="SPI_UNINIT", style="bold"];
|
||||
stop [label="SPI_STOP\nLow Power"];
|
||||
ready [label="SPI_IDLE\nClock Enabled"];
|
||||
active [label="SPI_ACTIVE\nBus Active"];
|
||||
uninit -> stop [label="spiInit()"];
|
||||
stop -> ready [label="spiStart()"];
|
||||
ready -> ready [label="spiStart()"];
|
||||
ready -> stop [label="spiStop()"];
|
||||
stop -> stop [label="spiStop()"];
|
||||
ready -> active [label="spiSelect()"];
|
||||
active -> ready [label="spiUnselect()"];
|
||||
active -> active [label="spiExchange()\nspiSend()\nspiReceive()"];
|
||||
}
|
||||
* @enddot
|
||||
*
|
||||
* The driver is not thread safe for performance reasons, if you need to access
|
||||
* the SPI bus from multiple thread then use the @p spiAcquireBus() and
|
||||
* @p spiReleaseBus() APIs in order to gain exclusive access.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup SPI_LLD SPI Low Level Driver
|
||||
* @brief @ref SPI low level driver template.
|
||||
* @details This file is a template for a SPI low level driver.
|
||||
*
|
||||
* @ingroup SPI
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup MAC MAC Driver
|
||||
* @brief Generic MAC driver.
|
||||
|
|
|
@ -179,7 +179,6 @@ void spi_lld_init(void) {
|
|||
SPID1.spd_dmarx = DMA1_Channel2;
|
||||
SPID1.spd_dmatx = DMA1_Channel3;
|
||||
SPID1.spd_dmaprio = SPI1_DMA_PRIORITY << 12;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
||||
GPIOA->CRH = (GPIOA->CRH & 0x000FFFFF) | 0xB4B00000;
|
||||
#endif
|
||||
|
||||
|
@ -190,17 +189,30 @@ void spi_lld_init(void) {
|
|||
SPID2.spd_dmarx = DMA1_Channel4;
|
||||
SPID2.spd_dmatx = DMA1_Channel5;
|
||||
SPID2.spd_dmaprio = SPI2_DMA_PRIORITY << 12;
|
||||
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
|
||||
GPIOB->CRL = (GPIOB->CRL & 0x000FFFFF) | 0xB4B00000;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level SPI bus setup.
|
||||
*
|
||||
* @brief Configures and activates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
void spi_lld_setup(SPIDriver *spip) {
|
||||
void spi_lld_start(SPIDriver *spip) {
|
||||
|
||||
/* If in stopped state then enables the SPI clock.*/
|
||||
if (spip->spd_state == SPI_STOP) {
|
||||
#if USE_STM32_SPI1
|
||||
if (&SPID1 == spip) {
|
||||
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
|
||||
}
|
||||
#endif
|
||||
#if USE_STM32_SPI2
|
||||
if (&SPID2 == spip) {
|
||||
RCC->APB1ENR |= RCC_APB1ENR_SPI2EN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* SPI setup.*/
|
||||
spip->spd_spi->CR1 = spip->spd_config->spc_cr1 | SPI_CR1_MSTR;
|
||||
|
@ -225,6 +237,28 @@ void spi_lld_setup(SPIDriver *spip) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
void spi_lld_stop(SPIDriver *spip) {
|
||||
|
||||
/* If in ready state then disables the SPI clock.*/
|
||||
if (spip->spd_state == SPI_READY) {
|
||||
#if USE_STM32_SPI1
|
||||
if (&SPID1 == spip) {
|
||||
RCC->APB2ENR &= ~RCC_APB2ENR_SPI1EN;
|
||||
}
|
||||
#endif
|
||||
#if USE_STM32_SPI2
|
||||
if (&SPID2 == spip) {
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_SPI2EN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Asserts the slave select signal and prepares for transfers.
|
||||
*
|
||||
|
@ -236,7 +270,7 @@ void spi_lld_select(SPIDriver *spip) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief De-asserts the slave select signal.
|
||||
* @brief Deasserts the slave select signal.
|
||||
* @details The previously selected peripheral is unselected.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
|
|
|
@ -81,15 +81,6 @@
|
|||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_UNINIT = 0,//!< SPI_UNINIT
|
||||
SPI_IDLE = 1, //!< SPI_IDLE
|
||||
SPI_ACTIVE = 2 //!< SPI_ACTIVE
|
||||
} spistate_t;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
*/
|
||||
|
@ -175,7 +166,8 @@ extern SPIDriver SPID2;
|
|||
extern "C" {
|
||||
#endif
|
||||
void spi_lld_init(void);
|
||||
void spi_lld_setup(SPIDriver *spip);
|
||||
void spi_lld_start(SPIDriver *spip);
|
||||
void spi_lld_stop(SPIDriver *spip);
|
||||
void spi_lld_select(SPIDriver *spip);
|
||||
void spi_lld_unselect(SPIDriver *spip);
|
||||
msg_t spi_lld_exchange(SPIDriver *spip, size_t n, void *rxbuf, void *txbuf);
|
||||
|
|
45
os/io/spi.c
45
os/io/spi.c
|
@ -42,7 +42,7 @@ void spiInit(void) {
|
|||
*/
|
||||
void spiObjectInit(SPIDriver *spip) {
|
||||
|
||||
spip->spd_state = SPI_IDLE;
|
||||
spip->spd_state = SPI_STOP;
|
||||
#if CH_USE_MUTEXES
|
||||
chMtxInit(&spip->spd_mutex);
|
||||
#elif CH_USE_SEMAPHORES
|
||||
|
@ -52,20 +52,37 @@ void spiObjectInit(SPIDriver *spip) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the SPI bus.
|
||||
* @brief Configures and activates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param config pointer to the @p SPIConfig object
|
||||
*/
|
||||
void spiSetup(SPIDriver *spip, const SPIConfig *config) {
|
||||
void spiStart(SPIDriver *spip, const SPIConfig *config) {
|
||||
|
||||
chDbgCheck((spip != NULL) && (config != NULL), "spiSetup");
|
||||
chDbgAssert(spip->spd_state == SPI_IDLE,
|
||||
"spiSetup(), #1",
|
||||
"not idle");
|
||||
chDbgCheck((spip != NULL) && (config != NULL), "spiStart");
|
||||
chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY),
|
||||
"spiStart(), #1",
|
||||
"invalid state");
|
||||
|
||||
spip->spd_config = config;
|
||||
spi_lld_setup(spip);
|
||||
spi_lld_start(spip);
|
||||
spip->spd_state = SPI_READY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
void spiStop(SPIDriver *spip) {
|
||||
|
||||
chDbgCheck(spip != NULL, "spiStop");
|
||||
chDbgAssert((spip->spd_state == SPI_STOP) || (spip->spd_state == SPI_READY),
|
||||
"spiStop(), #1",
|
||||
"invalid state");
|
||||
|
||||
spi_lld_stop(spip);
|
||||
spip->spd_state = SPI_STOP;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,19 +94,16 @@ void spiSelect(SPIDriver *spip) {
|
|||
|
||||
chDbgCheck(spip != NULL, "spiSelect");
|
||||
|
||||
chSysLock();
|
||||
|
||||
chDbgAssert(spip->spd_state == SPI_IDLE,
|
||||
chDbgAssert(spip->spd_state == SPI_READY,
|
||||
"spiSelect(), #1",
|
||||
"not idle");
|
||||
|
||||
spi_lld_select(spip);
|
||||
spip->spd_state = SPI_ACTIVE;
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-asserts the slave select signal.
|
||||
* @brief Deasserts the slave select signal.
|
||||
* @details The previously selected peripheral is unselected.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
|
@ -98,15 +112,12 @@ void spiUnselect(SPIDriver *spip) {
|
|||
|
||||
chDbgCheck(spip != NULL, "spiUnselect");
|
||||
|
||||
chSysLock();
|
||||
|
||||
chDbgAssert(spip->spd_state == SPI_ACTIVE,
|
||||
"spiUnselect(), #1",
|
||||
"not locked");
|
||||
|
||||
spi_lld_unselect(spip);
|
||||
spip->spd_state = SPI_IDLE;
|
||||
chSysUnlock();
|
||||
spip->spd_state = SPI_READY;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
13
os/io/spi.h
13
os/io/spi.h
|
@ -38,6 +38,16 @@
|
|||
#error "SPI_USE_MUTUAL_EXCLUSION requires CH_USE_MUTEXES and/or CH_USE_SEMAPHORES"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_UNINIT = 0, /**< @brief Not initialized. */
|
||||
SPI_STOP = 1, /**< @brief Stopped. */
|
||||
SPI_READY = 2, /**< @brief Ready. */
|
||||
SPI_ACTIVE = 3 /**< @brief Slave selected. */
|
||||
} spistate_t;
|
||||
|
||||
#include "spi_lld.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -45,7 +55,8 @@ extern "C" {
|
|||
#endif
|
||||
void spiInit(void);
|
||||
void spiObjectInit(SPIDriver *spip);
|
||||
void spiSetup(SPIDriver *spip, const SPIConfig *config);
|
||||
void spiStart(SPIDriver *spip, const SPIConfig *config);
|
||||
void spiStop(SPIDriver *spip);
|
||||
void spiSelect(SPIDriver *spip);
|
||||
void spiUnselect(SPIDriver *spip);
|
||||
msg_t spiExchange(SPIDriver *spip, size_t n, void *rxbuf, void *txbuf);
|
||||
|
|
|
@ -47,11 +47,24 @@ void spi_lld_init(void) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Low level SPI bus setup.
|
||||
*
|
||||
* @brief Configures and activates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
void spi_lld_setup(SPIDriver *spip) {
|
||||
void spi_lld_start(SPIDriver *spip) {
|
||||
|
||||
if (spip->spd_state == SPI_STOP) {
|
||||
/* Clock activation.*/
|
||||
}
|
||||
/* Configuration.*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
void spi_lld_stop(SPIDriver *spip) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -65,7 +78,7 @@ void spi_lld_select(SPIDriver *spip) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief De-asserts the slave select signal.
|
||||
* @brief Deasserts the slave select signal.
|
||||
* @details The previously selected peripheral is unselected.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
|
|
|
@ -46,15 +46,6 @@
|
|||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_UNINIT = 0,
|
||||
SPI_IDLE = 1,
|
||||
SPI_ACTIVE = 2
|
||||
} spistate_t;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
*/
|
||||
|
@ -99,7 +90,8 @@ typedef struct {
|
|||
extern "C" {
|
||||
#endif
|
||||
void spi_lld_init(void);
|
||||
void spi_lld_setup(SPIDriver *spip);
|
||||
void spi_lld_start(SPIDriver *spip);
|
||||
void spi_lld_stop(SPIDriver *spip);
|
||||
void spi_lld_select(SPIDriver *spip);
|
||||
void spi_lld_unselect(SPIDriver *spip);
|
||||
msg_t spi_lld_exchange(SPIDriver *spip, size_t n, void *rxbuf, void *txbuf);
|
||||
|
|
|
@ -255,7 +255,7 @@ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) {
|
|||
|
||||
#if CH_USE_MUTEXES
|
||||
#define H_LOCK() chMtxLock(&hmtx)
|
||||
#define H_UNLOCK() chMtxLock(&hmtx)
|
||||
#define H_UNLOCK() chMtxUnock()
|
||||
static Mutex hmtx;
|
||||
#elif CH_USE_SEMAPHORES
|
||||
#define H_LOCK() chSemWait(&hsem)
|
||||
|
|
|
@ -268,7 +268,9 @@ void chSchDoYieldS(void) {
|
|||
|
||||
/* Pick the first thread from the ready queue and makes it current.*/
|
||||
(currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR;
|
||||
#if CH_TIME_QUANTUM > 0
|
||||
rlist.r_preempt = CH_TIME_QUANTUM;
|
||||
#endif
|
||||
chDbgTrace(otp, currp);
|
||||
chSysSwitchI(otp, currp);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue