📄 mmc.c
字号:
#define MMC_BLOCK_LENGTH 512 /* Taille d'un bloc. */
//*************** VARIABLES GLOBALES ***************//
unsigned short mmc_temp[4]; /* Variable temporaire. */
#define mmc_int (*(unsigned int*)(&mmc_temp[0]))
#define mmc_long (*(unsigned long*)(&mmc_temp[0]))
//*************** MACROS ***************//
#define mmc_enable() /* Active le p閞iph閞ique. */ \
\
portc.f2 = 0
#define mmc_disable() /* D閟active le p閞iph閞ique. */ \
\
portc.f2 = 1
#define mmc_read() /* Lit un octet dans le bloc ouvert. */ \
\
spi_read(0xFF)
#define mmc_write(B) /* Ecrit un octet dans le bloc ouvert. */ \
\
spi_write(B)
//*************** FONCTIONS "PRIVEES" ***************//
#define mmc_send_command(CMD,ADDR,CRC) /* Envoie une commande
* au p閞iph閞ique. */ \
\
spi_write(0xFF); \
spi_write(CMD); \
mmc_long = ADDR; \
spi_write(highest(mmc_long)); \
spi_write(higher(mmc_long)); \
spi_write(hi(mmc_long)); \
spi_write(lo(mmc_long)); \
spi_write(CRC)
#define mmc_wait_response(RESP) /* Attend une r閜onse du p閞iph閞ique. */ \
\
mmc_int = 0xFFFF; \
\
while( (spi_read(0xFF) != RESP) && (--mmc_int > 0))
#define mmc_response_ok() /* Vrai si la r閜onse est celle attendue. */ \
\
(mmc_int > 0)
//*************** FONCTIONS "PUBLIQUES" ***************//
#define mmc_init_inline() /* Fonction d'initialisation. */ \
\
unsigned short i; \
\
trisc = 0b10010000; \
portc = 0b00000000; \
\
spi_init_advanced(MASTER_OSC_DIV4, \
DATA_SAMPLE_END,CLK_IDLE_HIGH,HIGH_2_LOW); \
\
mmc_disable(); \
\
for( i = 0; i < 10; ++i) spi_write(0xFF); \
\
mmc_enable(); \
\
mmc_send_command(0x40,0x00,0x95); \
\
mmc_wait_response(0x01); \
if( !mmc_response_ok()) return 1; \
\
i = 0; \
\
while(1) { \
\
mmc_wait_response(0x00); \
if( mmc_response_ok()) break; \
if( i++ == 0xFF) return 1; \
mmc_send_command(0x41,0x00,0xFF); \
} \
\
mmc_disable(); \
\
spi_write(0xFF); \
\
mmc_enable(); \
\
mmc_send_command(0x50,MMC_BLOCK_LENGTH,0xFF); \
\
mmc_wait_response(0x00); \
if( !mmc_response_ok()) return 1; \
\
mmc_disable()
unsigned short mmc_init() {
mmc_init_inline();
return 0;
}
#define mmc_open_read_block_inline(BLK) /* Ouvre un bloc pour la lecture. */ \
\
mmc_enable(); \
\
mmc_send_command(0x51,(BLK) * MMC_BLOCK_LENGTH,0xFF); \
\
mmc_wait_response(0x00); \
if( !mmc_response_ok()) return 1; \
\
mmc_wait_response(0xFE); \
if( !mmc_response_ok()) return 1
unsigned short mmc_open_read_block(unsigned long block) {
mmc_open_read_block_inline(block);
return 0;
}
#define mmc_open_write_block_inline(BLK) /* Ouvre un bloc pour l'閏riture. */ \
\
mmc_enable(); \
\
mmc_send_command(0x58,(BLK) * MMC_BLOCK_LENGTH,0xFF); \
\
mmc_wait_response(0x00); \
if( !mmc_response_ok()) return 1; \
\
spi_write(0xFF); \
spi_write(0xFF); \
spi_write(0xFE)
unsigned short mmc_open_write_block(unsigned long block) {
mmc_open_write_block_inline(block);
return 0;
}
#define mmc_write_verif_inline() /* V閞ifie que l'閏riture est ok. */ \
\
mmc_wait_response(0x00); \
if( !mmc_response_ok()) return 1; \
\
mmc_wait_response(0xFF); \
if( !mmc_response_ok()) return 1; \
\
while( spi_read(0xFF) < 0xFF)
unsigned short mmc_write_verif() {
mmc_write_verif_inline();
return 0;
}
#define mmc_close_block_inline() /* Ferme le dernier bloc ouvert. */ \
\
spi_read(0xFF); \
spi_read(0xFF); \
mmc_disable(); \
spi_write(0xFF)
void mmc_close_block() {
mmc_close_block_inline();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -