#include "public.h" #include #include "../Hardware/boardinit.h" #include "ota_update.h" #include "gd32f10x.h" #include "masterslave.h" typedef void (*otafun)(void); //定义一个函数类型的参数. otafun jump2_pt_app; DevMsg g_devMsg; DevFirmMsg g_devfirmMsg; nodeRun_t g_runNode; DevAppVersion g_devAppVer; LogMsg g_logMsg; // 日志 sysCmd1027 g_table1027; sysCmd1027 g_temtable1027; // 临时表 uint8_t g_bhavePrice = 0; // 是否有单价屏 0:没有单价屏 , 1:有单价屏 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; 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,group = 0; uint8_t portIndex,pinIndex,i=0; sysCmd1026 *msg = (sysCmd1026*)buff; len = sizeof(sysCmd1026); epprom_read((uint32_t)COMM_CONFIG_ADDR,buff,len); if(msg->comGroup>=4) msg->comGroup = 3; group = msg->comGroup; g_extimsg.groupNum = group; printf("group = %d\n",group); if((msg->confFileNum[0] == 'H')&&(msg->confFileNum[1]=='Y')){ printf("配置文件:HY\n"); g_devMsg.bHYdev = 0x01; } else { g_devMsg.bHYdev = 0x00; } init_test_coll_data_info(1); #if (1) g_devMsg.bhavePrice = msg->priceInuseCout; for(i=0;iparam[i][2]; if((3==portIndex) ||(4==portIndex)) { g_extimsg.csGroup[i] = GPIOA + (msg->param[i][0]*0x400); g_extimsg.csPin[i] = BIT(msg->param[i][1]); // switch(portIndex){ // case 3: // g_extimsg.extiPort = GPIOD; // g_extimsg.outputPort = GPIO_PORT_SOURCE_GPIOD; // break; // case 4: // g_extimsg.extiPort = GPIOE; // g_extimsg.outputPort = GPIO_PORT_SOURCE_GPIOE; // break; // default: // g_extimsg.extiPort = GPIOD; // g_extimsg.outputPort = GPIO_PORT_SOURCE_GPIOD; // break; // } pinIndex = msg->param[i][3]; // g_extimsg.extiLine = BIT(pinIndex); // g_extimsg.extiPin = BIT(pinIndex); // g_extimsg.extiPinSource = GPIO_PIN_SOURCE_0 + pinIndex; // if(pinIndex>=5 && pinIndex<=9) { // g_extimsg.extiIRQn = EXTI5_9_IRQn; // } // else if(pinIndex == 0){ // g_extimsg.extiIRQn = EXTI0_IRQn; // } // else if((pinIndex==14) || (pinIndex == 15 )){ // g_extimsg.extiIRQn = EXTI10_15_IRQn; // } printf("com config msg csport = %d, cspin= %d,extipt = %d, extipin=%d\r\n",msg->param[i][0],\ msg->param[i][1],portIndex,pinIndex); } else { g_extimsg.csGroup[i] = GPIOB; g_extimsg.csPin[i] = GPIO_PIN_9; // g_extimsg.extiPin = GPIO_PIN_6; // g_extimsg.extiPort = GPIOD; // g_extimsg.extiIRQn = EXTI5_9_IRQn; // g_extimsg.extiLine = EXTI_6; // g_extimsg.extiPinSource = GPIO_PIN_SOURCE_6; // g_extimsg.outputPort = GPIO_PORT_SOURCE_GPIOD; msg->param[i][1] = 9; msg->param[i][3] = 6;// printf(" com config msg default:cs:pb,cspin:9,ad:pd,adpin:6\r\n"); } if(msg->param[i][3] >=8) g_extimsg.comPin[i] = msg->param[i][3] - 8; else g_extimsg.comPin[i] = msg->param[i][3]; g_extimsg.csPin[i] = msg->param[i][1]; //9;// if(g_extimsg.csGroup[i] == GPIOB) { switch (g_extimsg.csPin[i]) { case 9: g_extimsg.comPort[i] = 14; break; // CS_U_2 case 8: g_extimsg.comPort[i] = 15; break; // CS_U_3 case 7: g_extimsg.comPort[i] = 16; break; // CS_U_4 case 6: g_extimsg.comPort[i] = 17; break; // CS_U_5 case 5: g_extimsg.comPort[i] = 18; break; // CS_U_6 case 15: g_extimsg.comPort[i] = 0; break; // CS_D_0 case 14: g_extimsg.comPort[i] = 1; break; // CS_D_1 case 13: g_extimsg.comPort[i] = 2; break; // CS_D_2 case 12: g_extimsg.comPort[i] = 3; break; // CS_D_3 case 1 : g_extimsg.comPort[i] = 5; break; // CS_D_5 case 0 : g_extimsg.comPort[i] = 6; break; // CS_D_6 } } else if(g_extimsg.csGroup[i] == GPIOA) { switch (g_extimsg.csPin[i]){ case 12: g_extimsg.comPort[i] = 22; break; // CS_U_10 case 11: g_extimsg.comPort[i] = 23; break; // CS_U_11 case 7: g_extimsg.comPort[i] = 9; break; // CS_D_9 case 6: g_extimsg.comPort[i] = 10; break; // CS_D_10 case 5: g_extimsg.comPort[i] = 11; break; // CS_D_11 } } else if(g_extimsg.csGroup[i] == GPIOC) { switch (g_extimsg.csPin[i]){ case 12: g_extimsg.comPort[i] = 19; break; // CS_U_7 case 11: g_extimsg.comPort[i] = 20; break; // CS_U_8 case 10: g_extimsg.comPort[i] = 21; break; // CS_U_9 case 5 : g_extimsg.comPort[i] = 7; break; // CS_D_7 case 4 : g_extimsg.comPort[i] = 8; break; // CS_D_8 } } else if(g_extimsg.csGroup[i] == GPIOD) { } else if(g_extimsg.csGroup[i] == GPIOE) { switch (g_extimsg.csPin[i]) { case 1: g_extimsg.comPort[i] = 12; break; // CS_U_0 case 0: g_extimsg.comPort[i] = 13; break; // CS_U_1 case 7 : g_extimsg.comPort[i] = 4; break; // CS_D_4 } } printf("comPort = %d, comPin = %d\n",g_extimsg.comPort[i],g_extimsg.comPin[i]); } #else // 用于串转并时的芯片,74CH165 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"); } #endif } 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) { g_bhavePrice = 0; epprom_read((uint32_t)PIN_CONFIG_ADDR,(uint8_t*)&g_table1027,sizeof(sysCmd1027)); if(g_table1027.groupNum<97) g_bhavePrice = 0; else g_bhavePrice = 1; if((g_table1027.confFileNum[0] == 'H') && (g_table1027.confFileNum[1] == 'Y')){ g_devMsg.bHYdev = 0x01; // 根据配置文件判断是否是鸿洋显示屏 } else g_devMsg.bHYdev = 0x00; init_test_coll_data_info(1); printf("table msg pointDev = 0x%04x,group = %d,bhaveprice = %d\r\n",g_table1027.appointDevModel,g_table1027.groupNum,g_bhavePrice); } 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 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_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(); epprom_read(0,(uint8_t*)&g_devPtMsg,sizeof(DevPtMsg)); 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; } g_devMsg.devType = DEV_TYPE;// g_devPtMsg.devType1; g_devMsg.devSn = g_devPtMsg.devSn; } ///////////////////////////////////////////////////////////////////////////// //设置栈顶地址 __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); }