#include "public.h" #include #include "../Hardware/boardinit.h" #include "air780e.h" #include "ota_update.h" #include "gd32f10x.h" #include "xspDataOpt.h" typedef void (*otafun)(void); //定义一个函数类型的参数. otafun jump2_pt_app; DevMsg g_devMsg; DevFirmMsg g_devfirmMsg; nodeRun_t g_runNode; DevAppVersion g_devAppVer; Up7segData g_up7segData; sysCmd1027 g_table1027; sysCmd1027 g_temtable1027; // 临时表 LogMsg g_logMsg; void init_dev_msg(void) { g_devMsg.devType = DEV_TYPE; g_devMsg.devSn = 0x08; } /*--------------------------------------------------------------------------------- * 上电读取UUID * ---------------------------------------------------------------------------------*/ void power_up_read_uuid(void) { memcpy(g_devfirmMsg.uuid,(uint8_t*)(0x1FFFF7E8),12); } void printf_dev_msg(void) { uint8_t i = 0; g_devResetMsg.resetflag = power_up_system_resettype(); // 读取上电的复位类型 power_up_read_uuid(); printf("dev_type:0x%04x\r\n",g_devMsg.devType); printf("dev_sn :%010u\r\n",g_devMsg.devSn); printf("app1Ver :%08x\r\n",g_devAppVer.app1Ver); printf("app2Ver :%08x\r\n",g_devAppVer.app2Ver); printf("app3Ver :%08x\r\n",g_devAppVer.app3Ver); printf("bootVer :%08x\r\n",g_devAppVer.bootVer); printf("ptVer :%08x\r\n",g_devAppVer.ptVer); printf("resetnum: %u\r\n",g_devResetMsg.resetNum); printf("work_mode: %d\r\n",g_devMsg.workMode); printf("timer : %u\r\n",rtc_counter_get()); printf("uuid = "); for(i=0;i<12;i++){ printf("%02x ",g_devfirmMsg.uuid[i]); } printf("\r\n"); } /*----------------------------------------------------------------------------- * 检查设备类型以及SN是否是设备本身的 * 返回值 1: 本设备 0: 错误 * ----------------------------------------------------------------------------*/ uint8_t check_dev_type_sn(uint16_t devType, uint32_t devSn) { if(devType == g_devMsg.devType){ if(devSn == g_devMsg.devSn) return 1; else if(0xFFFFFFFF == devSn) return 1; else return 0; } else return 0; } uint8_t check_dev_type_sn01(uint16_t devType, uint32_t devSn) { if(devType==g_devMsg.devType && devSn==g_devMsg.devSn) return 1; else if((0xFFFFFFFF == devSn) && (0xFFFF ==devType) ) return 1; else if(0xFFFF == devType){ if(devSn==g_devMsg.devSn) return 1; else return 0; } else if(0xFFFFFFFF == devSn) { if(devType == g_devMsg.devType) return 1; else return 0; } else return 0; } /*-------------------------------------------------------------------------------- * crc_16 校验 * -------------------------------------------------------------------------------*/ uint16_t crc16_get(uint8_t *data, uint8_t size) { uint16_t crc=0; int i; for(i = 0; i < size; i++) { crc += data[i]; } return crc; } uint16_t _crc16_get(uint8_t *_buff,uint32_t _len) { uint32_t i,j; uint16_t crc; uint16_t temp; crc=(uint16_t)CRC_INIT_VALUE; for(i=0;i<_len;i++) { temp=_buff[i]; temp &=0x00FF; crc^=temp; for(j=0;j<8;j++) { if((crc&0x0001)!=0x00) { crc>>=1; crc^=0xA001; } else { crc>>=1; } } } return crc; } /*-------------------------------------------------------------------------------- * 转义 * 帧中除了帧头为 BB 外,不再出现 BB,如果出现 BB 则转义为 BA 01;如果出现 BA 则转义为 BA 00;帧长度和校验码都按转义前 来计算。 * -------------------------------------------------------------------------------*/ int _ytsf_data_code(uint8_t *buff, uint8_t *len) { uint8_t buff_code[128]; uint8_t i, tlen = 0; for(i = 0;i < *len; i ++){ if(buff[i] == 0xba){ buff_code[tlen++] = 0xba; buff_code[tlen++] = 0x00; } else if(i&&buff[i] == 0xbb){ buff_code[tlen++] = 0xba; buff_code[tlen++] = 0x01; } else{ buff_code[tlen++] = buff[i]; } } memcpy(buff, buff_code, tlen); *len = tlen; return 0; } /*-------------------------------------------------------------------------------- * 反转义 * 帧中除了帧头为 BB 外,不再出现 BB,如果出现 BB 则转义为 BA 01;如果出现 BA 则转义为 BA 00;帧长度和校验码都按转义前 来计算。 * -------------------------------------------------------------------------------*/ int _ytsf_data_decode(uint8_t *buff, uint8_t *len) { uint8_t buff_code[128]; uint8_t i, tlen = 0; for(i = 0;i < *len; i ++){ if((buff[i] == 0xba)&&(buff[i+1] == 0x00)) { buff_code[tlen++] = 0xba; i += 1; } else if((buff[i] == 0xba)&&(buff[i+1] == 0x01)){ buff_code[tlen++] = 0xbb; i += 1; } else{ buff_code[tlen++] = buff[i]; } } memcpy(buff, buff_code, tlen); *len = tlen; return 0; } /*--------------------------------------------------------------------------- * 设置升级标志(设置标记高位取反) * 将一个数设置为高八位是第八位的取反 * --------------------------------------------------------------------------*/ uint16_t set_updata_state(uint16_t data) { uint16_t temp_data,ret_data = 0; uint16_t temp_h,temp_l; temp_data = data; temp_h = ((~temp_data)<<8)&0xff00; temp_l = temp_data&0x00ff; ret_data = temp_h | temp_l; return ret_data; } /*------------------------------------------------------------------------------- * 判断升级标志的本体和掩码 * 标记高位取反判断 * ------------------------------------------------------------------------------*/ uint8_t updata_state_cmp(uint16_t data) { uint8_t ret = 0; uint16_t temp_data; uint8_t temp_h,temp_l; temp_data = data; temp_h = (uint8_t)((temp_data&0xff00)>>8); temp_l = (uint8_t)(temp_data&0x00ff); if((temp_h^temp_l) == 0xff) { ret = 1; } return ret; } /*------------------------------------------------------------------------------------------ *对app进行校验 *参数:addr:app首地址 * len: app长度 * checkdata:计算的crc值 *返回:0:校验正确,1:校验失败 *-------------------------------------------------------------------------------------------*/ void app_check_crc(uint32_t addr, uint32_t len, uint32_t *checkdata) { uint32_t datalen,read_crc,get_crc; datalen = Flash_DatalenRead(addr,len); read_crc = *(uint32_t*)(addr + datalen-4); //CRC校验 rcu_periph_clock_enable(RCU_CRC); //打开crc时钟 crc_data_register_reset(); //复位crc数据寄存器 get_crc = crc_block_data_calculate((uint32_t*)addr,(datalen -4)/4);//计算crc数值 rcu_periph_clock_disable(RCU_CRC); //关闭crc时钟 *checkdata = get_crc; if(read_crc != get_crc) { return; //ret = 1; } return;// ret; } /*-------------------------------------------------------------------------- * 读取复位次数 * -------------------------------------------------------------------------*/ void epprom_read_reset_num(void) { uint32_t resetnum = 0; epprom_read(DEV_RESET_NUM,(uint8_t*)&resetnum,4); g_devResetMsg.resetNum = resetnum; } /*---------------------------------------------------------------------------- * 初始化、读取 、 写入 路由表到EPPROm中 * ---------------------------------------------------------------------------*/ void epprom_init_config_table(void) { uint8_t buff[128] = {0}; g_runNode.slaveNum = 0x00; memset(g_runNode.nodMsg,0,sizeof(nodeMsg_t)); epprom_write((uint32_t)CONFIGTABLE_ADDR,buff,128); } void epprom_read_config_table(void) { uint8_t buff[128] = {0},len,i; uint8_t *pbuff = buff; nodeMsg_t *pNode = NULL; epprom_read((uint32_t)CONFIGTABLE_ADDR,&g_runNode.slaveNum,1); // 读取从设备的个数 printf("config_table_num = %d\r\n",g_runNode.slaveNum); if(g_runNode.slaveNum >16) return; len = g_runNode.slaveNum*8+1; epprom_read((uint32_t)CONFIGTABLE_ADDR,buff,len); pbuff++; for(i=0;idevType = *(uint16_t*)pbuff; pbuff += 2; pNode->devSn = *(uint32_t*)pbuff; pbuff += 4; pbuff += 2; // 预留 if((pNode->devType == g_devMsg.devType) &&(pNode->devSn == g_devMsg.devSn)){ pNode->bSelf = 1; pNode->status = 1; } else { pNode->bSelf = 0; pNode->status = 0; } pNode->readCount = 0; printf("slave_table type = %04x, sn = %010u bself=%d\r\n",pNode->devType,pNode->devSn,pNode->bSelf); } } void epprom_write_config_table(uint8_t *data, uint8_t len) { epprom_write((uint32_t)CONFIGTABLE_ADDR,data,len); } /*----------------------------------------------------------------------------------------- * com 端的配置文件的初始化 读取 写入 * ----------------------------------------------------------------------------------------*/ void epprom_init_com_config(void) { } void epprom_read_com_config(void) { uint8_t buff[128] = {0},len; uint8_t portIndex,pinIndex; sysCmd1026 *msg = (sysCmd1026*)buff; len = sizeof(sysCmd1026); epprom_read((uint32_t)COMM_CONFIG_ADDR,buff,len); portIndex = msg->param[0][2]; if((3==portIndex) ||(4==portIndex)) { switch(portIndex){ case 3: g_extimsg.csGroup = GPIOD; break; case 4: g_extimsg.csGroup = GPIOE; break; default: g_extimsg.csGroup = GPIOD; break; } g_extimsg.outputPort = portIndex; pinIndex = msg->param[0][3]; g_extimsg.csPin = BIT(pinIndex); g_extimsg.extiLine = BIT(pinIndex); g_extimsg.extiPin = BIT(pinIndex); g_extimsg.extiPinSource = pinIndex; if(pinIndex>=5 && pinIndex<=9) { g_extimsg.extiIRQn = EXTI5_9_IRQn; } printf(" com config msg port = %d, pin=%d\r\n",portIndex,pinIndex); } else { g_extimsg.csGroup = GPIOD; g_extimsg.csPin = GPIO_PIN_6; g_extimsg.extiIRQn = EXTI5_9_IRQn; g_extimsg.extiLine = EXTI_6; g_extimsg.extiPinSource = GPIO_PIN_SOURCE_6; g_extimsg.extiPin = GPIO_PIN_6; g_extimsg.outputPort = 3; printf(" com config msg default\r\n"); } } void epprom_write_com_config(uint8_t *data, uint8_t len) { epprom_write((uint32_t)COMM_CONFIG_ADDR,data,len); } /*----------------------------------------------------------------------------------------- * 探针板的管脚的配置文件的初始化 读取 写入 * ----------------------------------------------------------------------------------------*/ void epprom_init_pin_config(void) { memset(&g_table1027,0,sizeof(sysCmd1027)); } void epprom_read_pin_config(void) { epprom_read((uint32_t)PIN_CONFIG_ADDR,(uint8_t*)&g_table1027,sizeof(sysCmd1027)); printf("table msg pointDev = 0x%04x,group = %d\r\n",g_table1027.appointDevModel,g_table1027.groupNum); } void epprom_write_pin_config(uint8_t *data, uint16_t len) { epprom_write((uint32_t)PIN_CONFIG_ADDR,data,len); } /*----------------------------------------------------------------- * 读取设备的基本信息 * ----------------------------------------------------------------*/ void epprom_read_dev_app_version(void) { epprom_read((uint32_t)DEV_APP_VER,(uint8_t*)&g_devAppVer,sizeof(DevAppVersion)); if(g_devAppVer.app1Ver != APP_VERSION){ g_devAppVer.app1Ver = APP_VERSION; epprom_write((uint32_t)DEV_APP_VER,(uint8_t*)&g_devAppVer,sizeof(DevAppVersion)); } } void eeprom_read_mqtt_msg(void) { epprom_read((uint32_t)DEV_READ_MQTT_MSG,(uint8_t*)&g_mqttMsg,sizeof(MqttMsg)); } void eeprom_write_mqtt_msg(uint8_t *msg,uint16_t len) { g_mqttCHmsg.mqttMsg.flag = 1; epprom_write((uint32_t)DEV_READ_MQTT_MSG,(uint8_t*)msg,len); } /*---------------------------------------------------- * 工作模式 * ----------------------------------------------------*/ void reset_work_mode(void) { if(g_devPtMsg.binit == 0x01){ g_devMsg.workMode = WORK_NORMAL; g_devMsg.ledgreen = 1; g_devMsg.ledred = 0; } else{ g_devMsg.ledgreen = 3; g_devMsg.ledred = 1; g_devMsg.workMode = WORK_NOINIT; } } /*------------------------------------------------------------------------------------------ * 上电读取设备类型 * -----------------------------------------------------------------------------------------*/ void epprom_power_up_deal(void) { uint8_t num = 0; epprom_read_dev_app_version(); num = (g_devAppVer.app1Ver&0x03); g_devMsg.ledred = (num == 0) ? 4: num; g_devMsg.ledgreen = 4; epprom_read(0,(uint8_t*)&g_devPtMsg,sizeof(DevPtMsg)); g_devMsg.devType = DEV_TYPE;//g_devPtMsg.devType1; g_devMsg.devSn = g_devPtMsg.devSn; epprom_read_reset_num(); epprom_read_config_table(); // 上电时不需要读取路由表,收到是主的身份时再读取 // epprom_read_pin_config(); start_delay_ms(3000); do{ if((g_devMsg.ledgreen == 0x06)) break; }while(!g_iDelayfinish); stop_delay_ms(); if(g_devPtMsg.binit == 0x01){ g_devMsg.workMode = WORK_NORMAL; g_devMsg.ledgreen = 1; g_devMsg.ledred = 0; } else{ g_devMsg.ledgreen = 3; g_devMsg.ledred = 1; g_devMsg.workMode = WORK_NOINIT; } } ///////////////////////////////////////////////////////////////////////////// //设置栈顶地址 __asm void MSR_MSP(u32 addr) { MSR MSP, r0 //set Main Stack value MSR PSP, r0 //set Main Stack value BX r14 } //THUMB指令不支持汇编内联 //采用如下方法实现执行汇编指令WFI void WFI_SET(void) { __ASM volatile("wfi"); } //关闭所有中断 void INTX_DISABLE(void) { __ASM volatile("cpsid i"); } //开启所有中断 void INTX_ENABLE(void) { __ASM volatile("cpsie i"); } typedef void (*usercode)(void); usercode EnterApp; //关中断 void nvic_disable(void) { int irq; __disable_irq(); for (irq = RTC_IRQn; irq <= DMA1_Channel3_Channel4_IRQn; irq++) { NVIC_DisableIRQ(irq); NVIC_ClearPendingIRQ(irq); } } //运行pt uint32_t run_pt(void) { uint32_t appxaddr=OTA_UPDATE_PT_FLASH_START_ADDR;//OTA_UPDATE_PT_FLASH_START_ADDR; printf("jump to 0x%08X.\r\n",appxaddr); if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法. { nvic_disable(); INTX_DISABLE(); jump2_pt_app=(otafun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) gpio_deinit(GPIOB); gpio_deinit(GPIOC); jump2_pt_app(); //跳转到APP. while(1); } else { printf("栈顶地址不合法\r\n"); } return 0; } //产测处理 void uart_pt_task(uint8_t *data,uint16_t len) { if(strstr((char *)data,"AT+PTMOD=ON\r\n")) { run_pt(); } } //usart0接收解析 void analysis_usart0_rx_fifo(void) { // uint8_t readBuf[256],readlen; // if(fifo_is_empty(&g_usart0rxfifo) == TRUE) return; // readlen = fifo_read(&g_usart0rxfifo,readBuf); // if(WORK_UPDATE != g_devMsg.workMode)//非升级模式 // uart_pt_task(readBuf,readlen); }