-- cgit v1.2.3 From 690fd6364bd682ade14f27e86cb3821c84524d78 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 5 Mar 2012 16:44:56 +0000 Subject: SDC. Code merged to fresh branch. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4021 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/sdc.h | 97 ++++- os/hal/platforms/STM32/sdc_lld.c | 647 +++++++++++++++++---------------- os/hal/platforms/STM32/sdc_lld.h | 85 ++++- os/hal/platforms/STM32F4xx/hal_lld.h | 4 + os/hal/platforms/STM32F4xx/platform.mk | 5 +- os/hal/platforms/STM32F4xx/stm32_rcc.h | 33 ++ os/hal/src/sdc.c | 134 +++++-- 7 files changed, 644 insertions(+), 361 deletions(-) diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index 52bef66f0..9be833dd3 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -88,6 +88,27 @@ #define SDC_CMD_LOCK_UNLOCK 42 #define SDC_CMD_APP_CMD 55 +/** + * @brief Returning status. + */ +#define SDC_SUCCESS FALSE +#define SDC_FAILED TRUE + +/** + * @name SDC bus error conditions + * @{ + */ +#define SDC_NO_ERROR 0 /**< @brief No error. */ +#define SDC_CMD_CRC_ERROR 1 /**< @brief Command CRC error. */ +#define SDC_DATA_CRC_ERROR 2 /**< @brief Data CRC error. */ +#define SDC_DATA_TIMEOUT 4 /**< @brief Hardware write timeout.*/ +#define SDC_COMMAND_TIMEOUT 8 /**< @brief Hardware read timeout. */ +#define SDC_TX_UNDERRUN 16 /**< @brief TX buffer underrun. */ +#define SDC_RX_OVERRUN 32 /**< @brief RX buffer overrun. */ +#define SDC_STARTBIT_ERROR 64 /**< @brief Start bit not detected.*/ +#define SDC_OVERFLOW_ERROR 128 /**< @brief Card overflow error. */ +#define SDC_UNHANDLED_ERROR 0xFFFFFFFF + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -122,6 +143,20 @@ #if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) #define SDC_NICE_WAITING TRUE #endif + +/** + * @brief Write timeout in milliseconds. + */ +#if !defined(SDC_WRITE_TIMEOUT_MS) || defined(__DOXYGEN__) +#define SDC_WRITE_TIMEOUT_MS 250 +#endif + +/** + * @brief Write timeout in milliseconds. + */ +#if !defined(SDC_READ_TIMEOUT_MS) || defined(__DOXYGEN__) +#define SDC_READ_TIMEOUT_MS 5 +#endif /** @} */ /*===========================================================================*/ @@ -223,6 +258,66 @@ typedef enum { * @api */ #define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp)) + +/** + * @brief Slice position of values in CSD register. + */ +/* CSD version 1.0 */ +#define SDC_CSD_20_CRC_SLICE 7,1 +#define SDC_CSD_20_FILE_FORMAT_SLICE 11,10 +#define SDC_CSD_20_TMP_WRITE_PROTECT_SLICE 12,12 +#define SDC_CSD_20_PERM_WRITE_PROTECT_SLICE 13,13 +#define SDC_CSD_20_COPY_SLICE 14,14 +#define SDC_CSD_20_FILE_FORMAT_GRP_SLICE 15,15 +#define SDC_CSD_20_WRITE_BL_PARTIAL_SLICE 21,21 +#define SDC_CSD_20_WRITE_BL_LEN_SLICE 25,12 +#define SDC_CSD_20_R2W_FACTOR_SLICE 28,26 +#define SDC_CSD_20_WP_GRP_ENABLE_SLICE 31,31 +#define SDC_CSD_20_WP_GRP_SIZE_SLICE 38,32 +#define SDC_CSD_20_ERASE_SECTOR_SIZE_SLICE 45,39 +#define SDC_CSD_20_ERASE_BLK_EN_SLICE 46,46 +#define SDC_CSD_20_C_SIZE_SLICE 69,48 +#define SDC_CSD_20_DSR_IMP_SLICE 76,76 +#define SDC_CSD_20_READ_BLK_MISALIGN_SLICE 77,77 +#define SDC_CSD_20_WRITE_BLK_MISALIGN_SLICE 78,78 +#define SDC_CSD_20_READ_BL_PARTIAL_SLICE 79,79 +#define SDC_CSD_20_READ_BL_LEN_SLICE 83,80 +#define SDC_CSD_20_CCC_SLICE 95,84 +#define SDC_CSD_20_TRANS_SPEED_SLICE 103,96 +#define SDC_CSD_20_NSAC_SLICE 111,104 +#define SDC_CSD_20_TAAC_SLICE 119,112 +#define SDC_CSD_20_STRUCTURE_SLICE 127,126 + +/* CSD version 2.0 */ +#define SDC_CSD_10_CRC_SLICE SDC_CSD_20_CRC_SLICE +#define SDC_CSD_10_FILE_FORMAT_SLICE SDC_CSD_20_FILE_FORMAT_SLICE +#define SDC_CSD_10_TMP_WRITE_PROTECT_SLICE SDC_CSD_20_TMP_WRITE_PROTECT_SLICE +#define SDC_CSD_10_PERM_WRITE_PROTECT_SLICE SDC_CSD_20_PERM_WRITE_PROTECT_SLICE +#define SDC_CSD_10_COPY_SLICE SDC_CSD_20_COPY_SLICE +#define SDC_CSD_10_FILE_FORMAT_GRP_SLICE SDC_CSD_20_FILE_FORMAT_GRP_SLICE +#define SDC_CSD_10_WRITE_BL_PARTIAL_SLICE SDC_CSD_20_WRITE_BL_PARTIAL_SLICE +#define SDC_CSD_10_WRITE_BL_LEN_SLICE SDC_CSD_20_WRITE_BL_LEN_SLICE +#define SDC_CSD_10_R2W_FACTOR_SLICE SDC_CSD_20_R2W_FACTOR_SLICE +#define SDC_CSD_10_WP_GRP_ENABLE_SLICE SDC_CSD_20_WP_GRP_ENABLE_SLICE +#define SDC_CSD_10_WP_GRP_SIZE_SLICE SDC_CSD_20_WP_GRP_SIZE_SLICE +#define SDC_CSD_10_ERASE_SECTOR_SIZE_SLICE SDC_CSD_20_ERASE_SECTOR_SIZE_SLICE +#define SDC_CSD_10_ERASE_BLK_EN_SLICE SDC_CSD_20_ERASE_BLK_EN_SLICE +#define SDC_CSD_10_C_SIZE_MULT_SLICE 49,47 +#define SDC_CSD_10_VDD_W_CURR_MAX_SLICE 52,50 +#define SDC_CSD_10_VDD_W_CURR_MIN_SLICE 55,53 +#define SDC_CSD_10_VDD_R_CURR_MAX_SLICE 58,56 +#define SDC_CSD_10_VDD_R_CURR_MIX_SLICE 61,59 +#define SDC_CSD_10_C_SIZE_SLICE 73,62 +#define SDC_CSD_10_DSR_IMP_SLICE SDC_CSD_20_DSR_IMP_SLICE +#define SDC_CSD_10_READ_BLK_MISALIGN_SLICE SDC_CSD_20_READ_BLK_MISALIGN_SLICE +#define SDC_CSD_10_WRITE_BLK_MISALIGN_SLICE SDC_CSD_20_WRITE_BLK_MISALIGN_SLICE +#define SDC_CSD_10_READ_BL_PARTIAL_SLICE SDC_CSD_20_READ_BL_PARTIAL_SLICE +#define SDC_CSD_10_READ_BL_LEN_SLICE 83, 80 +#define SDC_CSD_10_CCC_SLICE SDC_CSD_20_CCC_SLICE +#define SDC_CSD_10_TRANS_SPEED_SLICE SDC_CSD_20_TRANS_SPEED_SLICE +#define SDC_CSD_10_NSAC_SLICE SDC_CSD_20_NSAC_SLICE +#define SDC_CSD_10_TAAC_SLICE SDC_CSD_20_TAAC_SLICE +#define SDC_CSD_10_STRUCTURE_SLICE SDC_CSD_20_STRUCTURE_SLICE /** @} */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c index 42883e3b0..f74d06c9e 100644 --- a/os/hal/platforms/STM32/sdc_lld.c +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -26,6 +26,10 @@ * @{ */ +/* + TODO: Try preerase blocks before writing (ACMD23). + */ + #include #include "ch.h" @@ -33,6 +37,14 @@ #if HAL_USE_SDC || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SDC_SDIO_DMA_STREAM, \ + STM32_SDC_SDIO_DMA_CHN) + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -59,330 +71,193 @@ static union { /*===========================================================================*/ /** - * @brief Reads one or more blocks. + * @brief Prepares card to handle read transaction. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] startblk first block to read - * @param[out] buf pointer to the read buffer, it must be aligned to - * four bytes boundary * @param[in] n number of blocks to read + * @param[in] resp pointer to the response buffer + * * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * read. - * @retval TRUE operation failed, the state of the buffer is uncertain. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @notapi */ -static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk, - uint8_t *buf, uint32_t n) { - uint32_t resp[1]; - - /* Checks for errors and waits for the card to be ready for reading.*/ - if (_sdc_wait_for_transfer_state(sdcp)) - return TRUE; - - /* Prepares the DMA channel for reading.*/ - dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); - dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); - dmaStreamSetMode(STM32_DMA2_STREAM4, - STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | - STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | - STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); - - /* Setting up data transfer. - Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | - SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE; - SDIO->DLEN = n * SDC_BLOCK_SIZE; - SDIO->DCTRL = SDIO_DCTRL_DTDIR | - SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | - SDIO_DCTRL_DMAEN | - SDIO_DCTRL_DTEN; - - /* DMA channel activation.*/ - dmaStreamEnable(STM32_DMA2_STREAM4); +static bool_t sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk, + uint32_t n, uint32_t *resp){ - /* Read multiple blocks command.*/ - if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) + /* Driver handles data in 512 bytes blocks (just like HC cards). But if we + have not HC card than we must convert address from blocks to bytes.*/ + if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) startblk *= SDC_BLOCK_SIZE; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, - startblk, resp) || - SDC_R1_ERROR(resp[0])) - goto error; - chSysLock(); - if (SDIO->MASK != 0) { - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_read_multiple(), #1", "not NULL"); - sdcp->thread = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_read_multiple(), #2", "not NULL"); + if (n > 1){ + /* Send read multiple blocks command to card.*/ + if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, + startblk, resp) || SDC_R1_ERROR(resp[0])) + return SDC_FAILED; } - if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { - chSysUnlock(); - goto error; + else{ + /* Send read single block command.*/ + if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK, + startblk, resp) || SDC_R1_ERROR(resp[0])) + return SDC_FAILED; } - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->DCTRL = 0; - chSysUnlock(); - return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); -error: - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = 0; - SDIO->DCTRL = 0; - return TRUE; + return SDC_SUCCESS; } /** - * @brief Reads one block. + * @brief Prepares card to handle write transaction. * * @param[in] sdcp pointer to the @p SDCDriver object * @param[in] startblk first block to read - * @param[out] buf pointer to the read buffer, it must be aligned to - * four bytes boundary + * @param[in] n number of blocks to write + * @param[in] resp pointer to the response buffer + * * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * read. - * @retval TRUE operation failed, the state of the buffer is uncertain. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @notapi */ -static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk, - uint8_t *buf) { - uint32_t resp[1]; +static bool_t sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk, + uint32_t n, uint32_t *resp){ - /* Checks for errors and waits for the card to be ready for reading.*/ - if (_sdc_wait_for_transfer_state(sdcp)) - return TRUE; - - /* Prepares the DMA channel for reading.*/ - dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); - dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, - SDC_BLOCK_SIZE / sizeof (uint32_t)); - dmaStreamSetMode(STM32_DMA2_STREAM4, - STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | - STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_PSIZE_WORD | - STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); - - /* Setting up data transfer. - Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/ - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | - SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE; - SDIO->DLEN = SDC_BLOCK_SIZE; - SDIO->DCTRL = SDIO_DCTRL_DTDIR | - SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | - SDIO_DCTRL_DMAEN | - SDIO_DCTRL_DTEN; - - /* DMA channel activation.*/ - dmaStreamEnable(STM32_DMA2_STREAM4); - - /* Read single block command.*/ - if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) + /* Driver handles data in 512 bytes blocks (just like HC cards). But if we + have not HC card than we must convert address from blocks to bytes.*/ + if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) startblk *= SDC_BLOCK_SIZE; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK, - startblk, resp) || - SDC_R1_ERROR(resp[0])) - goto error; - chSysLock(); - if (SDIO->MASK != 0) { - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_read_single(), #1", "not NULL"); - sdcp->thread = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_read_single(), #2", "not NULL"); + if (n > 1){ + /* Write multiple blocks command.*/ + if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK, + startblk, resp) || SDC_R1_ERROR(resp[0])) + return SDC_FAILED; } - if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { - chSysUnlock(); - goto error; + else{ + /* Write single block command.*/ + if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK, + startblk, resp) || SDC_R1_ERROR(resp[0])) + return SDC_FAILED; } - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->DCTRL = 0; - chSysUnlock(); - return FALSE; -error: - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = 0; - SDIO->DCTRL = 0; - return TRUE; + return SDC_SUCCESS; } /** - * @brief Writes one or more blocks. + * @brief Wait end of data transaction and performs finalizations. * * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] startblk first block to write - * @param[out] buf pointer to the write buffer, it must be aligned to - * four bytes boundary - * @param[in] n number of blocks to write - * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * written. - * @retval TRUE operation failed. + * @param[in] n number of blocks in transaction + * @param[in] resp pointer to the response buffer * - * @notapi + * @return The operation status. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. */ -static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk, - const uint8_t *buf, uint32_t n) { - uint32_t resp[1]; - - /* Checks for errors and waits for the card to be ready for writing.*/ - if (_sdc_wait_for_transfer_state(sdcp)) - return TRUE; - - /* Prepares the DMA channel for writing.*/ - dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); - dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, - (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); - dmaStreamSetMode(STM32_DMA2_STREAM4, - STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | - STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | - STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); - - /* Write multiple blocks command.*/ - if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) - startblk *= SDC_BLOCK_SIZE; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK, - startblk, resp) || - SDC_R1_ERROR(resp[0])) - return TRUE; - - /* Setting up data transfer. - Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/ - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | - SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | - SDIO_MASK_STBITERRIE; - SDIO->DLEN = n * SDC_BLOCK_SIZE; - SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | - SDIO_DCTRL_DMAEN | - SDIO_DCTRL_DTEN; - - /* DMA channel activation.*/ - dmaStreamEnable(STM32_DMA2_STREAM4); +static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, + uint32_t *resp){ /* Note the mask is checked before going to sleep because the interrupt may have occurred before reaching the critical zone.*/ chSysLock(); if (SDIO->MASK != 0) { chDbgAssert(sdcp->thread == NULL, - "sdc_lld_write_multiple(), #1", "not NULL"); + "sdc_lld_start_data_transaction(), #1", "not NULL"); sdcp->thread = chThdSelf(); chSchGoSleepS(THD_STATE_SUSPENDED); chDbgAssert(sdcp->thread == NULL, - "sdc_lld_write_multiple(), #2", "not NULL"); + "sdc_lld_start_data_transaction(), #2", "not NULL"); } if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { chSysUnlock(); - goto error; + return SDC_FAILED; } - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; + + /* Wait until DMA channel enabled to be sure that all data transferred.*/ + while (sdcp->dma->stream->CR & STM32_DMA_CR_EN) + ; + + /* DMA event flags must be manually cleared.*/ + dmaStreamClearInterrupt(sdcp->dma); + + SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; SDIO->DCTRL = 0; chSysUnlock(); - return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); -error: - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = 0; - SDIO->DCTRL = 0; - return TRUE; + /* Wait until interrupt flags to be cleared.*/ + while (((DMA2->LISR) >> (sdcp->dma->ishift)) & STM32_DMA_ISR_TCIF) + dmaStreamClearInterrupt(sdcp->dma); + + /* Finalize transaction.*/ + if (n > 1) + return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); + else + return SDC_SUCCESS; } /** - * @brief Writes one block. + * @brief Gets SDC errors. * * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] startblk first block to write - * @param[out] buf pointer to the write buffer, it must be aligned to - * four bytes boundary - * @param[in] n number of blocks to write - * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * written. - * @retval TRUE operation failed. * * @notapi */ -static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk, - const uint8_t *buf) { - uint32_t resp[1]; +static void sdc_lld_collect_errors(SDCDriver *sdcp) { + uint32_t errors = SDC_NO_ERROR; - /* Checks for errors and waits for the card to be ready for writing.*/ - if (_sdc_wait_for_transfer_state(sdcp)) - return TRUE; - - /* Prepares the DMA channel for writing.*/ - dmaStreamSetMemory0(STM32_DMA2_STREAM4, buf); - dmaStreamSetTransactionSize(STM32_DMA2_STREAM4, - SDC_BLOCK_SIZE / sizeof (uint32_t)); - dmaStreamSetMode(STM32_DMA2_STREAM4, - STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | - STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_PSIZE_WORD | - STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_MINC); - - /* Write single block command.*/ - if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0) - startblk *= SDC_BLOCK_SIZE; - if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK, - startblk, resp) || - SDC_R1_ERROR(resp[0])) - return TRUE; - - /* Setting up data transfer. - Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/ - SDIO->ICR = 0xFFFFFFFF; - SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | - SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | - SDIO_MASK_STBITERRIE; - SDIO->DLEN = SDC_BLOCK_SIZE; - SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 | - SDIO_DCTRL_DMAEN | - SDIO_DCTRL_DTEN; - - /* DMA channel activation.*/ - dmaStreamEnable(STM32_DMA2_STREAM4); - - /* Note the mask is checked before going to sleep because the interrupt - may have occurred before reaching the critical zone.*/ - chSysLock(); - if (SDIO->MASK != 0) { - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_write_single(), #1", "not NULL"); - sdcp->thread = chThdSelf(); - chSchGoSleepS(THD_STATE_SUSPENDED); - chDbgAssert(sdcp->thread == NULL, - "sdc_lld_write_single(), #2", "not NULL"); + if (SDIO->STA & SDIO_STA_CCRCFAIL){ + SDIO->ICR |= SDIO_ICR_CCRCFAILC; + errors |= SDC_CMD_CRC_ERROR; } - if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { - chSysUnlock(); - goto error; + if (SDIO->STA & SDIO_STA_DCRCFAIL){ + SDIO->ICR |= SDIO_ICR_DCRCFAILC; + errors |= SDC_DATA_CRC_ERROR; + } + if (SDIO->STA & SDIO_STA_CTIMEOUT){ + SDIO->ICR |= SDIO_ICR_CTIMEOUTC; + errors |= SDC_COMMAND_TIMEOUT; + } + if (SDIO->STA & SDIO_STA_DTIMEOUT){ + SDIO->ICR |= SDIO_ICR_CTIMEOUTC; + errors |= SDC_DATA_TIMEOUT; + } + if (SDIO->STA & SDIO_STA_TXUNDERR){ + SDIO->ICR |= SDIO_ICR_TXUNDERRC; + errors |= SDC_TX_UNDERRUN; + } + if (SDIO->STA & SDIO_STA_RXOVERR){ + SDIO->ICR |= SDIO_ICR_RXOVERRC; + errors |= SDC_RX_OVERRUN; + } + if (SDIO->STA & SDIO_STA_STBITERR){ + SDIO->ICR |= SDIO_ICR_STBITERRC; + errors |= SDC_STARTBIT_ERROR; } - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; - SDIO->DCTRL = 0; - chSysUnlock(); - return FALSE; -error: - dmaStreamDisable(STM32_DMA2_STREAM4); - SDIO->ICR = 0xFFFFFFFF; + sdcp->errors |= errors; +} + +/** + * @brief Performs clean transaction stopping in case of errors. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] n number of blocks in transaction + * @param[in] resp pointer to the response buffer + * + * @notapi + */ +static void sdc_lld_error_cleanup(SDCDriver *sdcp, uint32_t n, uint32_t *resp){ + dmaStreamClearInterrupt(sdcp->dma); + dmaStreamDisable(sdcp->dma); + SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; SDIO->MASK = 0; SDIO->DCTRL = 0; - return TRUE; + sdc_lld_collect_errors(sdcp); + if (n > 1) + sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); } /*===========================================================================*/ @@ -391,6 +266,8 @@ error: /** * @brief SDIO IRQ handler. + * @details It just wakes transaction thread. All error handling performs in + * that thread. * * @isr */ @@ -398,17 +275,18 @@ CH_IRQ_HANDLER(SDIO_IRQHandler) { CH_IRQ_PROLOGUE(); - chSysLockFromIsr(); - if (SDCD1.thread != NULL) { - chSchReadyI(SDCD1.thread); - SDCD1.thread = NULL; - } - chSysUnlockFromIsr(); + chSysLockFromIsr() /* Disables the source but the status flags are not reset because the - read/write functions need to check them.*/ + read/write functions needs to check them.*/ SDIO->MASK = 0; + if (SDCD1.thread != NULL) { + chSchReadyI(SDCD1.thread); + SDCD1.thread = NULL; } + + chSysUnlockFromIsr(); + CH_IRQ_EPILOGUE(); } @@ -425,31 +303,52 @@ void sdc_lld_init(void) { sdcObjectInit(&SDCD1); SDCD1.thread = NULL; + SDCD1.dma = STM32_DMA_STREAM(STM32_SDC_SDIO_DMA_STREAM); +#if CH_DBG_ENABLE_ASSERTS + SDCD1.sdio = SDIO; +#endif } /** * @brief Configures and activates the SDC peripheral. * - * @param[in] sdcp pointer to the @p SDCDriver object, must be @p NULL, - * this driver does not require any configuration + * @param[in] sdcp pointer to the @p SDCDriver object * * @notapi */ void sdc_lld_start(SDCDriver *sdcp) { + sdcp->dmamode = STM32_DMA_CR_CHSEL(DMA_CHANNEL) | + STM32_DMA_CR_PL(STM32_SDC_SDIO_DMA_PRIORITY) | + STM32_DMA_CR_PSIZE_WORD | + STM32_DMA_CR_MSIZE_WORD | + STM32_DMA_CR_MINC; + + #if (defined(STM32F4XX) || defined(STM32F2XX)) + sdcp->dmamode |= STM32_DMA_CR_PFCTRL | + STM32_DMA_CR_PBURST_INCR4 | + STM32_DMA_CR_MBURST_INCR4; + #endif + if (sdcp->state == SDC_STOP) { /* Note, the DMA must be enabled before the IRQs.*/ - dmaStreamAllocate(STM32_DMA2_STREAM4, 0, NULL, NULL); - dmaStreamSetPeripheral(STM32_DMA2_STREAM4, &SDIO->FIFO); + bool_t b; + b = dmaStreamAllocate(sdcp->dma, STM32_SDC_SDIO_IRQ_PRIORITY, NULL, NULL); + chDbgAssert(!b, "i2c_lld_start(), #3", "stream already allocated"); + dmaStreamSetPeripheral(sdcp->dma, &SDIO->FIFO); + #if (defined(STM32F4XX) || defined(STM32F2XX)) + dmaStreamSetFIFO(sdcp->dma, STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FTH_FULL); + #endif nvicEnableVector(SDIO_IRQn, CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY)); rccEnableSDIO(FALSE); } + /* Configuration, card clock is initially stopped.*/ SDIO->POWER = 0; SDIO->CLKCR = 0; SDIO->DCTRL = 0; - SDIO->DTIMER = STM32_SDC_DATATIMEOUT; + SDIO->DTIMER = 0; } /** @@ -469,7 +368,7 @@ void sdc_lld_stop(SDCDriver *sdcp) { /* Clock deactivation.*/ nvicDisableVector(SDIO_IRQn); - dmaStreamRelease(STM32_DMA2_STREAM4); + dmaStreamRelease(sdcp->dma); rccDisableSDIO(FALSE); } } @@ -538,6 +437,7 @@ void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) { break; case SDC_MODE_8BIT: SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_1; + break; } } @@ -568,10 +468,10 @@ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) { * @param[in] cmd card command * @param[in] arg command argument * @param[out] resp pointer to the response buffer (one word) + * * @return The operation status. - * @retval FALSE the operation succeeded. - * @retval TRUE the operation failed because timeout, CRC check or - * other errors. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @notapi */ @@ -586,10 +486,12 @@ bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, SDIO_STA_CCRCFAIL)) == 0) ; SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; - if ((sta & (SDIO_STA_CTIMEOUT)) != 0) - return TRUE; + if ((sta & (SDIO_STA_CTIMEOUT)) != 0){ + sdc_lld_collect_errors(sdcp); + return SDC_FAILED; + } *resp = SDIO->RESP1; - return FALSE; + return SDC_SUCCESS; } /** @@ -599,10 +501,10 @@ bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, * @param[in] cmd card command * @param[in] arg command argument * @param[out] resp pointer to the response buffer (one word) + * * @return The operation status. - * @retval FALSE the operation succeeded. - * @retval TRUE the operation failed because timeout, CRC check or - * other errors. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @notapi */ @@ -617,10 +519,12 @@ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, SDIO_STA_CCRCFAIL)) == 0) ; SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; - if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) - return TRUE; + if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0){ + sdc_lld_collect_errors(sdcp); + return SDC_FAILED; + } *resp = SDIO->RESP1; - return FALSE; + return SDC_SUCCESS; } /** @@ -630,10 +534,10 @@ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, * @param[in] cmd card command * @param[in] arg command argument * @param[out] resp pointer to the response buffer (four words) + * * @return The operation status. - * @retval FALSE the operation succeeded. - * @retval TRUE the operation failed because timeout, CRC check or - * other errors. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @notapi */ @@ -650,10 +554,16 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, SDIO_STA_CCRCFAIL)) == 0) ; SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; - if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0) - return TRUE; - *resp = SDIO->RESP1; - return FALSE; + if ((sta & (STM32_SDIO_STA_ERROR_MASK)) != 0){ + sdc_lld_collect_errors(sdcp); + return SDC_FAILED; + } + /* save bytes in reverse order because MSB in response comes first */ + *resp++ = SDIO->RESP4; + *resp++ = SDIO->RESP3; + *resp++ = SDIO->RESP2; + *resp = SDIO->RESP1; + return SDC_SUCCESS; } /** @@ -663,10 +573,133 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, * @param[in] startblk first block to read * @param[out] buf pointer to the read buffer * @param[in] n number of blocks to read + * * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * read. - * @retval TRUE operation failed, the state of the buffer is uncertain. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. + * + * @notapi + */ +bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, + uint8_t *buf, uint32_t n) { + uint32_t resp[1]; + + chDbgCheck((n < (0x1000000 / SDC_BLOCK_SIZE)), "max transaction size"); + + SDIO->DTIMER = STM32_SDC_READ_TIMEOUT; + + /* Checks for errors and waits for the card to be ready for reading.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return SDC_FAILED; + + /* Prepares the DMA channel for writing.*/ + dmaStreamSetMemory0(sdcp->dma, buf); + dmaStreamSetTransactionSize(sdcp->dma, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M); + dmaStreamEnable(sdcp->dma); + + /* Setting up data transfer.*/ + SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; + SDIO->MASK = SDIO_MASK_DCRCFAILIE | + SDIO_MASK_DTIMEOUTIE | + SDIO_MASK_STBITERRIE | + SDIO_MASK_RXOVERRIE | + SDIO_MASK_DATAENDIE; + SDIO->DLEN = n * SDC_BLOCK_SIZE; + + /* Talk to card what we want from it.*/ + if (sdc_lld_prepare_read(sdcp, startblk, n, resp) == SDC_FAILED) + goto error; + + /* Transaction starts just after DTEN bit setting.*/ + SDIO->DCTRL = SDIO_DCTRL_DTDIR | + SDIO_DCTRL_DBLOCKSIZE_3 | + SDIO_DCTRL_DBLOCKSIZE_0 | + SDIO_DCTRL_DMAEN | + SDIO_DCTRL_DTEN; + if (sdc_lld_wait_transaction_end(sdcp, n, resp) == SDC_FAILED) + goto error; + else + return SDC_SUCCESS; + +error: + sdc_lld_error_cleanup(sdcp, n, resp); + return SDC_FAILED; +} + +/** + * @brief Writes one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to write + * @param[out] buf pointer to the write buffer + * @param[in] n number of blocks to write + * + * @return The operation status. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. + * + * @notapi + */ +bool_t sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk, + const uint8_t *buf, uint32_t n) { + uint32_t resp[1]; + + chDbgCheck((n < (0x1000000 / SDC_BLOCK_SIZE)), "max transaction size"); + + SDIO->DTIMER = STM32_SDC_WRITE_TIMEOUT; + + /* Checks for errors and waits for the card to be ready for writing.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return SDC_FAILED; + + /* Prepares the DMA channel for writing.*/ + dmaStreamSetMemory0(sdcp->dma, buf); + dmaStreamSetTransactionSize(sdcp->dma, + (n * SDC_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_M2P); + dmaStreamEnable(sdcp->dma); + + /* Setting up data transfer.*/ + SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; + SDIO->MASK = SDIO_MASK_DCRCFAILIE | + SDIO_MASK_DTIMEOUTIE | + SDIO_MASK_STBITERRIE | + SDIO_MASK_TXUNDERRIE | + SDIO_MASK_DATAENDIE; + SDIO->DLEN = n * SDC_BLOCK_SIZE; + + /* Talk to card what we want from it.*/ + if (sdc_lld_prepare_write(sdcp, startblk, n, resp) == SDC_FAILED) + goto error; + + /* Transaction starts just after DTEN bit setting.*/ + SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | + SDIO_DCTRL_DBLOCKSIZE_0 | + SDIO_DCTRL_DMAEN | + SDIO_DCTRL_DTEN; + if (sdc_lld_wait_transaction_end(sdcp, n, resp) == SDC_FAILED) + goto error; + else + return SDC_SUCCESS; + +error: + sdc_lld_error_cleanup(sdcp, n, resp); + return SDC_FAILED; +} + +/** + * @brief Reads one or more blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to read + * @param[out] buf pointer to the read buffer + * @param[in] n number of blocks to read + * + * @return The operation status. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @notapi */ @@ -677,18 +710,16 @@ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, if (((unsigned)buf & 3) != 0) { uint32_t i; for (i = 0; i < n; i++) { - if (sdc_lld_read_single(sdcp, startblk, u.buf)) - return TRUE; + if (sdc_lld_read_aligned(sdcp, startblk, u.buf, 1)) + return SDC_FAILED; memcpy(buf, u.buf, SDC_BLOCK_SIZE); buf += SDC_BLOCK_SIZE; startblk++; } - return FALSE; + return SDC_SUCCESS; } #endif - if (n == 1) - return sdc_lld_read_single(sdcp, startblk, buf); - return sdc_lld_read_multiple(sdcp, startblk, buf, n); + return sdc_lld_read_aligned(sdcp, startblk, buf, n); } /** @@ -698,32 +729,30 @@ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, * @param[in] startblk first block to write * @param[out] buf pointer to the write buffer * @param[in] n number of blocks to write + * * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * written. - * @retval TRUE operation failed. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @notapi */ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buf, uint32_t n) { -#if STM32_SDC_UNALIGNED_SUPPORT + #if STM32_SDC_UNALIGNED_SUPPORT if (((unsigned)buf & 3) != 0) { uint32_t i; for (i = 0; i < n; i++) { memcpy(u.buf, buf, SDC_BLOCK_SIZE); buf += SDC_BLOCK_SIZE; - if (sdc_lld_write_single(sdcp, startblk, u.buf)) - return TRUE; + if (sdc_lld_write_aligned(sdcp, startblk, u.buf, 1)) + return SDC_FAILED; startblk++; } - return FALSE; + return SDC_SUCCESS; } #endif - if (n == 1) - return sdc_lld_write_single(sdcp, startblk, buf); - return sdc_lld_write_multiple(sdcp, startblk, buf, n); + return sdc_lld_write_aligned(sdcp, startblk, buf, n); } #endif /* HAL_USE_SDC */ diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h index 1d4f21034..51db5b2aa 100644 --- a/os/hal/platforms/STM32/sdc_lld.h +++ b/os/hal/platforms/STM32/sdc_lld.h @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -35,6 +35,23 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * @brief Value to clear all interrupts flag at once. + */ +#define STM32_SDIO_ICR_ALL_FLAGS (SDIO_ICR_CCRCFAILC | SDIO_ICR_DCRCFAILC | \ + SDIO_ICR_CTIMEOUTC | SDIO_ICR_DTIMEOUTC | \ + SDIO_ICR_TXUNDERRC | SDIO_ICR_RXOVERRC | \ + SDIO_ICR_CMDRENDC | SDIO_ICR_CMDSENTC | \ + SDIO_ICR_DATAENDC | SDIO_ICR_STBITERRC | \ + SDIO_ICR_DBCKENDC | SDIO_ICR_SDIOITC | \ + SDIO_ICR_CEATAENDC) + +/** + * @brief Mask of error flags in STA register. + */ +#define STM32_SDIO_STA_ERROR_MASK (SDIO_STA_CCRCFAIL | SDIO_STA_DCRCFAIL | \ + SDIO_STA_CTIMEOUT | SDIO_STA_DTIMEOUT | \ + SDIO_STA_TXUNDERR | SDIO_STA_RXOVERR) /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -44,13 +61,6 @@ * @name Configuration options * @{ */ -/** - * @brief SDIO data timeout in SDIO clock cycles. - */ -#if !defined(STM32_SDC_DATATIMEOUT) || defined(__DOXYGEN__) -#define STM32_SDC_DATATIMEOUT 0x000FFFFF -#endif - /** * @brief SDIO DMA priority (0..3|lowest..highest). */ @@ -65,12 +75,6 @@ #define STM32_SDC_SDIO_IRQ_PRIORITY 9 #endif -/** - * @brief SDIO support for unaligned transfers. - */ -#if !defined(STM32_SDC_UNALIGNED_SUPPORT) || defined(__DOXYGEN__) -#define STM32_SDC_UNALIGNED_SUPPORT TRUE -#endif /** @} */ /*===========================================================================*/ @@ -88,14 +92,34 @@ /* * SDIO clock divider. */ -#if STM32_HCLK > 48000000 -#define STM32_SDIO_DIV_HS 0x01 -#define STM32_SDIO_DIV_LS 0xB2 +#if (defined(STM32F4XX) || defined(STM32F2XX)) + #define STM32_SDIO_DIV_HS 0 + #define STM32_SDIO_DIV_LS 120 +#elif STM32_HCLK > 48000000 + #define STM32_SDIO_DIV_HS 1 + #define STM32_SDIO_DIV_LS 178 +#else + #define STM32_SDIO_DIV_HS 0 + #define STM32_SDIO_DIV_LS 118 +#endif + +/** + * @brief SDIO data timeouts in SDIO clock cycles. + */ +#if (defined(STM32F4XX) || defined(STM32F2XX)) + #define STM32_SDC_WRITE_TIMEOUT \ + (((48000000 / (STM32_SDIO_DIV_HS + 2)) / 1000) * SDC_WRITE_TIMEOUT_MS) + #define STM32_SDC_READ_TIMEOUT \ + (((48000000 / (STM32_SDIO_DIV_HS + 2)) / 1000) * SDC_READ_TIMEOUT_MS) #else -#define STM32_SDIO_DIV_HS 0x00 -#define STM32_SDIO_DIV_LS 0x76 + #define STM32_SDC_WRITE_TIMEOUT \ + (((STM32_HCLK /((STM32_SDIO_DIV_HS + 2)) / 1000) * SDC_WRITE_TIMEOUT_MS) + #define STM32_SDC_READ_TIMEOUT \ + (((STM32_HCLK /((STM32_SDIO_DIV_HS + 2)) / 1000) * SDC_READ_TIMEOUT_MS) #endif + + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -143,6 +167,10 @@ struct SDCDriver { * @brief Various flags regarding the mounted card. */ sdcmode_t cardmode; + /** + * @brief Errors flags. + */ + uint32_t errors; /** * @brief Card CID. */ @@ -155,11 +183,30 @@ struct SDCDriver { * @brief Card RCA. */ uint32_t rca; + /** + * @brief Total number of blocks in card. + */ + uint32_t capacity; /* End of the mandatory fields.*/ /** * @brief Thread waiting for I/O completion IRQ. */ Thread *thread; + /** + * @brief DMA mode bit mask. + */ + uint32_t dmamode; + /** + * @brief Transmit DMA channel. + */ + const stm32_dma_stream_t *dma; + /** + * @brief Pointer to the SDIO registers block. + * @note Used only for dubugging purpose. + */ +#if CH_DBG_ENABLE_ASSERTS + SDIO_TypeDef *sdio; +#endif }; /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index c88ac3a96..a058e848a 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -339,6 +339,9 @@ /* SDIO attributes.*/ #define STM32_HAS_SDIO TRUE +#define STM32_SDC_SDIO_DMA_MSK (STM32_DMA_STREAM_ID_MSK(2, 3) | \ + STM32_DMA_STREAM_ID_MSK(2, 6)) +#define STM32_SDC_SDIO_DMA_CHN 0x04004000 /* SPI attributes.*/ #define STM32_HAS_SPI1 TRUE @@ -492,6 +495,7 @@ #define TIM8_CC_IRQHandler VectorF8 /**< TIM8 Capture Compare. */ #define DMA1_Stream7_IRQHandler VectorFC /**< DMA1 Stream 7. */ #define FSMC_IRQHandler Vector100 /**< FSMC. */ +#define SDIO_IRQHandler Vector104 /**< SDIO. */ #define TIM5_IRQHandler Vector108 /**< TIM5. */ #define SPI3_IRQHandler Vector10C /**< SPI3. */ #define UART4_IRQHandler Vector110 /**< UART4. */ diff --git a/os/hal/platforms/STM32F4xx/platform.mk b/os/hal/platforms/STM32F4xx/platform.mk index 475a5b35c..fa9caef41 100644 --- a/os/hal/platforms/STM32F4xx/platform.mk +++ b/os/hal/platforms/STM32F4xx/platform.mk @@ -11,10 +11,11 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/STM32F4xx/stm32_dma.c \ ${CHIBIOS}/os/hal/platforms/STM32/spi_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/uart_lld.c \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2/pal_lld.c \ - ${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c + ${CHIBIOS}/os/hal/platforms/STM32/RTCv2/rtc_lld.c \ + ${CHIBIOS}/os/hal/platforms/STM32/RTCv2/sdc_lld.c # Required include directories PLATFORMINC = ${CHIBIOS}/os/hal/platforms/STM32F4xx \ ${CHIBIOS}/os/hal/platforms/STM32 \ ${CHIBIOS}/os/hal/platforms/STM32/GPIOv2 \ - ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 \ No newline at end of file + ${CHIBIOS}/os/hal/platforms/STM32/RTCv2 diff --git a/os/hal/platforms/STM32F4xx/stm32_rcc.h b/os/hal/platforms/STM32F4xx/stm32_rcc.h index c7f5c8a51..181a2547c 100644 --- a/os/hal/platforms/STM32F4xx/stm32_rcc.h +++ b/os/hal/platforms/STM32F4xx/stm32_rcc.h @@ -502,6 +502,39 @@ #define rccResetI2C3() rccResetAPB1(RCC_APB1RSTR_I2C3RST) /** @} */ +/** + * @name SDIO peripheral specific RCC operations + * @{ + */ +/** + * @brief Enables the SDIO peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccEnableSDIO(lp) rccEnableAPB2(RCC_APB2ENR_SDIOEN, lp) + +/** + * @brief Disables the SDIO peripheral clock. + * @note The @p lp parameter is ignored in this family. + * + * @param[in] lp low power enable flag + * + * @api + */ +#define rccDisableSDIO(lp) rccDisableAPB2(RCC_APB2ENR_SDIOEN, lp) + +/** + * @brief Resets the SDIO peripheral. + * @note Not supported in this family, does nothing. + * + * @api + */ +#define rccResetSDIO() rccResetAPB2(RCC_APB2RSTR_SDIORST) +/** @} */ + /** * @name SPI peripherals specific RCC operations * @{ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index e8894a597..62f3cb45a 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -47,14 +47,50 @@ /* Driver local functions. */ /*===========================================================================*/ +/** + * @brief Get slice with data from uint32_t[4] array. + * + * @notapi + */ +static uint32_t _sdc_get_slice(uint32_t *data, int8_t end, int8_t start) { + uint32_t word = 0; + uint32_t mask = 0; + + chDbgCheck(((start >=0) && (end >=0) && (end >= start)), "sdc_get_slice"); + + while ((start - 32 * word) > 31){ + word++; + data++; + } + + end -= 32 * word; + start -= 32 * word; + + if (end < 31){ + /* Value lays in one word.*/ + mask = (1 << (end - start + 1)) - 1; + return (*data >> start) & mask; + } + else{ + /* Value spread on separate words.*/ + uint32_t lsb, msb; + lsb = *data >> start; + data++; + mask = (1 << (end - 32 + 1)) - 1; + msb = *data & mask; + msb = msb << (32 - start); + return (msb | lsb); + } +} + /** * @brief Wait for the card to complete pending operations. * * @param[in] sdcp pointer to the @p SDCDriver object + * * @return The operation status. - * @retval FALSE the card is now in transfer state. - * @retval TRUE an error occurred while waiting or the card is in an - * unexpected state. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @notapi */ @@ -65,10 +101,10 @@ bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) { if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_STATUS, sdcp->rca, resp) || SDC_R1_ERROR(resp[0])) - return TRUE; + return SDC_FAILED; switch (SDC_R1_STS(resp[0])) { case SDC_STS_TRAN: - return FALSE; + return SDC_SUCCESS; case SDC_STS_DATA: case SDC_STS_RCV: case SDC_STS_PRG: @@ -79,9 +115,11 @@ bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) { default: /* The card should have been initialized so any other state is not valid and is reported as an error.*/ - return TRUE; + return SDC_FAILED; } } + /* If something going too wrong.*/ + return SDC_FAILED; } /*===========================================================================*/ @@ -110,7 +148,9 @@ void sdcInit(void) { void sdcObjectInit(SDCDriver *sdcp) { sdcp->state = SDC_STOP; + sdcp->errors = SDC_NO_ERROR; sdcp->config = NULL; + sdcp->capacity = 0; } /** @@ -162,10 +202,10 @@ void sdcStop(SDCDriver *sdcp) { * to perform read and write operations. * * @param[in] sdcp pointer to the @p SDCDriver object + * * @return The operation status. - * @retval FALSE operation succeeded, the driver is now - * in the @p SDC_ACTIVE state. - * @retval TRUE operation failed. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @api */ @@ -282,24 +322,48 @@ bool_t sdcConnect(SDCDriver *sdcp) { if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SET_BUS_WIDTH, 2, resp) || SDC_R1_ERROR(resp[0])) goto failed; + break; + } + + /* Determine capacity.*/ + switch (sdcp->csd[3] >> 30) { + uint32_t a; + uint8_t b, c; + case 0: + /* CSD version 1.0 */ + a = _sdc_get_slice(sdcp->csd, SDC_CSD_10_C_SIZE_SLICE); + b = _sdc_get_slice(sdcp->csd, SDC_CSD_10_C_SIZE_MULT_SLICE); + c = _sdc_get_slice(sdcp->csd, SDC_CSD_10_READ_BL_LEN_SLICE); + sdcp->capacity = ((a + 1) << (b + 2) << c) / 512; + break; + case 1: + /* CSD version 2.0 */ + a = _sdc_get_slice(sdcp->csd, SDC_CSD_20_C_SIZE_SLICE); + sdcp->capacity = 1024 * (a + 1); + break; } + if (sdcp->capacity == 0) + goto failed; + /* Initialization complete.*/ sdcp->state = SDC_ACTIVE; - return FALSE; + return SDC_SUCCESS; + + /* Initialization failed.*/ failed: sdc_lld_stop_clk(sdcp); sdcp->state = SDC_READY; - return TRUE; + return SDC_FAILED; } /** * @brief Brings the driver in a state safe for card removal. * * @param[in] sdcp pointer to the @p SDCDriver object + * * @return The operation status. - * @retval FALSE the operation succeeded and the driver is now - * in the @p SDC_READY state. - * @retval TRUE the operation failed. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @api */ @@ -312,20 +376,20 @@ bool_t sdcDisconnect(SDCDriver *sdcp) { "sdcDisconnect(), #1", "invalid state"); if (sdcp->state == SDC_READY) { chSysUnlock(); - return FALSE; + return SDC_SUCCESS; } sdcp->state = SDC_DISCONNECTING; chSysUnlock(); /* Waits for eventual pending operations completion.*/ if (_sdc_wait_for_transfer_state(sdcp)) - return TRUE; + return SDC_FAILED; /* Card clock stopped.*/ sdc_lld_stop_clk(sdcp); sdcp->state = SDC_READY; - return FALSE; + return SDC_SUCCESS; } /** @@ -337,27 +401,32 @@ bool_t sdcDisconnect(SDCDriver *sdcp) { * @param[in] startblk first block to read * @param[out] buf pointer to the read buffer * @param[in] n number of blocks to read + * * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * read. - * @retval TRUE operation failed, the state of the buffer is uncertain. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @api */ bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk, uint8_t *buf, uint32_t n) { - bool_t err; + bool_t status; chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead"); + if ((startblk + n - 1) > sdcp->capacity){ + sdcp->errors |= SDC_OVERFLOW_ERROR; + return SDC_FAILED; + } + chSysLock(); chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcRead(), #1", "invalid state"); sdcp->state = SDC_READING; chSysUnlock(); - err = sdc_lld_read(sdcp, startblk, buf, n); + status = sdc_lld_read(sdcp, startblk, buf, n); sdcp->state = SDC_ACTIVE; - return err; + return status; } /** @@ -369,27 +438,32 @@ bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk, * @param[in] startblk first block to write * @param[out] buf pointer to the write buffer * @param[in] n number of blocks to write + * * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been - * written. - * @retval TRUE operation failed. + * @retval SDC_SUCCESS operation succeeded. + * @retval SDC_FAILED operation failed. * * @api */ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buf, uint32_t n) { - bool_t err; + bool_t status; chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcWrite"); + if ((startblk + n - 1) > sdcp->capacity){ + sdcp->errors |= SDC_OVERFLOW_ERROR; + return SDC_FAILED; + } + chSysLock(); chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcWrite(), #1", "invalid state"); sdcp->state = SDC_WRITING; chSysUnlock(); - err = sdc_lld_write(sdcp, startblk, buf, n); + status = sdc_lld_write(sdcp, startblk, buf, n); sdcp->state = SDC_ACTIVE; - return err; + return status; } #endif /* HAL_USE_SDC */ -- cgit v1.2.3 From 2c8470c2bb849823019a3fe573e0a4dded8ddbbf Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 6 Mar 2012 18:43:12 +0000 Subject: SDC. Added template of test suit for F4. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4028 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- testhal/STM32F4xx/SDC/Makefile | 212 ++++++++++++++++ testhal/STM32F4xx/SDC/chconf.h | 537 +++++++++++++++++++++++++++++++++++++++ testhal/STM32F4xx/SDC/csd.txt | 7 + testhal/STM32F4xx/SDC/halconf.h | 349 +++++++++++++++++++++++++ testhal/STM32F4xx/SDC/main.c | 158 ++++++++++++ testhal/STM32F4xx/SDC/mcuconf.h | 250 ++++++++++++++++++ testhal/STM32F4xx/SDC/readme.txt | 26 ++ 7 files changed, 1539 insertions(+) create mode 100755 testhal/STM32F4xx/SDC/Makefile create mode 100755 testhal/STM32F4xx/SDC/chconf.h create mode 100755 testhal/STM32F4xx/SDC/csd.txt create mode 100755 testhal/STM32F4xx/SDC/halconf.h create mode 100755 testhal/STM32F4xx/SDC/main.c create mode 100755 testhal/STM32F4xx/SDC/mcuconf.h create mode 100755 testhal/STM32F4xx/SDC/readme.txt diff --git a/testhal/STM32F4xx/SDC/Makefile b/testhal/STM32F4xx/SDC/Makefile new file mode 100755 index 000000000..73d23590d --- /dev/null +++ b/testhal/STM32F4xx/SDC/Makefile @@ -0,0 +1,212 @@ +############################################################################## +# Build global options +# NOTE: Can be overridden externally. +# + +# Compiler options here. +ifeq ($(USE_OPT),) + USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 #-mhard-float -mfpu=fpv4-sp-d16 -fsingle-precision-constant +endif + +# C specific options here (added to USE_OPT). +ifeq ($(USE_COPT),) + USE_COPT = +endif + +# C++ specific options here (added to USE_OPT). +ifeq ($(USE_CPPOPT),) + USE_CPPOPT = -fno-rtti +endif + +# Enable this if you want the linker to remove unused code and data +ifeq ($(USE_LINK_GC),) + USE_LINK_GC = yes +endif + +# If enabled, this option allows to compile the application in THUMB mode. +ifeq ($(USE_THUMB),) + USE_THUMB = yes +endif + +# Enable this if you want to see the full log while compiling. +ifeq ($(USE_VERBOSE_COMPILE),) + USE_VERBOSE_COMPILE = no +endif + +# +# Build global options +############################################################################## + +############################################################################## +# Architecture or project specific options +# + +# Enable this if you really want to use the STM FWLib. +ifeq ($(USE_FWLIB),) + USE_FWLIB = no +endif + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, sources and paths +# + +# Define project name here +PROJECT = ch + +# Define linker script file here +LDSCRIPT= ch.ld + +# Imported source files and paths +CHIBIOS = ../../.. +include $(CHIBIOS)/boards/NONSTANDARD_STM32F4_BARTHESS1/board.mk +include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk +include $(CHIBIOS)/os/hal/hal.mk +include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk +include $(CHIBIOS)/os/kernel/kernel.mk +#include $(CHIBIOS)/test/test.mk + +# Define linker script file here +LDSCRIPT= $(PORTLD)/STM32F407xG.ld + +# C sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CSRC = $(PORTSRC) \ + $(KERNSRC) \ + $(TESTSRC) \ + $(HALSRC) \ + $(PLATFORMSRC) \ + $(BOARDSRC) \ + $(CHIBIOS)/os/various/evtimer.c \ + $(CHIBIOS)/os/various/syscalls.c \ + main.c + +# C++ sources that can be compiled in ARM or THUMB mode depending on the global +# setting. +CPPSRC = + +# C sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACSRC = + +# C++ sources to be compiled in ARM mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +ACPPSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCSRC = + +# C sources to be compiled in THUMB mode regardless of the global setting. +# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler +# option that results in lower performance and larger code size. +TCPPSRC = + +# List ASM source files here +ASMSRC = $(PORTASM) + +INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \ + $(HALINC) $(PLATFORMINC) $(BOARDINC) \ + $(CHIBIOS)/os/various + +# +# Project, sources and paths +############################################################################## + +############################################################################## +# Compiler settings +# + +MCU = cortex-m4 + +#TRGT = arm-elf- +TRGT = arm-none-eabi- +CC = $(TRGT)gcc +CPPC = $(TRGT)g++ +# Enable loading with g++ only if you need C++ runtime support. +# NOTE: You can use C++ even without C++ support if you are careful. C++ +# runtime support makes code size explode. +LD = $(TRGT)gcc +#LD = $(TRGT)g++ +CP = $(TRGT)objcopy +AS = $(TRGT)gcc -x assembler-with-cpp +OD = $(TRGT)objdump +HEX = $(CP) -O ihex +BIN = $(CP) -O binary + +# ARM-specific options here +AOPT = + +# THUMB-specific options here +TOPT = -mthumb -DTHUMB + +# Define C warning options here +CWARN = -Wall -Wextra -Wstrict-prototypes + +# Define C++ warning options here +CPPWARN = -Wall -Wextra + +# +# Compiler settings +############################################################################## + +############################################################################## +# Start of default section +# + +# List all default C defines here, like -D_DEBUG=1 +DDEFS = + +# List all default ASM defines here, like -D_DEBUG=1 +DADEFS = + +# List all default directories to look for include files here +DINCDIR = + +# List the default directory to look for the libraries here +DLIBDIR = + +# List all default libraries here +DLIBS = + +# +# End of default section +############################################################################## + +############################################################################## +# Start of user section +# + +# List all user C define here, like -D_DEBUG=1 +UDEFS = + +# Define ASM defines here +UADEFS = + +# List all user directories here +UINCDIR = + +# List the user directory to look for the libraries here +ULIBDIR = + +# List all user libraries here +ULIBS = + +# +# End of user defines +############################################################################## + +ifeq ($(USE_FWLIB),yes) + include $(CHIBIOS)/ext/stm32lib/stm32lib.mk + CSRC += $(STM32SRC) + INCDIR += $(STM32INC) + USE_OPT += -DUSE_STDPERIPH_DRIVER +endif + +include $(CHIBIOS)/os/ports/GCC/ARMCMx/rules.mk diff --git a/testhal/STM32F4xx/SDC/chconf.h b/testhal/STM32F4xx/SDC/chconf.h new file mode 100755 index 000000000..5c06b9607 --- /dev/null +++ b/testhal/STM32F4xx/SDC/chconf.h @@ -0,0 +1,537 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef _CHCONF_H_ +#define _CHCONF_H_ + +#define CORTEX_USE_FPU FALSE + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#if !defined(CH_FREQUENCY) || defined(__DOXYGEN__) +#define CH_FREQUENCY 1000 +#endif + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + */ +#if !defined(CH_TIME_QUANTUM) || defined(__DOXYGEN__) +#define CH_TIME_QUANTUM 20 +#endif + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_USE_MEMCORE. + */ +#if !defined(CH_MEMCORE_SIZE) || defined(__DOXYGEN__) +#define CH_MEMCORE_SIZE 0 +#endif + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread automatically. The application has + * then the responsibility to do one of the following: + * - Spawn a custom idle thread at priority @p IDLEPRIO. + * - Change the main() thread priority to @p IDLEPRIO then enter + * an endless loop. In this scenario the @p main() thread acts as + * the idle thread. + * . + * @note Unless an idle thread is spawned the @p main() thread must not + * enter a sleep state. + */ +#if !defined(CH_NO_IDLE_THREAD) || defined(__DOXYGEN__) +#define CH_NO_IDLE_THREAD FALSE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#if !defined(CH_OPTIMIZE_SPEED) || defined(__DOXYGEN__) +#define CH_OPTIMIZE_SPEED TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_USE_REGISTRY) || defined(__DOXYGEN__) +#define CH_USE_REGISTRY TRUE +#endif + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_USE_WAITEXIT) || defined(__DOXYGEN__) +#define CH_USE_WAITEXIT TRUE +#endif + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_USE_SEMAPHORES) || defined(__DOXYGEN__) +#define CH_USE_SEMAPHORES TRUE +#endif + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special requirements. + * @note Requires @p CH_USE_SEMAPHORES. + */ +#if !defined(CH_USE_SEMAPHORES_PRIORITY) || defined(__DOXYGEN__) +#define CH_USE_SEMAPHORES_PRIORITY FALSE +#endif + +/** + * @brief Atomic semaphore API. + * @details If enabled then the semaphores the @p chSemSignalWait() API + * is included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_USE_SEMAPHORES. + */ +#if !defined(CH_USE_SEMSW) || defined(__DOXYGEN__) +#define CH_USE_SEMSW TRUE +#endif + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_USE_MUTEXES) || defined(__DOXYGEN__) +#define CH_USE_MUTEXES TRUE +#endif + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_USE_MUTEXES. + */ +#if !defined(CH_USE_CONDVARS) || defined(__DOXYGEN__) +#define CH_USE_CONDVARS TRUE +#endif + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_USE_CONDVARS. + */ +#if !defined(CH_USE_CONDVARS_TIMEOUT) || defined(__DOXYGEN__) +#define CH_USE_CONDVARS_TIMEOUT TRUE +#endif + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_USE_EVENTS) || defined(__DOXYGEN__) +#define CH_USE_EVENTS TRUE +#endif + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_USE_EVENTS. + */ +#if !defined(CH_USE_EVENTS_TIMEOUT) || defined(__DOXYGEN__) +#define CH_USE_EVENTS_TIMEOUT TRUE +#endif + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_USE_MESSAGES) || defined(__DOXYGEN__) +#define CH_USE_MESSAGES TRUE +#endif + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special requirements. + * @note Requires @p CH_USE_MESSAGES. + */ +#if !defined(CH_USE_MESSAGES_PRIORITY) || defined(__DOXYGEN__) +#define CH_USE_MESSAGES_PRIORITY FALSE +#endif + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_USE_SEMAPHORES. + */ +#if !defined(CH_USE_MAILBOXES) || defined(__DOXYGEN__) +#define CH_USE_MAILBOXES TRUE +#endif + +/** + * @brief I/O Queues APIs. + * @details If enabled then the I/O queues APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_USE_QUEUES) || defined(__DOXYGEN__) +#define CH_USE_QUEUES TRUE +#endif + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_USE_MEMCORE) || defined(__DOXYGEN__) +#define CH_USE_MEMCORE TRUE +#endif + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_USE_MEMCORE and either @p CH_USE_MUTEXES or + * @p CH_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#if !defined(CH_USE_HEAP) || defined(__DOXYGEN__) +#define CH_USE_HEAP TRUE +#endif + +/** + * @brief C-runtime allocator. + * @details If enabled the the heap allocator APIs just wrap the C-runtime + * @p malloc() and @p free() functions. + * + * @note The default is @p FALSE. + * @note Requires @p CH_USE_HEAP. + * @note The C-runtime may or may not require @p CH_USE_MEMCORE, see the + * appropriate documentation. + */ +#if !defined(CH_USE_MALLOC_HEAP) || defined(__DOXYGEN__) +#define CH_USE_MALLOC_HEAP FALSE +#endif + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#if !defined(CH_USE_MEMPOOLS) || defined(__DOXYGEN__) +#define CH_USE_MEMPOOLS TRUE +#endif + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_USE_WAITEXIT. + * @note Requires @p CH_USE_HEAP and/or @p CH_USE_MEMPOOLS. + */ +#if !defined(CH_USE_DYNAMIC) || defined(__DOXYGEN__) +#define CH_USE_DYNAMIC TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_SYSTEM_STATE_CHECK) || defined(__DOXYGEN__) +#define CH_DBG_SYSTEM_STATE_CHECK TRUE +#endif + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__) +#define CH_DBG_ENABLE_CHECKS TRUE +#endif + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__) +#define CH_DBG_ENABLE_ASSERTS TRUE +#endif + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the context switch circular trace buffer is + * activated. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_ENABLE_TRACE) || defined(__DOXYGEN__) +#define CH_DBG_ENABLE_TRACE TRUE +#endif + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#if !defined(CH_DBG_ENABLE_STACK_CHECK) || defined(__DOXYGEN__) +#define CH_DBG_ENABLE_STACK_CHECK TRUE +#endif + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#if !defined(CH_DBG_FILL_THREADS) || defined(__DOXYGEN__) +#define CH_DBG_FILL_THREADS TRUE +#endif + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p Thread structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p TRUE. + * @note This debug option is defaulted to TRUE because it is required by + * some test cases into the test suite. + */ +#if !defined(CH_DBG_THREADS_PROFILING) || defined(__DOXYGEN__) +#define CH_DBG_THREADS_PROFILING TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p Thread structure. + */ +#if !defined(THREAD_EXT_FIELDS) || defined(__DOXYGEN__) +#define THREAD_EXT_FIELDS \ + /* Add threads custom fields here.*/ +#endif + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p chThdInit() API. + * + * @note It is invoked from within @p chThdInit() and implicitily from all + * the threads creation APIs. + */ +#if !defined(THREAD_EXT_INIT_HOOK) || defined(__DOXYGEN__) +#define THREAD_EXT_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} +#endif + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + * + * @note It is inserted into lock zone. + * @note It is also invoked when the threads simply return in order to + * terminate. + */ +#if !defined(THREAD_EXT_EXIT_HOOK) || defined(__DOXYGEN__) +#define THREAD_EXT_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} +#endif + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + */ +#if !defined(THREAD_CONTEXT_SWITCH_HOOK) || defined(__DOXYGEN__) +#define THREAD_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* System halt code here.*/ \ +} +#endif + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#if !defined(IDLE_LOOP_HOOK) || defined(__DOXYGEN__) +#define IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} +#endif + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#if !defined(SYSTEM_TICK_EVENT_HOOK) || defined(__DOXYGEN__) +#define SYSTEM_TICK_EVENT_HOOK() { \ + /* System tick event code here.*/ \ +} +#endif + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#if !defined(SYSTEM_HALT_HOOK) || defined(__DOXYGEN__) +#define SYSTEM_HALT_HOOK() { \ + /* System halt code here.*/ \ +} +#endif + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* _CHCONF_H_ */ + +/** @} */ diff --git a/testhal/STM32F4xx/SDC/csd.txt b/testhal/STM32F4xx/SDC/csd.txt new file mode 100755 index 000000000..eefe5274c --- /dev/null +++ b/testhal/STM32F4xx/SDC/csd.txt @@ -0,0 +1,7 @@ +127 ... ... 0 + +00000000 00101110 00000000 00110010 - 01011011 01011010 10100011 10100000 - 11111111111111111111111110000000 - 00001010100000000000000010001110 kingmax 2 GB +00000000 00101110 00000000 00110010 - 01011011 01011010 10000011 10101001 - 11111111111111111111111110000000 - 00010110100000000000000010010000 kingstone 2 GB +01000000 00001110 00000000 00110010 - 01011011 01011001 00000000 00000000 - 00111011010010110111111110000000 - 00001010010000000100000001000000 samsung sdhc 8 GB +00000000 00100110 00000000 00110010 - 01011111 01011010 10000011 10101110 - 11111110111110111100111111111111 - 10010010100000000100000011011110 noname 2 GB + diff --git a/testhal/STM32F4xx/SDC/halconf.h b/testhal/STM32F4xx/SDC/halconf.h new file mode 100755 index 000000000..07fd86631 --- /dev/null +++ b/testhal/STM32F4xx/SDC/halconf.h @@ -0,0 +1,349 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef _HALCONF_H_ +#define _HALCONF_H_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the EXT subsystem. + */ +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) +#define HAL_USE_EXT FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C TRUE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC TRUE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL FALSE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Block size for MMC transfers. + */ +#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__) +#define MMC_SECTOR_SIZE 512 +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif + +/** + * @brief Number of positive insertion queries before generating the + * insertion event. + */ +#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__) +#define MMC_POLLING_INTERVAL 10 +#endif + +/** + * @brief Interval, in milliseconds, between insertion queries. + */ +#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__) +#define MMC_POLLING_DELAY 10 +#endif + +/** + * @brief Uses the SPI polled API for small data transfers. + * @details Polled transfers usually improve performance because it + * saves two context switches and interrupt servicing. Note + * that this option has no effect on large transfers which + * are always performed using DMAs/IRQs. + */ +#if !defined(MMC_USE_SPI_POLLING) || defined(__DOXYGEN__) +#define MMC_USE_SPI_POLLING TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intevals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/** + * @brief Write timeout in milliseconds. + */ +#if !defined(SDC_WRITE_TIMEOUT_MS) || defined(__DOXYGEN__) +#define SDC_WRITE_TIMEOUT_MS 250 +#endif + +/** + * @brief Write timeout in milliseconds. + */ +#if !defined(SDC_READ_TIMEOUT_MS) || defined(__DOXYGEN__) +#define SDC_READ_TIMEOUT_MS 5 +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 64 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +#endif /* _HALCONF_H_ */ + +/** @} */ diff --git a/testhal/STM32F4xx/SDC/main.c b/testhal/STM32F4xx/SDC/main.c new file mode 100755 index 000000000..2e1ab4bc4 --- /dev/null +++ b/testhal/STM32F4xx/SDC/main.c @@ -0,0 +1,158 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include "ch.h" +#include "hal.h" + + +#define SDC_DATA_DESTRUCTIVE_TEST FALSE + +#define SDC_BURST_SIZE 8 +static uint8_t outbuf[SDC_BLOCK_SIZE * SDC_BURST_SIZE + 1]; +static uint8_t inbuf[SDC_BLOCK_SIZE * SDC_BURST_SIZE + 1]; + + +/** + * @brief Clone of UNIX badblocks program. + * + * @param[in] start first block to check + * @param[in] end last block to check + * @param[in] blockatonce number of blocks to check at once + * @param[in] pattern check pattern + * + * @return The operation status. + * @retval FALSE operation succeeded, the requested blocks have been + * read. + * @retval TRUE operation failed, the state of the buffer is uncertain. + */ +bool_t badblocks(uint32_t start, uint32_t end, uint32_t blockatonce, uint8_t pattern){ + uint32_t position = 0; + uint32_t i = 0; + + chDbgCheck(blockatonce <= SDC_BURST_SIZE, "badblocks"); + + /* fill control buffer */ + for (i=0; i < SDC_BLOCK_SIZE * blockatonce; i++) + outbuf[i] = pattern; + + /* fill SD card with pattern. */ + position = start; + while (position < end){ + if (sdcWrite(&SDCD1, position, outbuf, blockatonce)) + goto ERROR; + position += blockatonce; + } + + /* read and compare. */ + position = start; + while (position < end){ + if (sdcRead(&SDCD1, position, inbuf, blockatonce)) + goto ERROR; + if (memcmp(inbuf, outbuf, blockatonce * SDC_BLOCK_SIZE) != 0) + goto ERROR; + position += blockatonce; + } + return SDC_SUCCESS; + +ERROR: + return SDC_FAILED; +} + +void clearbuffers(void){ + uint32_t i = 0; + for (i=0; i < SDC_BLOCK_SIZE * SDC_BURST_SIZE; i++) + outbuf[i] = 0x55; + for (i=0; i < SDC_BLOCK_SIZE * SDC_BURST_SIZE; i++) + inbuf[i] = 0x55; +} + +/* + * SDIO configuration. + */ +static const SDCConfig sdccfg = { + 0 +}; + +/* + * Application entry point. + */ +int main(void) { + uint32_t i = 0; + + /* + * System initializations. + * - HAL initialization, this also initializes the configured device drivers + * and performs the board-specific initializations. + * - Kernel initialization, the main() function becomes a thread and the + * RTOS is active. + */ + halInit(); + chSysInit(); + + /* + * Initializes the SDIO drivers. + */ + sdcStart(&SDCD1, &sdccfg); + /*http://en.wikipedia.org/wiki/Secure_Digital#Storage_capacity_calculations*/ + + if (!sdcConnect(&SDCD1)) { + + /* Single aligned read.*/ + + /* Multiple aligned read from one place.*/ + clearbuffers(); + if (sdcRead(&SDCD1, 0, inbuf, SDC_BURST_SIZE)) + chSysHalt(); + for (i=0; i<1000; i++){ + if (sdcRead(&SDCD1, 0, outbuf, SDC_BURST_SIZE)) + chSysHalt(); + if (memcmp(inbuf, outbuf, SDC_BURST_SIZE * SDC_BLOCK_SIZE) != 0) + chSysHalt(); + } + + /* Repeated multiple aligned reads.*/ + + /* Repeated multiple unaligned reads.*/ + + +#if SDC_DATA_DESTRUCTIVE_TEST + clearbuffers(); + if (sdcWrite(&SDCD1, 0x10000, outbuf, SDC_BURST_SIZE)) + chSysHalt(); + +// if(badblocks(0x10000, 0x11000, SDC_BURST_SIZE, 0xAA)) +// chSysHalt(); +#endif /* !SDC_DATA_DESTRUCTIVE_TEST */ + + if (sdcDisconnect(&SDCD1)) + chSysHalt(); + } + else{ + chSysHalt(); + } + /* + * Normal main() thread activity. + */ + while (TRUE) { + palTogglePad(GPIOB, GPIOB_LED_R); + chThdSleepMilliseconds(500); + } +} diff --git a/testhal/STM32F4xx/SDC/mcuconf.h b/testhal/STM32F4xx/SDC/mcuconf.h new file mode 100755 index 000000000..faf2e0d35 --- /dev/null +++ b/testhal/STM32F4xx/SDC/mcuconf.h @@ -0,0 +1,250 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * STM32F4xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_HSI_ENABLED TRUE +#define STM32_LSI_ENABLED FALSE +#define STM32_HSE_ENABLED TRUE +#define STM32_LSE_ENABLED TRUE +#define STM32_CLOCK48_REQUIRED TRUE +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSE +#define STM32_PLLM_VALUE 8 +#define STM32_PLLN_VALUE 336 +#define STM32_PLLP_VALUE 2 +#define STM32_PLLQ_VALUE 7 +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_PPRE1 STM32_PPRE1_DIV4 +#define STM32_PPRE2 STM32_PPRE2_DIV2 +#define STM32_RTCSEL STM32_RTCSEL_LSE +#define STM32_RTCPRE_VALUE 8 +#define STM32_MCO1SEL STM32_MCO1SEL_HSI +#define STM32_MCO1PRE STM32_MCO1PRE_DIV1 +#define STM32_MCO2SEL STM32_MCO2SEL_SYSCLK +#define STM32_MCO2PRE STM32_MCO2PRE_DIV5 +#define STM32_I2SSRC STM32_I2CSRC_CKIN +#define STM32_PLLI2SN_VALUE 192 +#define STM32_PLLI2SR_VALUE 5 +#define STM32_RTC STM32_RTC_LSE +#define STM32_VOS STM32_VOS_HIGH +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 + +/* + * ADC driver system settings. + */ +#define STM32_ADC_ADCPRE ADC_CCR_ADCPRE_DIV2 +#define STM32_ADC_USE_ADC1 TRUE +#define STM32_ADC_USE_ADC2 TRUE +#define STM32_ADC_USE_ADC3 TRUE +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_ADC_ADC2_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_ADC_ADC3_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_ADC2_DMA_PRIORITY 2 +#define STM32_ADC_ADC3_DMA_PRIORITY 2 +#define STM32_ADC_IRQ_PRIORITY 5 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC2_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC3_DMA_IRQ_PRIORITY 5 + +/* + * CAN driver system settings. + */ +#define STM32_CAN_USE_CAN1 FLASE +#define STM32_CAN_CAN1_IRQ_PRIORITY 11 + +/* + * EXT driver system settings. + */ +#define STM32_EXT_EXTI0_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI1_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI2_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI3_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI4_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI16_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI17_IRQ_PRIORITY 15 // RTC alarm +#define STM32_EXT_EXTI18_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI19_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI20_IRQ_PRIORITY 6 +#define STM32_EXT_EXTI21_IRQ_PRIORITY 15 // RTC tamper-timestamp +#define STM32_EXT_EXTI22_IRQ_PRIORITY 15 // RTC wakeup + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM3 FALSE +#define STM32_GPT_USE_TIM4 FALSE +#define STM32_GPT_USE_TIM5 FALSE +#define STM32_GPT_USE_TIM8 FALSE +#define STM32_GPT_USE_TIM9 FALSE +#define STM32_GPT_USE_TIM10 FALSE +#define STM32_GPT_USE_TIM11 FALSE +#define STM32_GPT_USE_TIM12 FALSE +#define STM32_GPT_USE_TIM12 FALSE +#define STM32_GPT_USE_TIM14 FALSE + +#define STM32_GPT_TIM1_IRQ_PRIORITY 7 +#define STM32_GPT_TIM2_IRQ_PRIORITY 7 +#define STM32_GPT_TIM3_IRQ_PRIORITY 7 +#define STM32_GPT_TIM4_IRQ_PRIORITY 7 +#define STM32_GPT_TIM5_IRQ_PRIORITY 7 +#define STM32_GPT_TIM8_IRQ_PRIORITY 7 + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM1 FALSE +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM3 FALSE +#define STM32_ICU_USE_TIM4 FALSE +#define STM32_ICU_USE_TIM5 FALSE +#define STM32_ICU_USE_TIM8 FALSE +#define STM32_ICU_TIM1_IRQ_PRIORITY 7 +#define STM32_ICU_TIM2_IRQ_PRIORITY 7 +#define STM32_ICU_TIM3_IRQ_PRIORITY 7 +#define STM32_ICU_TIM4_IRQ_PRIORITY 7 +#define STM32_ICU_TIM5_IRQ_PRIORITY 7 +#define STM32_ICU_TIM8_IRQ_PRIORITY 7 + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_ADVANCED FALSE +#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM3 TRUE +#define STM32_PWM_USE_TIM4 TRUE +#define STM32_PWM_USE_TIM5 FALSE +#define STM32_PWM_USE_TIM8 FLASE +#define STM32_PWM_TIM1_IRQ_PRIORITY 7 +#define STM32_PWM_TIM2_IRQ_PRIORITY 7 +#define STM32_PWM_TIM3_IRQ_PRIORITY 7 +#define STM32_PWM_TIM4_IRQ_PRIORITY 7 +#define STM32_PWM_TIM5_IRQ_PRIORITY 7 +#define STM32_PWM_TIM8_IRQ_PRIORITY 7 + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 TRUE +#define STM32_SERIAL_USE_USART2 TRUE +#define STM32_SERIAL_USE_USART3 FALSE +#define STM32_SERIAL_USE_UART4 FALSE +#define STM32_SERIAL_USE_UART5 FALSE +#define STM32_SERIAL_USE_USART6 FALSE +#define STM32_SERIAL_USART1_PRIORITY 12 +#define STM32_SERIAL_USART2_PRIORITY 12 +#define STM32_SERIAL_USART3_PRIORITY 12 +#define STM32_SERIAL_UART4_PRIORITY 12 +#define STM32_SERIAL_UART5_PRIORITY 12 +#define STM32_SERIAL_USART6_PRIORITY 12 + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI2 FLASE +#define STM32_SPI_USE_SPI3 FLASE +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_SPI_SPI2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI2_DMA_PRIORITY 1 +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI2_IRQ_PRIORITY 10 +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) chSysHalt() + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USE_USART3 FALSE +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#define STM32_UART_USART3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_UART_USART1_IRQ_PRIORITY 12 +#define STM32_UART_USART2_IRQ_PRIORITY 12 +#define STM32_UART_USART3_IRQ_PRIORITY 12 +#define STM32_UART_USART1_DMA_PRIORITY 0 +#define STM32_UART_USART2_DMA_PRIORITY 0 +#define STM32_UART_USART3_DMA_PRIORITY 0 +#define STM32_UART_DMA_ERROR_HOOK(uartp) chSysHalt() + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C2 TRUE +#define STM32_I2C_USE_I2C3 FALSE +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#define STM32_I2C_I2C1_IRQ_PRIORITY 6 +#define STM32_I2C_I2C2_IRQ_PRIORITY 6 +#define STM32_I2C_I2C3_IRQ_PRIORITY 6 +#define STM32_I2C_I2C1_DMA_PRIORITY 1 +#define STM32_I2C_I2C2_DMA_PRIORITY 1 +#define STM32_I2C_I2C3_DMA_PRIORITY 1 +#define STM32_I2C_I2C1_DMA_ERROR_HOOK() chSysHalt() +#define STM32_I2C_I2C2_DMA_ERROR_HOOK() chSysHalt() +#define STM32_I2C_I2C3_DMA_ERROR_HOOK() chSysHalt() + +/* + * SDC driver system settings. + */ +#define STM32_SDC_SDIO_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SDC_SDIO_DMA_PRIORITY 3 +#define STM32_SDC_SDIO_IRQ_PRIORITY 9 +#define STM32_SDC_SDIO_UNALIGNED_SUPPORT TRUE + diff --git a/testhal/STM32F4xx/SDC/readme.txt b/testhal/STM32F4xx/SDC/readme.txt new file mode 100755 index 000000000..66a260e7a --- /dev/null +++ b/testhal/STM32F4xx/SDC/readme.txt @@ -0,0 +1,26 @@ +***************************************************************************** +** ChibiOS/RT HAL - SDC driver demo for STM32. ** +***************************************************************************** + +** TARGET ** + +The demo runs on an Olimex ST_STM3210E_EVAL board. + +** The Demo ** + +The application demonstrates the use of the STM32 SDC driver. + +** Build Procedure ** + +The demo has been tested using the free Codesourcery GCC-based toolchain +and YAGARTO. +Just modify the TRGT line in the makefile in order to use different GCC ports. + +** Notes ** + +Some files used by the demo are not part of ChibiOS/RT but are copyright of +ST Microelectronics and are licensed under a different license. +Also note that not all the files present in the ST library are distribited +with ChibiOS/RT, you can find the whole library on the ST web site: + + http://www.st.com -- cgit v1.2.3 From 41895e5c3682637c17e42f3d78c195266721e6dd Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 6 Mar 2012 21:27:13 +0000 Subject: SDC. Some additions in testhal. Not tested at all. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4029 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- testhal/STM32F4xx/SDC/main.c | 101 ++++++++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 25 deletions(-) diff --git a/testhal/STM32F4xx/SDC/main.c b/testhal/STM32F4xx/SDC/main.c index 2e1ab4bc4..28bfdfca5 100755 --- a/testhal/STM32F4xx/SDC/main.c +++ b/testhal/STM32F4xx/SDC/main.c @@ -23,15 +23,15 @@ #include "hal.h" -#define SDC_DATA_DESTRUCTIVE_TEST FALSE +#define SDC_DATA_DESTRUCTIVE_TEST TRUE -#define SDC_BURST_SIZE 8 +#define SDC_BURST_SIZE 8 /* how many sectors reads at once */ static uint8_t outbuf[SDC_BLOCK_SIZE * SDC_BURST_SIZE + 1]; static uint8_t inbuf[SDC_BLOCK_SIZE * SDC_BURST_SIZE + 1]; /** - * @brief Clone of UNIX badblocks program. + * @brief Parody of UNIX badblocks program. * * @param[in] start first block to check * @param[in] end last block to check @@ -39,9 +39,9 @@ static uint8_t inbuf[SDC_BLOCK_SIZE * SDC_BURST_SIZE + 1]; * @param[in] pattern check pattern * * @return The operation status. - * @retval FALSE operation succeeded, the requested blocks have been + * @retval SDC_SUCCESS operation succeeded, the requested blocks have been * read. - * @retval TRUE operation failed, the state of the buffer is uncertain. + * @retval SDC_FAILED operation failed, the state of the buffer is uncertain. */ bool_t badblocks(uint32_t start, uint32_t end, uint32_t blockatonce, uint8_t pattern){ uint32_t position = 0; @@ -76,12 +76,21 @@ ERROR: return SDC_FAILED; } -void clearbuffers(void){ +/** + * + */ +void fillbuffer(uint8_t pattern, uint8_t *b){ uint32_t i = 0; for (i=0; i < SDC_BLOCK_SIZE * SDC_BURST_SIZE; i++) - outbuf[i] = 0x55; - for (i=0; i < SDC_BLOCK_SIZE * SDC_BURST_SIZE; i++) - inbuf[i] = 0x55; + b[i] = pattern; +} + +/** + * + */ +void fillbuffers(uint8_t pattern){ + fillbuffer(pattern, inbuf); + fillbuffer(pattern, outbuf); } /* @@ -97,13 +106,6 @@ static const SDCConfig sdccfg = { int main(void) { uint32_t i = 0; - /* - * System initializations. - * - HAL initialization, this also initializes the configured device drivers - * and performs the board-specific initializations. - * - Kernel initialization, the main() function becomes a thread and the - * RTOS is active. - */ halInit(); chSysInit(); @@ -111,14 +113,24 @@ int main(void) { * Initializes the SDIO drivers. */ sdcStart(&SDCD1, &sdccfg); - /*http://en.wikipedia.org/wiki/Secure_Digital#Storage_capacity_calculations*/ if (!sdcConnect(&SDCD1)) { /* Single aligned read.*/ + if (sdcRead(&SDCD1, 0, inbuf, 1)) + chSysHalt(); + + /* Single unaligned read.*/ + if (sdcRead(&SDCD1, 0, inbuf + 1, 1)) + chSysHalt(); + if (sdcRead(&SDCD1, 0, inbuf + 2, 1)) + chSysHalt(); + if (sdcRead(&SDCD1, 0, inbuf + 3, 1)) + chSysHalt(); - /* Multiple aligned read from one place.*/ - clearbuffers(); + /* Multiple aligned reads from one place to ensure in bus stability */ + fillbuffers(0x55); + /* fill reference buffer from SD card */ if (sdcRead(&SDCD1, 0, inbuf, SDC_BURST_SIZE)) chSysHalt(); for (i=0; i<1000; i++){ @@ -128,28 +140,67 @@ int main(void) { chSysHalt(); } - /* Repeated multiple aligned reads.*/ - /* Repeated multiple unaligned reads.*/ + fillbuffers(0x55); + /* fill reference buffer from SD card */ + if (sdcRead(&SDCD1, 0, inbuf + 1, SDC_BURST_SIZE)) + chSysHalt(); + for (i=0; i<1000; i++){ + if (sdcRead(&SDCD1, 0, outbuf + 1, SDC_BURST_SIZE)) + chSysHalt(); + if (memcmp(inbuf, outbuf, SDC_BURST_SIZE * SDC_BLOCK_SIZE) != 0) + chSysHalt(); + } + + + + + #if SDC_DATA_DESTRUCTIVE_TEST - clearbuffers(); - if (sdcWrite(&SDCD1, 0x10000, outbuf, SDC_BURST_SIZE)) + + /* Single aligned write.*/ + fillbuffer(0xAA, inbuf); + if (sdcWrite(&SDCD1, 0, inbuf, 1)) + chSysHalt(); + fillbuffer(0, outbuf); + if (sdcRead(&SDCD1, 0, outbuf, 1)) + chSysHalt(); + if (memcmp(inbuf, outbuf, SDC_BLOCK_SIZE) != 0) + chSysHalt(); + + /* Single unaligned write.*/ + fillbuffer(0xFF, inbuf); + if (sdcWrite(&SDCD1, 0, inbuf+1, 1)) chSysHalt(); + fillbuffer(0, outbuf); + if (sdcRead(&SDCD1, 0, outbuf+1, 1)) + chSysHalt(); + if (memcmp(inbuf+1, outbuf+1, SDC_BLOCK_SIZE) != 0) + chSysHalt(); + -// if(badblocks(0x10000, 0x11000, SDC_BURST_SIZE, 0xAA)) -// chSysHalt(); + if(badblocks(0x10000, 0x11000, SDC_BURST_SIZE, 0xAA)) + chSysHalt(); #endif /* !SDC_DATA_DESTRUCTIVE_TEST */ + + + + + + if (sdcDisconnect(&SDCD1)) chSysHalt(); } else{ chSysHalt(); } + /* * Normal main() thread activity. + * Blinking signaling about successful passing. */ while (TRUE) { palTogglePad(GPIOB, GPIOB_LED_R); -- cgit v1.2.3 From 2b35b5a2a5a9484332edebaca861a87910cf6715 Mon Sep 17 00:00:00 2001 From: barthess Date: Thu, 8 Mar 2012 19:52:44 +0000 Subject: SDC. Added RTC support. Improved testhal. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4031 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- ext/fatfs-0.8b-patched.zip | Bin 668144 -> 845970 bytes os/hal/include/rtc.h | 1 + os/hal/platforms/STM32/RTCv1/rtc_lld.c | 24 +++ os/hal/platforms/STM32/RTCv1/rtc_lld.h | 1 + os/hal/platforms/STM32/RTCv2/rtc_lld.c | 23 +++ os/hal/platforms/STM32/RTCv2/rtc_lld.h | 1 + os/hal/platforms/STM32/sdc_lld.c | 12 +- os/hal/platforms/STM32F1xx/hal_lld.h | 14 ++ os/hal/platforms/STM32F1xx/hal_lld_f100.h | 3 - os/hal/platforms/STM32F1xx/hal_lld_f103.h | 4 - os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h | 4 - os/hal/platforms/STM32F2xx/hal_lld.h | 1 + os/hal/platforms/STM32F4xx/hal_lld.h | 1 + os/hal/platforms/STM32L1xx/hal_lld.h | 1 + os/hal/src/rtc.c | 20 +++ testhal/STM32F4xx/SDC/Makefile | 5 + testhal/STM32F4xx/SDC/chconf.h | 3 +- testhal/STM32F4xx/SDC/halconf.h | 4 +- testhal/STM32F4xx/SDC/main.c | 207 +++++++++++++++++++++---- 19 files changed, 279 insertions(+), 50 deletions(-) diff --git a/ext/fatfs-0.8b-patched.zip b/ext/fatfs-0.8b-patched.zip index 55de3fe64..ff7548985 100644 Binary files a/ext/fatfs-0.8b-patched.zip and b/ext/fatfs-0.8b-patched.zip differ diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index 9b5cba848..3acce33e4 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -151,6 +151,7 @@ extern "C" { void rtcInit(void); void rtcSetTime(RTCDriver *rtcp, const RTCTime *timespec); void rtcGetTime(RTCDriver *rtcp, RTCTime *timespec); + uint32_t rtcGetFatTime(RTCDriver *rtcp); #if RTC_ALARMS > 0 void rtcSetAlarm(RTCDriver *rtcp, rtcalarm_t alarm, diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c index 066e0f659..6496cfae9 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -30,6 +30,8 @@ * @{ */ +#include + #include "ch.h" #include "hal.h" @@ -290,6 +292,28 @@ void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { } } +/** + * @brief Get current time in format suitable for usage in FatFS. + * + * @param[in] timespec pointer to RTCTime structure + * @return FAT time value. + * + * @api + */ +uint32_t rtc_lld_calc_fat_time(RTCTime *timespec){ + uint32_t fattime = 0; + struct tm *timp; + + timp = localtime((time_t *)(timespec->tv_sec)); + + fattime |= (timp->tm_sec / 2); + fattime |= (timp->tm_min) << 5; + fattime |= (timp->tm_hour) << 11; + fattime |= (timp->tm_mday) << 16; + fattime |= (timp->tm_mon + 1) << 21; + fattime |= (timp->tm_year - 80) << 25; + return fattime; +} #endif /* HAL_USE_RTC */ /** @} */ diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h index 4944ff735..64287d978 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -178,6 +178,7 @@ extern "C" { rtcalarm_t alarm, RTCAlarm *alarmspec); void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); + uint32_t rtc_lld_calc_fat_time(RTCTime *timespec); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/RTCv2/rtc_lld.c b/os/hal/platforms/STM32/RTCv2/rtc_lld.c index cae3f812b..c2268fd82 100644 --- a/os/hal/platforms/STM32/RTCv2/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv2/rtc_lld.c @@ -264,6 +264,29 @@ void rtcGetPeriodicWakeup_v2(RTCDriver *rtcp, RTCWakeup *wakeupspec){ wakeupspec->wakeup |= (((uint32_t)rtcp->id_rtc->CR) & 0x7) << 16; } +/** + * @brief Get current time in format suitable for usage in FatFS. + * + * @param[in] timespec pointer to RTCTime structure + * @return FAT time value. + * + * @api + */ +uint32_t rtc_lld_calc_fat_time(RTCTime *timespec){ + uint32_t fattime = 0; + struct tm timp; + + stm32_rtc_bcd2tm(&timp, timespec); + + fattime |= (timp.tm_sec / 2); + fattime |= (timp.tm_min) << 5; + fattime |= (timp.tm_hour) << 11; + fattime |= (timp.tm_mday) << 16; + fattime |= (timp.tm_mon + 1) << 21; + fattime |= (timp.tm_year - 80) << 25; + return fattime; +} + /** * @brief Converts from STM32 BCD to canonicalized time format. * diff --git a/os/hal/platforms/STM32/RTCv2/rtc_lld.h b/os/hal/platforms/STM32/RTCv2/rtc_lld.h index 3f0139f00..88959294c 100644 --- a/os/hal/platforms/STM32/RTCv2/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv2/rtc_lld.h @@ -200,6 +200,7 @@ extern "C" { RTCAlarm *alarmspec); void rtcSetPeriodicWakeup_v2(RTCDriver *rtcp, RTCWakeup *wakeupspec); void rtcGetPeriodicWakeup_v2(RTCDriver *rtcp, RTCWakeup *wakeupspec); + uint32_t rtc_lld_calc_fat_time(RTCTime *timespec); void stm32_rtc_bcd2tm(struct tm *timp, RTCTime *timespec); void stm32_rtc_tm2bcd(struct tm *timp, RTCTime *timespec); #ifdef __cplusplus diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c index f74d06c9e..c42867ffe 100644 --- a/os/hal/platforms/STM32/sdc_lld.c +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -56,7 +56,7 @@ SDCDriver SDCD1; /* Driver local variables. */ /*===========================================================================*/ -#if STM32_SDC_UNALIGNED_SUPPORT +#if STM32_SDC_SDIO_UNALIGNED_SUPPORT /** * @brief Buffer for temporary storage during unaligned transfers. */ @@ -64,7 +64,7 @@ static union { uint32_t alignment; uint8_t buf[SDC_BLOCK_SIZE]; } u; -#endif +#endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */ /*===========================================================================*/ /* Driver local functions. */ @@ -706,7 +706,7 @@ error: bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, uint8_t *buf, uint32_t n) { -#if STM32_SDC_UNALIGNED_SUPPORT +#if STM32_SDC_SDIO_UNALIGNED_SUPPORT if (((unsigned)buf & 3) != 0) { uint32_t i; for (i = 0; i < n; i++) { @@ -718,7 +718,7 @@ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, } return SDC_SUCCESS; } -#endif +#endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */ return sdc_lld_read_aligned(sdcp, startblk, buf, n); } @@ -739,7 +739,7 @@ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buf, uint32_t n) { - #if STM32_SDC_UNALIGNED_SUPPORT +#if STM32_SDC_SDIO_UNALIGNED_SUPPORT if (((unsigned)buf & 3) != 0) { uint32_t i; for (i = 0; i < n; i++) { @@ -751,7 +751,7 @@ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, } return SDC_SUCCESS; } -#endif +#endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */ return sdc_lld_write_aligned(sdcp, startblk, buf, n); } diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index c79769e80..4a375ab4e 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -77,6 +77,20 @@ #define STM32_PLS_LEV7 (7 << 5) /**< PVD level 7. */ /** @} */ +/*===========================================================================*/ +/* Platform capabilities. */ +/*===========================================================================*/ + +/** + * @name STM32F1xx capabilities + * @{ + */ +/* RTC attributes.*/ +#define STM32_HAS_RTC TRUE +#define STM32_RTC_HAS_SUBSECONDS TRUE +#define STM32_RTC_IS_CALENDAR TRUE +/** @} */ + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f100.h b/os/hal/platforms/STM32F1xx/hal_lld_f100.h index 509b20054..25dd3a186 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f100.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f100.h @@ -239,9 +239,6 @@ #define STM32_SPI3_TX_DMA_MSK 0 #define STM32_SPI3_TX_DMA_CHN 0x00000000 -#define STM32_HAS_RTC TRUE -#define STM32_RTCSEL_HAS_SUBSECONDS TRUE - /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f103.h b/os/hal/platforms/STM32F1xx/hal_lld_f103.h index 7bcbb3043..deda9f67a 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f103.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f103.h @@ -249,10 +249,6 @@ #define STM32_SPI3_TX_DMA_MSK 0 #define STM32_SPI3_TX_DMA_CHN 0x00000000 -/* RTC attributes.*/ -#define STM32_HAS_RTC TRUE -#define STM32_RTCSEL_HAS_SUBSECONDS TRUE - /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE diff --git a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h index 88193fa8a..57b47f003 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h +++ b/os/hal/platforms/STM32F1xx/hal_lld_f105_f107.h @@ -266,10 +266,6 @@ #define STM32_I2C3_TX_DMA_MSK 0 #define STM32_I2C3_TX_DMA_CHN 0x00000000 -/* RTC attributes.*/ -#define STM32_HAS_RTC TRUE -#define STM32_RTCSEL_HAS_SUBSECONDS TRUE - /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE diff --git a/os/hal/platforms/STM32F2xx/hal_lld.h b/os/hal/platforms/STM32F2xx/hal_lld.h index ae60b7806..165a10448 100644 --- a/os/hal/platforms/STM32F2xx/hal_lld.h +++ b/os/hal/platforms/STM32F2xx/hal_lld.h @@ -337,6 +337,7 @@ /* RTC attributes.*/ #define STM32_HAS_RTC TRUE #define STM32_RTC_HAS_SUBSECONDS TRUE +#define STM32_RTC_IS_CALENDAR TRUE /* SDIO attributes.*/ #define STM32_HAS_SDIO TRUE diff --git a/os/hal/platforms/STM32F4xx/hal_lld.h b/os/hal/platforms/STM32F4xx/hal_lld.h index a058e848a..3585379e4 100644 --- a/os/hal/platforms/STM32F4xx/hal_lld.h +++ b/os/hal/platforms/STM32F4xx/hal_lld.h @@ -336,6 +336,7 @@ /* RTC attributes.*/ #define STM32_HAS_RTC TRUE #define STM32_RTC_HAS_SUBSECONDS TRUE +#define STM32_RTC_IS_CALENDAR TRUE /* SDIO attributes.*/ #define STM32_HAS_SDIO TRUE diff --git a/os/hal/platforms/STM32L1xx/hal_lld.h b/os/hal/platforms/STM32L1xx/hal_lld.h index 9f47c4da5..f7402dfe6 100644 --- a/os/hal/platforms/STM32L1xx/hal_lld.h +++ b/os/hal/platforms/STM32L1xx/hal_lld.h @@ -233,6 +233,7 @@ /* RTC attributes.*/ #define STM32_HAS_RTC TRUE #define STM32_RTC_HAS_SUBSECONDS FALSE +#define STM32_RTC_IS_CALENDAR TRUE /* SDIO attributes.*/ #define STM32_HAS_SDIO FALSE diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index 01f88e82d..a6601fd1c 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -101,6 +101,26 @@ void rtcGetTime(RTCDriver *rtcp, RTCTime *timespec) { chSysUnlock(); } +/** + * @brief Get current time in format suitable for usage in FatFS. + * + * @param[in] rtcp pointer to RTC driver structure + * @return FAT time value. + * + * @api + */ +uint32_t rtcGetFatTime(RTCDriver *rtcp) { + RTCTime timespec; + + chDbgCheck((rtcp != NULL), "rtcGetTime"); + + chSysLock(); + rtcGetTimeI(rtcp, ×pec); + chSysUnlock(); + + return rtc_lld_calc_fat_time(×pec); +} + #if (RTC_ALARMS > 0) || defined(__DOXYGEN__) /** * @brief Set alarm time. diff --git a/testhal/STM32F4xx/SDC/Makefile b/testhal/STM32F4xx/SDC/Makefile index 73d23590d..ed147a37e 100755 --- a/testhal/STM32F4xx/SDC/Makefile +++ b/testhal/STM32F4xx/SDC/Makefile @@ -67,6 +67,7 @@ include $(CHIBIOS)/os/hal/platforms/STM32F4xx/platform.mk include $(CHIBIOS)/os/hal/hal.mk include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F4xx/port.mk include $(CHIBIOS)/os/kernel/kernel.mk +include $(CHIBIOS)/ext/fatfs/fatfs.mk #include $(CHIBIOS)/test/test.mk # Define linker script file here @@ -80,8 +81,11 @@ CSRC = $(PORTSRC) \ $(HALSRC) \ $(PLATFORMSRC) \ $(BOARDSRC) \ + $(FATFSSRC) \ $(CHIBIOS)/os/various/evtimer.c \ $(CHIBIOS)/os/various/syscalls.c \ + $(CHIBIOS)/os/various/shell.c \ + $(CHIBIOS)/os/various/chprintf.c \ main.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global @@ -113,6 +117,7 @@ ASMSRC = $(PORTASM) INCDIR = $(PORTINC) $(KERNINC) $(TESTINC) \ $(HALINC) $(PLATFORMINC) $(BOARDINC) \ + $(CHIBIOS)/os/various $(FATFSINC) \ $(CHIBIOS)/os/various # diff --git a/testhal/STM32F4xx/SDC/chconf.h b/testhal/STM32F4xx/SDC/chconf.h index 5c06b9607..eb6d391da 100755 --- a/testhal/STM32F4xx/SDC/chconf.h +++ b/testhal/STM32F4xx/SDC/chconf.h @@ -32,7 +32,8 @@ #ifndef _CHCONF_H_ #define _CHCONF_H_ -#define CORTEX_USE_FPU FALSE +#define PORT_IDLE_THREAD_STACK_SIZE 32 +#define CORTEX_USE_FPU FALSE /*===========================================================================*/ /** diff --git a/testhal/STM32F4xx/SDC/halconf.h b/testhal/STM32F4xx/SDC/halconf.h index 07fd86631..9fbefdfbc 100755 --- a/testhal/STM32F4xx/SDC/halconf.h +++ b/testhal/STM32F4xx/SDC/halconf.h @@ -108,7 +108,7 @@ * @brief Enables the RTC subsystem. */ #if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) -#define HAL_USE_RTC FALSE +#define HAL_USE_RTC TRUE #endif /** @@ -122,7 +122,7 @@ * @brief Enables the SERIAL subsystem. */ #if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) -#define HAL_USE_SERIAL FALSE +#define HAL_USE_SERIAL TRUE #endif /** diff --git a/testhal/STM32F4xx/SDC/main.c b/testhal/STM32F4xx/SDC/main.c index 28bfdfca5..6bbcdea89 100755 --- a/testhal/STM32F4xx/SDC/main.c +++ b/testhal/STM32F4xx/SDC/main.c @@ -22,13 +22,22 @@ #include "ch.h" #include "hal.h" +#include "shell.h" +#include "chprintf.h" -#define SDC_DATA_DESTRUCTIVE_TEST TRUE +#include "ff.h" + +#define SDC_DATA_DESTRUCTIVE_TEST FALSE #define SDC_BURST_SIZE 8 /* how many sectors reads at once */ static uint8_t outbuf[SDC_BLOCK_SIZE * SDC_BURST_SIZE + 1]; static uint8_t inbuf[SDC_BLOCK_SIZE * SDC_BURST_SIZE + 1]; +/* FS object.*/ +static FATFS SDC_FS; + +/* FS mounted and ready.*/ +static bool_t fs_ready = FALSE; /** * @brief Parody of UNIX badblocks program. @@ -93,42 +102,49 @@ void fillbuffers(uint8_t pattern){ fillbuffer(pattern, outbuf); } -/* - * SDIO configuration. +/** + * */ -static const SDCConfig sdccfg = { - 0 -}; +bool_t sdc_lld_is_write_protected(SDCDriver *sdcp) { + (void)sdcp; + return FALSE; +} -/* - * Application entry point. +/** + * */ -int main(void) { +void cmd_sdiotest(BaseChannel *chp, int argc, char *argv[]){ + (void)argc; + (void)argv; uint32_t i = 0; - halInit(); - chSysInit(); - - /* - * Initializes the SDIO drivers. - */ - sdcStart(&SDCD1, &sdccfg); + chprintf(chp, "Trying to connect SDIO... "); + chThdSleepMilliseconds(100); if (!sdcConnect(&SDCD1)) { - /* Single aligned read.*/ + chprintf(chp, "OK\r\nSingle aligned read..."); + chThdSleepMilliseconds(100); if (sdcRead(&SDCD1, 0, inbuf, 1)) chSysHalt(); + chprintf(chp, " OK\r\n"); + chThdSleepMilliseconds(100); - /* Single unaligned read.*/ + + chprintf(chp, "Single unaligned read..."); + chThdSleepMilliseconds(100); if (sdcRead(&SDCD1, 0, inbuf + 1, 1)) chSysHalt(); if (sdcRead(&SDCD1, 0, inbuf + 2, 1)) chSysHalt(); if (sdcRead(&SDCD1, 0, inbuf + 3, 1)) chSysHalt(); + chprintf(chp, " OK\r\n"); + chThdSleepMilliseconds(100); + - /* Multiple aligned reads from one place to ensure in bus stability */ + chprintf(chp, "Multiple aligned reads..."); + chThdSleepMilliseconds(100); fillbuffers(0x55); /* fill reference buffer from SD card */ if (sdcRead(&SDCD1, 0, inbuf, SDC_BURST_SIZE)) @@ -139,8 +155,12 @@ int main(void) { if (memcmp(inbuf, outbuf, SDC_BURST_SIZE * SDC_BLOCK_SIZE) != 0) chSysHalt(); } + chprintf(chp, " OK\r\n"); + chThdSleepMilliseconds(100); + - /* Repeated multiple unaligned reads.*/ + chprintf(chp, "Multiple unaligned reads..."); + chThdSleepMilliseconds(100); fillbuffers(0x55); /* fill reference buffer from SD card */ if (sdcRead(&SDCD1, 0, inbuf + 1, SDC_BURST_SIZE)) @@ -151,16 +171,13 @@ int main(void) { if (memcmp(inbuf, outbuf, SDC_BURST_SIZE * SDC_BLOCK_SIZE) != 0) chSysHalt(); } - - - - - - + chprintf(chp, " OK\r\n"); + chThdSleepMilliseconds(100); #if SDC_DATA_DESTRUCTIVE_TEST - /* Single aligned write.*/ + chprintf(chp, "Single aligned write..."); + chThdSleepMilliseconds(100); fillbuffer(0xAA, inbuf); if (sdcWrite(&SDCD1, 0, inbuf, 1)) chSysHalt(); @@ -169,8 +186,10 @@ int main(void) { chSysHalt(); if (memcmp(inbuf, outbuf, SDC_BLOCK_SIZE) != 0) chSysHalt(); + chprintf(chp, " OK\r\n"); - /* Single unaligned write.*/ + chprintf(chp, "Single unaligned write..."); + chThdSleepMilliseconds(100); fillbuffer(0xFF, inbuf); if (sdcWrite(&SDCD1, 0, inbuf+1, 1)) chSysHalt(); @@ -179,24 +198,152 @@ int main(void) { chSysHalt(); if (memcmp(inbuf+1, outbuf+1, SDC_BLOCK_SIZE) != 0) chSysHalt(); + chprintf(chp, " OK\r\n"); - + chprintf(chp, "Running badblocks at 0x10000 offset..."); + chThdSleepMilliseconds(100); if(badblocks(0x10000, 0x11000, SDC_BURST_SIZE, 0xAA)) chSysHalt(); + chprintf(chp, " OK\r\n"); #endif /* !SDC_DATA_DESTRUCTIVE_TEST */ + /** + * Now some perform FS tests. + */ + FRESULT err; + uint32_t clusters; + FATFS *fsp; + FIL FileObject; + uint32_t bytes_written; + chprintf(chp, "Register working area for filesystem... "); + chThdSleepMilliseconds(100); + err = f_mount(0, &SDC_FS); + if (err != FR_OK){ + chSysHalt(); + } + else{ + fs_ready = TRUE; + chprintf(chp, "OK\r\n"); + } + + +#if SDC_DATA_DESTRUCTIVE_TEST + chprintf(chp, "Formatting... "); + chThdSleepMilliseconds(100); + err = f_mkfs (0,0,0); + if (err != FR_OK){ + chSysHalt(); + } + else{ + chprintf(chp, "OK\r\n"); + } +#endif /* SDC_DATA_DESTRUCTIVE_TEST */ + chprintf(chp, "Mount filesystem... "); + chThdSleepMilliseconds(100); + err = f_getfree("/", &clusters, &fsp); + if (err != FR_OK) { + chSysHalt(); + } + chprintf(chp, "OK\r\n"); + chprintf(chp, + "FS: %lu free clusters, %lu sectors per cluster, %lu bytes free\r\n", + clusters, (uint32_t)SDC_FS.csize, + clusters * (uint32_t)SDC_FS.csize * (uint32_t)SDC_BLOCK_SIZE); + + + chprintf(chp, "Create file \"chtest.txt\"... "); + chThdSleepMilliseconds(100); + err = f_open(&FileObject, "0:chtest.txt", FA_WRITE | FA_OPEN_ALWAYS); + if (err != FR_OK) { + chSysHalt(); + } + chprintf(chp, "OK\r\n"); + chprintf(chp, "Write some data in it... "); + chThdSleepMilliseconds(100); + err = f_write(&FileObject, "This is test file", 17, (void *)&bytes_written); + if (err != FR_OK) { + chSysHalt(); + } + else + chprintf(chp, "OK\r\n"); + + + chprintf(chp, "Close file \"chtest.txt\"... "); + err = f_close(&FileObject); + if (err != FR_OK) { + chSysHalt(); + } + else + chprintf(chp, "OK\r\n"); + + chprintf(chp, "Umount filesystem... "); + f_mount(0, NULL); + chprintf(chp, "OK\r\n"); + + + chprintf(chp, "Disconnecting from SDIO..."); + chThdSleepMilliseconds(100); if (sdcDisconnect(&SDCD1)) chSysHalt(); + chprintf(chp, " OK\r\n"); + chprintf(chp, "------------------------------------------------------\r\n"); + chprintf(chp, "All tests passed successfully.\r\n"); + chThdSleepMilliseconds(100); } else{ chSysHalt(); } +} + + +/* + * SDIO configuration. + */ +static const SDCConfig sdccfg = { + 0 +}; + +/** + * + */ +static SerialConfig ser_cfg = { + 115200, + 0, + 0, + 0, +}; +static const ShellCommand commands[] = { + {"sdiotest", cmd_sdiotest}, + {NULL, NULL} +}; +static const ShellConfig shell_cfg1 = { + (BaseChannel *)&SD2, + commands +}; + +/* + * Application entry point. + */ +int main(void) { + halInit(); + chSysInit(); + + /* start debugging serial link */ + sdStart(&SD2, &ser_cfg); + shellInit(); + static WORKING_AREA(waShell, 2048); + shellCreateStatic(&shell_cfg1, waShell, sizeof(waShell), NORMALPRIO); + + /* + * Initializes the SDIO drivers. + */ + sdcStart(&SDCD1, &sdccfg); /* * Normal main() thread activity. @@ -204,6 +351,6 @@ int main(void) { */ while (TRUE) { palTogglePad(GPIOB, GPIOB_LED_R); - chThdSleepMilliseconds(500); + chThdSleepMilliseconds(100); } } -- cgit v1.2.3 From 3c311dfe589b6a6b1fd46af2e3138512fe2135fa Mon Sep 17 00:00:00 2001 From: barthess Date: Fri, 9 Mar 2012 18:33:26 +0000 Subject: RTC. High level staff moved to chrtclib. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4032 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/rtc.h | 1 - os/hal/platforms/STM32/RTCv1/rtc_lld.c | 23 --- os/hal/platforms/STM32/RTCv1/rtc_lld.h | 1 - os/hal/platforms/STM32/RTCv2/rtc_lld.c | 120 ------------ os/hal/platforms/STM32/RTCv2/rtc_lld.h | 5 - os/hal/platforms/STM32F1xx/hal_lld.h | 2 +- os/hal/src/rtc.c | 20 -- os/various/chrtclib.c | 338 +++++++++++++++++++++++++++++++++ os/various/chrtclib.h | 56 ++++++ testhal/STM32F1xx/RTC/Makefile | 1 + testhal/STM32F1xx/RTC/main.c | 2 + testhal/STM32F4xx/RTC/Makefile | 1 + testhal/STM32F4xx/RTC/main.c | 10 +- testhal/STM32F4xx/SDC/Makefile | 1 + 14 files changed, 404 insertions(+), 177 deletions(-) create mode 100755 os/various/chrtclib.c create mode 100755 os/various/chrtclib.h diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index 3acce33e4..9b5cba848 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -151,7 +151,6 @@ extern "C" { void rtcInit(void); void rtcSetTime(RTCDriver *rtcp, const RTCTime *timespec); void rtcGetTime(RTCDriver *rtcp, RTCTime *timespec); - uint32_t rtcGetFatTime(RTCDriver *rtcp); #if RTC_ALARMS > 0 void rtcSetAlarm(RTCDriver *rtcp, rtcalarm_t alarm, diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.c b/os/hal/platforms/STM32/RTCv1/rtc_lld.c index 6496cfae9..a417194b1 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.c @@ -291,29 +291,6 @@ void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { rtcp->callback = NULL; } } - -/** - * @brief Get current time in format suitable for usage in FatFS. - * - * @param[in] timespec pointer to RTCTime structure - * @return FAT time value. - * - * @api - */ -uint32_t rtc_lld_calc_fat_time(RTCTime *timespec){ - uint32_t fattime = 0; - struct tm *timp; - - timp = localtime((time_t *)(timespec->tv_sec)); - - fattime |= (timp->tm_sec / 2); - fattime |= (timp->tm_min) << 5; - fattime |= (timp->tm_hour) << 11; - fattime |= (timp->tm_mday) << 16; - fattime |= (timp->tm_mon + 1) << 21; - fattime |= (timp->tm_year - 80) << 25; - return fattime; -} #endif /* HAL_USE_RTC */ /** @} */ diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h index 64287d978..4944ff735 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -178,7 +178,6 @@ extern "C" { rtcalarm_t alarm, RTCAlarm *alarmspec); void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); - uint32_t rtc_lld_calc_fat_time(RTCTime *timespec); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32/RTCv2/rtc_lld.c b/os/hal/platforms/STM32/RTCv2/rtc_lld.c index c2268fd82..870734fba 100644 --- a/os/hal/platforms/STM32/RTCv2/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv2/rtc_lld.c @@ -264,126 +264,6 @@ void rtcGetPeriodicWakeup_v2(RTCDriver *rtcp, RTCWakeup *wakeupspec){ wakeupspec->wakeup |= (((uint32_t)rtcp->id_rtc->CR) & 0x7) << 16; } -/** - * @brief Get current time in format suitable for usage in FatFS. - * - * @param[in] timespec pointer to RTCTime structure - * @return FAT time value. - * - * @api - */ -uint32_t rtc_lld_calc_fat_time(RTCTime *timespec){ - uint32_t fattime = 0; - struct tm timp; - - stm32_rtc_bcd2tm(&timp, timespec); - - fattime |= (timp.tm_sec / 2); - fattime |= (timp.tm_min) << 5; - fattime |= (timp.tm_hour) << 11; - fattime |= (timp.tm_mday) << 16; - fattime |= (timp.tm_mon + 1) << 21; - fattime |= (timp.tm_year - 80) << 25; - return fattime; -} - -/** - * @brief Converts from STM32 BCD to canonicalized time format. - * - * @param[out] timp pointer to a @p tm structure defined in time.h - * @param[in] timespec pointer to a @p RTCTime structure - * - * @api - */ -void stm32_rtc_bcd2tm(struct tm *timp, RTCTime *timespec){ - uint32_t tv_time = timespec->tv_time; - uint32_t tv_date = timespec->tv_date; - -#if CH_DBG_ENABLE_CHECKS - timp->tm_isdst = 0; - timp->tm_wday = 0; - timp->tm_mday = 0; - timp->tm_yday = 0; - timp->tm_mon = 0; - timp->tm_year = 0; - timp->tm_sec = 0; - timp->tm_min = 0; - timp->tm_hour = 0; -#endif - - timp->tm_isdst = -1; - - timp->tm_wday = (tv_date & RTC_DR_WDU) >> RTC_DR_WDU_OFFSET; - if(timp->tm_wday == 7) - timp->tm_wday = 0; - - timp->tm_mday = (tv_date & RTC_DR_DU) >> RTC_DR_DU_OFFSET; - timp->tm_mday += ((tv_date & RTC_DR_DT) >> RTC_DR_DT_OFFSET) * 10; - - timp->tm_mon = (tv_date & RTC_DR_MU) >> RTC_DR_MU_OFFSET; - timp->tm_mon += ((tv_date & RTC_DR_MT) >> RTC_DR_MT_OFFSET) * 10; - timp->tm_mon -= 1; - - timp->tm_year = (tv_date & RTC_DR_YU) >> RTC_DR_YU_OFFSET; - timp->tm_year += ((tv_date & RTC_DR_YT) >> RTC_DR_YT_OFFSET) * 10; - timp->tm_year += 2000 - 1900; - - timp->tm_sec = (tv_time & RTC_TR_SU) >> RTC_TR_SU_OFFSET; - timp->tm_sec += ((tv_time & RTC_TR_ST) >> RTC_TR_ST_OFFSET) * 10; - - timp->tm_min = (tv_time & RTC_TR_MNU) >> RTC_TR_MNU_OFFSET; - timp->tm_min += ((tv_time & RTC_TR_MNT) >> RTC_TR_MNT_OFFSET) * 10; - - timp->tm_hour = (tv_time & RTC_TR_HU) >> RTC_TR_HU_OFFSET; - timp->tm_hour += ((tv_time & RTC_TR_HT) >> RTC_TR_HT_OFFSET) * 10; - timp->tm_hour += 12 * ((tv_time & RTC_TR_PM) >> RTC_TR_PM_OFFSET); -} - -/** - * @brief Converts from canonicalized to STM32 BCD time format. - * - * @param[in] timp pointer to a @p tm structure defined in time.h - * @param[out] timespec pointer to a @p RTCTime structure - * - * @api - */ -void stm32_rtc_tm2bcd(struct tm *timp, RTCTime *timespec){ - uint32_t v = 0; - - timespec->tv_date = 0; - timespec->tv_time = 0; - - v = timp->tm_year - 100; - timespec->tv_date |= ((v / 10) << RTC_DR_YT_OFFSET) & RTC_DR_YT; - timespec->tv_date |= (v % 10) << RTC_DR_YU_OFFSET; - - if (timp->tm_wday == 0) - v = 7; - else - v = timp->tm_wday; - timespec->tv_date |= (v << RTC_DR_WDU_OFFSET) & RTC_DR_WDU; - - v = timp->tm_mon + 1; - timespec->tv_date |= ((v / 10) << RTC_DR_MT_OFFSET) & RTC_DR_MT; - timespec->tv_date |= (v % 10) << RTC_DR_MU_OFFSET; - - v = timp->tm_mday; - timespec->tv_date |= ((v / 10) << RTC_DR_DT_OFFSET) & RTC_DR_DT; - timespec->tv_date |= (v % 10) << RTC_DR_DU_OFFSET; - - v = timp->tm_hour; - timespec->tv_time |= ((v / 10) << RTC_TR_HT_OFFSET) & RTC_TR_HT; - timespec->tv_time |= (v % 10) << RTC_TR_HU_OFFSET; - - v = timp->tm_min; - timespec->tv_time |= ((v / 10) << RTC_TR_MNT_OFFSET) & RTC_TR_MNT; - timespec->tv_time |= (v % 10) << RTC_TR_MNU_OFFSET; - - v = timp->tm_sec; - timespec->tv_time |= ((v / 10) << RTC_TR_ST_OFFSET) & RTC_TR_ST; - timespec->tv_time |= (v % 10) << RTC_TR_SU_OFFSET; -} - #endif /* HAL_USE_RTC */ /** @} */ diff --git a/os/hal/platforms/STM32/RTCv2/rtc_lld.h b/os/hal/platforms/STM32/RTCv2/rtc_lld.h index 88959294c..4cae5744d 100644 --- a/os/hal/platforms/STM32/RTCv2/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv2/rtc_lld.h @@ -35,8 +35,6 @@ #if HAL_USE_RTC || defined(__DOXYGEN__) -#include - /*===========================================================================*/ /* Driver constants. */ /*===========================================================================*/ @@ -200,9 +198,6 @@ extern "C" { RTCAlarm *alarmspec); void rtcSetPeriodicWakeup_v2(RTCDriver *rtcp, RTCWakeup *wakeupspec); void rtcGetPeriodicWakeup_v2(RTCDriver *rtcp, RTCWakeup *wakeupspec); - uint32_t rtc_lld_calc_fat_time(RTCTime *timespec); - void stm32_rtc_bcd2tm(struct tm *timp, RTCTime *timespec); - void stm32_rtc_tm2bcd(struct tm *timp, RTCTime *timespec); #ifdef __cplusplus } #endif diff --git a/os/hal/platforms/STM32F1xx/hal_lld.h b/os/hal/platforms/STM32F1xx/hal_lld.h index 4a375ab4e..c8d87b7c5 100644 --- a/os/hal/platforms/STM32F1xx/hal_lld.h +++ b/os/hal/platforms/STM32F1xx/hal_lld.h @@ -88,7 +88,7 @@ /* RTC attributes.*/ #define STM32_HAS_RTC TRUE #define STM32_RTC_HAS_SUBSECONDS TRUE -#define STM32_RTC_IS_CALENDAR TRUE +#define STM32_RTC_IS_CALENDAR FALSE /** @} */ /*===========================================================================*/ diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index a6601fd1c..01f88e82d 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -101,26 +101,6 @@ void rtcGetTime(RTCDriver *rtcp, RTCTime *timespec) { chSysUnlock(); } -/** - * @brief Get current time in format suitable for usage in FatFS. - * - * @param[in] rtcp pointer to RTC driver structure - * @return FAT time value. - * - * @api - */ -uint32_t rtcGetFatTime(RTCDriver *rtcp) { - RTCTime timespec; - - chDbgCheck((rtcp != NULL), "rtcGetTime"); - - chSysLock(); - rtcGetTimeI(rtcp, ×pec); - chSysUnlock(); - - return rtc_lld_calc_fat_time(×pec); -} - #if (RTC_ALARMS > 0) || defined(__DOXYGEN__) /** * @brief Set alarm time. diff --git a/os/various/chrtclib.c b/os/various/chrtclib.c new file mode 100755 index 000000000..38f5a3627 --- /dev/null +++ b/os/various/chrtclib.c @@ -0,0 +1,338 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +#include + +#include "ch.h" +#include "hal.h" + +#include "chrtclib.h" + +#if (defined(STM32F4XX) || defined(STM32F2XX) || defined(STM32L1XX) || \ + defined(STM32F1XX) || defined(STM32F10X_MD) || defined(STM32F10X_LD) || \ + defined(STM32F10X_HD)) +#if STM32_RTC_IS_CALENDAR +/** + * @brief Converts from STM32 BCD to canonicalized time format. + * + * @param[out] timp pointer to a @p tm structure defined in time.h + * @param[in] timespec pointer to a @p RTCTime structure + * + * @notapi + */ +void stm32_rtc_bcd2tm(struct tm *timp, RTCTime *timespec){ + uint32_t tv_time = timespec->tv_time; + uint32_t tv_date = timespec->tv_date; + +#if CH_DBG_ENABLE_CHECKS + timp->tm_isdst = 0; + timp->tm_wday = 0; + timp->tm_mday = 0; + timp->tm_yday = 0; + timp->tm_mon = 0; + timp->tm_year = 0; + timp->tm_sec = 0; + timp->tm_min = 0; + timp->tm_hour = 0; +#endif + + timp->tm_isdst = -1; + + timp->tm_wday = (tv_date & RTC_DR_WDU) >> RTC_DR_WDU_OFFSET; + if(timp->tm_wday == 7) + timp->tm_wday = 0; + + timp->tm_mday = (tv_date & RTC_DR_DU) >> RTC_DR_DU_OFFSET; + timp->tm_mday += ((tv_date & RTC_DR_DT) >> RTC_DR_DT_OFFSET) * 10; + + timp->tm_mon = (tv_date & RTC_DR_MU) >> RTC_DR_MU_OFFSET; + timp->tm_mon += ((tv_date & RTC_DR_MT) >> RTC_DR_MT_OFFSET) * 10; + timp->tm_mon -= 1; + + timp->tm_year = (tv_date & RTC_DR_YU) >> RTC_DR_YU_OFFSET; + timp->tm_year += ((tv_date & RTC_DR_YT) >> RTC_DR_YT_OFFSET) * 10; + timp->tm_year += 2000 - 1900; + + timp->tm_sec = (tv_time & RTC_TR_SU) >> RTC_TR_SU_OFFSET; + timp->tm_sec += ((tv_time & RTC_TR_ST) >> RTC_TR_ST_OFFSET) * 10; + + timp->tm_min = (tv_time & RTC_TR_MNU) >> RTC_TR_MNU_OFFSET; + timp->tm_min += ((tv_time & RTC_TR_MNT) >> RTC_TR_MNT_OFFSET) * 10; + + timp->tm_hour = (tv_time & RTC_TR_HU) >> RTC_TR_HU_OFFSET; + timp->tm_hour += ((tv_time & RTC_TR_HT) >> RTC_TR_HT_OFFSET) * 10; + timp->tm_hour += 12 * ((tv_time & RTC_TR_PM) >> RTC_TR_PM_OFFSET); +} + +/** + * @brief Converts from canonicalized to STM32 BCD time format. + * + * @param[in] timp pointer to a @p tm structure defined in time.h + * @param[out] timespec pointer to a @p RTCTime structure + * + * @notapi + */ +void stm32_rtc_tm2bcd(struct tm *timp, RTCTime *timespec){ + uint32_t v = 0; + + timespec->tv_date = 0; + timespec->tv_time = 0; + + v = timp->tm_year - 100; + timespec->tv_date |= ((v / 10) << RTC_DR_YT_OFFSET) & RTC_DR_YT; + timespec->tv_date |= (v % 10) << RTC_DR_YU_OFFSET; + + if (timp->tm_wday == 0) + v = 7; + else + v = timp->tm_wday; + timespec->tv_date |= (v << RTC_DR_WDU_OFFSET) & RTC_DR_WDU; + + v = timp->tm_mon + 1; + timespec->tv_date |= ((v / 10) << RTC_DR_MT_OFFSET) & RTC_DR_MT; + timespec->tv_date |= (v % 10) << RTC_DR_MU_OFFSET; + + v = timp->tm_mday; + timespec->tv_date |= ((v / 10) << RTC_DR_DT_OFFSET) & RTC_DR_DT; + timespec->tv_date |= (v % 10) << RTC_DR_DU_OFFSET; + + v = timp->tm_hour; + timespec->tv_time |= ((v / 10) << RTC_TR_HT_OFFSET) & RTC_TR_HT; + timespec->tv_time |= (v % 10) << RTC_TR_HU_OFFSET; + + v = timp->tm_min; + timespec->tv_time |= ((v / 10) << RTC_TR_MNT_OFFSET) & RTC_TR_MNT; + timespec->tv_time |= (v % 10) << RTC_TR_MNU_OFFSET; + + v = timp->tm_sec; + timespec->tv_time |= ((v / 10) << RTC_TR_ST_OFFSET) & RTC_TR_ST; + timespec->tv_time |= (v % 10) << RTC_TR_SU_OFFSET; +} + +/** + * @brief Gets raw time from RTC and converts it to canonicalized format. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timp pointer to a @p tm structure defined in time.h + * + * @api + */ +void rtcGetTimeTm(RTCDriver *rtcp, struct tm *timp){ + RTCTime timespec = {0,0,FALSE,0}; + rtcGetTime(rtcp, ×pec); + stm32_rtc_bcd2tm(timp, ×pec); +} + +/** + * @brief Sets RTC time. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timp pointer to a @p tm structure defined in time.h + * + * @api + */ +void rtcSetTimeTm(RTCDriver *rtcp, struct tm *timp){ + RTCTime timespec = {0,0,FALSE,0}; + + stm32_rtc_tm2bcd(timp, ×pec); + rtcSetTime(rtcp, ×pec); +} + +/** + * @brief Gets raw time from RTC and converts it to unix format. + * + * @param[in] rtcp pointer to RTC driver structure + * + * @return Unix time value in seconds. + * + * @api + */ +time_t rtcGetTimeUnixSec(RTCDriver *rtcp){ + RTCTime timespec = {0,0,FALSE,0}; + struct tm timp; + + rtcGetTime(rtcp, ×pec); + stm32_rtc_bcd2tm(&timp, ×pec); + + return mktime(&timp); +} + +/** + * @brief Sets RTC time. + * + * @param[in] rtcp pointer to RTC driver structure + * + * @return Unix time value in seconds. + * + * @api + */ +void rtcSetTimeUnixSec(RTCDriver *rtcp, time_t tv_sec){ + RTCTime timespec = {0,0,FALSE,0}; + struct tm *timp; + + timp = localtime(&tv_sec); + stm32_rtc_tm2bcd(timp, ×pec); + rtcSetTime(rtcp, ×pec); +} + +/** + * @brief Gets raw time from RTC and converts it to unix format. + * + * @param[in] rtcp pointer to RTC driver structure + * + * @return Unix time value in microseconds. + * + * @api + */ +uint64_t rtcGetTimeUnixUsec(RTCDriver *rtcp){ + uint64_t result = 0; + + RTCTime timespec = {0,0,FALSE,0}; + struct tm timp; + + rtcGetTime(rtcp, ×pec); + stm32_rtc_bcd2tm(&timp, ×pec); + + result = mktime(&timp) * 1000000; + +#if STM32_RTC_HAS_SUBSECONDS + return result + timespec.tv_msec * 1000; +#else + return result; +#endif +} + +#else /* STM32_RTC_IS_CALENDAR */ +/** + * @brief Gets raw time from RTC and converts it to canonicalized format. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timp pointer to a @p tm structure defined in time.h + * + * @api + */ +void rtcGetTimeTm(RTCDriver *rtcp, struct tm *timp){ + RTCTime timespec = {0,0,FALSE,0}; + + rtcGetTime(rtcp, ×pec); + if (timp != NULL) /* this comparison needed to avoid compiler warning */ + timp = localtime((time_t *)&(timespec.tv_sec)); +} + +/** + * @brief Sets RTC time. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] timp pointer to a @p tm structure defined in time.h + * + * @api + */ +void rtcSetTimeTm(RTCDriver *rtcp, struct tm *timp){ + RTCTime timespec = {0,0,FALSE,0}; + + timespec.tv_sec = mktime(timp); + timespec.tv_msec = 0; + rtcSetTime(rtcp, ×pec); +} + +/** + * @brief Gets raw time from RTC and converts it to unix format. + * + * @param[in] rtcp pointer to RTC driver structure + * + * @return Unix time value in seconds. + * + * @api + */ +time_t rtcGetTimeUnixSec(RTCDriver *rtcp){ + RTCTime timespec = {0,0,FALSE,0}; + + rtcGetTime(rtcp, ×pec); + return timespec.tv_sec; +} + +/** + * @brief Sets RTC time. + * + * @param[in] rtcp pointer to RTC driver structure + * + * @return Unix time value in seconds. + * + * @api + */ +void rtcSetTimeUnixSec(RTCDriver *rtcp, time_t tv_sec){ + RTCTime timespec = {0,0,FALSE,0}; + + timespec.tv_sec = tv_sec; + timespec.tv_msec = 0; + rtcSetTime(rtcp, ×pec); +} + +/** + * @brief Gets raw time from RTC and converts it to unix format. + * + * @param[in] rtcp pointer to RTC driver structure + * + * @return Unix time value in microseconds. + * + * @api + */ +uint64_t rtcGetTimeUnixUsec(RTCDriver *rtcp){ + uint64_t result = 0; + RTCTime timespec = {0,0,FALSE,0}; + + rtcGetTime(rtcp, ×pec); + result = timespec.tv_sec * 1000000; + +#if STM32_RTC_HAS_SUBSECONDS + return result + timespec.tv_msec * 1000; +#else + return result; +#endif +} +#endif /* STM32_RTC_IS_CALENDAR */ +#endif /* (defined(STM32F4XX) || defined(STM32F2XX) || defined(STM32L1XX) || defined(STM32F1XX)) */ + +/** + * @brief Get current time in format suitable for usage in FatFS. + * + * @param[in] timespec pointer to time value structure + * @return FAT time value. + * + * @api + */ +uint32_t rtcGetTimeFat(RTCDriver *rtcp){ + uint32_t fattime = 0; + struct tm *timp = NULL; + + rtcGetTimeTm(rtcp, timp); + + fattime |= (timp->tm_sec / 2); + fattime |= (timp->tm_min) << 5; + fattime |= (timp->tm_hour) << 11; + fattime |= (timp->tm_mday) << 16; + fattime |= (timp->tm_mon + 1) << 21; + fattime |= (timp->tm_year - 80) << 25; + return fattime; +} diff --git a/os/various/chrtclib.h b/os/various/chrtclib.h new file mode 100755 index 000000000..7831be83d --- /dev/null +++ b/os/various/chrtclib.h @@ -0,0 +1,56 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/* + Concepts and parts of this file have been contributed by Uladzimir Pylinsky + aka barthess. + */ + +#ifndef CHRTCLIB_H_ +#define CHRTCLIB_H_ + +#include + +/** + * @file chrtclib.h + * @brief Various time conversion functionality. + * + * @addtogroup chrtclib + * @{ + */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + uint32_t rtcGetTimeFat(RTCDriver *rtcp); + void rtcGetTimeTm(RTCDriver *rtcp, struct tm *timp); + void rtcSetTimeTm(RTCDriver *rtcp, struct tm *timp); + time_t rtcGetTimeUnixSec(RTCDriver *rtcp); + void rtcSetTimeUnixSec(RTCDriver *rtcp, time_t tv_sec); +#ifdef __cplusplus +} +#endif + +#endif /* CHRTCLIB_H_ */ + +/** @} */ diff --git a/testhal/STM32F1xx/RTC/Makefile b/testhal/STM32F1xx/RTC/Makefile index 9fc777248..3d28124f2 100644 --- a/testhal/STM32F1xx/RTC/Makefile +++ b/testhal/STM32F1xx/RTC/Makefile @@ -79,6 +79,7 @@ CSRC = $(PORTSRC) \ $(BOARDSRC) \ $(CHIBIOS)/os/various/evtimer.c \ $(CHIBIOS)/os/various/syscalls.c \ + $(CHIBIOS)/os/various/chrtclib.c \ main.c \ # C++ sources that can be compiled in ARM or THUMB mode depending on the global diff --git a/testhal/STM32F1xx/RTC/main.c b/testhal/STM32F1xx/RTC/main.c index bd3faa493..380afdad3 100644 --- a/testhal/STM32F1xx/RTC/main.c +++ b/testhal/STM32F1xx/RTC/main.c @@ -21,6 +21,8 @@ #include "ch.h" #include "hal.h" +#include "chrtclib.h" + RTCTime timespec; RTCAlarm alarmspec; diff --git a/testhal/STM32F4xx/RTC/Makefile b/testhal/STM32F4xx/RTC/Makefile index e60937914..82511a750 100644 --- a/testhal/STM32F4xx/RTC/Makefile +++ b/testhal/STM32F4xx/RTC/Makefile @@ -81,6 +81,7 @@ CSRC = $(PORTSRC) \ $(CHIBIOS)/os/various/syscalls.c \ $(CHIBIOS)/os/various/shell.c \ $(CHIBIOS)/os/various/chprintf.c \ + $(CHIBIOS)/os/various/chrtclib.c \ main.c \ # C++ sources that can be compiled in ARM or THUMB mode depending on the global diff --git a/testhal/STM32F4xx/RTC/main.c b/testhal/STM32F4xx/RTC/main.c index 5bc51c7b6..ce3e7f13f 100644 --- a/testhal/STM32F4xx/RTC/main.c +++ b/testhal/STM32F4xx/RTC/main.c @@ -43,11 +43,11 @@ int tm_isdst daylight savings indicator (1 = yes, 0 = no, -1 = unknown) #include "shell.h" #include "chprintf.h" +#include "chrtclib.h" #if WAKEUP_TEST static RTCWakeup wakeupspec; #endif -static RTCTime timespec = {0,0,FALSE,0}; static RTCAlarm alarmspec; static time_t unix_time; @@ -147,15 +147,14 @@ static void cmd_date(BaseChannel *chp, int argc, char *argv[]){ } if ((argc == 1) && (strcmp(argv[0], "get") == 0)){ - rtcGetTime(&RTCD1, ×pec); - stm32_rtc_bcd2tm(&timp, ×pec); - unix_time = mktime(&timp); + unix_time = rtcGetTimeUnixSec(&RTCD1); if (unix_time == -1){ chprintf(chp, "incorrect time in RTC cell\r\n"); } else{ chprintf(chp, "%D%s",unix_time," - unix time\r\n"); + rtcGetTimeTm(&RTCD1, &timp); chprintf(chp, "%s%s",asctime(&timp)," - formatted time string\r\n"); } return; @@ -164,8 +163,7 @@ static void cmd_date(BaseChannel *chp, int argc, char *argv[]){ if ((argc == 2) && (strcmp(argv[0], "set") == 0)){ unix_time = atol(argv[1]); if (unix_time > 0){ - stm32_rtc_tm2bcd((localtime(&unix_time)), ×pec); - rtcSetTime(&RTCD1, ×pec); + rtcSetTimeUnixSec(&RTCD1, unix_time); return; } else{ diff --git a/testhal/STM32F4xx/SDC/Makefile b/testhal/STM32F4xx/SDC/Makefile index ed147a37e..cf4d7b333 100755 --- a/testhal/STM32F4xx/SDC/Makefile +++ b/testhal/STM32F4xx/SDC/Makefile @@ -86,6 +86,7 @@ CSRC = $(PORTSRC) \ $(CHIBIOS)/os/various/syscalls.c \ $(CHIBIOS)/os/various/shell.c \ $(CHIBIOS)/os/various/chprintf.c \ + $(CHIBIOS)/os/various/chrtclib.c \ main.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global -- cgit v1.2.3 From 04da61495794ed3e22381cdead5a8f1919b512a2 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 16 Apr 2012 17:45:19 +0000 Subject: SDC. Fixed mixed usage of uint8_t and uint32_t. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4098 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/sdc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 62f3cb45a..6cb6dbe06 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -327,8 +327,7 @@ bool_t sdcConnect(SDCDriver *sdcp) { /* Determine capacity.*/ switch (sdcp->csd[3] >> 30) { - uint32_t a; - uint8_t b, c; + uint32_t a, b, c; case 0: /* CSD version 1.0 */ a = _sdc_get_slice(sdcp->csd, SDC_CSD_10_C_SIZE_SLICE); -- cgit v1.2.3 From 973d8da5eabeead58445937e5be4c740ffaf2c56 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 16 Apr 2012 18:19:34 +0000 Subject: SDC. Added function sdcGetAndClearErrors. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4099 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/sdc.h | 1 + os/hal/platforms/STM32/sdc_lld.c | 13 +++++++++++++ os/hal/platforms/STM32/sdc_lld.h | 9 +++++++-- os/hal/src/sdc.c | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index 9be833dd3..83f16d111 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -337,6 +337,7 @@ extern "C" { uint8_t *buffer, uint32_t n); bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buffer, uint32_t n); + sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp); bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp); #ifdef __cplusplus } diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c index c42867ffe..0c535e2dc 100644 --- a/os/hal/platforms/STM32/sdc_lld.c +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -755,6 +755,19 @@ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, return sdc_lld_write_aligned(sdcp, startblk, buf, n); } +/** + * @brief Get errors from SDC driver and clear error field. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * + * @notapi + */ +sdcflags_t sdc_lld_get_and_clear_errors(SDCDriver *sdcp) { + sdcflags_t flags = sdcp->errors; + sdcp->errors = SDC_NO_ERROR; + return flags; +} + #endif /* HAL_USE_SDC */ /** @} */ diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h index 51db5b2aa..000100396 100644 --- a/os/hal/platforms/STM32/sdc_lld.h +++ b/os/hal/platforms/STM32/sdc_lld.h @@ -119,7 +119,6 @@ #endif - /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -138,6 +137,11 @@ typedef enum { */ typedef uint32_t sdcmode_t; +/** + * @brief SDC Driver condition flags type. + */ +typedef uint32_t sdcflags_t; + /** * @brief Type of a structure representing an SDC driver. */ @@ -170,7 +174,7 @@ struct SDCDriver { /** * @brief Errors flags. */ - uint32_t errors; + sdcflags_t errors; /** * @brief Card CID. */ @@ -242,6 +246,7 @@ extern "C" { uint8_t *buf, uint32_t n); bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buf, uint32_t n); + sdcflags_t sdc_lld_get_and_clear_errors(SDCDriver *sdcp); bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp); bool_t sdc_lld_is_write_protected(SDCDriver *sdcp); #ifdef __cplusplus diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 6cb6dbe06..10baa38e8 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -465,6 +465,21 @@ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, return status; } +/** + * @brief Returns the errors mask associated to the previous operation. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @return The errors mask. + * + * @api + */ +sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp) { + + chDbgCheck(sdcp != NULL, "sdcGetAndClearErrors"); + + return sdc_lld_get_and_clear_errors(sdcp); +} + #endif /* HAL_USE_SDC */ /** @} */ -- cgit v1.2.3 From 6206a3c5a5a019bffd2db6fe6e9b3e7aca535fa7 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 16 Apr 2012 19:18:14 +0000 Subject: SDC. sdcGetAndClearErrors() now reside in HL driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4100 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/STM32/sdc_lld.c | 13 ------------- os/hal/platforms/STM32/sdc_lld.h | 1 - os/hal/src/sdc.c | 4 +++- 3 files changed, 3 insertions(+), 15 deletions(-) diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c index 0c535e2dc..c42867ffe 100644 --- a/os/hal/platforms/STM32/sdc_lld.c +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -755,19 +755,6 @@ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, return sdc_lld_write_aligned(sdcp, startblk, buf, n); } -/** - * @brief Get errors from SDC driver and clear error field. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * - * @notapi - */ -sdcflags_t sdc_lld_get_and_clear_errors(SDCDriver *sdcp) { - sdcflags_t flags = sdcp->errors; - sdcp->errors = SDC_NO_ERROR; - return flags; -} - #endif /* HAL_USE_SDC */ /** @} */ diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h index 000100396..437ca9c1d 100644 --- a/os/hal/platforms/STM32/sdc_lld.h +++ b/os/hal/platforms/STM32/sdc_lld.h @@ -246,7 +246,6 @@ extern "C" { uint8_t *buf, uint32_t n); bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, const uint8_t *buf, uint32_t n); - sdcflags_t sdc_lld_get_and_clear_errors(SDCDriver *sdcp); bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp); bool_t sdc_lld_is_write_protected(SDCDriver *sdcp); #ifdef __cplusplus diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 10baa38e8..6fd4e211d 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -477,7 +477,9 @@ sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp) { chDbgCheck(sdcp != NULL, "sdcGetAndClearErrors"); - return sdc_lld_get_and_clear_errors(sdcp); + sdcflags_t flags = sdcp->errors; + sdcp->errors = SDC_NO_ERROR; + return flags; } #endif /* HAL_USE_SDC */ -- cgit v1.2.3 From f41de7bb8b526fa9ad16120ed5b6a6505a132c92 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 16 Apr 2012 19:20:30 +0000 Subject: SDC. One more uint8_t, uint32_t mixture fixed. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4101 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/sdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 6fd4e211d..c2e6c1b74 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -52,7 +52,7 @@ * * @notapi */ -static uint32_t _sdc_get_slice(uint32_t *data, int8_t end, int8_t start) { +static uint32_t _sdc_get_slice(uint32_t *data, int32_t end, int32_t start) { uint32_t word = 0; uint32_t mask = 0; -- cgit v1.2.3 From 579fffb63c4d932c63882cb643cc95a55d8bf06e Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 16 Apr 2012 19:25:16 +0000 Subject: SDC. Typo in commetns fixed. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4102 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/sdc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index 83f16d111..d26692ab5 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -262,7 +262,7 @@ typedef enum { /** * @brief Slice position of values in CSD register. */ -/* CSD version 1.0 */ +/* CSD version 2.0 */ #define SDC_CSD_20_CRC_SLICE 7,1 #define SDC_CSD_20_FILE_FORMAT_SLICE 11,10 #define SDC_CSD_20_TMP_WRITE_PROTECT_SLICE 12,12 @@ -288,7 +288,7 @@ typedef enum { #define SDC_CSD_20_TAAC_SLICE 119,112 #define SDC_CSD_20_STRUCTURE_SLICE 127,126 -/* CSD version 2.0 */ +/* CSD version 1.0 */ #define SDC_CSD_10_CRC_SLICE SDC_CSD_20_CRC_SLICE #define SDC_CSD_10_FILE_FORMAT_SLICE SDC_CSD_20_FILE_FORMAT_SLICE #define SDC_CSD_10_TMP_WRITE_PROTECT_SLICE SDC_CSD_20_TMP_WRITE_PROTECT_SLICE -- cgit v1.2.3 From 671cb8ab9dbbfaf9832f7529fc8966a5d042b6f4 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 16 Apr 2012 20:12:16 +0000 Subject: SDC. Reverted from SDC_SUCCESS/SDC_FAILED to boolean values. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4103 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/sdc.h | 6 --- os/hal/platforms/STM32/sdc_lld.c | 96 ++++++++++++++++++++-------------------- os/hal/src/sdc.c | 42 +++++++++--------- testhal/STM32F4xx/SDC/main.c | 4 +- 4 files changed, 71 insertions(+), 77 deletions(-) diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index d26692ab5..aa02e4f5b 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -88,12 +88,6 @@ #define SDC_CMD_LOCK_UNLOCK 42 #define SDC_CMD_APP_CMD 55 -/** - * @brief Returning status. - */ -#define SDC_SUCCESS FALSE -#define SDC_FAILED TRUE - /** * @name SDC bus error conditions * @{ diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c index c42867ffe..61d91b044 100644 --- a/os/hal/platforms/STM32/sdc_lld.c +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -79,8 +79,8 @@ static union { * @param[in] resp pointer to the response buffer * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -96,16 +96,16 @@ static bool_t sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk, /* Send read multiple blocks command to card.*/ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK, startblk, resp) || SDC_R1_ERROR(resp[0])) - return SDC_FAILED; + return TRUE; } else{ /* Send read single block command.*/ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK, startblk, resp) || SDC_R1_ERROR(resp[0])) - return SDC_FAILED; + return TRUE; } - return SDC_SUCCESS; + return FALSE; } /** @@ -117,8 +117,8 @@ static bool_t sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk, * @param[in] resp pointer to the response buffer * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -134,16 +134,16 @@ static bool_t sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk, /* Write multiple blocks command.*/ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK, startblk, resp) || SDC_R1_ERROR(resp[0])) - return SDC_FAILED; + return TRUE; } else{ /* Write single block command.*/ if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK, startblk, resp) || SDC_R1_ERROR(resp[0])) - return SDC_FAILED; + return TRUE; } - return SDC_SUCCESS; + return FALSE; } /** @@ -154,8 +154,8 @@ static bool_t sdc_lld_prepare_write(SDCDriver *sdcp, uint32_t startblk, * @param[in] resp pointer to the response buffer * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. */ static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, uint32_t *resp){ @@ -173,7 +173,7 @@ static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, } if ((SDIO->STA & SDIO_STA_DATAEND) == 0) { chSysUnlock(); - return SDC_FAILED; + return TRUE; } /* Wait until DMA channel enabled to be sure that all data transferred.*/ @@ -195,7 +195,7 @@ static bool_t sdc_lld_wait_transaction_end(SDCDriver *sdcp, uint32_t n, if (n > 1) return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp); else - return SDC_SUCCESS; + return FALSE; } /** @@ -470,8 +470,8 @@ void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) { * @param[out] resp pointer to the response buffer (one word) * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -488,10 +488,10 @@ bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; if ((sta & (SDIO_STA_CTIMEOUT)) != 0){ sdc_lld_collect_errors(sdcp); - return SDC_FAILED; + return TRUE; } *resp = SDIO->RESP1; - return SDC_SUCCESS; + return FALSE; } /** @@ -503,8 +503,8 @@ bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, * @param[out] resp pointer to the response buffer (one word) * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -521,10 +521,10 @@ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0){ sdc_lld_collect_errors(sdcp); - return SDC_FAILED; + return TRUE; } *resp = SDIO->RESP1; - return SDC_SUCCESS; + return FALSE; } /** @@ -536,8 +536,8 @@ bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, * @param[out] resp pointer to the response buffer (four words) * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -556,14 +556,14 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC; if ((sta & (STM32_SDIO_STA_ERROR_MASK)) != 0){ sdc_lld_collect_errors(sdcp); - return SDC_FAILED; + return TRUE; } /* save bytes in reverse order because MSB in response comes first */ *resp++ = SDIO->RESP4; *resp++ = SDIO->RESP3; *resp++ = SDIO->RESP2; *resp = SDIO->RESP1; - return SDC_SUCCESS; + return FALSE; } /** @@ -575,8 +575,8 @@ bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, * @param[in] n number of blocks to read * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -590,7 +590,7 @@ bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, /* Checks for errors and waits for the card to be ready for reading.*/ if (_sdc_wait_for_transfer_state(sdcp)) - return SDC_FAILED; + return TRUE; /* Prepares the DMA channel for writing.*/ dmaStreamSetMemory0(sdcp->dma, buf); @@ -609,7 +609,7 @@ bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, SDIO->DLEN = n * SDC_BLOCK_SIZE; /* Talk to card what we want from it.*/ - if (sdc_lld_prepare_read(sdcp, startblk, n, resp) == SDC_FAILED) + if (sdc_lld_prepare_read(sdcp, startblk, n, resp) == TRUE) goto error; /* Transaction starts just after DTEN bit setting.*/ @@ -618,14 +618,14 @@ bool_t sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DBLOCKSIZE_0 | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN; - if (sdc_lld_wait_transaction_end(sdcp, n, resp) == SDC_FAILED) + if (sdc_lld_wait_transaction_end(sdcp, n, resp) == TRUE) goto error; else - return SDC_SUCCESS; + return FALSE; error: sdc_lld_error_cleanup(sdcp, n, resp); - return SDC_FAILED; + return TRUE; } /** @@ -637,8 +637,8 @@ error: * @param[in] n number of blocks to write * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -652,7 +652,7 @@ bool_t sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk, /* Checks for errors and waits for the card to be ready for writing.*/ if (_sdc_wait_for_transfer_state(sdcp)) - return SDC_FAILED; + return TRUE; /* Prepares the DMA channel for writing.*/ dmaStreamSetMemory0(sdcp->dma, buf); @@ -671,7 +671,7 @@ bool_t sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk, SDIO->DLEN = n * SDC_BLOCK_SIZE; /* Talk to card what we want from it.*/ - if (sdc_lld_prepare_write(sdcp, startblk, n, resp) == SDC_FAILED) + if (sdc_lld_prepare_write(sdcp, startblk, n, resp) == TRUE) goto error; /* Transaction starts just after DTEN bit setting.*/ @@ -679,14 +679,14 @@ bool_t sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DBLOCKSIZE_0 | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN; - if (sdc_lld_wait_transaction_end(sdcp, n, resp) == SDC_FAILED) + if (sdc_lld_wait_transaction_end(sdcp, n, resp) == TRUE) goto error; else - return SDC_SUCCESS; + return FALSE; error: sdc_lld_error_cleanup(sdcp, n, resp); - return SDC_FAILED; + return TRUE; } /** @@ -698,8 +698,8 @@ error: * @param[in] n number of blocks to read * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -711,12 +711,12 @@ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, uint32_t i; for (i = 0; i < n; i++) { if (sdc_lld_read_aligned(sdcp, startblk, u.buf, 1)) - return SDC_FAILED; + return TRUE; memcpy(buf, u.buf, SDC_BLOCK_SIZE); buf += SDC_BLOCK_SIZE; startblk++; } - return SDC_SUCCESS; + return FALSE; } #endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */ return sdc_lld_read_aligned(sdcp, startblk, buf, n); @@ -731,8 +731,8 @@ bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk, * @param[in] n number of blocks to write * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -746,10 +746,10 @@ bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk, memcpy(u.buf, buf, SDC_BLOCK_SIZE); buf += SDC_BLOCK_SIZE; if (sdc_lld_write_aligned(sdcp, startblk, u.buf, 1)) - return SDC_FAILED; + return TRUE; startblk++; } - return SDC_SUCCESS; + return FALSE; } #endif /* STM32_SDC_SDIO_UNALIGNED_SUPPORT */ return sdc_lld_write_aligned(sdcp, startblk, buf, n); diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index c2e6c1b74..d883eac39 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -89,8 +89,8 @@ static uint32_t _sdc_get_slice(uint32_t *data, int32_t end, int32_t start) { * @param[in] sdcp pointer to the @p SDCDriver object * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @notapi */ @@ -101,10 +101,10 @@ bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) { if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_SEND_STATUS, sdcp->rca, resp) || SDC_R1_ERROR(resp[0])) - return SDC_FAILED; + return TRUE; switch (SDC_R1_STS(resp[0])) { case SDC_STS_TRAN: - return SDC_SUCCESS; + return FALSE; case SDC_STS_DATA: case SDC_STS_RCV: case SDC_STS_PRG: @@ -115,11 +115,11 @@ bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp) { default: /* The card should have been initialized so any other state is not valid and is reported as an error.*/ - return SDC_FAILED; + return TRUE; } } /* If something going too wrong.*/ - return SDC_FAILED; + return TRUE; } /*===========================================================================*/ @@ -204,8 +204,8 @@ void sdcStop(SDCDriver *sdcp) { * @param[in] sdcp pointer to the @p SDCDriver object * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @api */ @@ -346,13 +346,13 @@ bool_t sdcConnect(SDCDriver *sdcp) { /* Initialization complete.*/ sdcp->state = SDC_ACTIVE; - return SDC_SUCCESS; + return FALSE; /* Initialization failed.*/ failed: sdc_lld_stop_clk(sdcp); sdcp->state = SDC_READY; - return SDC_FAILED; + return TRUE; } /** @@ -361,8 +361,8 @@ failed: * @param[in] sdcp pointer to the @p SDCDriver object * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @api */ @@ -375,20 +375,20 @@ bool_t sdcDisconnect(SDCDriver *sdcp) { "sdcDisconnect(), #1", "invalid state"); if (sdcp->state == SDC_READY) { chSysUnlock(); - return SDC_SUCCESS; + return FALSE; } sdcp->state = SDC_DISCONNECTING; chSysUnlock(); /* Waits for eventual pending operations completion.*/ if (_sdc_wait_for_transfer_state(sdcp)) - return SDC_FAILED; + return TRUE; /* Card clock stopped.*/ sdc_lld_stop_clk(sdcp); sdcp->state = SDC_READY; - return SDC_SUCCESS; + return FALSE; } /** @@ -402,8 +402,8 @@ bool_t sdcDisconnect(SDCDriver *sdcp) { * @param[in] n number of blocks to read * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @api */ @@ -415,7 +415,7 @@ bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk, if ((startblk + n - 1) > sdcp->capacity){ sdcp->errors |= SDC_OVERFLOW_ERROR; - return SDC_FAILED; + return TRUE; } chSysLock(); @@ -439,8 +439,8 @@ bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk, * @param[in] n number of blocks to write * * @return The operation status. - * @retval SDC_SUCCESS operation succeeded. - * @retval SDC_FAILED operation failed. + * @retval FALSE operation succeeded. + * @retval TRUE operation failed. * * @api */ @@ -452,7 +452,7 @@ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, if ((startblk + n - 1) > sdcp->capacity){ sdcp->errors |= SDC_OVERFLOW_ERROR; - return SDC_FAILED; + return TRUE; } chSysLock(); diff --git a/testhal/STM32F4xx/SDC/main.c b/testhal/STM32F4xx/SDC/main.c index 6bbcdea89..e641aa555 100755 --- a/testhal/STM32F4xx/SDC/main.c +++ b/testhal/STM32F4xx/SDC/main.c @@ -79,10 +79,10 @@ bool_t badblocks(uint32_t start, uint32_t end, uint32_t blockatonce, uint8_t pat goto ERROR; position += blockatonce; } - return SDC_SUCCESS; + return FALSE; ERROR: - return SDC_FAILED; + return TRUE; } /** -- cgit v1.2.3 From 469211b330aaa187de511a8e3963feac1db51053 Mon Sep 17 00:00:00 2001 From: barthess Date: Mon, 16 Apr 2012 20:14:08 +0000 Subject: SDC. Safety improvements in capacity detection code. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/sdc_dev2@4104 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/sdc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index d883eac39..96c1b4561 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -340,6 +340,10 @@ bool_t sdcConnect(SDCDriver *sdcp) { a = _sdc_get_slice(sdcp->csd, SDC_CSD_20_C_SIZE_SLICE); sdcp->capacity = 1024 * (a + 1); break; + default: + /* Reserved value detected. */ + sdcp->capacity = 0; + break; } if (sdcp->capacity == 0) goto failed; -- cgit v1.2.3