X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fdrv%2Fsd.h;h=8b85240a0c60ac7da020a32bde146e4581bca023;hb=00a373a2b0382bcf9fe234db2964eb75a0cd2a5d;hp=9436c71a1879abf78657fcdccf23b329385c6fad;hpb=6fc70471426c7427c1c4f1e8dffbed557ff90b44;p=bertos.git diff --git a/bertos/drv/sd.h b/bertos/drv/sd.h index 9436c71a..8b85240a 100644 --- a/bertos/drv/sd.h +++ b/bertos/drv/sd.h @@ -31,88 +31,161 @@ * * \brief Function library for secure digital memory. * - * Right now, the interface for these function is the one defined in diskio.h from - * the FatFS module. * - * \version $Id$ * \author Francesco Sacchi - * + * * $WIZ$ module_name = "sd" - * $WIZ$ module_configuration = "bertos/cfg/cfg_fat.h" - * $WIZ$ module_depends = "kfile", "timer" + * $WIZ$ module_depends = "kfile", "timer", "kblock", "sd_spi" * $WIZ$ module_hw = "bertos/hw/hw_sd.h" + * $WIZ$ module_configuration = "bertos/cfg/cfg_sd.h" */ #ifndef DRV_SD_H #define DRV_SD_H +#include "cfg/cfg_sd.h" + +#include +#include + #include -#include -#include "cfg/cfg_fat.h" -bool sd_test(void); +typedef struct SdCID +{ + uint8_t manfid; + uint8_t prod_name[8]; + uint32_t serial; + uint16_t oemid; + uint32_t year_off; + uint8_t m_rev; + uint8_t l_rev; +}SdCID; + +typedef struct SdCSD +{ + uint8_t structure; + uint8_t ccc; ///< Card command classes + uint32_t erase_size; ///< The size of an erasable sector, in write block len + uint32_t capacity; ///< Card size in byte + uint32_t max_data_rate; ///< Step rate, usec + uint32_t block_len; ///< Block data size len in byte + uint32_t block_num; ///< Number of block in card + uint32_t write_blk_bits; ///< Max write block length in bits + uint32_t read_blk_bits; ///< Max read block length in bits + uint8_t read_partial:1, + read_misalign:1, + write_partial:1, + write_misalign:1; +} SdCSD; + +typedef struct SdSSR +{ + uint8_t bus_width; + uint8_t card_type; + uint8_t speed_class; + uint8_t au_size; + uint8_t erase_size; +} SdSSR; + +#define SD_START_DELAY 10 +#define SD_INIT_TIMEOUT ms_to_ticks(2000) +#define SD_IDLE_RETRIES 4 +#define SD_DEFAULT_BLOCKLEN 512 /** - * Initializes the SD driver. - * - * \param _fd A pointer to a kfile where the SD will read/write to. - * \return true if initialization succeds, false otherwise. + * $WIZ$ sd_mode = "SD_SDMMC_MODE", "SD_SPI_MODE" + * \{ */ -bool sd_init(KFile *_fd); +#define SD_SDMMC_MODE 0 +#define SD_SPI_MODE 1 +/** \} */ -#if CONFIG_FAT_DRIVES == 1 +#define SD_UNBUFFERED BV(0) ///< Open SD memory disabling page caching, no modification and partial write are allowed. - /** - * Same as sd_disk_status. - * - * Card initialization must be done with sd_init. - */ - #define sd_disk_initialize disk_initialize +struct SdHardware* hw; +/** + * SD Card context structure. + */ +typedef struct Sd +{ + KBlock b; ///< KBlock base class + KFile *ch; ///< SPI communication channel + struct SdHardware* hw; + uint32_t addr; + uint32_t status; +} Sd; + +bool sd_hw_initUnbuf(Sd *sd, KFile *ch); +bool sd_hw_initBuf(Sd *sd, KFile *ch); + +bool sd_spi_initUnbuf(Sd *sd, KFile *ch); +bool sd_spi_initBuf(Sd *sd, KFile *ch); + +// For old compatibility. +#ifndef CONFIG_SD_MODE + #define CONFIG_SD_MODE SD_SPI_MODE + #define SD_INCLUDE_SPI_SOURCE +#endif + +#if CONFIG_SD_OLD_INIT + + #if !(ARCH & ARCH_NIGHTTEST) + #warning "Deprecated: this API will be removed in the next major release," + #warning "please disable CONFIG_SD_OLD_INIT and pass explicitly the SD context to sd_init()." + #endif /** - * Return the status of the disk. + * Initializes the SD driver. * - * \param drv The number of the drive to initialize. Currently only drive 0 is allowed. - * \return RES_OK if the sd card was correctly initialized by a previous call to sd_init(), STA_NOINIT otherwise. - */ - #define sd_disk_status disk_status - /** - * Read \a count sectors from SD card. + * \param ch A pointer to a SPI channel where the SD will read/write to. + * + * \return true if initialization succeds, false otherwise. * - * \param drv The drive number to read from. Only 0 is supported. - * \param buf A buffer to store read data. You can get sector size using sd_disk_ioctl. - * \param sector Start sector number. - * \param count The number of sectors to read. - * \return RES_OK if the function succeded, RES_ERROR if any error occurred, RES_NOTRDY if the disk is not initialized. + * \note This API is deprecated, disable CONFIG_SD_OLD_INIT and + * use the new one instead. * - * \sa diskio.h + * \see CONFIG_SD_OLD_INIT. */ - #define sd_disk_read disk_read - - #if CONFIG_FAT_FS_READONLY == 0 - - /** - * Write \a count sectors to SD card. - * - * \param drv The drive number to read from. Only 0 is supported. - * \param buf The data to be written. - * \param sector Start sector number. - * \param count The number of sectors to write. - * \return RES_OK if the function succeded, RES_ERROR if any error occurred, RES_NOTRDY if the disk is not initialized. - * - * \sa diskio.h - */ - #define sd_disk_write disk_write + #if CONFIG_SD_MODE == SD_SPI_MODE + #define sd_init(ch) {static struct Sd sd; sd_spi_initUnbuf(&sd, (ch));} + #else + #define sd_init(ch) {static struct Sd sd; sd_hw_initUnbuf(&sd, (ch));} #endif +#else + /** - * Interface to send device independant commands to the device. + * Initializes the SD driver. * - * \sa diskio.h and related documentation for further explanations. + * \param sd The SD KBlock context. + * \param ch A pointer to a SPI channel where the SD will read/write to. + * \param buffered Set to true if you want the KBlock to be buffered, + * to false otherwise. The FatFs module does not require the device + * to be buffered because it has an internal cache. This will save + * 512 bytes of RAM in this case. + * + * \return true if initialization succeds, false otherwise. */ - #define sd_disk_ioctl disk_ioctl + #if CONFIG_SD_MODE == SD_SPI_MODE + #define sd_init(sd, ch, buffered) ((buffered & SD_UNBUFFERED) ? sd_spi_initUnbuf((sd), (ch)) : sd_spi_initBuf((sd), (ch))) + #else + #define sd_init(sd, ch, buffered) ((buffered & SD_UNBUFFERED) ? sd_hw_initUnbuf((sd), (ch)) : sd_hw_initBuf((sd), (ch))) + #endif + +#endif + -#endif /* CONFIG_FAT_DRIVES == 1 */ +#define KBT_SD MAKE_ID('S', 'D', 'B', 'K') + +bool sd_test(Sd *sd); +void sd_writeTest(Sd *sd); + +INLINE Sd *SD_CAST(KBlock *b) +{ + ASSERT(b->priv.type == KBT_SD); + return (Sd *)b; +} #endif /* DRV_SD_H */ +