| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544 |
- #include "download.h"
- #include "upload.h"
- #include "user_uart.h"
- #include "user_crc16.h"
- #include "base64.h"
- #include "string.h"
- #include "user_server.h"
- static uint32_t download_delay_count = 0;
- static bool coll_ready_stat = false;
- static uint16_t coll_sw_count = 0;
- static uint16_t check_download_count = 0;
- static download_work_stat_e download_work_stat = DOWNLOAD_DEV_TYPE;
- static uint32_t download_offline_timeout = 0;
- static bool download_offline_stat = true;
- static void set_download_offline(bool stat);
- modbus_work_s download_work = {
- .rtu_addr = COLL_UART_ADDR,
- .tx_size = 0,
- .rx_size = 0,
- .tx_buffer = {0},
- .rx_buffer = {0},
- .rtu_rec = {0},
- .modbusRx_stat = false,
- .modbusTx_stat = false,
- };
- /*******************************************************************************
- * @函数名称 downloadRx_receive
- * @函数说明 处理接收数据
- * @输入参数 data:数据指针
- size:数据长度
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static void downloadRx_receive(uint8_t *data, uint16_t size)
- {
- memcpy(download_work.rx_buffer, data, size);
- download_work.rx_size = size;
- #if USE_BASE64 == 1
- uint8_t data[MODBUS_DATA_SIZE] = {0};
- if(download_work.rx_buffer[download_work.rx_size - 2] == '\r'
- && download_work.rx_buffer[download_work.rx_size - 1] == '\n')
- {
- download_work.rx_buffer[download_work.rx_size - 2] = '\0';
- int len = base64_decode((char *)download_work.rx_buffer, data);
-
- memcpy((void *)&(download_work.rtu_rd), data, len);
- memcpy((void *)&(download_work.rtu_rd.crc), &(data[len - 2]), 2);
- memcpy((void *)&(download_work.rtu_rec), data, len);
- memcpy((void *)&(download_work.rtu_rec.crc), &(data[len - 2]), 2);
- download_work.rtu_rec.dataSize = len - 6;
- download_work.modbusRx_stat = true;
- }
- #else
- memcpy((void *)&(download_work.rtu_rd), download_work.rx_buffer, download_work.rx_size);
- memcpy((void *)&(download_work.rtu_rd.crc), &(download_work.rx_buffer[download_work.rx_size - 2]), 2);
- memcpy((void *)&(download_work.rtu_rec), download_work.rx_buffer, download_work.rx_size);
- memcpy((void *)&(download_work.rtu_rec.crc), &(download_work.rx_buffer[download_work.rx_size - 2]), 2);
- download_work.rtu_rec.dataSize = download_work.rx_size - 6;
- download_work.modbusRx_stat = true;
- #endif
- }
- /*******************************************************************************
- * @函数名称 downloadTx_send
- * @函数说明 发送数据
- * @输入参数 无
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static void downloadTx_send(uint8_t *data, int size)
- {
- #if USE_BASE64 == 1
- base64_encode(data, (char *)download_work.tx_buffer, size);
- int len = strlen((char *)download_work.tx_buffer);
- download_work.tx_buffer[len] = '\r';
- download_work.tx_buffer[len + 1] = '\n';
- download_work.tx_buffer[len + 2] = '\0';
-
- download_work.tx_size = len + 2;
- #else
- memcpy(download_work.tx_buffer, data, size);
- download_work.tx_size = size;
- #endif
- download_work.modbusTx_stat = true;
-
- vUser_usart1_send(download_work.tx_buffer, download_work.tx_size);
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_sd_dev_type
- * @函数说明 设置询问从机设备类型数据
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint16_t rtu_protocol_sd_dev_type(uint8_t *data)
- {
- data[0] = download_work.rtu_addr;
- data[1] = CMD_RD_REG;
- data[2] = (uint8_t)(REG_DEV_TYPE_ADDR >> 8);
- data[3] = (uint8_t)REG_DEV_TYPE_ADDR;
- data[4] = 0x00;
- data[5] = 0x01;
- check_download_count++;
- return 6;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_sd_coll_stat
- * @函数说明 设置询问从机就绪状态数据
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint16_t rtu_protocol_sd_coll_stat(uint8_t *data)
- {
- data[0] = download_work.rtu_addr;
- data[1] = CMD_RD_REG;
- data[2] = (uint8_t)(REG_COLL_STAT_ADDR >> 8);
- data[3] = (uint8_t)REG_COLL_STAT_ADDR;
- data[4] = 0x00;
- data[5] = 0x01;
- return 6;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_sd_coll_count
- * @函数说明 设置询问从机包含的主板总数数据
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint16_t rtu_protocol_sd_coll_count(uint8_t *data)
- {
- data[0] = download_work.rtu_addr;
- data[1] = CMD_RD_REG;
- data[2] = (uint8_t)(REG_COLL_COUNT_ADDR >> 8);
- data[3] = (uint8_t)REG_COLL_COUNT_ADDR;
- data[4] = 0x00;
- data[5] = 0x01;
- return 6;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_sd_sw_stat
- * @函数说明 设置询问从机包含的开关量数据
- * @输入参数 data:数据指针
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static uint16_t rtu_protocol_sd_sw_stat(uint8_t *data)
- {
- data[0] = download_work.rtu_addr;
- data[1] = CMD_RD_REG;
- data[2] = (uint8_t)(REG_COLL_SW_HIGH_STAT_ADDR >> 8);
- data[3] = (uint8_t)REG_COLL_SW_HIGH_STAT_ADDR;
- data[4] = 0x00;
- data[5] = 0x02;
- return 6;
- }
- /*******************************************************************************
- * @函数名称 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);
- downloadTx_send(data, size + 2);
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_sd_task
- * @函数说明 发送数据任务
- * @输入参数 无
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static void rtu_protocol_sd_task(void)
- {
- uint8_t data[MODBUS_DATA_SIZE] = {0};
- uint16_t datasize = 0;
- switch(download_work_stat)
- {
- case DOWNLOAD_DEV_TYPE:datasize = rtu_protocol_sd_dev_type(data);break;
- case DOWNLOAD_COLL_REDAY_STAT:datasize = rtu_protocol_sd_coll_stat(data);break;
- case DOWNLOAD_COLL_COUNT:datasize = rtu_protocol_sd_coll_count(data);break;
- case DOWNLOAD_SW_STAT:datasize = rtu_protocol_sd_sw_stat(data);break;
- default:{
- download_work_stat = DOWNLOAD_DEV_TYPE;
- datasize = rtu_protocol_sd_dev_type(data);
- }break;
- }
- rtu_protocol_send(data, datasize);
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_rd_dev_type_parsing
- * @函数说明 解析读取设备类型
- * @输入参数 rd:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_protocol_rd_dev_type_parsing(rtu_rd_s *rd)
- {
- uint16_t temp = 0;
-
- temp = rd->data[0];
- temp <<= 8;
- temp += rd->data[1];
- if(temp == (uint16_t)COLL_UART_ADDR)
- {
- download_work_stat = DOWNLOAD_COLL_REDAY_STAT;
- check_download_count = 0;
- return true;
- }
- return false;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_rd_coll_stat_parsing
- * @函数说明 解析读取设备就绪状态
- * @输入参数 rd:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_protocol_rd_coll_stat_parsing(rtu_rd_s *rd)
- {
- uint16_t temp = 0;
-
- temp = rd->data[0];
- temp <<= 8;
- temp += rd->data[1];
- if(temp == COLL_READY_STAT)
- {
- download_work_stat = DOWNLOAD_COLL_COUNT;
- coll_ready_stat = true;
-
- return true;
- }
- return false;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_rd_coll_count_parsing
- * @函数说明 解析读取下挂主板数量
- * @输入参数 rd:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_protocol_rd_coll_count_parsing(rtu_rd_s *rd)
- {
- uint16_t temp = 0;
-
- temp = rd->data[0];
- temp <<= 8;
- temp += rd->data[1];
- if(temp < COLL_MAX_COUNT)
- {
- coll_sw_count = temp;
- download_work_stat = DOWNLOAD_SW_STAT;
- vUser_server_set_coll_stat(coll_sw_count);
- return true;
- }
- return false;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_rd_sw_stat_parsing
- * @函数说明 解析读取下挂主板开关量状态
- * @输入参数 rd:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_protocol_rd_sw_stat_parsing(rtu_rd_s *rd)
- {
- uint32_t temp = 0;
- if(rd->dataSize != 4)
- {
- return false;
- }
-
- temp = rd->data[0];
- temp <<= 8;
- temp += rd->data[1];
- temp <<= 8;
- temp += rd->data[2];
- temp <<= 8;
- temp += rd->data[3];
- vUser_server_set_download_sw_stat(temp);
- return true;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_rd_reg_parsing
- * @函数说明 解析读指令返回的数据
- * @输入参数 rd:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_protocol_rd_reg_parsing(rtu_rd_s *rd)
- {
- bool stat = false;
- switch(download_work_stat)
- {
- case DOWNLOAD_DEV_TYPE:stat = rtu_protocol_rd_dev_type_parsing(rd);break;
- case DOWNLOAD_COLL_REDAY_STAT:stat = rtu_protocol_rd_coll_stat_parsing(rd);break;
- case DOWNLOAD_COLL_COUNT:stat = rtu_protocol_rd_coll_count_parsing(rd);break;
- case DOWNLOAD_SW_STAT:stat = rtu_protocol_rd_sw_stat_parsing(rd);break;
- default:break;
- }
- return stat;
- }
- /*******************************************************************************
- * @函数名称 rtu_rd_protocol_parsing
- * @函数说明 读指令返回解析
- * @输入参数 rd:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_rd_protocol_parsing(rtu_rd_s *rd)
- {
- uint16_t crc = 0xFFFF;
-
- crc = GetCRC16((uint8_t *)rd, rd->dataSize + 3, crc);
- if(crc != rd->crc)
- {
- return false;
- }
- if(rd->func == CMD_RD_REG)
- {
- if(true == rtu_protocol_rd_reg_parsing(rd))
- {
- return true;
- }
- }
- return false;
- }
- /*******************************************************************************
- * @函数名称 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;
- }
- /*******************************************************************************
- * @函数名称 rtu_rec_protocol_parsing
- * @函数说明 写指令返回解析
- * @输入参数 rec:数据
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_rec_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->func == CMD_WR_REG)
- {
- if(true == rtu_protocol_wr_reg_parsing(rec))
- {
- return true;
- }
- }
- return false;
- }
- /*******************************************************************************
- * @函数名称 rtu_protocol_parsing
- * @函数说明 返回数据解析
- * @输入参数 无
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- static bool rtu_protocol_parsing(void)
- {
- if(download_work.rtu_rec.addr != download_work.rtu_addr)
- {
- return false;
- }
-
- if(download_work.rtu_rec.func == CMD_RD_REG)
- {
- if(true == rtu_rd_protocol_parsing(&(download_work.rtu_rd)))
- {
- set_download_offline(false);
- }
- }
- else if(download_work.rtu_rec.func == CMD_WR_REG)
- {
- if(true == rtu_rec_protocol_parsing(&(download_work.rtu_rec)))
- {
- set_download_offline(false);
- }
- }
- else{
- download_work_stat = DOWNLOAD_DEV_TYPE;
- }
- }
- /************************************************
- * 函数名:set_dowload_offline
- * 描述 :设置从机通讯状态灯
- * 输入 :stat:通讯状态
- * 输出 :无
- * 注意 :无
- ************************************************/
- static void set_download_offline(bool stat)
- {
- if(stat == true)
- {
- download_offline_timeout = 5000;
- if(download_offline_stat == false)
- {
- download_offline_stat = true;
- }
- }
- else{
- if(download_offline_stat == true)
- {
- download_offline_stat = false;
- }
- }
- }
- /************************************************
- * 函数名:vDowload_tick
- * 描述 :任务计时器
- * 输入 :无
- * 输出 :无
- * 注意 :无
- ************************************************/
- void vDownload_tick(void)
- {
- if(download_delay_count > 0)
- {
- download_delay_count--;
- }
-
- if(download_offline_timeout > 0)
- {
- download_offline_timeout--;
- }
- else{
- set_download_offline(true);
- }
- }
- /************************************************
- * 函数名:vDownload_pro
- * 描述 :执行任务
- * 输入 :无
- * 输出 :无
- * 注意 :无
- ************************************************/
- void vDownload_pro(void)
- {
- if(download_delay_count == 0)
- {
- download_delay_count = 500;
- if(check_download_count >= MAX_REPLAY_COUNT)
- {
- vUser_server_set_coll_stat(0);
- }
- rtu_protocol_sd_task();
- }
- if(download_work.modbusRx_stat == true)
- {
- download_work.modbusRx_stat = false;
- rtu_protocol_parsing();
- }
- }
- /*******************************************************************************
- * @函数名称 vUpload_init
- * @函数说明 初始化
- * @输入参数 无
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- void vDownload_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_usart1_set_data_upload_func(downloadRx_receive);
- }
|