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

This commit is contained in:
gdisirio 2009-11-10 16:43:04 +00:00
parent 727ba84c9b
commit 3077b40452
9 changed files with 169 additions and 122 deletions

View File

@ -153,13 +153,14 @@
uninit -> stop [label="spiObjectInit()"];
stop -> ready [label="spiStart()"];
ready -> ready [label="spiStart()"];
ready -> ready [label="spiIgnore()"];
ready -> stop [label="spiStop()"];
stop -> stop [label="spiStop()"];
ready -> active [label="spiSelect()"];
active -> active [label="spiSelect()"];
active -> ready [label="spiUnselect()"];
ready -> ready [label="spiUnselect()"];
active -> active [label="spiExchange()\nspiSend()\nspiReceive()"];
active -> active [label="spiIgnore()\nspiExchange()\nspiSend()\nspiReceive()"];
}
* @enddot
*

View File

@ -155,14 +155,13 @@ static uint8_t send_command(MMCDriver *mmcp, uint8_t cmd, uint32_t arg) {
*/
static bool_t get_data(MMCDriver *mmcp, uint8_t *buf) {
int i;
uint8_t ignored[2];
for (i = 0; i < MMC_WAIT_DATA; i++) {
spiReceive(mmcp->mmc_spip, 1, buf);
if (buf[0] == 0xFE) {
spiReceive(mmcp->mmc_spip, 512, buf);
/* CRC ignored. */
spiReceive(mmcp->mmc_spip, 2, ignored);
spiIgnore(mmcp->mmc_spip, 2);
return FALSE;
}
}
@ -228,7 +227,7 @@ void mmcStart(MMCDriver *mmcp, const MMCConfig *config) {
}
/**
* @brief Deactivates the MMC peripheral.
* @brief Disables the MMC peripheral.
*
* @param[in] mmcp pointer to the @p MMCDriver object
*/
@ -238,7 +237,8 @@ void mmcStop(MMCDriver *mmcp) {
chSysLock();
chDbgAssert((mmcp->mmc_state != MMC_UNINIT) &&
(mmcp->mmc_state != MMC_RUNNING),
(mmcp->mmc_state != MMC_READING) &&
(mmcp->mmc_state != MMC_WRITING),
"mmcStop(), #1",
"invalid state");
if (mmcp->mmc_state != MMC_STOP) {
@ -277,6 +277,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
if (mmcp->mmc_state == MMC_INSERTED) {
/* Slow clock mode and 128 clock pulses.*/
spiStart(mmcp->mmc_spip, mmcp->mmc_lscfg);
spiIgnore(mmcp->mmc_spip, 16);
/* SPI mode selection.*/
i = 0;
@ -331,7 +332,7 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
chSysUnlock();
return TRUE;
}
mmcp->mmc_state = MMC_RUNNING;
mmcp->mmc_state = MMC_READING;
chSysUnlock();
spiSelect(mmcp->mmc_spip);
@ -339,7 +340,7 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
if (recvr1() != 0x00) {
spiUnselect(mmcp->mmc_spip);
chSysLock();
if (mmcp->mmc_state == MMC_RUNNING)
if (mmcp->mmc_state == MMC_READING)
mmcp->mmc_state = MMC_READY;
chSysUnlock();
return TRUE;
@ -359,26 +360,29 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
*/
bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
int i;
uint8_t ignored[2];
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialRead");
if (mmcp->mmc_state != MMC_RUNNING)
chSysLock();
if (mmcp->mmc_state != MMC_READING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
for (i = 0; i < MMC_WAIT_DATA; i++) {
spiReceive(mmcp->mmc_spip, 1, buf);
if (buf[0] == 0xFE) {
spiReceive(mmcp->mmc_spip, 512, buf);
/* CRC ignored. */
spiReceive(mmcp->mmc_spip, 2, ignored);
spiIgnore(mmcp->mmc_spip, 2);
return FALSE;
}
}
/* Timeout.*/
spiUnselect(mmcp->mmc_spip);
chSysLock();
if (mmcp->mmc_state == MMC_RUNNING)
if (mmcp->mmc_state == MMC_READING)
mmcp->mmc_state = MMC_READY;
chSysUnlock();
return TRUE;
@ -397,10 +401,17 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
chDbgCheck(mmcp != NULL, "mmcStopSequentialRead");
if (mmcp->mmc_state != MMC_RUNNING)
chSysLock();
if (mmcp->mmc_state != MMC_READING) {
chSysUnlock();
return TRUE;
}
chSysUnlock();
chSysLock();
if (mmcp->mmc_state == MMC_READING)
mmcp->mmc_state = MMC_READY;
chSysUnlock();
return FALSE;
}

View File

@ -88,7 +88,8 @@ typedef enum {
MMC_WAIT = 2, /**< @brief Waiting card. */
MMC_INSERTED = 3, /**< @brief Card inserted. */
MMC_READY = 4, /**< @brief Card ready. */
MMC_RUNNING = 5 /**< @brief Reading or writing. */
MMC_READING = 5, /**< @brief Reading. */
MMC_WRITING = 6 /**< @brief Writing. */
} mmcstate_t;
/**

View File

@ -233,18 +233,6 @@ void spi_lld_start(SPIDriver *spip) {
/* DMA setup.*/
spip->spd_dmarx->CPAR = (uint32_t)&spip->spd_spi->DR;
spip->spd_dmatx->CPAR = (uint32_t)&spip->spd_spi->DR;
/*
* If specified in the configuration then emits a pulses train on
* the SPI clock line without asserting any slave.
*/
if (spip->spd_config->spc_initcnt > 0) {
spip->spd_dmarx->CCR = DMA_CCR1_TCIE | DMA_CCR1_TEIE;
spip->spd_dmatx->CCR = DMA_CCR1_DIR | DMA_CCR1_TEIE;
dma_start(spip, (size_t)spip->spd_config->spc_initcnt,
&dummyrx, &dummytx);
(void) spi_start_wait(spip);
}
}
/**
@ -296,18 +284,36 @@ void spi_lld_unselect(SPIDriver *spip) {
palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
}
/**
* @brief Ignores data on the SPI bus.
* @details This function transmits a series of idle words on the SPI bus and
* ignores the received data. This function can be invoked even
* when a slave select signal has not been yet asserted.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be ignored
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.
*/
msg_t spi_lld_ignore(SPIDriver *spip, size_t n) {
spip->spd_dmarx->CCR = DMA_CCR1_TCIE | DMA_CCR1_TEIE;
spip->spd_dmatx->CCR = DMA_CCR1_DIR | DMA_CCR1_TEIE;
dma_start(spip, n, &dummyrx, &dummytx);
return spi_start_wait(spip);
}
/**
* @brief Exchanges data on the SPI bus.
* @details This function performs a simultaneous transmit/receive operation.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to exchange
* @param[in] txbuf the pointer to the transmit buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[out] rxbuf the pointer to the receive buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[in] n number of words to be exchanged
* @param[in] txbuf the pointer to the transmit buffer
* @param[out] rxbuf the pointer to the receive buffer
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.
@ -328,9 +334,8 @@ msg_t spi_lld_exchange(SPIDriver *spip, size_t n, void *txbuf, void *rxbuf) {
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to send
* @param[in] txbuf the pointer to the transmit buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[in] txbuf the pointer to the transmit buffer
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.
@ -351,9 +356,8 @@ msg_t spi_lld_send(SPIDriver *spip, size_t n, void *txbuf) {
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to receive
* @param[out] rxbuf the pointer to the receive buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[out] rxbuf the pointer to the receive buffer
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.

View File

@ -101,11 +101,6 @@
* @brief Driver configuration structure.
*/
typedef struct {
/**
* @brief Clock pulses to be generated after initialization.
*/
cnt_t spc_initcnt;
/* End of the mandatory fields.*/
/**
* @brief The chip select line port.
*/
@ -186,6 +181,7 @@ extern "C" {
void spi_lld_stop(SPIDriver *spip);
void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip);
msg_t spi_lld_ignore(SPIDriver *spip, size_t n);
msg_t spi_lld_exchange(SPIDriver *spip, size_t n, void *txbuf, void *rxbuf);
msg_t spi_lld_send(SPIDriver *spip, size_t n, void *txbuf);
msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);

View File

@ -128,18 +128,44 @@ void spiUnselect(SPIDriver *spip) {
chSysUnlock();
}
/**
* @brief Ignores data on the SPI bus.
* @details This function transmits a series of idle words on the SPI bus and
* ignores the received data. This function can be invoked even
* when a slave select signal has not been yet asserted.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be ignored
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.
*/
msg_t spiIgnore(SPIDriver *spip, size_t n) {
chDbgCheck((spip != NULL) && (n > 0), "spiIgnore");
chDbgAssert((spip->spd_state == SPI_READY) || (spip->spd_state == SPI_ACTIVE),
"spiIgnore(), #1",
"not active");
return spi_lld_ignore(spip, n);
}
/**
* @brief Exchanges data on the SPI bus.
* @details This function performs a simultaneous transmit/receive operation.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be exchanged
* @param[in] txbuf the pointer to the transmit buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[out] rxbuf the pointer to the receive buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[in] txbuf the pointer to the transmit buffer
* @param[out] rxbuf the pointer to the receive buffer
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.
*
* @note The buffers are organized as uint8_t arrays for data sizes below or
* equal to 8 bits else it is organized as uint16_t arrays.
*/
msg_t spiExchange(SPIDriver *spip, size_t n, void *txbuf, void *rxbuf) {
@ -157,9 +183,8 @@ msg_t spiExchange(SPIDriver *spip, size_t n, void *txbuf, void *rxbuf) {
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to send
* @param[in] txbuf the pointer to the transmit buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[in] txbuf the pointer to the transmit buffer
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.
@ -183,9 +208,8 @@ msg_t spiSend(SPIDriver *spip, size_t n, void *txbuf) {
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to receive
* @param[out] rxbuf the pointer to the receive buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[out] rxbuf the pointer to the receive buffer
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.

View File

@ -59,6 +59,7 @@ extern "C" {
void spiStop(SPIDriver *spip);
void spiSelect(SPIDriver *spip);
void spiUnselect(SPIDriver *spip);
msg_t spiIgnore(SPIDriver *spip, size_t n);
msg_t spiExchange(SPIDriver *spip, size_t n, void *txbuf, void *rxbuf);
msg_t spiSend(SPIDriver *spip, size_t n, void *txbuf);
msg_t spiReceive(SPIDriver *spip, size_t n, void *rxbuf);

View File

@ -87,18 +87,32 @@ void spi_lld_unselect(SPIDriver *spip) {
}
/**
* @brief Ignores data on the SPI bus.
* @details This function transmits a series of idle words on the SPI bus and
* ignores the received data. This function can be invoked even
* when a slave select signal has not been yet asserted.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to be ignored
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.
*/
msg_t spi_lld_ignore(SPIDriver *spip, size_t n) {
}
/**
* @brief Exchanges data on the SPI bus.
* @details This function performs a simultaneous transmit/receive operation.
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to exchange
* @param[in] txbuf the pointer to the transmit buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[out] rxbuf the pointer to the receive buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[in] n number of words to be exchanged
* @param[in] txbuf the pointer to the transmit buffer
* @param[out] rxbuf the pointer to the receive buffer
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.
@ -115,9 +129,8 @@ msg_t spi_lld_exchange(SPIDriver *spip, size_t n, void *rxbuf, void *txbuf) {
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to send
* @param[in] txbuf the pointer to the transmit buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[in] txbuf the pointer to the transmit buffer
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.
@ -134,9 +147,8 @@ msg_t spi_lld_send(SPIDriver *spip, size_t n, void *txbuf) {
*
* @param[in] spip pointer to the @p SPIDriver object
* @param[in] n number of words to receive
* @param[out] rxbuf the pointer to the receive buffer. Note that the buffer is
* organized as an uint8_t array for data sizes below or equal
* to 8 bits else it is organized as an uint16_t array.
* @param[out] rxbuf the pointer to the receive buffer
*
* @return The operation status is returned.
* @retval RDY_OK operation complete.
* @retval RDY_RESET hardware failure.

View File

@ -50,11 +50,7 @@
* @brief Driver configuration structure.
*/
typedef struct {
/**
* @brief Clock pulses to be generated after initialization.
*/
cnt_t spc_initcnt;
/* End of the mandatory fields.*/
} SPIConfig;
/**
@ -94,6 +90,7 @@ extern "C" {
void spi_lld_stop(SPIDriver *spip);
void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip);
msg_t spi_lld_ignore(SPIDriver *spip, size_t n);
msg_t spi_lld_exchange(SPIDriver *spip, size_t n, void *txbuf, void *rxbuf);
msg_t spi_lld_send(SPIDriver *spip, size_t n, void *txbuf);
msg_t spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);