| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- #include "upload.h"
- #include "user_uart.h"
- #include "user_crc16.h"
- #include "base64.h"
- #include "string.h"
- #include "user_check.h"
- modbus_work_s upload_work = {
- .rtu_addr = DEV_UART_ADDR,
- .tx_size = 0,
- .rx_size = 0,
- .tx_buffer = {0},
- .rx_buffer = {0},
- .rtu_rec = {0},
- .modbusRx_stat = false,
- .modbusTx_stat = false,
- };
- static coll_data_s coll_data = {
- .coll_stat = COLL_NOT_READY_STAT,
- .count = 1,
- .download_sw_stat = 0,
- .sw_stat = false,
- };
- static uint32_t upload_offline_timeout = 0;
- static bool upload_offline_stat = true;
- static void set_upload_offline(bool stat);
- /*******************************************************************************
- * @函数名称 uploadRx_receive
- * @函数说明 处理接收数据
- * @输入参数 data:数据指针
- size:数据长度
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static void uploadRx_receive(uint8_t *data, uint16_t size)
- {
- memcpy(upload_work.rx_buffer, data, size);
- upload_work.rx_size = size;
- #if USE_BASE64 == 1
- uint8_t data[MODBUS_DATA_SIZE] = {0};
- if(upload_work.rx_buffer[upload_work.rx_size - 2] == '\r'
- && upload_work.rx_buffer[upload_work.rx_size - 1] == '\n')
- {
- upload_work.rx_buffer[upload_work.rx_size - 2] = '\0';
- int len = base64_decode((char *)upload_work.rx_buffer, data);
-
- memcpy((void *)&(upload_work.rtu_rec), data, len);
- memcpy((void *)&(upload_work.rtu_rec.crc), &(data[len - 2]), 2);
- upload_work.rtu_rec.dataSize = len - 6;
- upload_work.modbusRx_stat = true;
- }
- #else
- memcpy((void *)&(upload_work.rtu_rec), upload_work.rx_buffer, upload_work.rx_size);
- memcpy((void *)&(upload_work.rtu_rec.crc), &(upload_work.rx_buffer[upload_work.rx_size - 2]), 2);
- upload_work.rtu_rec.dataSize = upload_work.rx_size - 6;
- upload_work.modbusRx_stat = true;
- #endif
- }
- /*******************************************************************************
- * @函数名称 uploadTx_send
- * @函数说明 发送数据
- * @输入参数 无
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static void uploadTx_send(uint8_t *data, int size)
- {
- #if USE_BASE64 == 1
- base64_encode(data, (char *)upload_work.tx_buffer, size);
- int len = strlen((char *)upload_work.tx_buffer);
- upload_work.tx_buffer[len] = '\r';
- upload_work.tx_buffer[len + 1] = '\n';
- upload_work.tx_buffer[len + 2] = '\0';
-
- upload_work.tx_size = len + 2;
- #else
- memcpy(upload_work.tx_buffer, data, size);
- upload_work.tx_size = size;
- #endif
- upload_work.modbusTx_stat = true;
-
- vUser_usart1_send(upload_work.tx_buffer, upload_work.tx_size);
- }
- /*******************************************************************************
- * @函数名称 set_sw_stat
- * @函数说明 设置开关量状态
- * @输入参数 stat:开关量状态
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- void set_download_sw_stat(uint32_t stat)
- {
- coll_data.download_sw_stat = stat;
- }
- /*******************************************************************************
- * @函数名称 set_coll_stat
- * @函数说明 设置就绪状态
- * @输入参数 count:下挂主板个数
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- void set_coll_stat(uint16_t count)
- {
- coll_data.coll_stat = COLL_READY_STAT;
- coll_data.count = count + 1;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_rd_dev_type
- * @函数说明 设置设备类型数据
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint8_t * rtu_protocol_rd_dev_type(uint8_t *data)
- {
- *data++ = 0x00;
- *data++ = DEV_UART_ADDR;
- return data;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_rd_version
- * @函数说明 设置版本号数据
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint8_t * rtu_protocol_rd_version(uint8_t *data)
- {
- *data++ = HARDWARE_VERSION;
- *data++ = SOFTWARE_VERSION;
- return data;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_coll_stat
- * @函数说明 设置主板状态数据
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint8_t * rtu_protocol_coll_stat(uint8_t *data)
- {
- *data++ = coll_data.coll_stat >> 8;
- *data++ = coll_data.coll_stat;
- return data;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_coll_count
- * @函数说明 设置包含的主板数
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint8_t * rtu_protocol_coll_count(uint8_t *data)
- {
- *data++ = coll_data.count >> 8;
- *data++ = coll_data.count;
- return data;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_sw_low_stat
- * @函数说明 设置采集到的所有开关量
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint8_t * rtu_protocol_sw_low_stat(uint8_t *data)
- {
- uint32_t value = 0;
- memcpy((void *)&value, (void *)&(coll_data.download_sw_stat), 4);
- value <<= 2;
- if(coll_data.sw_stat == true)
- {
- value += 0x01;
- }
- *data++ = (uint8_t)(value >> 8);
- *data++ = (uint8_t)value;
- return data;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_sw_low_stat
- * @函数说明 设置采集到的所有开关量
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint8_t * rtu_protocol_sw_high_stat(uint8_t *data)
- {
- uint32_t value = 0;
- memcpy((void *)&value, (void *)&(coll_data.download_sw_stat), 4);
- value = value & ~(0x03 << ((coll_data.count - 1) * 2));
- if(coll_data.sw_stat == true)
- {
- value = value | (1 << ((coll_data.count - 1) * 2));
- }
- *data++ = (uint8_t)(value >> 24);
- *data++ = (uint8_t)(value >> 16);
- return data;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_send
- * @函数说明 发送数据
- * @输入参数 data:数据指针
- size:数据长度
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static void rtu_protocol_send(uint8_t *data, int size)
- {
- uint16_t crc = 0xFFFF;
- crc = GetCRC16(data, size, crc);
- memcpy(&data[size], &crc, 2);
- uploadTx_send(data, size + 2);
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_rd_reg_parsing
- * @函数说明 解析接收到的上位机数据
- * @输入参数 rec:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_protocol_rd_reg_parsing(rtu_rec_s *rec)
- {
- uint8_t data[MODBUS_DATA_SIZE] = {0};
- uint16_t dataSize = 0;
- data[0] = upload_work.rtu_addr;
- data[1] = CMD_RD_REG;
- dataSize = rec->data[0];
- dataSize <<= 8;
- dataSize += rec->data[1];
- data[2] = dataSize * 2;
- uint16_t reg_addr = 0;
- reg_addr = rec->regAddr[0];
- reg_addr <<= 8;
- reg_addr += rec->regAddr[1];
- uint8_t *ptr = &data[3];
- switch(reg_addr)
- {
- case REG_DEV_TYPE_ADDR: ptr = rtu_protocol_rd_dev_type(ptr);
- case 0x0001: ptr += 4;
- case REG_VERSION_ADDR:ptr = rtu_protocol_rd_version(ptr);
- case 0x0004: ptr += 24;
- case REG_COLL_STAT_ADDR: ptr = rtu_protocol_coll_stat(ptr);
- case REG_COLL_COUNT_ADDR: ptr = rtu_protocol_coll_count(ptr);
- case REG_COLL_SW_HIGH_STAT_ADDR: ptr = rtu_protocol_sw_high_stat(ptr);
- case REG_COLL_SW_LOW_STAT_ADDR: ptr = rtu_protocol_sw_low_stat(ptr);
- default:break;
- }
- rtu_protocol_send(data, dataSize * 2 + 3);
- return true;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_wr_reg_return
- * @函数说明 写入数据成功返回
- * @输入参数 rec:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static void rtu_protocol_wr_reg_return(rtu_rec_s *rec)
- {
- uint8_t data[MODBUS_DATA_SIZE] = {0};
- data[0] = rec->addr;
- data[1] = rec->func;
- data[2] = rec->regAddr[0];
- data[3] = rec->regAddr[1];
- memcpy(&data[4], rec->data, rec->dataSize);
- memcpy(&data[rec->dataSize + 4], (uint8_t *)&(rec->crc), 2);
- uploadTx_send(data, rec->dataSize + 6);
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_wr_reg_parsing
- * @函数说明 写指令数据解析
- * @输入参数 rec:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_protocol_wr_reg_parsing(rtu_rec_s *rec)
- {
- uint16_t reg_addr = 0;
- reg_addr = rec->regAddr[0];
- reg_addr <<= 8;
- reg_addr += rec->regAddr[1];
- switch(reg_addr)
- {
- default:break;
- }
- return false;
- }
- static bool rtu_protocol_parsing(rtu_rec_s *rec)
- {
- uint16_t crc = 0xFFFF;
- crc = GetCRC16((uint8_t *)rec, rec->dataSize + 4, crc);
- if(crc != rec->crc)
- {
- return false;
- }
- if(rec->addr != upload_work.rtu_addr)
- {
- return false;
- }
- if(rec->func == CMD_RD_REG)
- {
- if(true == rtu_protocol_rd_reg_parsing(rec))
- {
- set_upload_offline(false);
- return true;
- }
- }
- else if(rec->func == CMD_WR_REG)
- {
- if(true == rtu_protocol_wr_reg_parsing(rec))
- {
- set_upload_offline(false);
- return true;
- }
- }
- else if(rec->func == CMD_WR_MULTI_REG)
- {
- return false;
- }
- return false;
- }
- static void set_upload_offline(bool stat)
- {
- if(stat == true)
- {
- upload_offline_timeout = 5000;
- if(upload_offline_stat == false)
- {
- upload_offline_stat = true;
- }
- }
- else{
- if(upload_offline_stat == true)
- {
- upload_offline_stat = false;
- }
- }
- }
- /*******************************************************************************
- * @函数名称 prvUser_check_upload_callback
- * @函数说明 光敏状态上报回调
- * @输入参数 无
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static void prvUser_check_upload_callback(bool stat)
- {
- coll_data.sw_stat = stat;
- }
- /*******************************************************************************
- * @函数名称 vUpload_tick
- * @函数说明 任务计时器
- * @输入参数 无
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- void vUpload_tick(void)
- {
- if(upload_offline_timeout > 0)
- {
- upload_offline_timeout--;
- }
- else{
- set_upload_offline(true);
- }
- }
- /*******************************************************************************
- * @函数名称 upload_pro
- * @函数说明 任务
- * @输入参数 无
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- void vUpload_pro(void)
- {
- if(upload_work.modbusRx_stat == true)
- {
- upload_work.modbusRx_stat = false;
- rtu_protocol_parsing(&(upload_work.rtu_rec));
- }
- }
- /*******************************************************************************
- * @函数名称 vUpload_init
- * @函数说明 初始化
- * @输入参数 无
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- void vUpload_init(void)
- {
- user_uart_param_s param = {
- .baudrate = 115200,
- .wordlength = USART_WordLength_8b,
- .stopbit = USART_StopBits_1,
- .parity = USART_Parity_No,
- };
- vUser_usart1_init(¶m);
- vUser_check_set_upload_func(prvUser_check_upload_callback);
- vUser_usart1_set_data_upload_func(uploadRx_receive);
- }
|