diff --git a/bthome_phy6222/source/ble_ota.c b/bthome_phy6222/source/ble_ota.c new file mode 100644 index 0000000..8990b58 --- /dev/null +++ b/bthome_phy6222/source/ble_ota.c @@ -0,0 +1,184 @@ +/****************************************************************************** + * @file ble_ota.c + * + ******************************************************************************/ +#include "bcomdef.h" +#include "config.h" +#include "OSAL.h" +#include "sbp_profile.h" +#include "ble_ota.h" + +struct { + u8 err_flag; + u8 version; + u8 start_flag; + u8 reboot_flag; + u32 program_offset; + u16 pkt_index; + u16 pkt_total; + u32 fw_value; + u32 crc32; + u32 erase_offset; +} ota; + +#define blt_ota_timeout_us 30000; // default 30 second + +unsigned short crc16(unsigned char *pD, int len) { + + static unsigned short poly[2] = { 0, 0xa001 }; //0x8005 <==> 0xa001 + unsigned short crc = 0xffff; + int i, j; + + for (j = len; j > 0; j--) { + unsigned char ds = *pD++; + for (i = 0; i < 8; i++) { + crc = (crc >> 1) ^ poly[(crc ^ ds) & 1]; + ds = ds >> 1; + } + } + + return crc; +} + +static const unsigned int crc32_half_tbl[16] = { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c +}; + +unsigned int crc32_half_cal(unsigned int crc, unsigned char *input, + unsigned int *table, int len) { + unsigned char *pch = input; + for (int i = 0; i < len; i++) { + crc = (crc >> 4) ^ table[(crc ^ *pch) & 0x0f]; + pch++; + } + return crc; +} + +u32 get_crc32_16bytes(unsigned int crc_init, unsigned char *data) { + // split 16 bytes OTA data into 32 half bytes to caculate CRC. + u8 ota_dat[32]; + for (int i = 0; i < 16; i++) { + ota_dat[i * 2] = data[i] & 0x0f; + ota_dat[i * 2 + 1] = data[i] >> 4; + } + return crc32_half_cal(crc_init, ota_dat, + (unsigned int*) crc32_half_tbl, 32); +} + + +void ota_reload_imer(void) { + +} + +int otaWrite(unsigned char imsg, unsigned char isize) { + u32 tmp; + u16 crc; + u16 ota_adr = imsg[0] | (imsg[1] << 8); + u8 flash_check[16]; + u8 err_flg = OTA_SUCCESS; + if(isize > 2) { + // ota_reload_imer(); + if (ota_adr >= CMD_OTA_START) { + if (ota_adr == CMD_OTA_START) { + ota.erase_offset = FADD_APP_SEC; + ota.fw_value = START_UP_FLAG; + ota.start_flag = 0; + ota.err_flag = OTA_SUCCESS; + } else if (ota_adr == CMD_OTA_SET) { + if(ota.start_flag) { + err_flg = OTA_NO_START; + } else if(isize >= 2 + 10) { + ota.program_offset = ((imsg[2] & 0xf0) + | (imsg[3] << 8) + | (imsg[4] << 16) + | (imsg[5] << 24)); + ota.fw_value = (imsg[6] + | (imsg[7] << 8) + | (imsg[8] << 16) + | (imsg[9] << 24)); + ota.pkt_total = (imsg[10] + | (imsg[11] << 8)); + if(ota.program_offset >= FADD_APP_SEC + && ota.program_offset + (ota.pkt_total << 4) <= FLASH_MAX_SIZE) { + ota.pkt_index = -1; + ota.start_flag = 1; //set flag + } else + err_flg = OTA_ERR_PARAM; // invalid offset + } else + err_flg = OTA_PKT_SIZE_ERR; // size error + } else if (ota_adr == CMD_OTA_END) { + //terminateConnection(0x13); + //timer(reboot) + } else + err_flg = OTA_UNKNOWN_CMD; // unknown commad + } else if(ota.start_flag) { + if (ota.pkt_index + 1 == ota_adr) { // correct OTA data index + if(isize < 2+16+2) { + crc = (imsg[19] << 8) | imsg[18]; + if (crc == crc16(imsg, 18)) { + if (ota_adr == 0) { + ota.crc32 = 0xFFFFFFFF; // crc init set to 0xFFFFFFFF + tmp = ((imsg[2]) + | (imsg[3] << 8) + | (imsg[4] << 16) + | (imsg[5] << 24)); + if (tmp != ota.fw_value) // id != ? + err_flg = OTA_FW_CHECK_ERR; + } else if (ota_adr == ota.pkt_total - 1) { + tmp = ((imsg[2]) + | (imsg[3] << 8) + | (imsg[4] << 16) + | (imsg[5] << 24)); + if (ota.crc32 != tmp) // crc32 != ? + err_flg = OTA_FW_CRC32_ERR; + else { + hal_flash_write(ota.program_offset, + (uint8_t*) &ota.fw_value, 4); + hal_flash_read(ota.program_offset, + (uint8_t*) &tmp, 4); + if (ota.fw_value == tmp) { // OK + err_flg = OTA_END; + } else + err_flg = OTA_WRITE_FLASH_ERR; // flash write err + } + } + if (((ota_adr == 0) || ota_adr < ota.pkt_total - 1)) + ota.crc32 = get_crc32_16bytes(ota.crc32, imsg + 2); + if (ota_adr < ota.pkt_total) { + if (ota_adr == 0) { + imsg[2] = 0xff; + imsg[3] = 0xff; + imsg[4] = 0xff; + imsg[5] = 0xff; + } + hal_flash_write(ota.program_offset + (ota_adr << 4), + imsg + 2, 16); + hal_flash_read(ota.program_offset + (ota_adr << 4), + flash_check, 16); + if (!memcmp(flash_check, imsg + 2, 16)) { // OK + ota.pkt_index = ota_adr; + } else + err_flg = OTA_WRITE_FLASH_ERR; // flash write err + } else + err_flg = OTA_OVERFLOW; + } else + err_flg = OTA_PKT_CRC_ERR; // crc err + } else + err_flg = OTA_PKT_SIZE_ERR; // size error + } else if (ota_adr <= ota.pkt_index) { + // maybe repeated OTA data, we neglect it, do not consider it ERR + } else + err_flg = OTA_PACKET_LOSS; // adr index err, missing at least one OTA data + } else + err_flg = OTA_NO_PARAM; + } else + err_flg = OTA_PKT_SIZE_ERR; // size error + if (err_flg) { + ota.err_flag = err_flg; + blt_ota_finished_flag_set(err_flg); + } + return 0; +} diff --git a/bthome_phy6222/source/ble_ota.h b/bthome_phy6222/source/ble_ota.h new file mode 100644 index 0000000..d0e4805 --- /dev/null +++ b/bthome_phy6222/source/ble_ota.h @@ -0,0 +1,51 @@ +/****************************************************************************** + * @file ble_ota.h + * + ******************************************************************************/ + +#ifndef BLE_OTA_H_ +#define BLE_OTA_H_ + +/* FLASH */ + +#define FLASH_SIZE 0x80000 // 512k (512*1024) +#define FLASH_MAX_SIZE 0x200000 // 2M (2048*1024) +#define FLASH_SECTOR_SIZE 0x01000 // 4k (4*1024) +#define FADD_START_ADDR 0x11000000 +#define FADD_BOOT_ROM_INFO (FADD_START_ADDR + 0x02000) // 4k +#define FADD_BOOT_OTA (FADD_START_ADDR + 0x03000) // 4k +#define FADD_APP_INFO (FADD_START_ADDR + 0x04000) // 4k +#define FADD_OTA_SEC (FADD_START_ADDR + 0x05000) // 44k +#define FADD_APP_SEC (FADD_START_ADDR + 0x10000) // 236k (2x118k) +#define FADD_DATA_SEC (FADD_START_ADDR + 0x40000) // 248k +#define FADD_EEP_SEC (FADD_START_ADDR + (FLASH_SIZE - 2*FLASH_SECTOR_SIZE)) + +#define START_UP_FLAG 0x12345678 + + +#define CMD_OTA_START 0xff00 +#define CMD_OTA_SET 0xff01 +#define CMD_OTA_END 0xff02 + +enum { + OTA_SUCCESS = 0, // success + OTA_UNKNOWN_CMD, // bad command + OTA_NO_START, // no start + OTA_NO_PARAM, // no parameters specified + OTA_ERR_PARAM, // invalid parameter(s) + OTA_PKT_SIZE_ERR, // packet size err + OTA_PKT_CRC_ERR, // packet CRC err + OTA_PACKET_LOSS, // lost one or more OTA PDU + OTA_WRITE_FLASH_ERR, // write OTA data to flash ERR + OTA_DATA_UNCOMPLETE, //lost last one or more OTA PDU + OTA_TIMEOUT, // timeout + OTA_OVERFLOW, // the ota adr overflow to 0x30000 + OTA_FW_CHECK_ERR, // + OTA_FW_CRC32_ERR, // + OTA_END = 0xff +}; + +extern int otaWrite(void *p); +extern int otaRead(void *p); + +#endif /* BLE_OTA_H_ */ diff --git a/bthome_phy6222/source/cmd_parcer.c b/bthome_phy6222/source/cmd_parcer.c index 1576fe8..2af6348 100644 --- a/bthome_phy6222/source/cmd_parcer.c +++ b/bthome_phy6222/source/cmd_parcer.c @@ -35,7 +35,7 @@ int cmd_parser(uint8_t * obuf, uint8_t * ibuf, uint32_t len) { if (cmd == CMD_ID_DEVID) { // Get DEV_ID pdev_id_t p = (pdev_id_t) obuf; // p->pid = CMD_ID_DEV_ID; - // p->revision = 0; // уже = 0 + p->revision = 1; p->hw_version = DEVICE; p->sw_version = APP_VERSION; p->dev_spec_data = 0; @@ -64,13 +64,13 @@ int cmd_parser(uint8_t * obuf, uint8_t * ibuf, uint32_t len) { osal_memcpy(&thsensor_cfg.coef, &ibuf[1], len); flash_write_cfg(&thsensor_cfg.coef, EEP_ID_CFS, sizeof(thsensor_cfg.coef)); } - osal_memcpy(&obuf[1], &thsensor_cfg, sizeof(thsensor_cfg)-3); - olen = sizeof(thsensor_cfg)-3 + 1; + osal_memcpy(&obuf[1], &thsensor_cfg, thsensor_cfg_size); + olen = thsensor_cfg_size + 1; } else if (cmd == CMD_ID_CFS_DEF) { // Get/Set default sensor config - osal_memset(&thsensor_cfg, 0, sizeof(thsensor_cfg)); + osal_memset(&thsensor_cfg, 0, thsensor_cfg_size); init_sensor(); - osal_memcpy(&obuf[1], &thsensor_cfg, sizeof(thsensor_cfg)-3); - olen = sizeof(thsensor_cfg)-3 + 1; + osal_memcpy(&obuf[1], &thsensor_cfg, thsensor_cfg_size); + olen = thsensor_cfg_size + 1; //---------- Debug commands (unsupported in different versions!): diff --git a/bthome_phy6222/source/sbp_profile.c b/bthome_phy6222/source/sbp_profile.c index 7ea39b3..88cebce 100644 --- a/bthome_phy6222/source/sbp_profile.c +++ b/bthome_phy6222/source/sbp_profile.c @@ -369,7 +369,7 @@ static bStatus_t simpleProfile_ReadAttrCB( uint16_t connHandle, gattAttribute_t osal_memcpy(pAttr->pValue, pValue, len ); cmd_in_len = len; LOG("receive data = 0x "); - LOG_DUMP_BYTE(pCurValue, len); + LOG_DUMP_BYTE(pAttr->pValue, len); osal_set_event(simpleBLEPeripheral_TaskID, SBP_DEALDATA); } break; diff --git a/bthome_phy6222/source/sensor.h b/bthome_phy6222/source/sensor.h index 2efbafe..6a812da 100644 --- a/bthome_phy6222/source/sensor.h +++ b/bthome_phy6222/source/sensor.h @@ -131,6 +131,8 @@ typedef struct _measured_data_t { uint8_t battery; // 0..100 % } measured_data_t; +extern measured_data_t measured_data; + typedef struct _thsensor_coef_t { uint32_t temp_k; uint32_t humi_k; @@ -149,9 +151,8 @@ typedef struct _thsensor_cfg_t { uint16_t vid; uint8_t i2c_addr; } thsensor_cfg_t; - -extern measured_data_t measured_data; extern thsensor_cfg_t thsensor_cfg; +#define thsensor_cfg_size (sizeof(thsensor_cfg)-3) void init_sensor(void); int read_sensor(void); diff --git a/bthome_phy6222/source/thb2_main.c b/bthome_phy6222/source/thb2_main.c index 5ba6bdf..7bc2143 100644 --- a/bthome_phy6222/source/thb2_main.c +++ b/bthome_phy6222/source/thb2_main.c @@ -128,8 +128,6 @@ static void set_mac(void) { extern uint8 ownPublicAddr[LL_DEVICE_ADDR_LEN]; if (read_chip_mAddr(ownPublicAddr) != CHIP_ID_VALID) { - //uint16 len; - //if(hal_fs_item_read(FS_ID_MAC, ownPublicAddr, LL_DEVICE_ADDR_LEN, &len) != PPlus_SUCCESS) { if(flash_read_cfg(ownPublicAddr, EEP_ID_MAC, LL_DEVICE_ADDR_LEN) != LL_DEVICE_ADDR_LEN) { LL_Rand(ownPublicAddr,3); // Tuya mac[0:3] @@ -137,7 +135,6 @@ static void set_mac(void) ownPublicAddr[4] = 0x1f; ownPublicAddr[5] = 0x38; flash_write_cfg(ownPublicAddr, EEP_ID_MAC, LL_DEVICE_ADDR_LEN); - //hal_fs_item_write(FS_ID_MAC, ownPublicAddr, LL_DEVICE_ADDR_LEN); } } set_def_name(ownPublicAddr); @@ -453,7 +450,7 @@ uint16 BLEPeripheral_ProcessEvent( uint8 task_id, uint16 events ) if ( events & ADV_BROADCAST_EVT) { adv_measure(); - LOG("advN%u\n", adv_count); + LOG("advN%u\n", adv_wrk.adv_count); // return unprocessed events return (events ^ ADV_BROADCAST_EVT); }