Пример #1
0
void TWLCard::restoreSaveFile(u8* in, void (*cb)(u32, u32)) const {
	u32 sz = saveSize();
	u32 pageSize = SPIGetPageSize(cardType_);
	
	cb(0, sz);
	for(u32 i = 0; i < sz/pageSize; ++i){
		Result res = SPIWriteSaveData(cardType_, pageSize*i, in + pageSize*i, pageSize);
		if(res != 0) throw Error(res, __FILE__, __LINE__);
		cb(pageSize*(i+1), sz);
	}	
}
Пример #2
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;
}