#ifndef IO_H #define IO_H #include #include #include #include "iodev.h" static inline void pause(void) { /* Placeholder for anything that might want to be done while waiting */ } static inline void set_led(uint8_t leds) { LED = leds; } extern const uint32_t time_zero; static inline uint32_t rdtime(void) { uint32_t t; asm volatile("rdtime %0" : "=r" (t)); return t; } static inline uint64_t rdtimeq(void) { uint32_t l, h1, h0; asm volatile("rdtimeh %0; rdtime %1; %rdtimeh %2" : "=r" (h1), "=r" (l), "=r" (h0)); return ((int32_t)l < 0) ? h1 : h0; } static inline void udelay(uint32_t us) { uint32_t cycles = us * (CPU_HZ / 1000000); uint32_t start = rdtime(); while (rdtime() - start < cycles) pause(); } static inline void sd_set_mode(uint8_t divisor, bool cs) { SD_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) { flags ^= (flags & SD_BE) ? 3 : 0; *(volatile uint8_t *)IODEVA(SD_DEV,0,flags | SD_DATA) = d; } static inline void sd_writeh(uint16_t d, enum sd_data_flags flags) { flags ^= (flags & SD_BE) ? 2 : 0; *(volatile uint16_t *)IODEVA(SD_DEV,0,flags | SD_DATA) = d; } static inline void sd_writel(uint32_t d, enum sd_data_flags flags) { *(volatile uint32_t *)IODEVA(SD_DEV,0,flags | SD_DATA) = d; } static inline uint8_t sd_readb(enum sd_data_flags flags) { flags ^= (flags & SD_BE) ? 0 : 3; return *(volatile uint8_t *)IODEVA(SD_DEV,0,flags | SD_DATA); } static inline uint16_t sd_readh(enum sd_data_flags flags) { flags ^= (flags & SD_BE) ? 0 : 2; return *(volatile uint16_t *)IODEVA(SD_DEV,0,flags | SD_DATA); } static inline uint32_t sd_readl(enum sd_data_flags flags) { return *(volatile uint32_t *)IODEVA(SD_DEV,0,flags | SD_DATA); } static inline uint8_t sd_crc7_rd(void) { return SD_CRC7_RD; } static inline uint8_t sd_crc7_wr(void) { return SD_CRC7_WR; } static inline uint16_t sd_crc16_rd(void) { return SD_CRC16_RD; } static inline uint8_t sd_crc16_wr(void) { return SD_CRC16_WR; } #endif /* IO_H */