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/src/sdc.c | 134 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 104 insertions(+), 30 deletions(-) (limited to 'os/hal/src') 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 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 --- os/hal/src/rtc.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'os/hal/src') 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. -- 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/src/rtc.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'os/hal/src') 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. -- 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(-) (limited to 'os/hal/src') 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/src/sdc.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'os/hal/src') 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/src/sdc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'os/hal/src') 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(-) (limited to 'os/hal/src') 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 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/src/sdc.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'os/hal/src') 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(); -- 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(+) (limited to 'os/hal/src') 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