Beispiel #1
0
Result SPIReadSaveData(CardType type, u32 offset, void* data, u32 size) {	
	u8 cmd[4] = { SPI_CMD_READ };
	u32 cmdSize = 4;
	if(size == 0) return 0;
	if(type == NO_CHIP) return 0xC8E13404;
	
	Result res = SPIWaitWriteEnd(type);
	if(res) return res;
	
	size = (size <= SPIGetCapacity(type) - offset) ? size : SPIGetCapacity(type) - offset; 
	u32 pos = offset;
	switch(type) {
		case EEPROM_512B:
			return _SPIReadSaveData_512B_impl(offset, data, size);
			break;
		case EEPROM_8KB:
		case EEPROM_64KB:
			cmdSize = 3;
			cmd[1] = (u8)(pos >> 8);
			cmd[2] = (u8) pos;
			break;
		case FLASH_256KB_1:
		case FLASH_256KB_2:
		case FLASH_512KB_1:
		case FLASH_512KB_2:
		case FLASH_1MB:
		case FLASH_8MB:
		case FLASH_512KB_INFRARED:
		case FLASH_256KB_INFRARED:
			cmdSize = 4;
			cmd[1] = (u8)(pos >> 16);
			cmd[2] = (u8)(pos >> 8);
			cmd[3] = (u8) pos;
			break;
		default:
			return 0; // never happens
	}
	
	return SPIWriteRead(type, cmd, cmdSize, data, size, NULL, 0);
}
Beispiel #2
0
void TWLCard::eraseSaveData(void (*cb)(u32, u32)) const {
	u32 pos;
	u32 sz = SPIGetCapacity(cardType_);
	Result res;
	
	cb(0, sz);

	for(pos = 0; pos < sz; pos += 0x10000) {
		res = SPIEraseSector(cardType_, pos);
		if(res != 0) throw Error(res, __FILE__, __LINE__);
		cb((sz < pos + 0x10000) ? sz : pos + 0x10000, sz);
	}
	
	
}
Beispiel #3
0
u32 TWLCard::saveSize(void) const {
	return SPIGetCapacity(cardType_);
}
Beispiel #4
0
Result SPIWriteSaveData(CardType type, u32 offset, void* data, u32 size) {
	u8 cmd[4] = { 0 };
	u32 cmdSize = 4;
	
	u32 end = offset + size;
	u32 pos = offset;
	if(size == 0) return 0;
	u32 pageSize = SPIGetPageSize(type);
	if(pageSize == 0) return 0xC8E13404;
	
	Result res = SPIWaitWriteEnd(type);
	if(res) return res;
	
	size = (size <= SPIGetCapacity(type) - offset) ? size : SPIGetCapacity(type) - offset; 

	while(pos < end) {
		switch(type) {
			case EEPROM_512B:
				cmdSize = 2;
				cmd[0] = (pos >= 0x100) ? SPI_512B_EEPROM_CMD_WRHI : SPI_512B_EEPROM_CMD_WRLO;
				cmd[1] = (u8) pos;
				break;
			case EEPROM_8KB:
			case EEPROM_64KB:
				cmdSize = 3;
				cmd[0] = SPI_CMD_PP;
				cmd[1] = (u8)(pos >> 8);
				cmd[2] = (u8) pos;
				break;
			case FLASH_256KB_1:
			/*	
			This is what is done in the official implementation, but I think it's wrong
				cmdSize = 4;
				cmd[0] = SPI_CMD_PP;
				cmd[1] = (u8)(pos >> 16);
				cmd[2] = (u8)(pos >> 8);
				cmd[3] = (u8) pos;
				break;
			*/
			case FLASH_256KB_2:
			case FLASH_512KB_1:
			case FLASH_512KB_2:
			case FLASH_1MB:
			case FLASH_512KB_INFRARED:
			case FLASH_256KB_INFRARED:
				cmdSize = 4;
				cmd[0] = SPI_FLASH_CMD_PW;
				cmd[1] = (u8)(pos >> 16);
				cmd[2] = (u8)(pos >> 8);
				cmd[3] = (u8) pos;
				break;
			case FLASH_8MB:
				return 0xC8E13404; // writing is unsupported (so is reading? need to test)
			default:
				return 0; // never happens
		}
		
		u32 remaining = end - pos;
		u32 nb = pageSize - (pos % pageSize);
		
		u32 dataSize = (remaining < nb) ? remaining : nb;
		
		if( (res = SPIEnableWriting(type)) ) return res;
		if( (res = SPIWriteRead(type, cmd, cmdSize, NULL, 0, (void*) ((u8*) data - offset + pos), dataSize)) ) return res;
		if( (res = SPIWaitWriteEnd(type)) ) return res;
		
		pos = ((pos / pageSize) + 1) * pageSize; // truncate
	}
	
	return 0;
}