/*! \file main.c \brief led spark with systick, USART print and key example \version 2014-12-26, V1.0.0, firmware for GD32F10x \version 2017-06-20, V2.0.0, firmware for GD32F10x \version 2018-07-31, V2.1.0, firmware for GD32F10x \version 2020-09-30, V2.2.0, firmware for GD32F10x */ /* Copyright (c) 2020, GigaDevice Semiconductor Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "gd32f10x.h" #include "systick.h" #include #include "main.h" #include "usart.h" #include "led.h" #include "config.h" #include "log.h" #include "ec800m.h" #include "parseDeviceMessage.h" #include "otaEvent.h" #include "systick.h" #include "w25q32.h" #include "key.h" #define UNIQUE_ID 0x1FFFF7E8 #define VERSION "V1.0.2" // 版本号写死、通过人工手动控制 #define GATEWAYNAME "DTU" #define GATEWAYMODE "4G" // 后续此mode可以切换4g void MQTT_Alarm_clock(uint32_t time, GATEWAY_PARAMS *gateway); void readID(char *strId); void http_load_config(uint8_t *httpURL); void fwdgt_init(); void task_fwdgt_reload(); int main(void) { /* configure systick */ rcu_osci_on(RCU_HXTAL); systick_config(); nvic_config(); /* initilize the LEDs, USART */ // W25Q32_Init(); //弃用w25q32,改用片内flash存储 gd_eval_led_init(LED1); gd_com_init(COM_232); gd_com_init(COM_EC800); dma_config(); gd_EC800M_pin_init(); gd_eval_key_init(KEY_SYS_RECOVERY, KEY_MODE_EXTI); EC800MPwoerOn(); EC800MWaitReady(); EC800MSetPDP(); char *strID = malloc(24); readID(strID); //加载网关信息 GATEWAY_PARAMS *gateway; gateway = get_gateway_config_params(); strcpy((char *)&gateway->gatewayId, strID); strcpy((char *)&gateway->gatewayMode, GATEWAYMODE); strcpy((char *)&gateway->gateName,GATEWAYNAME); char *httpURL = malloc(100); memset(httpURL, 0, 100); sprintf(httpURL, "http://gpu.ringzle.com:8082/iot/transmit/getTransmitConfig/%s",strID); http_load_config(httpURL); free(httpURL); httpURL=NULL; gateway = get_gateway_config_params(); strcpy((char *)&gateway->gatewayId, strID); strcpy((char *)&gateway->gatewayMode, GATEWAYMODE); strcpy((char *)&gateway->gateName,GATEWAYNAME); free(strID); config_485_port(COM_485, gateway->baudrate, gateway->dataBits, gateway->stopBit, gateway->checkBit); gd_485_DE_pin_init(); gd_485_DE_tx(); ConnectMQTTSever(gateway->host, gateway->port, 60, gateway->deviceId); MQTTSubTopic(gateway->commandTopic); ring_buffer_init(&mqttRecv); mmodbus_init(1); dlt645_init(1); //开启看门狗 // fwdgt_init(); while (1) { check_ota_event(); //检测是否有ota事件产生 MQTT_Alarm_clock(gateway->inboundTime, gateway); } } /* * 函数名:void MQTT_Alarm_clock(uint32_t time) * 输入参数:time设定MQTT多久进行一次上传 * 输出参数:无 * 返回值:无 * 函数作用:按照设定好时间进行执行,在未到达指定时间之前重复做led反转、MQTT订阅的主题是否有下发主题信息判断 * 当time为0时进行数据采集和数据上传 */ void MQTT_Alarm_clock(uint32_t time, GATEWAY_PARAMS *gateway) { while (1) { if (time <= 0) { Read_Data(); MQTTPublish(); break; // 跳出while循环 } else { gd_eval_led_toggle(LED1); parseMQTTData(gateway); check_ota_event(); } delay_1ms(1000); time-=1000; task_fwdgt_reload(); } } /* * 函数名:void readID(char *strId) * 输入参数:无 * 输出参数:strId * 返回值:无 * 函数作用:读取长度12的芯片Id并组合从中取出对应字符防止其重复 */ void readID(char *strId) { static const char *hex_table = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN"; uint32_t CpuID1, CpuID2, CpuID3; CpuID1 = *(volatile uint32_t *)(0x1FFFF7E8); CpuID2 = *(volatile uint32_t *)(0x1FFFF7EC); CpuID3 = *(volatile uint32_t *)(0x1FFFF7F0); strId[0] = 'D'; strId[1] = 'T'; for (uint8_t i = 0, j = 0; i < 8; i += 2) { uint32_t sum1 = (CpuID1 >> ((j % 4) * 8)) & 0xFF; // 按字节取出 uint8_t index1 = sum1 / 16; uint8_t remainder1 = sum1 % 16; uint32_t sum2 = (CpuID2 >> ((j % 4) * 8)) & 0xFF; // 按字节取出 uint8_t index2 = sum2 / 16; uint8_t remainder2 = sum2 % 16; uint32_t sum3 = (CpuID3 >> ((j % 4) * 8)) & 0xFF; // 按字节取出 uint8_t index3 = sum3 / 16; uint8_t remainder3 = sum3 % 16; strId[i + 2] = hex_table[index1 + index2 + index3]; strId[i + 1 + 2] = hex_table[remainder1 + remainder2 + remainder3]; j++; } strId[10] = '\0'; } /* * 函数名:void http_load_config(uint8_t *httpURL) * 输入参数:httpURL 获取参数配置的网址 * 输出参数:strId * 返回值:无 * 函数作用:拉取http配置 */ void http_load_config(uint8_t *httpURL) { uint32_t BufferSize=46*1024;//最大获取的数据空间 char *dmabuffer=malloc(BufferSize); __LOAD_CONFIG: if (EC800MGetUrl(httpURL,dmabuffer,BufferSize) == true) // 从http获取信息,获取成功则保存到本地 { if(WaitForUpData(dmabuffer)==false) goto __LOAD_CONFIG; } else//如果没有从http拉取到配置则直接读取文件系统内的json数据 { dma_config_change(dmabuffer,BufferSize); delay_1ms(1000); EC800MSendCmd(CMD_READ_FILE, strlen(CMD_READ_FILE)); //"AT+QFDWL=http.txt\r\n" delay_1ms(3000); WaitForUpData(dmabuffer); } dma_config(); free(dmabuffer); } /* * 函数名:void fwdgt_init(void) * 输入参数:无 * 输出参数:无 * 返回值:无 * 函数作用:初始化硬件看门狗 */ void fwdgt_init(void) { rcu_osci_on(RCU_IRC40K); // IRC40K时钟打开 /* confiure FWDGT counter clock: 40KHz(IRC40K) / 256= 0.015625 KHz */ fwdgt_config(0x0FFF, FWDGT_PSC_DIV256); // 看门狗时间设置 fwdgt_enable(); // 看门狗使能 } void task_fwdgt_reload(void) { /* uncock fwdgt write protect*/ fwdgt_write_enable(); /* feed fwdgt */ fwdgt_counter_reload(); } #if 0 // 本地信息调试使用 gateway->dataSource=MODBUS; gateway->baudrate=9600; gateway->dataBits=8; gateway->stopBit=1; gateway->checkBit=0; gateway->flowControl=0; gateway->device_read_data_num=1; gateway->device_read_data[0].deviceID645[0]=0x20; gateway->device_read_data[0].deviceID645[1]=0x92; gateway->device_read_data[0].deviceID645[2]=0x20; gateway->device_read_data[0].deviceID645[3]=0x00; gateway->device_read_data[0].deviceID645[4]=0x73; gateway->device_read_data[0].deviceID645[5]=0x81; gateway->device_read_data[0].dataType645=0x01010000; gateway->device_read_data[0].mdbSlave=0x17; gateway->device_read_data[0].mdbFunctionCode=0x03; gateway->device_read_data[0].mdbRegister=0x0000; gateway->device_read_data[0].registerLength=2; #endif