Code formatting for card_spi.c

This commit is contained in:
Balint Kovacs 2019-07-27 20:32:26 +02:00 committed by d0k3
parent 84d5f800a9
commit bef427dfdb
2 changed files with 313 additions and 313 deletions

View File

@ -61,40 +61,40 @@ const CardSPITypeData EEPROM_512B_ = { CardSPIEnableWriting_512B, CardSPIReadSav
const CardSPITypeData EEPROM_STD_DUMMY = { CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, UINT32_MAX, 1, 1, 1, false, SPI_EEPROM_CMD_WRITE, 0, 0 }; const CardSPITypeData EEPROM_STD_DUMMY = { CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, UINT32_MAX, 1, 1, 1, false, SPI_EEPROM_CMD_WRITE, 0, 0 };
const CardSPITypeData EEPROMTypes[] = { const CardSPITypeData EEPROMTypes[] = {
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 13, 32, 32, 32, false, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 8 KB { CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 13, 32, 32, 32, false, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 8 KB
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 16, 128, 128, 128, false, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 64 KB { CardSPIEnableWriting_regular, CardSPIReadSaveData_16bit, CardSPIWriteSaveData_16bit, CardSPIEraseSector_emulated, 0xffffff, 1 << 16, 128, 128, 128, false, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 64 KB
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_emulated, 0xffffff, 1 << 17, 256, 256, 256, false, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 128 KB { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_emulated, 0xffffff, 1 << 17, 256, 256, 256, false, SPI_EEPROM_CMD_WRITE, 0, 0}, // EEPROM 128 KB
}; };
const CardSPITypeData FLASH_STD_DUMMY = { NULL, CardSPIReadSaveData_24bit, NULL, NULL, 0x0, 0, 0, 0, 0, false, 0, 0, 0 }; const CardSPITypeData FLASH_STD_DUMMY = { NULL, CardSPIReadSaveData_24bit, NULL, NULL, 0x0, 0, 0, 0, 0, false, 0, 0, 0 };
const CardSPITypeData FlashStdTypes[] = { const CardSPITypeData FlashStdTypes[] = {
// NTR/TWL // NTR/TWL
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204012, 1 << 18, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204012, 1 << 18, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x621600, 1 << 18, 65536, 256, 65536, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x621600, 1 << 18, 65536, 256, 65536, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204013, 1 << 19, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204013, 1 << 19, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x621100, 1 << 19, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x621100, 1 << 19, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204014, 1 << 20, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204014, 1 << 20, 65536, 256, 256, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
// Untested (but pretty safe bet), for Art Academy // Untested (but pretty safe bet), for Art Academy
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x202017, 1 << 23, 65536, 32, 65536, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x202017, 1 << 23, 65536, 32, 65536, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x204017, 1 << 23, 65536, 32, 65536, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x204017, 1 << 23, 65536, 32, 65536, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
// CTR // CTR
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22210, 1 << 16, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22210, 1 << 16, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22211, 1 << 17, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22211, 1 << 17, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22212, 1 << 18, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22212, 1 << 18, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22213, 1 << 19, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22213, 1 << 19, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22214, 1 << 20, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22214, 1 << 20, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22215, 1 << 21, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22215, 1 << 21, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22216, 1 << 22, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22216, 1 << 22, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22217, 1 << 23, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0xC22217, 1 << 23, 4096, 32, 4096, false, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_MXIC_SE },
}; };
const CardSPITypeData FLASH_INFRARED_DUMMY = { NULL, CardSPIReadSaveData_24bit, NULL, NULL, 0x0, 0, 0, 0, 0, true, 0, 0, 0 }; const CardSPITypeData FLASH_INFRARED_DUMMY = { NULL, CardSPIReadSaveData_24bit, NULL, NULL, 0x0, 0, 0, 0, 0, true, 0, 0, 0 };
const CardSPITypeData FlashInfraredTypes[] = { const CardSPITypeData FlashInfraredTypes[] = {
// NTR/TWL // NTR/TWL
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204012, 1 << 18, 65536, 256, 256, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204012, 1 << 18, 65536, 256, 256, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x621600, 1 << 18, 65536, 256, 65536, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_erase_program, CardSPIEraseSector_real, 0x621600, 1 << 18, 65536, 256, 65536, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204013, 1 << 19, 65536, 256, 256, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x204013, 1 << 19, 65536, 256, 256, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
{ CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x621100, 1 << 19, 65536, 256, 256, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE }, { CardSPIEnableWriting_regular, CardSPIReadSaveData_24bit, CardSPIWriteSaveData_24bit_write, CardSPIEraseSector_real, 0x621100, 1 << 19, 65536, 256, 256, true, SPI_FLASH_CMD_PW, SPI_CMD_PP, SPI_FLASH_CMD_SE },
}; };
const CardSPIType EEPROM_512B = &EEPROM_512B_; const CardSPIType EEPROM_512B = &EEPROM_512B_;
@ -129,275 +129,275 @@ const CardSPIType FLASH_512KB_2_INFRARED = FlashInfraredTypes + 3;
#define CARDCTL_SPICARD (1u<<8) #define CARDCTL_SPICARD (1u<<8)
int CardSPIWriteRead(CardSPIType type, const void* cmd, u32 cmdSize, void* answer, u32 answerSize, const void* data, u32 dataSize) { int CardSPIWriteRead(CardSPIType type, const void* cmd, u32 cmdSize, void* answer, u32 answerSize, const void* data, u32 dataSize) {
u32 headerFooterVal = 0; u32 headerFooterVal = 0;
REG_CFG9_CARDCTL |= CARDCTL_SPICARD; REG_CFG9_CARDCTL |= CARDCTL_SPICARD;
if (type->infrared) { if (type->infrared) {
SPI_XferInfo irXfer = { &headerFooterVal, 1, false }; SPI_XferInfo irXfer = { &headerFooterVal, 1, false };
SPI_DoXfer(SPI_DEV_CART_IR, &irXfer, 1, false); SPI_DoXfer(SPI_DEV_CART_IR, &irXfer, 1, false);
} }
SPI_XferInfo transfers[3] = { SPI_XferInfo transfers[3] = {
{ (u8*) cmd, cmdSize, false }, { (u8*) cmd, cmdSize, false },
{ answer, answerSize, true }, { answer, answerSize, true },
{ (u8*) data, dataSize, false }, { (u8*) data, dataSize, false },
}; };
SPI_DoXfer(SPI_DEV_CART_FLASH, transfers, 3, true); SPI_DoXfer(SPI_DEV_CART_FLASH, transfers, 3, true);
REG_CFG9_CARDCTL &= ~CARDCTL_SPICARD; REG_CFG9_CARDCTL &= ~CARDCTL_SPICARD;
return 0; return 0;
} }
int CardSPIWaitWriteEnd(CardSPIType type) { int CardSPIWaitWriteEnd(CardSPIType type) {
u8 cmd = SPI_CMD_RDSR, statusReg = 0; u8 cmd = SPI_CMD_RDSR, statusReg = 0;
int res = 0; int res = 0;
u64 time_start = timer_start(); u64 time_start = timer_start();
do{ do {
res = CardSPIWriteRead(type, &cmd, 1, &statusReg, 1, 0, 0); res = CardSPIWriteRead(type, &cmd, 1, &statusReg, 1, 0, 0);
if(res) return res; if (res) return res;
if(timer_msec(time_start) > 1000) return 1; if (timer_msec(time_start) > 1000) return 1;
} while(statusReg & SPI_FLG_WIP); } while(statusReg & SPI_FLG_WIP);
return 0; return 0;
} }
int CardSPIEnableWriting_512B(CardSPIType type) { int CardSPIEnableWriting_512B(CardSPIType type) {
u8 cmd = SPI_CMD_WREN; u8 cmd = SPI_CMD_WREN;
return CardSPIWriteRead(type, &cmd, 1, NULL, 0, 0, 0); return CardSPIWriteRead(type, &cmd, 1, NULL, 0, 0, 0);
} }
int CardSPIEnableWriting_regular(CardSPIType type) { int CardSPIEnableWriting_regular(CardSPIType type) {
u8 cmd = SPI_CMD_WREN, statusReg = 0; u8 cmd = SPI_CMD_WREN, statusReg = 0;
int res = CardSPIWriteRead(type, &cmd, 1, NULL, 0, 0, 0); int res = CardSPIWriteRead(type, &cmd, 1, NULL, 0, 0, 0);
if(res) return res; if (res) return res;
cmd = SPI_CMD_RDSR; cmd = SPI_CMD_RDSR;
do{ do {
res = CardSPIWriteRead(type, &cmd, 1, &statusReg, 1, 0, 0); res = CardSPIWriteRead(type, &cmd, 1, &statusReg, 1, 0, 0);
if(res) return res; if (res) return res;
} while(statusReg & ~SPI_FLG_WEL); } while(statusReg & ~SPI_FLG_WEL);
return 0; return 0;
} }
int CardSPIEnableWriting(CardSPIType type) { int CardSPIEnableWriting(CardSPIType type) {
if(type == NO_CHIP) return 1; if (type == NO_CHIP) return 1;
return type->enableWriting(type); return type->enableWriting(type);
} }
int _SPIWriteTransaction(CardSPIType type, void* cmd, u32 cmdSize, const void* data, u32 dataSize) { int _SPIWriteTransaction(CardSPIType type, void* cmd, u32 cmdSize, const void* data, u32 dataSize) {
int res; int res;
if( (res = CardSPIEnableWriting(type)) ) return res; if ((res = CardSPIEnableWriting(type))) return res;
if( (res = CardSPIWriteRead(type, cmd, cmdSize, NULL, 0, (void*) ((u8*) data), dataSize)) ) return res; if ((res = CardSPIWriteRead(type, cmd, cmdSize, NULL, 0, (void*) ((u8*) data), dataSize))) return res;
return CardSPIWaitWriteEnd(type); return CardSPIWaitWriteEnd(type);
} }
int CardSPIReadJEDECIDAndStatusReg(CardSPIType type, u32* id, u8* statusReg) { int CardSPIReadJEDECIDAndStatusReg(CardSPIType type, u32* id, u8* statusReg) {
u8 cmd = SPI_FLASH_CMD_RDID; u8 cmd = SPI_FLASH_CMD_RDID;
u8 reg = 0; u8 reg = 0;
u8 idbuf[3] = { 0 }; u8 idbuf[3] = { 0 };
u32 id_ = 0; u32 id_ = 0;
int res = CardSPIWaitWriteEnd(type); int res = CardSPIWaitWriteEnd(type);
if(res) return res; if (res) return res;
if((res = CardSPIWriteRead(type, &cmd, 1, idbuf, 3, 0, 0))) return res; if ((res = CardSPIWriteRead(type, &cmd, 1, idbuf, 3, 0, 0))) return res;
id_ = (idbuf[0] << 16) | (idbuf[1] << 8) | idbuf[2]; id_ = (idbuf[0] << 16) | (idbuf[1] << 8) | idbuf[2];
cmd = SPI_CMD_RDSR; cmd = SPI_CMD_RDSR;
if((res = CardSPIWriteRead(type, &cmd, 1, &reg, 1, 0, 0))) return res; if ((res = CardSPIWriteRead(type, &cmd, 1, &reg, 1, 0, 0))) return res;
if(id) *id = id_; if (id) *id = id_;
if(statusReg) *statusReg = reg; if (statusReg) *statusReg = reg;
return 0; return 0;
} }
u32 CardSPIGetPageSize(CardSPIType type) { u32 CardSPIGetPageSize(CardSPIType type) {
if(type == NO_CHIP) return 0; if (type == NO_CHIP) return 0;
return type->pageSize; return type->pageSize;
} }
u32 CardSPIGetEraseSize(CardSPIType type) { u32 CardSPIGetEraseSize(CardSPIType type) {
if(type == NO_CHIP) return 0; if (type == NO_CHIP) return 0;
return type->eraseSize; return type->eraseSize;
} }
u32 CardSPIGetCapacity(CardSPIType type) { u32 CardSPIGetCapacity(CardSPIType type) {
if(type == NO_CHIP) return 0; if (type == NO_CHIP) return 0;
return type->capacity; return type->capacity;
} }
int CardSPIWriteSaveData_9bit(CardSPIType type, u32 offset, const void* data, u32 size) { int CardSPIWriteSaveData_9bit(CardSPIType type, u32 offset, const void* data, u32 size) {
u8 cmd[2] = { (offset >= 0x100) ? SPI_512B_EEPROM_CMD_WRHI : SPI_512B_EEPROM_CMD_WRLO, (u8) offset }; u8 cmd[2] = { (offset >= 0x100) ? SPI_512B_EEPROM_CMD_WRHI : SPI_512B_EEPROM_CMD_WRLO, (u8) offset };
return _SPIWriteTransaction(type, cmd, 2, (void*) ((u8*) data), size); return _SPIWriteTransaction(type, cmd, 2, (void*) ((u8*) data), size);
} }
int CardSPIWriteSaveData_16bit(CardSPIType type, u32 offset, const void* data, u32 size) { int CardSPIWriteSaveData_16bit(CardSPIType type, u32 offset, const void* data, u32 size) {
u8 cmd[3] = { type->writeCommand, (u8)(offset >> 8), (u8) offset }; u8 cmd[3] = { type->writeCommand, (u8)(offset >> 8), (u8) offset };
return _SPIWriteTransaction(type, cmd, 3, (void*) ((u8*) data), size); return _SPIWriteTransaction(type, cmd, 3, (void*) ((u8*) data), size);
} }
int CardSPIWriteSaveData_24bit_write(CardSPIType type, u32 offset, const void* data, u32 size) { int CardSPIWriteSaveData_24bit_write(CardSPIType type, u32 offset, const void* data, u32 size) {
u8 cmd[4] = { type->writeCommand, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset }; u8 cmd[4] = { type->writeCommand, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset };
return _SPIWriteTransaction(type, cmd, 4, (void*) ((u8*) data), size); return _SPIWriteTransaction(type, cmd, 4, (void*) ((u8*) data), size);
} }
int CardSPIWriteSaveData_24bit_erase_program(CardSPIType type, u32 offset, const void* data, u32 size) { int CardSPIWriteSaveData_24bit_erase_program(CardSPIType type, u32 offset, const void* data, u32 size) {
u8 cmd[4] = { type->programCommand }; u8 cmd[4] = { type->programCommand };
const u32 pageSize = CardSPIGetPageSize(type); const u32 pageSize = CardSPIGetPageSize(type);
const u32 eraseSize = CardSPIGetEraseSize(type); const u32 eraseSize = CardSPIGetEraseSize(type);
int res; int res;
u8 *newData = NULL; u8 *newData = NULL;
if(offset % eraseSize || size < eraseSize) { if (offset % eraseSize || size < eraseSize) {
u32 sectorStart = (offset / eraseSize) * eraseSize; u32 sectorStart = (offset / eraseSize) * eraseSize;
newData = malloc(eraseSize); newData = malloc(eraseSize);
if(!newData) return 1; if (!newData) return 1;
if( (res = CardSPIReadSaveData(type, sectorStart, newData, eraseSize)) ) { if ((res = CardSPIReadSaveData(type, sectorStart, newData, eraseSize))) {
free(newData); free(newData);
return res; return res;
} }
memcpy(newData + (offset % eraseSize), data, size); memcpy(newData + (offset % eraseSize), data, size);
data = newData; data = newData;
offset = sectorStart; offset = sectorStart;
} }
if( (res = CardSPIEraseSector(type, offset)) ) { if ((res = CardSPIEraseSector(type, offset))) {
free(newData); free(newData);
return res; return res;
} }
for(u32 pos = offset; pos < offset + eraseSize; pos += pageSize) { for(u32 pos = offset; pos < offset + eraseSize; pos += pageSize) {
cmd[1] = (u8)(pos >> 16); cmd[1] = (u8)(pos >> 16);
cmd[2] = (u8)(pos >> 8); cmd[2] = (u8)(pos >> 8);
cmd[3] = (u8) pos; cmd[3] = (u8) pos;
if( (res = _SPIWriteTransaction(type, cmd, 4, (void*) ((u8*) data - offset + pos), pageSize)) ) { if ((res = _SPIWriteTransaction(type, cmd, 4, (void*) ((u8*) data - offset + pos), pageSize))) {
free(newData); free(newData);
return res; return res;
} }
} }
free(newData); free(newData);
return 0; return 0;
} }
int CardSPIWriteSaveData(CardSPIType type, u32 offset, const void* data, u32 size) { int CardSPIWriteSaveData(CardSPIType type, u32 offset, const void* data, u32 size) {
if(type == NO_CHIP) return 1; if (type == NO_CHIP) return 1;
if(size == 0) return 0; if (size == 0) return 0;
size = min(size, CardSPIGetCapacity(type) - offset); size = min(size, CardSPIGetCapacity(type) - offset);
u32 end = offset + size; u32 end = offset + size;
u32 pos = offset; u32 pos = offset;
u32 writeSize = type->writeSize; u32 writeSize = type->writeSize;
if(writeSize == 0) return 0xC8E13404; if (writeSize == 0) return 0xC8E13404;
int res = CardSPIWaitWriteEnd(type); int res = CardSPIWaitWriteEnd(type);
if(res) return res; if (res) return res;
while(pos < end) { while(pos < end) {
u32 remaining = end - pos; u32 remaining = end - pos;
u32 nb = writeSize - (pos % writeSize); u32 nb = writeSize - (pos % writeSize);
u32 dataSize = (remaining < nb) ? remaining : nb; u32 dataSize = (remaining < nb) ? remaining : nb;
if( (res = type->writeSaveData(type, pos, (void*) ((u8*) data - offset + pos), dataSize)) ) return res; if ((res = type->writeSaveData(type, pos, (void*) ((u8*) data - offset + pos), dataSize))) return res;
pos = ((pos / writeSize) + 1) * writeSize; // truncate pos = ((pos / writeSize) + 1) * writeSize; // truncate
} }
return 0; return 0;
} }
int CardSPIReadSaveData_9bit(CardSPIType type, u32 pos, void* data, u32 size) { int CardSPIReadSaveData_9bit(CardSPIType type, u32 pos, void* data, u32 size) {
u8 cmd[4]; u8 cmd[4];
u32 cmdSize = 2; u32 cmdSize = 2;
u32 end = pos + size; u32 end = pos + size;
u32 read = 0; u32 read = 0;
if(pos < 0x100) { if (pos < 0x100) {
u32 len = 0x100 - pos; u32 len = 0x100 - pos;
cmd[0] = SPI_512B_EEPROM_CMD_RDLO; cmd[0] = SPI_512B_EEPROM_CMD_RDLO;
cmd[1] = (u8) pos; cmd[1] = (u8) pos;
int res = CardSPIWriteRead(type, cmd, cmdSize, data, len, NULL, 0); int res = CardSPIWriteRead(type, cmd, cmdSize, data, len, NULL, 0);
if(res) return res; if (res) return res;
read += len; read += len;
} }
if(end >= 0x100) { if (end >= 0x100) {
u32 len = end - 0x100; u32 len = end - 0x100;
cmd[0] = SPI_512B_EEPROM_CMD_RDHI; cmd[0] = SPI_512B_EEPROM_CMD_RDHI;
cmd[1] = (u8)(pos + read); cmd[1] = (u8)(pos + read);
int res = CardSPIWriteRead(type, cmd, cmdSize, (void*)((u8*)data + read), len, NULL, 0); int res = CardSPIWriteRead(type, cmd, cmdSize, (void*)((u8*)data + read), len, NULL, 0);
if(res) return res; if (res) return res;
} }
return 0; return 0;
} }
int CardSPIReadSaveData_16bit(CardSPIType type, u32 offset, void* data, u32 size) { int CardSPIReadSaveData_16bit(CardSPIType type, u32 offset, void* data, u32 size) {
u8 cmd[3] = { SPI_CMD_READ, (u8)(offset >> 8), (u8) offset }; u8 cmd[3] = { SPI_CMD_READ, (u8)(offset >> 8), (u8) offset };
return CardSPIWriteRead(type, cmd, 3, data, size, NULL, 0); return CardSPIWriteRead(type, cmd, 3, data, size, NULL, 0);
} }
int CardSPIReadSaveData_24bit(CardSPIType type, u32 offset, void* data, u32 size) { int CardSPIReadSaveData_24bit(CardSPIType type, u32 offset, void* data, u32 size) {
u8 cmd[4] = { SPI_CMD_READ, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset }; u8 cmd[4] = { SPI_CMD_READ, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset };
return CardSPIWriteRead(type, cmd, 4, data, size, NULL, 0); return CardSPIWriteRead(type, cmd, 4, data, size, NULL, 0);
} }
int CardSPIReadSaveData(CardSPIType type, u32 offset, void* data, u32 size) { int CardSPIReadSaveData(CardSPIType type, u32 offset, void* data, u32 size) {
if(type == NO_CHIP) return 1; if (type == NO_CHIP) return 1;
if(size == 0) return 0; if (size == 0) return 0;
int res = CardSPIWaitWriteEnd(type); int res = CardSPIWaitWriteEnd(type);
if(res) return res; if (res) return res;
size = (size <= CardSPIGetCapacity(type) - offset) ? size : CardSPIGetCapacity(type) - offset; size = (size <= CardSPIGetCapacity(type) - offset) ? size : CardSPIGetCapacity(type) - offset;
return type->readSaveData(type, offset, data, size); return type->readSaveData(type, offset, data, size);
} }
int CardSPIEraseSector_emulated(CardSPIType type, u32 offset) { int CardSPIEraseSector_emulated(CardSPIType type, u32 offset) {
u32 blockSize = CardSPIGetEraseSize(type); u32 blockSize = CardSPIGetEraseSize(type);
u8 *fill_buf = malloc(CardSPIGetEraseSize(type)); u8 *fill_buf = malloc(CardSPIGetEraseSize(type));
if (!fill_buf) return 1; if (!fill_buf) return 1;
memset(fill_buf, 0xff, blockSize); memset(fill_buf, 0xff, blockSize);
offset = (offset / blockSize) * blockSize; offset = (offset / blockSize) * blockSize;
int res = CardSPIWriteSaveData(type, offset, fill_buf, blockSize); int res = CardSPIWriteSaveData(type, offset, fill_buf, blockSize);
free(fill_buf); free(fill_buf);
return res; return res;
} }
int CardSPIEraseSector_real(CardSPIType type, u32 offset) { int CardSPIEraseSector_real(CardSPIType type, u32 offset) {
u8 cmd[4] = { type->eraseCommand, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset }; u8 cmd[4] = { type->eraseCommand, (u8)(offset >> 16), (u8)(offset >> 8), (u8) offset };
int res = CardSPIWaitWriteEnd(type); int res = CardSPIWaitWriteEnd(type);
if(res) return res; if (res) return res;
return _SPIWriteTransaction(type, cmd, 4, NULL, 0); return _SPIWriteTransaction(type, cmd, 4, NULL, 0);
} }
int CardSPIEraseSector(CardSPIType type, u32 offset) { int CardSPIEraseSector(CardSPIType type, u32 offset) {
if(type == NO_CHIP) return 1; if (type == NO_CHIP) return 1;
return type->eraseSector(type, offset); return type->eraseSector(type, offset);
} }
@ -431,92 +431,92 @@ int CardSPIEraseSector(CardSPIType type, u32 offset) {
int _SPIIsDataMirrored(CardSPIType type, int size, bool* mirrored) { int _SPIIsDataMirrored(CardSPIType type, int size, bool* mirrored) {
u32 offset0 = (size-1); // n KB u32 offset0 = (size-1); // n KB
u32 offset1 = (2*size-1); // 2n KB u32 offset1 = (2*size-1); // 2n KB
u8 buf1; // +0k data read -> write u8 buf1; // +0k data read -> write
u8 buf2; // +n k data read -> read u8 buf2; // +n k data read -> read
u8 buf3; // +0k ~data write u8 buf3; // +0k ~data write
u8 buf4; // +n k data new comp buf2 u8 buf4; // +n k data new comp buf2
int res; int res;
if( (res = CardSPIReadSaveData(type, offset0, &buf1, 1)) ) return res; if ((res = CardSPIReadSaveData(type, offset0, &buf1, 1))) return res;
if( (res = CardSPIReadSaveData(type, offset1, &buf2, 1)) ) return res; if ((res = CardSPIReadSaveData(type, offset1, &buf2, 1))) return res;
buf3=~buf1; buf3=~buf1;
if( (res = CardSPIWriteSaveData(type, offset0, &buf3, 1)) ) return res; if ((res = CardSPIWriteSaveData(type, offset0, &buf3, 1))) return res;
if( (res = CardSPIReadSaveData(type, offset1, &buf4, 1)) ) return res; if ((res = CardSPIReadSaveData(type, offset1, &buf4, 1))) return res;
if( (res = CardSPIWriteSaveData(type, offset0, &buf1, 1)) ) return res; if ((res = CardSPIWriteSaveData(type, offset0, &buf1, 1))) return res;
*mirrored = buf2 != buf4; *mirrored = buf2 != buf4;
return 0; return 0;
} }
int CardSPIGetCardSPIType(CardSPIType* type, int infrared) { int CardSPIGetCardSPIType(CardSPIType* type, int infrared) {
u8 sr = 0; u8 sr = 0;
u32 jedec = 0; u32 jedec = 0;
u32 tries = 0; u32 tries = 0;
CardSPIType t = (infrared == 1) ? &FLASH_INFRARED_DUMMY : &FLASH_STD_DUMMY; CardSPIType t = (infrared == 1) ? &FLASH_INFRARED_DUMMY : &FLASH_STD_DUMMY;
int res; int res;
u32 maxTries = (infrared == -1) ? 2 : 1; // note: infrared = -1 fails 1/3 of the time u32 maxTries = (infrared == -1) ? 2 : 1; // note: infrared = -1 fails 1/3 of the time
while(tries < maxTries){ while(tries < maxTries){
res = CardSPIReadJEDECIDAndStatusReg(t, &jedec, &sr); // dummy res = CardSPIReadJEDECIDAndStatusReg(t, &jedec, &sr); // dummy
if(res) return res; if (res) return res;
if ((sr & 0xfd) == 0x00 && (jedec != 0x00ffffff)) { break; } if ((sr & 0xfd) == 0x00 && (jedec != 0x00ffffff)) { break; }
if ((sr & 0xfd) == 0xF0 && (jedec == 0x00ffffff)) { t = EEPROM_512B; break; } if ((sr & 0xfd) == 0xF0 && (jedec == 0x00ffffff)) { t = EEPROM_512B; break; }
if ((sr & 0xfd) == 0x00 && (jedec == 0x00ffffff)) { t = &EEPROM_STD_DUMMY; break; } if ((sr & 0xfd) == 0x00 && (jedec == 0x00ffffff)) { t = &EEPROM_STD_DUMMY; break; }
++tries; ++tries;
t = &FLASH_INFRARED_DUMMY; t = &FLASH_INFRARED_DUMMY;
} }
if(t == EEPROM_512B) { *type = t; return 0; } if (t == EEPROM_512B) { *type = t; return 0; }
else if(t == &EEPROM_STD_DUMMY) { else if (t == &EEPROM_STD_DUMMY) {
bool mirrored = false; bool mirrored = false;
size_t i; size_t i;
for(i = 0; i < sizeof(EEPROMTypes) / sizeof(CardSPITypeData) - 1; i++) { for(i = 0; i < sizeof(EEPROMTypes) / sizeof(CardSPITypeData) - 1; i++) {
if( (res = _SPIIsDataMirrored(t, CardSPIGetCapacity(EEPROMTypes + i), &mirrored)) ) return res; if ((res = _SPIIsDataMirrored(t, CardSPIGetCapacity(EEPROMTypes + i), &mirrored))) return res;
if(mirrored) { if (mirrored) {
*type = EEPROMTypes + i; *type = EEPROMTypes + i;
return 0; return 0;
} }
} }
*type = EEPROMTypes + i; *type = EEPROMTypes + i;
return 0; return 0;
} }
else if(t == &FLASH_INFRARED_DUMMY) { else if (t == &FLASH_INFRARED_DUMMY) {
size_t i; size_t i;
if(infrared == 0) *type = NO_CHIP; // did anything go wrong? if (infrared == 0) *type = NO_CHIP; // did anything go wrong?
for(i = 0; i < sizeof(FlashInfraredTypes) / sizeof(CardSPITypeData); i++) { for(i = 0; i < sizeof(FlashInfraredTypes) / sizeof(CardSPITypeData); i++) {
if(FlashInfraredTypes[i].jedecId == jedec) { if (FlashInfraredTypes[i].jedecId == jedec) {
*type = FlashInfraredTypes + i; *type = FlashInfraredTypes + i;
return 0; return 0;
} }
} }
*type = NO_CHIP; *type = NO_CHIP;
return 0; return 0;
} }
else { else {
size_t i; size_t i;
if(infrared == 1) *type = NO_CHIP; // did anything go wrong? if (infrared == 1) *type = NO_CHIP; // did anything go wrong?
for(i = 0; i < sizeof(FlashStdTypes) / sizeof(CardSPITypeData); i++) { for(i = 0; i < sizeof(FlashStdTypes) / sizeof(CardSPITypeData); i++) {
if(FlashStdTypes[i].jedecId == jedec) { if (FlashStdTypes[i].jedecId == jedec) {
*type = FlashStdTypes + i; *type = FlashStdTypes + i;
return 0; return 0;
} }
} }
*type = NO_CHIP; *type = NO_CHIP;
return 0; return 0;
} }
} }

View File

@ -30,19 +30,19 @@ typedef struct CardSPITypeData CardSPITypeData;
typedef const CardSPITypeData * CardSPIType; typedef const CardSPITypeData * CardSPIType;
struct CardSPITypeData { struct CardSPITypeData {
int (*enableWriting) (CardSPIType type); int (*enableWriting) (CardSPIType type);
int (*readSaveData) (CardSPIType type, u32 offset, void* data, u32 size); int (*readSaveData) (CardSPIType type, u32 offset, void* data, u32 size);
int (*writeSaveData) (CardSPIType type, u32 offset, const void* data, u32 size); int (*writeSaveData) (CardSPIType type, u32 offset, const void* data, u32 size);
int (*eraseSector) (CardSPIType type, u32 offset); int (*eraseSector) (CardSPIType type, u32 offset);
u32 jedecId; u32 jedecId;
u32 capacity; u32 capacity;
u32 eraseSize; u32 eraseSize;
u32 pageSize; u32 pageSize;
u32 writeSize; u32 writeSize;
bool infrared; bool infrared;
u8 writeCommand; u8 writeCommand;
u8 programCommand; u8 programCommand;
u8 eraseCommand; u8 eraseCommand;
}; };
#define NO_CHIP NULL #define NO_CHIP NULL