flash-io.c (3943B)
1 #include "flash-io.h" 2 #include <stdint.h> 3 #include <string.h> 4 #include <stdbool.h> 5 #include "shared/parameters.h" 6 #include "shared/fwinfo.h" 7 #include "shared/mem-blocks.h" 8 9 static uint32_t mainAppEntry = 0XFFFF; 10 11 uint8_t flash_io_read_params(uint8_t *buffer, uint8_t offset, uint8_t length){ 12 if ((offset + length) > (sizeof(Parameters_t))) { 13 return 0; 14 } 15 memcpy(buffer, (uint8_t *)(MEM_PARAMS_OFFSET + offset), length); 16 // TODO: handle errors here 17 return length; 18 } 19 20 uint8_t flash_io_write_params(uint8_t *buffer, uint8_t offset, uint8_t length){ 21 if (length == 0 || offset != 0) { 22 return 0; 23 } 24 if ((offset + length) > (sizeof(Parameters_t))) { 25 // TODO: send address out of range message 26 return 0; 27 } 28 flash_unlock(); 29 flash_erase_sector(MEM_PARAMS_SECTOR, 3); 30 for (uint16_t i = 0; i < length; i++) { 31 flash_program_byte(MEM_PARAMS_OFFSET + i, buffer[i]); 32 } 33 flash_lock(); 34 // TODO: handle errors here 35 return length; 36 } 37 38 uint8_t flash_io_read_fw_info(uint8_t *buffer, uint8_t offset, uint8_t length){ 39 if ((offset + length) > (sizeof(FirmwareInfo_t))) { 40 // TODO: send address out of range message 41 return 0; 42 } 43 memcpy(buffer, (uint8_t *)(MEM_FW_INFO_OFFSET + offset), length); 44 return length; 45 } 46 47 uint8_t flash_io_read_diagnostic(uint8_t *buffer) { 48 uint32_t *diagAddr = (uint32_t *)MEM_DOGGY_LITTER_BOX_OFFSET; 49 uint16_t diagCount = 0; 50 while ((uint16_t) * (diagAddr + diagCount) != 0xFFFF) { 51 diagCount++; 52 } 53 memcpy(buffer, (uint8_t *)(MEM_DOGGY_LITTER_BOX_OFFSET), diagCount); 54 return diagCount; 55 } 56 57 void flash_io_dump_diagnostic(uint16_t diagReg) { 58 uint16_t *dumpAddr = (uint16_t *)MEM_DOGGY_LITTER_BOX_OFFSET; 59 static bool registerDumped = false; 60 // Search for empty untouched memory 61 while (!registerDumped) { 62 if (*dumpAddr == 0xFFFF) { 63 flash_unlock(); 64 flash_program_half_word((uint32_t)dumpAddr, diagReg); 65 flash_lock(); 66 registerDumped = true; 67 while(true); 68 } 69 dumpAddr++; 70 if (((uint32_t)dumpAddr - MEM_DOGGY_LITTER_BOX_OFFSET) >= 71 MEM_DOGGY_LITTER_BOX_SIZE) { 72 // Memory area is full. Reboot without dumping 73 break; 74 } 75 } 76 } 77 78 bool flash_io_check_dev_id(uint32_t *id) { 79 FirmwareInfo_t *fwInfo = (FirmwareInfo_t *)MEM_FW_INFO_OFFSET; 80 uint32_t devID = fwInfo->deviceID; 81 return *id == devID; 82 } 83 84 uint32_t flash_io_check_update_size(uint32_t *size) { 85 if (*size > MEM_FW_CAPACITY) { 86 return 0; 87 } 88 return *size; 89 } 90 91 bool flash_io_erase_fw_partition(void) { 92 flash_unlock(); 93 for (uint8_t i = 0; i + MEM_PARAMS_SECTOR < 12; i++) { 94 flash_erase_sector(MEM_PARAMS_SECTOR + i, 3); 95 } 96 // TODO: Check if the flash area is erased completely 97 flash_lock(); 98 return true; 99 } 100 101 uint32_t flash_io_write_new_firmware(uint8_t *chunk, uint16_t len) { 102 static uint32_t writtenBytesNo = 0; 103 if (writtenBytesNo == MEM_PARAMS_SIZE) { 104 // Hold on to first 4-bytes of vector table to flash it after everything else 105 mainAppEntry = *(uint32_t *)chunk; 106 *(uint32_t *)chunk = 0xFFFFFFFF; // Replace entry with all 1s 107 } 108 flash_unlock(); 109 for (uint8_t writeOffset = 0; writeOffset < len; writeOffset++) { 110 flash_program_byte(MEM_PARAMS_OFFSET + (writeOffset + writtenBytesNo), chunk[writeOffset]); 111 } 112 flash_lock(); 113 writtenBytesNo += len; 114 return len; 115 } 116 117 bool flash_io_check_fw_integrity(void) { 118 uint32_t vecTableEntry = *(uint32_t *)MEM_APP_OFFSET; 119 return !(vecTableEntry == 0xFFFFFFFF || vecTableEntry == 0x0); // Vector table is not written 120 } 121 122 // Write the vector table entry to flash memory 123 bool flash_io_write_main_entry(void) { 124 flash_unlock(); 125 flash_program_word(MEM_APP_OFFSET, mainAppEntry); 126 flash_lock(); 127 return true; 128 }