| 162 | } |
| 163 | |
| 164 | Result SPIWriteSaveData(CardType type, u32 offset, void* data, u32 size) |
| 165 | { |
| 166 | u8 cmd[4] = {0}; |
| 167 | u32 cmdSize = 4; |
| 168 | |
| 169 | u32 end = offset + size; |
| 170 | u32 pos = offset; |
| 171 | if (size == 0) |
| 172 | return 0; |
| 173 | u32 pageSize = SPIGetPageSize(type); |
| 174 | if (pageSize == 0) |
| 175 | return 0xC8E13404; |
| 176 | |
| 177 | Result res = SPIWaitWriteEnd(type); |
| 178 | if (res) |
| 179 | return res; |
| 180 | |
| 181 | size = (size <= SPIGetCapacity(type) - offset) ? size : SPIGetCapacity(type) - offset; |
| 182 | |
| 183 | while (pos < end) { |
| 184 | switch (type) { |
| 185 | case EEPROM_512B: |
| 186 | cmdSize = 2; |
| 187 | cmd[0] = (pos >= 0x100) ? SPI_512B_EEPROM_CMD_WRHI : SPI_512B_EEPROM_CMD_WRLO; |
| 188 | cmd[1] = (u8)pos; |
| 189 | break; |
| 190 | case EEPROM_8KB: |
| 191 | case EEPROM_64KB: |
| 192 | cmdSize = 3; |
| 193 | cmd[0] = SPI_EEPROM_CMD_WRITE; |
| 194 | cmd[1] = (u8)(pos >> 8); |
| 195 | cmd[2] = (u8)pos; |
| 196 | break; |
| 197 | case EEPROM_128KB: |
| 198 | cmdSize = 4; |
| 199 | cmd[0] = SPI_EEPROM_CMD_WRITE; |
| 200 | cmd[1] = (u8)(pos >> 16); |
| 201 | cmd[2] = (u8)(pos >> 8); |
| 202 | cmd[3] = (u8)pos; |
| 203 | break; |
| 204 | case FLASH_256KB_1: |
| 205 | case FLASH_256KB_2: |
| 206 | case FLASH_512KB_1: |
| 207 | case FLASH_512KB_2: |
| 208 | case FLASH_1MB: |
| 209 | case FLASH_512KB_INFRARED: |
| 210 | case FLASH_256KB_INFRARED: |
| 211 | cmdSize = 4; |
| 212 | cmd[0] = SPI_FLASH_CMD_PW; |
| 213 | cmd[1] = (u8)(pos >> 16); |
| 214 | cmd[2] = (u8)(pos >> 8); |
| 215 | cmd[3] = (u8)pos; |
| 216 | break; |
| 217 | case FLASH_8MB: |
| 218 | // 8MB flash chips do not |
| 219 | // support the auto-erasing page-write command. They must be erased one sector at a time |
| 220 | // and then written with the plain page-program command. The restore loop writes the save |
| 221 | // sequentially from offset 0, so each 64KB sector gets erased the first time it is reached. |
no test coverage detected