#include "comm.h" #include "os.h" #include "stdint.h" #include "uart.h" #include "gd32f303r_eval.h" #include "bsp_charge.h" #include "charge.h" #define APP_TASK_COMM_PRIO 5 #define APP_TASK_COMM_STK_SIZE (256) static OS_TCB AppTaskCOMMTCB; static CPU_STK AppTaskCOMMStk[APP_TASK_COMM_STK_SIZE]; static void AppTaskComm(void *p_arg); void app_task_comm(void) { OS_ERR err; /* Create the start task */ OSTaskCreate((OS_TCB *)&AppTaskCOMMTCB, (CPU_CHAR *)"App Task Comm", (OS_TASK_PTR )AppTaskComm, (void *)0u, (OS_PRIO )APP_TASK_COMM_PRIO, (CPU_STK *)&AppTaskCOMMStk[0u], (CPU_STK_SIZE )AppTaskCOMMStk[APP_TASK_COMM_STK_SIZE / 10u], (CPU_STK_SIZE )APP_TASK_COMM_STK_SIZE, (OS_MSG_QTY )0u, (OS_TICK )0u, (void *)0u, (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), (OS_ERR *)&err); } #define MODBUS_SERIAL_PORT 0 #define MODBUS_LIST_MAX 1 #define MODBUS_RX_BUFFER_SIZE BUFFER_SIZE #define MODBUS_TX_BUFFER_SIZE BUFFER_SIZE //系统升级 #define IAP_FLAG_ADDR ((uint32_t)0x0807F000) #define WRITEFLAG ((uint16_t)0xAAAA) #define FlASH_PAGE_SIZE ((uint16_t)0x800) #define NEW_SYSTEM_START_ADDR ((uint32_t)0x0802A000) typedef struct { uint8_t *buffer; uint8_t *read; uint8_t *write; uint8_t data_size; uint8_t buffer_size; } CircularBuffer; typedef struct { unsigned short RxDataCnt; unsigned short TxDataCnt; unsigned char TimerEn; unsigned char TimeOutCnt; unsigned char RxBuf[MODBUS_RX_BUFFER_SIZE]; unsigned char TxBuf[MODBUS_TX_BUFFER_SIZE]; } ComParaDef; extern uint8_t rxbuffer[]; extern uint8_t rx_count; extern uint8_t tx_count; extern uint8_t UPdataState; extern Filter FilterBuffer[]; extern GlobalVariableDef GlobalVariable; uint16_t RWRegister[16] = { 0 }; CircularBuffer BufferCtrl; static ComParaDef ComPara[MODBUS_LIST_MAX] = { 0 }; static ComParaDef * PortList[MODBUS_LIST_MAX] = { (void *) 0 }; uint8_t ModbusRead_buffer[MODBUS_RX_BUFFER_SIZE]; uint8_t ModbusSend_buffer[MODBUS_TX_BUFFER_SIZE]; static void FixedParaInit() { GlobalVariable.FixePara.DeviceType = 0x0073; //115 GlobalVariable.FixePara.Version1 = (GlobalVariable.FixePara.DeviceType << 8); // | MCU_DeviceID; GlobalVariable.FixePara.Version2 = 0x741E; //116.30板上丝印V3.0 GlobalVariable.FixePara.DeviceEdition = (GlobalVariable.FixePara.Version2 & 0xff00) | 0;//GetHardwareVersion(); // GlobalVariable.FixePara.ProtocolVersion = 0xAAF2; //支持精简协议 } //浮点转2字节整型 uint16_t FloatStoreINT(float temp) { uint16_t variableU; float variableF = temp*100.0f; if(temp >= 0) { variableU = variableF; } else { variableF = 0-variableF; variableU = variableF; variableU = variableU|0x8000; } return variableU; } float filter_Ctrl(uint8_t location) { float temp1 = 0, temp2 = 0; for(int i=0;i>= 1; w_crc ^= 0xA001; } else { w_crc >>= 1; } } } return w_crc; } //系统升级 void EraseNewSystemFlash() { unsigned int i; fmc_unlock(); fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR); for(i = 0; i < 80; i ++ ) { fmc_page_erase(NEW_SYSTEM_START_ADDR + i * FlASH_PAGE_SIZE); fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR); } fmc_page_erase(IAP_FLAG_ADDR); fmc_lock(); } void WriteIAPFlagToFlash(unsigned int num_of_halfword) { fmc_unlock(); fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR); fmc_halfword_program(IAP_FLAG_ADDR, WRITEFLAG); fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR); fmc_word_reprogram(IAP_FLAG_ADDR + 2, num_of_halfword); fmc_lock(); } void WriteNewSystemToFlash(unsigned short *data, unsigned short pack_number) { unsigned int i; fmc_unlock(); fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR); for(i = 0;i < 128; i++) { fmc_halfword_program(NEW_SYSTEM_START_ADDR + 256*pack_number + 2*i, *(data + i)); fmc_flag_clear(FMC_FLAG_BANK0_END); fmc_flag_clear(FMC_FLAG_BANK0_WPERR); fmc_flag_clear(FMC_FLAG_BANK0_PGERR); } fmc_lock(); } void SystemUpdate(unsigned int *status) { switch(*status) { case 1:/*Flash wipe*/ EraseNewSystemFlash(); *status = 2; break; case 2: GlobalVariable.IAPUpdateSys.UpdateTimeOut ++; if(GlobalVariable.IAPUpdateSys.UpdateTimeOut >= ((15*60*1000)/12) )//15*60*1000/10) /*TimeOut 15min*/ { *status = 0; } else { if(GlobalVariable.WriteFlag.UpdatePackWrite == 1) { __disable_irq();// GlobalVariable.WriteFlag.UpdatePackWrite = 0; WriteNewSystemToFlash((unsigned short *)GlobalVariable.IAPUpdateSys.UpdateBuffer,GlobalVariable.IAPUpdateSys.PackNumber); __enable_irq(); } } break; case 3:/*Update finish*/ *status = 0; WriteIAPFlagToFlash(GlobalVariable.IAPUpdateSys.PackNumber * 256 / 2 + 10); NVIC_SystemReset(); break; default: *status = 0; break; } } void BspBle_RxCb(uint8_t *buf, uint32_t len) { PortList[MODBUS_SERIAL_PORT]->TimerEn = 0xAB; PortList[MODBUS_SERIAL_PORT]->TimeOutCnt = 6; if(len <= MODBUS_RX_BUFFER_SIZE) { for(PortList[MODBUS_SERIAL_PORT]->RxDataCnt=0; PortList[MODBUS_SERIAL_PORT]->RxDataCntRxDataCnt++) { PortList[MODBUS_SERIAL_PORT]->RxBuf[PortList[MODBUS_SERIAL_PORT]->RxDataCnt] = buf[PortList[MODBUS_SERIAL_PORT]->RxDataCnt]; } } } //数据解析 uint16_t ProtocolAnalysis(uint8_t *read_buffer, uint8_t *send_buffer, uint16_t read_num_of_bytes) { uint16_t i,j; uint16_t temp_data = 0; uint16_t num_of_register = 0; uint16_t reply_num_of_bytes = 0; if( read_buffer[0] == 0 || read_buffer[0] == 1 ) //判断ID是否正确 { switch (read_buffer[1]) { case 0x03: { temp_data = (((uint16_t)rxbuffer[2])<<8) + rxbuffer[3]; num_of_register = (((uint16_t)rxbuffer[4])<<8) + rxbuffer[5]; if((num_of_register <= 0x0A) && ( temp_data <= 0x0F))//一次最多10个,地址不超过0x0F { send_buffer[0] = read_buffer[0]; send_buffer[1] = 0x03; send_buffer[2] = num_of_register*2; ASProtocol(); for( i=0; i>8; send_buffer[2*i+4] = RWRegister[temp_data+i]; } reply_num_of_bytes = send_buffer[2]+3; } break; } case 0x64: { temp_data = read_buffer[2]; temp_data <<= 8; temp_data |= read_buffer[3]; if (temp_data == GlobalVariable.FixePara.DeviceType) { GlobalVariable.WorkMode.SystemStatus = 1; /*Flash wipe*/ GlobalVariable.IAPUpdateSys.UpdateTimeOut = 0; GlobalVariable.IAPUpdateSys.PackNumber = 0; for (i = 0; i < 500; i++) { GlobalVariable.IAPUpdateSys.PackNo[i] = 0; } send_buffer[0] = read_buffer[0]; send_buffer[1] = read_buffer[1]; send_buffer[2] = read_buffer[2]; send_buffer[3] = read_buffer[3]; send_buffer[4] = read_buffer[4]; send_buffer[5] = read_buffer[5]; reply_num_of_bytes = 6; Charge_Stop(); ChargeSetMode(CHARGE_STATE_STANDY); UPdataState = ENABLE; } else { reply_num_of_bytes = 0; } break; } case 0x65: { if ((read_num_of_bytes == 262) && (GlobalVariable.WorkMode.SystemStatus == 2)) { GlobalVariable.IAPUpdateSys.UpdateTimeOut = 0; temp_data = read_buffer[2]; temp_data <<= 8; temp_data |= read_buffer[3]; /*PackNumber is the expected packet number*/ GlobalVariable.IAPUpdateSys.PackNo[temp_data] = 1; GlobalVariable.IAPUpdateSys.PackNumber = temp_data; for (i = 0; i < 256; i++) { GlobalVariable.IAPUpdateSys.UpdateBuffer[i] = read_buffer[i + 4]; } GlobalVariable.WriteFlag.UpdatePackWrite = 1; send_buffer[0] = read_buffer[0]; send_buffer[1] = read_buffer[1]; send_buffer[2] = read_buffer[2]; send_buffer[3] = read_buffer[3]; send_buffer[4] = read_buffer[4]; send_buffer[5] = read_buffer[5]; reply_num_of_bytes = 6; } else { reply_num_of_bytes = 0; } break; } case 0x66: { if ((read_num_of_bytes == 6) && (GlobalVariable.WorkMode.SystemStatus == 2)) { GlobalVariable.IAPUpdateSys.UpdateTimeOut = 0; temp_data = read_buffer[2]; temp_data <<= 8; temp_data |= read_buffer[3]; j = 0; for (i = 0; i < temp_data; i++) { j += GlobalVariable.IAPUpdateSys.PackNo[i]; } if (j == temp_data) { GlobalVariable.IAPUpdateSys.PackNumber = temp_data; GlobalVariable.WorkMode.SystemStatus = 3; } send_buffer[0] = read_buffer[0]; send_buffer[1] = read_buffer[1]; send_buffer[2] = read_buffer[2]; send_buffer[3] = read_buffer[3]; send_buffer[4] = read_buffer[4]; send_buffer[5] = read_buffer[5]; reply_num_of_bytes = 6; } else { reply_num_of_bytes = 0; } break; } default: { reply_num_of_bytes = 0; } break; } } else { reply_num_of_bytes = 0; } return reply_num_of_bytes; } //数据接收 uint16_t ModbusRead(uint8_t port_number, uint16_t * num_of_byte, uint8_t * ReadBuffer) { uint16_t crc_value; uint16_t i = 0; if (PortList[port_number]->TimerEn == 0xAB) { if (PortList[port_number]->TimeOutCnt++ >= 6) /* Receive a frame */ { PortList[port_number]->TimerEn = 0x56; PortList[port_number]->TimeOutCnt = 0; *num_of_byte = PortList[port_number]->RxDataCnt; PortList[port_number]->RxDataCnt = 0; crc_value = CRC16_Byte(PortList[port_number]->RxBuf, *num_of_byte); if (crc_value == 0) { for (i = 0; i < *num_of_byte; i++) { * (ReadBuffer + i) = PortList[port_number]->RxBuf[i]; PortList[port_number]->RxBuf[i] = 0xFF; } return 0; } } } else { PortList[port_number]->TimeOutCnt = 0; } return 1; } //数据发送 uint16_t ModbusSend(uint8_t port_number, uint16_t num_of_byte, uint8_t * SendBuffer) { uint16_t i; uint16_t crc_value; uint16_t TxSize = 0; if ( (num_of_byte > 0) && (num_of_byte < (MODBUS_TX_BUFFER_SIZE-1)) ) { for (i = 0; i < num_of_byte; i++) { PortList[port_number]->TxBuf[i] = * (SendBuffer + i); } crc_value = CRC16_Byte(PortList[port_number]->TxBuf, num_of_byte); PortList[port_number]->TxBuf[num_of_byte] = (crc_value) & 0xFF; PortList[port_number]->TxBuf[num_of_byte + 1] = (crc_value >> 8) & 0xFF; switch (port_number) { case MODBUS_SERIAL_PORT: //串口发送 { TxSize = num_of_byte+2; for (i = 0; i < TxSize; i++) { if(PortList[port_number]->TxBuf[0] == 1) { while(RESET == usart_flag_get(USART0, USART_FLAG_TBE)) { } } usart_data_transmit(USART0, PortList[port_number]->TxBuf[i]); } break; } default: //参数异常 { break; } } } return TxSize; } static void AppTaskComm(void *p_arg) { OS_ERR err; uint16_t num_of_bytes; uint16_t reply_num_of_bytes; FixedParaInit(); PortList[MODBUS_SERIAL_PORT] = &ComPara[MODBUS_SERIAL_PORT]; while(1) { if (ModbusRead(0, &num_of_bytes, ModbusRead_buffer) == 0) //判断串口接受的信息是否符合CRC { reply_num_of_bytes = ProtocolAnalysis(ModbusRead_buffer, ModbusSend_buffer, num_of_bytes); ModbusSend(0, reply_num_of_bytes, ModbusSend_buffer); //进行回复 SystemUpdate((unsigned int *) &GlobalVariable.WorkMode.SystemStatus); } OSTimeDly(500, OS_OPT_TIME_DLY, &err); //0.5秒轮询一次 } } /*! \brief this function handles USART interrupt request \param[in] none \param[out] none \retval none */ void USART0_IRQHandler(void) { if( (RESET != usart_flag_get(USART0, USART_FLAG_TC)) && (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_TC)) ) { usart_interrupt_flag_clear(USART0, USART_INT_FLAG_TC); } if( RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE) ) { dma_channel_disable(DMA0, DMA_CH4); /* clear IDLE flag */ usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE); usart_data_receive(USART0); /* number of data received */ BspBle_RxCb(rxbuffer, BUFFER_SIZE - (dma_transfer_number_get(DMA0, DMA_CH4))); /* disable DMA and reconfigure */ dma_transfer_number_config(DMA0, DMA_CH4, BUFFER_SIZE); dma_channel_enable(DMA0, DMA_CH4); } }