aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-05-09 17:00:03 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-05-09 17:00:03 +0000
commit7f87eee586adf22f28b1687ef92051065a0a5ee5 (patch)
treea3d199558c7671e31e9ebac4f79f8f4596e2493e /os
parent8f8b7f2c69575736da9004c8dc45c770b0f08c48 (diff)
downloadChibiOS-7f87eee586adf22f28b1687ef92051065a0a5ee5.tar.gz
ChibiOS-7f87eee586adf22f28b1687ef92051065a0a5ee5.tar.bz2
ChibiOS-7f87eee586adf22f28b1687ef92051065a0a5ee5.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4178 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/include/hal.h7
-rw-r--r--os/hal/include/io_block.h8
-rw-r--r--os/hal/include/mmc_spi.h31
-rw-r--r--os/hal/include/mmcsd.h160
-rw-r--r--os/hal/include/sdc.h3
-rw-r--r--os/hal/platforms/STM32/sdc_lld.h4
-rw-r--r--os/hal/src/mmc_spi.c180
-rw-r--r--os/hal/src/sdc.c72
8 files changed, 419 insertions, 46 deletions
diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h
index 4e5bf0b24..d8de4d936 100644
--- a/os/hal/include/hal.h
+++ b/os/hal/include/hal.h
@@ -34,9 +34,14 @@
#include "hal_lld.h"
+/* Abstract interfaces.*/
#include "io_channel.h"
#include "io_block.h"
+/* Shared headers.*/
+#include "mmcsd.h"
+
+/* Layered drivers.*/
#include "tm.h"
#include "pal.h"
#include "adc.h"
@@ -53,6 +58,8 @@
#include "spi.h"
#include "uart.h"
#include "usb.h"
+
+/* Complex drivers.*/
#include "mmc_spi.h"
#include "serial_usb.h"
diff --git a/os/hal/include/io_block.h b/os/hal/include/io_block.h
index b12ae4588..2e47eb10a 100644
--- a/os/hal/include/io_block.h
+++ b/os/hal/include/io_block.h
@@ -192,6 +192,10 @@ typedef struct {
*
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
*
+ * @return The operation status.
+ * @retval FALSE operation succeeded.
+ * @retval TRUE operation failed.
+ *
* @api
*/
#define blkSync(ip) ((ip)->vmt->sync(ip))
@@ -202,6 +206,10 @@ typedef struct {
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
* @param[out] bdip pointer to a @p BlockDeviceInfo structure
*
+ * @return The operation status.
+ * @retval FALSE operation succeeded.
+ * @retval TRUE operation failed.
+ *
* @api
*/
#define blkGetInfo(ip, bdip) ((ip)->vmt->get_info(ip, bdip))
diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h
index 1d624aeff..fd2850576 100644
--- a/os/hal/include/mmc_spi.h
+++ b/os/hal/include/mmc_spi.h
@@ -40,20 +40,6 @@
#define MMC_ACMD41_RETRY 100
#define MMC_WAIT_DATA 10000
-#define MMC_CMDGOIDLE 0
-#define MMC_CMDINIT 1
-#define MMC_CMDINTERFACE_CONDITION 8
-#define MMC_CMDREADCSD 9
-#define MMC_CMDSTOP 12
-#define MMC_CMDSETBLOCKLEN 16
-#define MMC_CMDREAD 17
-#define MMC_CMDREADMULTIPLE 18
-#define MMC_CMDWRITE 24
-#define MMC_CMDWRITEMULTIPLE 25
-#define MMC_CMDAPP 55
-#define MMC_CMDREADOCR 58
-#define MMC_ACMDOPCONDITION 41
-
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -63,13 +49,6 @@
* @{
*/
/**
- * @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
@@ -138,10 +117,16 @@ typedef struct {
} MMCConfig;
/**
- * @brief Structure representing a MMC driver.
+ * @extends MMCSDBlockDevice
+ *
+ * @brief Structure representing a MMC/SD over SPI driver.
*/
typedef struct {
/**
+ * @brief Virtual Methods Table.
+ */
+ const struct MMCSDBlockDeviceVMT *vmt;
+ /**
* @brief Driver state.
*/
mmcstate_t state;
@@ -243,6 +228,8 @@ extern "C" {
bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk);
bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer);
bool_t mmcStopSequentialWrite(MMCDriver *mmcp);
+ bool_t mmcSync(MMCDriver *mmcp);
+ bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/include/mmcsd.h b/os/hal/include/mmcsd.h
new file mode 100644
index 000000000..fbea45245
--- /dev/null
+++ b/os/hal/include/mmcsd.h
@@ -0,0 +1,160 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file mmcsd.h
+ * @brief MMC/SD cards header.
+ *
+ * @addtogroup MMCSD
+ * @{
+ */
+
+#ifndef _MMCSD_H_
+#define _MMCSD_H_
+
+#if HAL_USE_MMC_SPI || HAL_USE_SDC || defined(__DOXYGEN__)
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Fixed block size for MMC/SD block devices.
+ */
+#define SDMMC_BLOCK_SIZE 512
+
+/**
+ * @brief Mask of error bits in R1 responses.
+ */
+#define SDMMC_R1_ERROR_MASK 0xFDFFE008
+
+/**
+ * @brief Fixed pattern for CMD8.
+ */
+#define SDMMC_CMD8_PATTERN 0x000001AA
+
+/**
+ * @name SD/MMC status conditions
+ * @{
+ */
+#define SDMMC_STS_IDLE 0
+#define SDMMC_STS_READY 1
+#define SDMMC_STS_IDENT 2
+#define SDMMC_STS_STBY 3
+#define SDMMC_STS_TRAN 4
+#define SDMMC_STS_DATA 5
+#define SDMMC_STS_RCV 6
+#define SDMMC_STS_PRG 7
+#define SDMMC_STS_DIS 8
+/** @} */
+
+/**
+ * @name SD/MMC commands
+ * @{
+ */
+#define SDMMC_CMD_GO_IDLE_STATE 0
+#define SDMMC_CMD_INIT 1
+#define SDMMC_CMD_ALL_SEND_CID 2
+#define SDMMC_CMD_SEND_RELATIVE_ADDR 3
+#define SDMMC_CMD_SET_BUS_WIDTH 6
+#define SDMMC_CMD_SEL_DESEL_CARD 7
+#define SDMMC_CMD_SEND_IF_COND 8
+#define SDMMC_CMD_SEND_CSD 9
+#define SDMMC_CMD_STOP_TRANSMISSION 12
+#define SDMMC_CMD_SEND_STATUS 13
+#define SDMMC_CMD_SET_BLOCKLEN 16
+#define SDMMC_CMD_READ_SINGLE_BLOCK 17
+#define SDMMC_CMD_READ_MULTIPLE_BLOCK 18
+#define SDMMC_CMD_SET_BLOCK_COUNT 23
+#define SDMMC_CMD_WRITE_BLOCK 24
+#define SDMMC_CMD_WRITE_MULTIPLE_BLOCK 25
+#define SDMMC_CMD_APP_OP_COND 41
+#define SDMMC_CMD_LOCK_UNLOCK 42
+#define SDMMC_CMD_APP_CMD 55
+#define SDMMC_CMD_READ_OCR 58
+/** @} */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief @p MMCSDBlockDevice specific methods.
+ */
+#define _mmcsd_block_device_methods \
+ _base_block_device_methods
+
+/**
+ * @brief @p MMCSDBlockDevice specific data.
+ * @note It is empty because @p MMCSDBlockDevice is only an interface
+ * without implementation.
+ */
+#define _mmcsd_block_device_data \
+ _base_block_device_data
+
+/**
+ * @extends BaseBlockDeviceVMT
+ *
+ * @brief @p MMCSDBlockDevice virtual methods table.
+ */
+struct MMCSDBlockDeviceVMT {
+ _base_block_device_methods
+};
+
+/**
+ * @extends BaseBlockDevice
+ *
+ * @brief MCC/SD block device class.
+ * @details This class represents a, block-accessible, MMC/SD device.
+ */
+typedef struct {
+ /** @brief Virtual Methods Table.*/
+ const struct MMCSDBlockDeviceVMT *vmt;
+ _mmcsd_block_device_data
+} MMCSDBlockDevice;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_USE_MMC_SPI || HAL_USE_MMC_SDC*/
+
+#endif /* _MMCSD_H_ */
+
+/** @} */
diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h
index 82b083125..20c15c211 100644
--- a/os/hal/include/sdc.h
+++ b/os/hal/include/sdc.h
@@ -102,6 +102,7 @@
#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. */
@@ -332,6 +333,8 @@ extern "C" {
bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
const uint8_t *buffer, uint32_t n);
sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp);
+ bool_t sdcSync(SDCDriver *sdcp);
+ bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip);
bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp);
#ifdef __cplusplus
}
diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h
index cfa36fd25..5d31827b4 100644
--- a/os/hal/platforms/STM32/sdc_lld.h
+++ b/os/hal/platforms/STM32/sdc_lld.h
@@ -198,6 +198,10 @@ typedef struct {
*/
struct SDCDriver {
/**
+ * @brief Virtual Methods Table.
+ */
+ const struct MMCSDBlockDeviceVMT *vmt;
+ /**
* @brief Driver state.
*/
sdcstate_t state;
diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c
index c022e4a68..4fdec3f12 100644
--- a/os/hal/src/mmc_spi.c
+++ b/os/hal/src/mmc_spi.c
@@ -48,6 +48,28 @@
/* Driver local variables. */
/*===========================================================================*/
+/* Forward declarations required by mmc_vmt.*/
+bool_t mmc_is_inserted(void *instance);
+bool_t mmc_is_protected(void *instance);
+bool_t mmc_read(void *instance, uint32_t startblk,
+ uint8_t *buffer, uint32_t n);
+bool_t mmc_write(void *instance, uint32_t startblk,
+ const uint8_t *buffer, uint32_t n);
+
+/**
+ * @brief Virtual methods table.
+ */
+static const struct MMCSDBlockDeviceVMT mmc_vmt = {
+ mmc_is_inserted,
+ mmc_is_protected,
+ (bool_t (*)(void *))mmcConnect,
+ (bool_t (*)(void *))mmcDisconnect,
+ mmc_read,
+ mmc_write,
+ (bool_t (*)(void *))mmcSync,
+ (bool_t (*)(void *, BlockDeviceInfo *))mmcGetInfo
+};
+
/**
* @brief Lookup table for CRC-7 ( based on polynomial x^7 + x^3 + 1).
*/
@@ -80,6 +102,48 @@ static const uint8_t crc7_lookup_table[256] = {
/* Driver local functions. */
/*===========================================================================*/
+bool_t mmc_is_inserted(void *instance) {
+
+ return ((MMCDriver *)instance)->is_inserted();
+}
+
+bool_t mmc_is_protected(void *instance) {
+
+ return ((MMCDriver *)instance)->is_protected();
+}
+
+bool_t mmc_read(void *instance, uint32_t startblk,
+ uint8_t *buffer, uint32_t n) {
+
+ if (mmcStartSequentialRead((MMCDriver *)instance, startblk))
+ return TRUE;
+ while (n > 0) {
+ if (mmcSequentialRead((MMCDriver *)instance, buffer))
+ return TRUE;
+ buffer += SDMMC_BLOCK_SIZE;
+ n--;
+ }
+ if (mmcStopSequentialRead((MMCDriver *)instance))
+ return TRUE;
+ return FALSE;
+}
+
+bool_t mmc_write(void *instance, uint32_t startblk,
+ const uint8_t *buffer, uint32_t n) {
+
+ if (mmcStartSequentialWrite((MMCDriver *)instance, startblk))
+ return TRUE;
+ while (n > 0) {
+ if (mmcSequentialWrite((MMCDriver *)instance, buffer))
+ return TRUE;
+ buffer += SDMMC_BLOCK_SIZE;
+ n--;
+ }
+ if (mmcStopSequentialWrite((MMCDriver *)instance))
+ return TRUE;
+ return FALSE;
+}
+
/**
* @brief Calculate the MMC standard CRC-7 based on a lookup table.
*
@@ -321,6 +385,7 @@ void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip,
const SPIConfig *lscfg, const SPIConfig *hscfg,
mmcquery_t is_protected, mmcquery_t is_inserted) {
+ mmcp->vmt = &mmc_vmt;
mmcp->state = MMC_STOP;
mmcp->config = NULL;
mmcp->spip = spip;
@@ -387,6 +452,7 @@ void mmcStop(MMCDriver *mmcp) {
* handler.
*
* @param[in] mmcp pointer to the @p MMCDriver object
+ *
* @return The operation status.
* @retval FALSE the operation succeeded and the driver is now
* in the @p MMC_READY state.
@@ -411,7 +477,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
/* SPI mode selection.*/
i = 0;
while (TRUE) {
- if (send_command_R1(mmcp, MMC_CMDGOIDLE, 0) == 0x01)
+ if (send_command_R1(mmcp, SDMMC_CMD_GO_IDLE_STATE, 0) == 0x01)
break;
if (++i >= MMC_CMD0_RETRY)
return TRUE;
@@ -419,20 +485,19 @@ bool_t mmcConnect(MMCDriver *mmcp) {
}
/* Try to detect if this is a high capacity card and switch to block
- * addresses if possible.
- *
- * This method is based on "How to support SDC Ver2 and high capacity cards"
- * by ElmChan.
- *
- * */
+ addresses if possible.
+ This method is based on "How to support SDC Ver2 and high capacity cards"
+ by ElmChan.*/
uint8_t r3[4];
- if(send_command_R3(mmcp, MMC_CMDINTERFACE_CONDITION, 0x01AA, r3) != 0x05){
+ if (send_command_R3(mmcp, SDMMC_CMD_SEND_IF_COND,
+ SDMMC_CMD8_PATTERN, r3) != 0x05) {
- /* Switch to SDHC mode */
+ /* Switch to SDHC mode.*/
i = 0;
while (TRUE) {
- if ((send_command_R1(mmcp, MMC_CMDAPP, 0) == 0x01) &&
- (send_command_R3(mmcp, MMC_ACMDOPCONDITION, 0x400001aa, r3) == 0x00))
+ if ((send_command_R1(mmcp, SDMMC_CMD_APP_CMD, 0) == 0x01) &&
+ (send_command_R3(mmcp, SDMMC_CMD_APP_OP_COND,
+ 0x400001aa, r3) == 0x00))
break;
if (++i >= MMC_ACMD41_RETRY)
@@ -441,17 +506,17 @@ bool_t mmcConnect(MMCDriver *mmcp) {
}
/* Execute dedicated read on OCR register */
- send_command_R3(mmcp, MMC_CMDREADOCR, 0, r3);
+ send_command_R3(mmcp, SDMMC_CMD_READ_OCR, 0, r3);
- /* Check if CCS is set in response. Card operates in block mode if set */
+ /* Check if CCS is set in response. Card operates in block mode if set.*/
if(r3[0] & 0x40)
mmcp->block_addresses = TRUE;
}
- /* Initialization. */
+ /* Initialization.*/
i = 0;
while (TRUE) {
- uint8_t b = send_command_R1(mmcp, MMC_CMDINIT, 0);
+ uint8_t b = send_command_R1(mmcp, SDMMC_CMD_INIT, 0);
if (b == 0x00)
break;
if (b != 0x01)
@@ -461,11 +526,12 @@ bool_t mmcConnect(MMCDriver *mmcp) {
chThdSleepMilliseconds(10);
}
- /* Initialization complete, full speed. */
+ /* Initialization complete, full speed.*/
spiStart(mmcp->spip, mmcp->hscfg);
/* Setting block size.*/
- if (send_command_R1(mmcp, MMC_CMDSETBLOCKLEN, MMC_SECTOR_SIZE) != 0x00)
+ if (send_command_R1(mmcp, SDMMC_CMD_SET_BLOCKLEN,
+ SDMMC_BLOCK_SIZE) != 0x00)
return TRUE;
/* Transition to MMC_READY state (if not extracted).*/
@@ -490,6 +556,7 @@ bool_t mmcConnect(MMCDriver *mmcp) {
*
* @param[in] mmcp pointer to the @p MMCDriver object
* @return The operation status.
+ *
* @retval FALSE the operation succeeded and the driver is now
* in the @p MMC_INSERTED state.
* @retval TRUE the operation failed.
@@ -525,6 +592,7 @@ bool_t mmcDisconnect(MMCDriver *mmcp) {
*
* @param[in] mmcp pointer to the @p MMCDriver object
* @param[in] startblk first block to read
+ *
* @return The operation status.
* @retval FALSE the operation succeeded.
* @retval TRUE the operation failed.
@@ -547,9 +615,9 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
spiSelect(mmcp->spip);
if(mmcp->block_addresses)
- send_hdr(mmcp, MMC_CMDREADMULTIPLE, startblk);
+ send_hdr(mmcp, SDMMC_CMD_READ_MULTIPLE_BLOCK, startblk);
else
- send_hdr(mmcp, MMC_CMDREADMULTIPLE, startblk * MMC_SECTOR_SIZE);
+ send_hdr(mmcp, SDMMC_CMD_READ_MULTIPLE_BLOCK, startblk * SDMMC_BLOCK_SIZE);
if (recvr1(mmcp) != 0x00) {
spiUnselect(mmcp->spip);
@@ -567,6 +635,7 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
*
* @param[in] mmcp pointer to the @p MMCDriver object
* @param[out] buffer pointer to the read buffer
+ *
* @return The operation status.
* @retval FALSE the operation succeeded.
* @retval TRUE the operation failed.
@@ -588,7 +657,7 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
for (i = 0; i < MMC_WAIT_DATA; i++) {
spiReceive(mmcp->spip, 1, buffer);
if (buffer[0] == 0xFE) {
- spiReceive(mmcp->spip, MMC_SECTOR_SIZE, buffer);
+ spiReceive(mmcp->spip, SDMMC_BLOCK_SIZE, buffer);
/* CRC ignored. */
spiIgnore(mmcp->spip, 2);
return FALSE;
@@ -607,6 +676,7 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
* @brief Stops a sequential read gracefully.
*
* @param[in] mmcp pointer to the @p MMCDriver object
+ *
* @return The operation status.
* @retval FALSE the operation succeeded.
* @retval TRUE the operation failed.
@@ -614,7 +684,8 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
* @api
*/
bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
- static const uint8_t stopcmd[] = {0x40 | MMC_CMDSTOP, 0, 0, 0, 0, 1, 0xFF};
+ static const uint8_t stopcmd[] = {0x40 | SDMMC_CMD_STOP_TRANSMISSION,
+ 0, 0, 0, 0, 1, 0xFF};
bool_t result;
chDbgCheck(mmcp != NULL, "mmcStopSequentialRead");
@@ -645,6 +716,7 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
*
* @param[in] mmcp pointer to the @p MMCDriver object
* @param[in] startblk first block to write
+ *
* @return The operation status.
* @retval FALSE the operation succeeded.
* @retval TRUE the operation failed.
@@ -666,9 +738,10 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
spiStart(mmcp->spip, mmcp->hscfg);
spiSelect(mmcp->spip);
if(mmcp->block_addresses)
- send_hdr(mmcp, MMC_CMDWRITEMULTIPLE, startblk);
+ send_hdr(mmcp, SDMMC_CMD_WRITE_MULTIPLE_BLOCK, startblk);
else
- send_hdr(mmcp, MMC_CMDWRITEMULTIPLE, startblk * MMC_SECTOR_SIZE);
+ send_hdr(mmcp, SDMMC_CMD_WRITE_MULTIPLE_BLOCK,
+ startblk * SDMMC_BLOCK_SIZE);
if (recvr1(mmcp) != 0x00) {
@@ -687,6 +760,7 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
*
* @param[in] mmcp pointer to the @p MMCDriver object
* @param[out] buffer pointer to the write buffer
+ *
* @return The operation status.
* @retval FALSE the operation succeeded.
* @retval TRUE the operation failed.
@@ -707,7 +781,7 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
chSysUnlock();
spiSend(mmcp->spip, sizeof(start), start); /* Data prologue. */
- spiSend(mmcp->spip, MMC_SECTOR_SIZE, buffer); /* Data. */
+ spiSend(mmcp->spip, SDMMC_BLOCK_SIZE, buffer); /* Data. */
spiIgnore(mmcp->spip, 2); /* CRC ignored. */
spiReceive(mmcp->spip, 1, b);
if ((b[0] & 0x1F) == 0x05) {
@@ -728,6 +802,7 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
* @brief Stops a sequential write gracefully.
*
* @param[in] mmcp pointer to the @p MMCDriver object
+ *
* @return The operation status.
* @retval FALSE the operation succeeded.
* @retval TRUE the operation failed.
@@ -759,6 +834,63 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) {
return TRUE;
}
+/**
+ * @brief Waits for card idle condition.
+ *
+ * @param[in] mmcp pointer to the @p MMCDriver object
+ *
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed.
+ *
+ * @api
+ */
+bool_t mmcSync(MMCDriver *mmcp) {
+
+ chDbgCheck(mmcp != NULL, "mmcSync");
+
+ chSysLock();
+ if (mmcp->state != MMC_READY) {
+ chSysUnlock();
+ return TRUE;
+ }
+ chSysUnlock();
+
+ sync(mmcp);
+
+ return FALSE;
+}
+
+/**
+ * @brief Returns the media info.
+ *
+ * @param[in] mmcp pointer to the @p MMCDriver object
+ * @param[out] bdip pointer to a @p BlockDeviceInfo structure
+ *
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed.
+ *
+ * @api
+ */
+bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip) {
+
+
+ chDbgCheck((mmcp != NULL) && (bdip != NULL), "mmcGetInfo");
+
+ chSysLock();
+ if (mmcp->state != MMC_READY) {
+ chSysUnlock();
+ return TRUE;
+ }
+ chSysUnlock();
+
+ bdip->blk_num = 0; /* NOTE: To be implemented.*/
+ bdip->blk_size = SDMMC_BLOCK_SIZE;
+
+ return FALSE;
+}
+
#endif /* HAL_USE_MMC_SPI */
/** @} */
diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c
index 6e9dcabd4..483263776 100644
--- a/os/hal/src/sdc.c
+++ b/os/hal/src/sdc.c
@@ -43,6 +43,20 @@
/* Driver local variables. */
/*===========================================================================*/
+/**
+ * @brief Virtual methods table.
+ */
+static const struct MMCSDBlockDeviceVMT sdc_vmt = {
+ (bool_t (*)(void *))sdc_lld_is_card_inserted,
+ (bool_t (*)(void *))sdc_lld_is_write_protected,
+ (bool_t (*)(void *))sdcConnect,
+ (bool_t (*)(void *))sdcDisconnect,
+ (bool_t (*)(void *, uint32_t, uint8_t *, uint32_t))sdcRead,
+ (bool_t (*)(void *, uint32_t, const uint8_t *, uint32_t))sdcWrite,
+ (bool_t (*)(void *))sdcSync,
+ (bool_t (*)(void *, BlockDeviceInfo *))sdcGetInfo
+};
+
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
@@ -147,6 +161,7 @@ void sdcInit(void) {
*/
void sdcObjectInit(SDCDriver *sdcp) {
+ sdcp->vmt = &sdc_vmt;
sdcp->state = SDC_STOP;
sdcp->errors = SDC_NO_ERROR;
sdcp->config = NULL;
@@ -486,6 +501,63 @@ sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp) {
return flags;
}
+/**
+ * @brief Waits for card idle condition.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ *
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed.
+ *
+ * @api
+ */
+bool_t sdcSync(SDCDriver *sdcp) {
+
+ chDbgCheck(sdcp != NULL, "sdcSync");
+
+ chSysLock();
+ if (sdcp->state != SDC_READY) {
+ chSysUnlock();
+ return TRUE;
+ }
+ chSysUnlock();
+
+ /* TODO: implement.*/
+
+ return FALSE;
+}
+
+/**
+ * @brief Returns the media info.
+ *
+ * @param[in] sdcp pointer to the @p SDCDriver object
+ * @param[out] bdip pointer to a @p BlockDeviceInfo structure
+ *
+ * @return The operation status.
+ * @retval FALSE the operation succeeded.
+ * @retval TRUE the operation failed.
+ *
+ * @api
+ */
+bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip) {
+
+
+ chDbgCheck((sdcp != NULL) && (bdip != NULL), "sdcGetInfo");
+
+ chSysLock();
+ if (sdcp->state != SDC_READY) {
+ chSysUnlock();
+ return TRUE;
+ }
+ chSysUnlock();
+
+ bdip->blk_num = 0; /* NOTE: To be implemented.*/
+ bdip->blk_size = SDMMC_BLOCK_SIZE;
+
+ return FALSE;
+}
+
#endif /* HAL_USE_SDC */
/** @} */