#include "flash.h" #include "ota_flash.h" #include "ota_flash_mesh.h" #include "ota_app_service.h" #include "ota_protocol.h" #include "string.h" #include "error.h" #include "crc16.h" #include "log.h" #include "hal_mcu.h" typedef struct{ uint8_t flg; uint8_t rsv; uint16_t dev_type; uint8_t mac[6]; }otafm_meshinfo_t; int otafm_write_partition(uint32 addr, uint32_t* p_sect, uint32_t size) { uint32_t i; int ret = 0; uint32_t offset = OTAFM_FW_OTA_DATA_ADDR; if(addr % 4) return PPlus_ERR_DATA_ALIGN; size = (size + 3) & 0xfffffffc; for(i = 0; i < size /4; i++){ ret = WriteFlash(offset + addr + i*4, p_sect[i]); if(ret == 1) continue; ret = WriteFlash(offset + addr + i*4, p_sect[i]); if(ret == 1) continue; ret = WriteFlash(offset + addr + i*4, p_sect[i]); if(ret == 1) continue; ret = WriteFlash(offset + addr + i*4, p_sect[i]); if(ret == 0) return PPlus_ERR_SPI_FLASH; } return PPlus_SUCCESS; } int otafm_write_boot_sector(uint32_t* p_sect, uint32_t size, uint32_t offset) { uint32_t i; int ret = 0; if(size % 4) return PPlus_ERR_DATA_ALIGN; for(i = 0; i < size /4; i++){ ret = WriteFlash(OTAFM_FW_OTA_ADDR + OTAFM_FW_OTA_INFO_SZ + i*4 + offset, p_sect[i]); if(ret == 0) ret = WriteFlash(OTAFM_FW_OTA_ADDR + OTAFM_FW_OTA_INFO_SZ + i*4 + offset, p_sect[i]); if(ret == 0) ret = WriteFlash(OTAFM_FW_OTA_ADDR + OTAFM_FW_OTA_INFO_SZ + i*4 + offset, p_sect[i]); if(ret == 0) ret = WriteFlash(OTAFM_FW_OTA_ADDR + OTAFM_FW_OTA_INFO_SZ + i*4 + offset, p_sect[i]); if(ret == 0) return PPlus_ERR_SPI_FLASH; } return PPlus_SUCCESS; } int otafm_dev_add(otafmesh_dev_t* pdev) { return PPlus_SUCCESS; } int otafm_dev_pull(otafmesh_dev_t* pdev) { uint32_t i = 0; uint32_t faddr = OTAFM_FW_OTA_ADDR; uint8_t* pdata = (uint8_t*) (faddr); uint32_t data_u32 = NULL; otafm_meshinfo_t* pinfo; uint8_t flg = 0; if(!((char)(pdata[0]) == 'M' && (char)(pdata[1]) == 'O' &&(char)(pdata[2]) == 'T'&&(char)(pdata[3]) == 'A')) { return PPlus_ERR_INVALID_DATA; } pdata += 0x100; for(i = 0; i<240; i++){ if(pdata[0] == OTAFM_DEV_FLG_UNINIT) return PPlus_ERR_NOT_FOUND; if(pdata[0] == OTAFM_DEV_FLG_READY|| pdata[0] == OTAFM_DEV_FLG_FAILED|| pdata[0] == OTAFM_DEV_FLG_OTAING) { pinfo = (otafm_meshinfo_t*) pdata; pdev->dev_type = pinfo->dev_type; pdev->dev_addr[0] = pinfo->mac[5]; pdev->dev_addr[1] = pinfo->mac[4]; pdev->dev_addr[2] = pinfo->mac[3]; pdev->dev_addr[3] = pinfo->mac[2]; pdev->dev_addr[4] = pinfo->mac[1]; pdev->dev_addr[5] = pinfo->mac[0]; pdev->index = (uint16_t)i; flg = pinfo->flg & OTAFM_DEV_FLG_OTAING; data_u32 = *((uint32_t*)pdata); data_u32 &= 0xffffff00; data_u32 |= flg; WriteFlash((uint32_t)pdata, data_u32); return PPlus_SUCCESS; } pdata += 16; } return PPlus_ERR_NOT_FOUND; } int otafm_dev_clear(otafmesh_dev_t* pdev) { uint32_t faddr = OTAFM_FW_OTA_ADDR; uint8_t* pdata = (uint8_t*) (faddr); otafm_meshinfo_t* pinfo; uint32_t data_u32; if(!((char)(pdata[0]) == 'M' && (char)(pdata[1]) == 'O' &&(char)(pdata[2]) == 'T'&&(char)(pdata[3]) == 'A')) { return PPlus_ERR_INVALID_DATA; } pdata += 0x100 + pdev->index * 16; pinfo = (otafm_meshinfo_t*)pdata; if(memcmp(pdev->dev_addr, pinfo->mac, 6) != 0){ return PPlus_ERR_INVALID_ADDR; } if(pinfo->flg != OTAFM_DEV_FLG_READY && pinfo->flg != OTAFM_DEV_FLG_FAILED && pinfo->flg != OTAFM_DEV_FLG_COMPLETED && pinfo->flg != OTAFM_DEV_FLG_OTAING ) { return PPlus_ERR_INVALID_FLAGS; } data_u32 = *(uint32_t*)pdata; data_u32 &= 0xffffff00; data_u32 |= OTAFM_DEV_FLG_USED; WriteFlash((uint32_t)pdata, data_u32); return PPlus_SUCCESS; } int otafm_fw_load(ota_fw_t* pfw) { uint32_t faddr = OTAFM_FW_OTA_ADDR + OTAFM_FW_OTA_INFO_SZ; uint8_t* pdata = (uint8_t*) (faddr); uint32_t* pdata32 = (uint32_t*) pdata; LOG("load fw %x\n", faddr); memset((void*)pfw, 0 ,sizeof(ota_fw_t)); if(!((char)(pdata[0]) == 'O' && (char)(pdata[1]) == 'T' &&(char)(pdata[2]) == 'A'&&(char)(pdata[3]) == 'F')) { return PPlus_ERR_INVALID_DATA; } pfw->part_num = (uint8_t)(pdata32[1]); pfw->total_size = 0; for (uint8_t i = 0; i < pfw->part_num; i++){ uint16_t checksum = 0; pfw->part[i].flash_addr = pdata32[i*4+4]; pfw->part[i].run_addr = pdata32[i*4+5]; pfw->part[i].size = pdata32[i*4+6]; pfw->part[i].checksum = (uint16_t)(pdata32[i*4+7]); checksum = crc16(0, (const volatile void * )(pfw->part[i].flash_addr + OTAFM_FW_OTA_DATA_ADDR), pfw->part[i].size); if(checksum != pfw->part[i].checksum) return PPlus_ERR_INVALID_DATA; pfw->total_size += pfw->part[i].size; } return PPlus_SUCCESS; } //load data to int otafm_fw_execute() { return PPlus_SUCCESS; } int otafm_format(void) { uint32_t i; for(i = 0; i< 4; i++){ flash_block64_erase(OTAFM_FW_OTA_ADDR + i * OTAF_SECTOR_SIZE); } return PPlus_SUCCESS; }