#ifndef SDCARD_H #define SDCARD_H #include "common.h" #include "io.h" #include "irq.h" #include "ff.h" #include "diskio.h" #define SECTOR_SHIFT 9 #define SECTOR_SIZE (1UL << SECTOR_SHIFT) struct sdcard_csd { uint32_t raw[4]; }; struct sdcard_cid { uint32_t raw[4]; }; struct sdcard_info { DSTATUS status; /* Physical status */ DSTATUS fsstatus; /* Filesystem visible status */ int8_t card_type; unsigned long lbasize; uint32_t if_cond; uint32_t ocr; struct sdcard_csd csd; struct sdcard_cid cid; }; extern struct sdcard_info sdc; typedef unsigned int sector_t; extern int sdcard_read_sectors(void *, sector_t, int); extern int sdcard_write_sectors(const void *, sector_t, int); extern void sdcard_reset(void); extern DSTATUS sdcard_init(void); extern DSTATUS sdcard_present_poll(void); static inline void sd_set_mode(uint8_t divisor, bool cs) { waitfor(SDCARD_IRQ); SDCARD_CTL_SPEED = (divisor - 1) | (cs << 7); } /* Read/write SD card and start transaction */ enum sd_data_flags { SD_B0 = 0x00, /* Byte offset 0 */ SD_B1 = 0x01, /* Byte offset 1 */ SD_B2 = 0x02, /* Byte offset 2 */ SD_B3 = 0x03, /* Byte offset 3 */ SD_GO8 = 0x04, /* Start 8-bit transaction */ SD_GO16 = 0x08, /* Start 16-bit transaction */ SD_GO32 = 0x0c, /* Start 32-bit transaction */ SD_BE = 0x10, /* Bigendian data */ SD_DATA = 0x20, /* Data register access (assumed) */ SD_CLEARCRC = 0x40 /* Clear CRC registers */ }; static inline void sd_writeb(uint8_t d, enum sd_data_flags flags) { waitfor(SDCARD_IRQ); flags ^= (flags & SD_BE) ? 3 : 0; *(volatile uint8_t *)IODEVA(SDCARD,0,flags | SD_DATA) = d; } static inline void sd_writeh(uint16_t d, enum sd_data_flags flags) { waitfor(SDCARD_IRQ); flags ^= (flags & SD_BE) ? 2 : 0; *(volatile uint16_t *)IODEVA(SDCARD,0,flags | SD_DATA) = d; } static inline void sd_writel(uint32_t d, enum sd_data_flags flags) { waitfor(SDCARD_IRQ); *(volatile uint32_t *)IODEVA(SDCARD,0,flags | SD_DATA) = d; } static inline uint8_t sd_readb(enum sd_data_flags flags) { waitfor(SDCARD_IRQ); flags ^= (flags & SD_BE) ? 0 : 3; return *(volatile uint8_t *)IODEVA(SDCARD,0,flags | SD_DATA); } static inline uint16_t sd_readh(enum sd_data_flags flags) { waitfor(SDCARD_IRQ); flags ^= (flags & SD_BE) ? 0 : 2; return *(volatile uint16_t *)IODEVA(SDCARD,0,flags | SD_DATA); } static inline uint32_t sd_readl(enum sd_data_flags flags) { waitfor(SDCARD_IRQ); return *(volatile uint32_t *)IODEVA(SDCARD,0,flags | SD_DATA); } static inline uint8_t sd_crc7_rd(void) { waitfor(SDCARD_IRQ); return SDCARD_CRC7_RD; } static inline uint8_t sd_crc7_wr(void) { waitfor(SDCARD_IRQ); return SDCARD_CRC7_WR; } static inline uint16_t sd_crc16_rd(void) { waitfor(SDCARD_IRQ); return SDCARD_CRC16_RD; } static inline uint16_t sd_crc16_wr(void) { waitfor(SDCARD_IRQ); return SDCARD_CRC16_WR; } #endif /* SDCARD_H */