git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1258 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2009-10-30 15:45:38 +00:00
parent 5ccb308ed8
commit 43f9fd4180
12 changed files with 151 additions and 53 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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);

View File

@ -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;
}
/**

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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);
}