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

master
gdisirio 2012-05-09 17:00:03 +00:00
parent 8f8b7f2c69
commit 7f87eee586
11 changed files with 440 additions and 76 deletions

View File

@ -49,6 +49,21 @@ void __early_init(void) {
stm32_clock_init();
}
#if HAL_USE_SDC
/* Board-related functions related to the SDC driver.*/
bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp) {
(void)sdcp;
return !palReadPad(GPIOF, GPIOF_SD_DETECT);
}
bool_t sdc_lld_is_write_protected(SDCDriver *sdcp) {
(void)sdcp;
return FALSE;
}
#endif
/*
* Board-specific initialization code.
*/

View File

@ -52,33 +52,6 @@ static unsigned cnt;
*/
static EventSource inserted_event, removed_event;
/**
* @brief Insertion monitor function.
*
* @param[in] sdcp pointer to the @p SDCDriver object
*
* @notapi
*/
bool_t sdc_lld_is_card_inserted(SDCDriver *sdcp) {
(void)sdcp;
return !palReadPad(GPIOF, GPIOF_SD_DETECT);
}
/**
* @brief Protection detection.
* @note Not supported.
*
* @param[in] sdcp pointer to the @p SDCDriver object
*
* @notapi
*/
bool_t sdc_lld_is_write_protected(SDCDriver *sdcp) {
(void)sdcp;
return FALSE;
}
/**
* @brief Insertion monitor timer callback function.
*

View File

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

View File

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

View File

@ -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. */
/*===========================================================================*/
@ -62,13 +48,6 @@
* @name MMC_SPI configuration options
* @{
*/
/**
* @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
@ -138,9 +117,15 @@ 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.
*/
@ -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

160
os/hal/include/mmcsd.h Normal file
View File

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

View File

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

View File

@ -197,6 +197,10 @@ typedef struct {
* @brief Structure representing an SDC driver.
*/
struct SDCDriver {
/**
* @brief Virtual Methods Table.
*/
const struct MMCSDBlockDeviceVMT *vmt;
/**
* @brief Driver state.
*/

View File

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

View File

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

View File

@ -123,13 +123,16 @@
3484947)(backported to 2.4.1).
- FIX: Fixed various minor documentation errors (bug 3484942)(backported
to 2.4.1).
- NEW: Added two new functions to the MMC_SPI driver: mmcSync() and
mmc_Get_Info(). Also added the capability to operate through the new
block devices abstract interface.
- NEW: Added an abstract interface for block devices in the HAL. This
abstraction layer is meant to unify the access protocol to the SDC and
MMC_SPI (and potentially others) device drivers.
- NEW: Added an abstract interface for serial devices in the HAL. This
interface is meant to replace the equivalent class already present in the
kernel. access macros are similar except for the prefix, "chn" instead
of "chIO".
- NEW: Added an abstract interface for block devices in the HAL. This
abstraction layer is meant to unify the access protocol to the SDC and
MMC_SPI (and potentially others) device drivers.
- NEW: Updated the MSP port to work with the latest MSPGCC compiler (4.6.3
LTS 20120406 unpatched), now the old MSPGCC 3.2.3 is no more supported
(backported to 2.4.1).