123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- #include "ec800.h"
- #include "delay.h"
- #include "string.h"
- #include <stdlib.h>
- #include "fmc.h"
- #include "main.h"
- /*!
- \brief configure EC800M pin
- \param[out] none
- \retval none
- */
- #define RSP_READY "RDY"
- #define CMD_SET_PDP "AT+QICSGP=1,1,\"CTNET\",\"\",\"\",1\r\n"
- #define RSP_OK "OK"
- #define CMD_SET_ACTIVE "AT+QIACT=1\r\n"
- #define cmdOpenFile(cmd,filename) sprintf(cmd,"AT+QFOPEN=\"%s\",2\r\n",filename)
- #define cmdSetSeek(cmd,handle,offset) sprintf(cmd,"AT+QFSEEK=%d,%d,0\r\n",handle,offset)
- #define cmdReadFileData(cmd,handle) sprintf(cmd,"AT+QFREAD=%d,1024\r\n",handle)
- #define cmdLoadFile(cmd,filename) sprintf(cmd,"AT+QFDWL=%s\r\n",filename)
- uint8_t UART0_RX_BUF[UART0_RX_LEN];
- uint8_t UART0_RX_STAT;
- bool WaitResponse(char *expectStr, int timeout);
- void EC800MSendCmd(char *buf, uint16_t len);
- int get_file_handle(char *filename);
- static const char* my_memmem(const uint8_t* haystack, size_t hlen, const char* needle, size_t nlen);
- static void extract_data_from_buffer(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr);
- static uint16_t checksum(const uint8_t *str, uint16_t len);
- void gd_EC800M_pin_init(void)
- {
- /* enable the EC800M power pin clock */
- rcu_periph_clock_enable(EC800M_PER_GPIO_CLK);
- /* configure EC800M GPIO port */
- gpio_init(EC800M_PER_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, EC800M_PER_PIN);
- GPIO_BC(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN;
- /* enable the EC800M reset pin clock */
- rcu_periph_clock_enable(EC800M_RST_GPIO_CLK);
- /* configure EC800M GPIO port */
- gpio_init(EC800M_RST_GPIO_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, EC800M_RST_PIN);
- GPIO_BC(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN;
-
- }
- void gd_pull_EC800M_pwr_up(void)
- {
- GPIO_BOP(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN;
- }
- void gd_pull_EC800M_pwr_down(void)
- {
- GPIO_BC(EC800M_PER_GPIO_PORT) = EC800M_PER_PIN;
- }
- void gd_pull_EC800M_rst_up(void)
- {
- GPIO_BOP(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN;
- }
- void gd_pull_EC800M_rst_down(void)
- {
- GPIO_BC(EC800M_RST_GPIO_PORT) = EC800M_RST_PIN;
- }
- /*!
- \brief configure COM port
- \param[in] com: COM on the board
- \arg COM_EC800: EC800
- \arg COM_485: 485
- \arg COM_232: 232
- \param[out] none
- \retval none
- */
- void gd_com_init()
- {
- nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // 设置抢占优先级和子优先级的位数为 2
- nvic_irq_enable(USART0_IRQn, 0, 0);
-
- /* enable GPIO clock */
- rcu_periph_clock_enable(COM_EC800_GPIO_CLK);
- /* enable USART clock */
- rcu_periph_clock_enable(COM_EC800_CLK);
- /* connect port to USARTx_Tx */
- gpio_init(COM_EC800_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, COM_EC800_TX_PIN);
- /* connect port to USARTx_Rx */
- gpio_init(COM_EC800_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, COM_EC800_RX_PIN);
-
- /* USART configure */
- usart_deinit(COM_EC800);
- usart_baudrate_set(COM_EC800, COM_EC800_BAUDRATE);
- usart_word_length_set(COM_EC800, USART_WL_8BIT);
- usart_stop_bit_set(COM_EC800, USART_STB_1BIT);
- usart_parity_config(COM_EC800, USART_PM_NONE);
- usart_hardware_flow_rts_config(COM_EC800, USART_RTS_DISABLE);
- usart_hardware_flow_cts_config(COM_EC800, USART_CTS_DISABLE);
- usart_receive_config(COM_EC800, USART_RECEIVE_ENABLE);
- usart_transmit_config(COM_EC800, USART_TRANSMIT_ENABLE);
- usart_enable(COM_EC800);
- usart_interrupt_enable(COM_EC800, USART_INT_IDLE);
-
- }
- void dma_config(void)
- {
- dma_parameter_struct dma_init_struct;
- rcu_periph_clock_enable(RCU_DMA0);
- dma_deinit(DMA0, DMA_CH4);
- dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
- dma_init_struct.memory_addr = (uint32_t)UART0_RX_BUF;
- dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
- dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
- dma_init_struct.number = UART0_RX_LEN;
- dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(USART0));// ((uint32_t)0x40013804);
- dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
- dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
- dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
- dma_init(DMA0, DMA_CH4, &dma_init_struct);
-
- dma_circulation_disable(DMA0, DMA_CH4);
- dma_memory_to_memory_disable(DMA0, DMA_CH4);
- usart_dma_transmit_config(USART0, USART_DENT_ENABLE|USART_DENR_ENABLE);
- nvic_irq_enable(DMA0_Channel4_IRQn, 2, 1);
-
- dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF|DMA_INT_HTF|DMA_INT_ERR);
- dma_channel_enable(DMA0, DMA_CH4);
- }
- // 4G模块
- void USART0_IRQHandler(void)
- {
- if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) // 空闲中断
- {
- usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE); /* 清除空闲中断标志位 */
- usart_data_receive(USART0); /* 清除接收完成标志位 */
- dma_channel_disable(DMA0, DMA_CH4); /* 关闭DMA传输 */
- UART0_RX_STAT = 0x01; /* 接受状态 0x01:已接收到数据 */
- dma_channel_enable(DMA0, DMA_CH4);
-
- }
- }
- void DMA0_Channel4_IRQHandler(void)
- {
- dma_interrupt_flag_clear(DMA0, DMA_CH4, DMA_INT_FLAG_G);
- }
- //清除dma buffer内数据
- void Clear_DMA_Buffer(void)
- {
- memset(UART0_RX_BUF,0,UART0_RX_LEN);
- }
- void EC800MPwoerOn(void)
- {
- rcu_periph_clock_enable(RCU_GPIOD);
- gpio_init(GPIOD, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
- gpio_bit_set(GPIOD,GPIO_PIN_2);
- Delay_Ms(5000);
- gd_pull_EC800M_pwr_up();
- gd_pull_EC800M_rst_down();
- Delay_Ms(50);
- gd_pull_EC800M_pwr_down();
- Delay_Ms(320);
- gd_pull_EC800M_rst_up();
- Delay_Ms(800);
- gd_pull_EC800M_pwr_up();
- }
- void EC800MWaitReady()
- {
- if(WaitResponse(RSP_READY, 5000)==FALSE) NVIC_SystemReset();
- }
- /*
- * 函数名:bool WaitResponse(char *expectStr, int timeout)
- * 输入参数:expectStr 需要匹配的关键字 timeout超时时间
- * 输出参数:true flase
- * 返回值:无
- * 函数作用:从UART0_RX_BUF缓冲区中匹配有无对应关键字有关键字则返回true无返回false
- */
- bool WaitResponse(char *expectStr, int timeout)
- {
- bool timeoutFlag = FALSE;
- if (timeout >= 0)
- {
- timeoutFlag = TRUE;
- }
- // gd_485_send((char *)&UART0_RX_BUF, strlen(UART0_RX_BUF)); 不清楚此处调用485意义
- while (1)
- {
- Delay_Ms(50);
- if (UART0_RX_STAT > 0)
- {
- UART0_RX_STAT = 0;
- char *p = strstr((char *)&UART0_RX_BUF, expectStr);
- if (p)
- {
- Clear_DMA_Buffer();
- return TRUE;
- }
- }
- timeout -= 50;
- if (timeoutFlag == TRUE && timeout <= 0)
- {
- Clear_DMA_Buffer();
- return FALSE;
- }
- };
- }
- /*
- * 函数名:bool WaitResponse(char *expectStr, int timeout)
- * 输入参数:expectStr 需要匹配的关键字 timeout超时时间
- * 输出参数:true flase
- * 返回值:无
- * 函数作用:从UART0_RX_BUF缓冲区中匹配有无对应关键字有关键字则返回true无返回false
- */
- bool WaitResponseNotclear(char *expectStr, int timeout)
- {
- bool timeoutFlag = FALSE;
- if (timeout >= 0)
- {
- timeoutFlag = TRUE;
- }
- // gd_485_send((char *)&UART0_RX_BUF, strlen(UART0_RX_BUF)); 不清楚此处调用485意义
- while (1)
- {
- Delay_Ms(50);
- if (UART0_RX_STAT > 0)
- {
- UART0_RX_STAT = 0;
- char *p = strstr((char *)&UART0_RX_BUF, expectStr);
- if (p)
- {
- return TRUE;
- }
- }
- timeout -= 50;
- if (timeoutFlag == TRUE && timeout <= 0)
- {
- return FALSE;
- }
- };
- }
- /*
- * 函数名:void EC800MSetPDP()
- * 输入参数:无
- * 输出参数:无
- * 返回值:无
- * 函数作用:设置对应运营商和激活ip
- */
- void EC800MSetPDP()
- {
- Delay_Ms(200);
- EC800MSendCmd(CMD_SET_PDP, strlen(CMD_SET_PDP));
- WaitResponse(RSP_OK, 1000);
- Delay_Ms(200);
- EC800MSendCmd(CMD_SET_ACTIVE, strlen(CMD_SET_ACTIVE));
- WaitResponse(RSP_OK, 1000);
- Delay_Ms(2000);
- }
- void EC800MSendCmd(char *buf, uint16_t len)
- {
- uint16_t i;
- uint16_t data;
- for (i = 0; i < len; i++)
- {
- data = buf[i];
- usart_data_transmit(COM_EC800, data);
- while (RESET == usart_flag_get(COM_EC800, USART_FLAG_TBE))
- ;
- }
- }
- //读取bin文件内容
- int read_bin_txt()
- {
- char *ptr;
- uint32_t len;
- uint16_t checkCode;
- char sub_str[] = "\r\n+QFDWL:";
- char cmd[50];
- uint32_t BufferSize=40*1024;//最大获取的数据空间
- uint8_t *dmabuffer=malloc(BufferSize);
- dma_config_change(dmabuffer,BufferSize);
- cmdLoadFile(cmd,"bin.txt");
- // Delay_Ms(1000);
- // EC800MSendCmd("AT+QFLST=\"*\"\r\n", strlen("AT+QFLST=\"*\"\r\n"));
-
- Delay_Ms(1000);
- EC800MSendCmd(cmd, strlen(cmd));
- Delay_Ms(5000);
-
-
-
- ptr = (char *)my_memmem(dmabuffer, BufferSize, sub_str, strlen(sub_str));
- if(ptr==NULL){ free(dmabuffer);return 2;}
- if(strstr(ptr,"ERROR"))
- {
- return 2;
- }
- extract_data_from_buffer(ptr,&len, &checkCode);
- uint16_t code=checksum(dmabuffer,len);
- if(checkCode==checksum(dmabuffer,len))
- {
- //校验成功数据正常,写入数据
- GD32_EraseFlash(GD32_A_START_PAGE,GD32_A_PAGE_NUM);//擦除A区原有程序
- GD32_WriteFlash(GD32_A_SADDR,(uint32_t *)dmabuffer,len);
- free(dmabuffer);
- return 1;
- }
-
- dma_config();
- free(dmabuffer);
- return 0;
- }
- ////获取文件句柄
- //int get_file_handle(char *filename)
- //{
- // int num;
- // char *ptr_start;
- // ptr_start=strstr((char *)&UART0_RX_BUF, filename);
- // if (ptr_start == NULL) {}
- // ptr_start = strchr(ptr_start, ':');
- // ptr_start++; // 跳过逗号
- // sscanf(ptr_start, "%d", &num);
- // return num;
- //}
- //手动控制dma搬运的数据地址和大小,在使用完成后需要恢复到默认的dma配置
- void dma_config_change(char *dmaBuffer,uint32_t bufferSize)
- {
- dma_parameter_struct dma_init_struct;
- rcu_periph_clock_enable(RCU_DMA0);
- dma_deinit(DMA0, DMA_CH4);
- dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
- dma_init_struct.memory_addr = (uint32_t)dmaBuffer;
- dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
- dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
- dma_init_struct.number = bufferSize;
- dma_init_struct.periph_addr = (uint32_t)(&USART_DATA(USART0));// ((uint32_t)0x40013804);
- dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
- dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
- dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
- dma_init(DMA0, DMA_CH4, &dma_init_struct);
-
- dma_circulation_disable(DMA0, DMA_CH4);
- dma_memory_to_memory_disable(DMA0, DMA_CH4);
- usart_dma_transmit_config(USART0, USART_DENT_ENABLE|USART_DENR_ENABLE);
- //nvic_irq_enable(DMA0_Channel4_IRQn, 2, 2);
-
- dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF|DMA_INT_ERR);
- dma_channel_enable(DMA0, DMA_CH4);
- }
- static const char* my_memmem(const uint8_t* haystack, size_t hlen, const char* needle, size_t nlen)
- {
- const char* cur;
- const char* last;
- last = haystack + hlen - nlen;
- for (cur = haystack; cur <= last; ++cur) {
- if (cur[0] == needle[0] && memcmp(cur, needle, nlen) == 0) {
- return cur;
- }
- }
- return NULL;
- }
- /*
- * 函数名:static void extract_data_from_buffer(const char* buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr)
- * 输入参数:buffer字符串
- * 输出参数:json有效字符串长度len_ptr,checkCode_ptr校验码指针
- * 返回值:无
- * 函数作用:eg. QFDWL: 621,3e23 从json信息最后端取出这段json的有效长度和校验码
- */
- static void extract_data_from_buffer(const char *buffer, uint32_t *len_ptr, uint16_t *checkCode_ptr)
- {
- char *start = strstr(buffer, "+QFDWL:");
- if (start != NULL)
- {
- start += 8; // 跳过"+QFDWL:"
- uint32_t len = 0;
- sscanf(start, "%u,", &len); // 读取长度
- start = strchr(start, ',') + 1; // 跳过逗号
- uint16_t checkCode = 0;
- sscanf(start, "%hx", &checkCode); // 读取16进制数据
- // 将提取的数据存入形参
- *len_ptr = len;
- *checkCode_ptr = checkCode;
- }
- }
- // 模块下载download校验值
- static uint16_t checksum(const uint8_t *str, uint16_t len)
- {
- uint16_t sum = 0;
- uint8_t odd = 0;
- // 如果字符串长度为奇数,则将最后一个字符设置为高8位,低8位设置为0
- if (len % 2 == 1)
- {
- odd = 1;
- len--;
- }
- // 将每两个字符作为一个16位的数值进行异或操作
- for (uint16_t i = 0; i < len; i += 2)
- {
- sum ^= ((uint16_t)str[i] << 8) | (uint16_t)str[i + 1];
- }
- // 如果字符串长度为奇数,则还需要将最后一个字符与0xFF00异或
- if (odd)
- {
- sum ^= (uint16_t)str[len] << 8;
- }
- // 返回校验和
- return sum;
- }
|