/************************************************************************************ * @Copyright (c) :(C)2017, Qindao ieslab Co., Ltd * @FileName :pic24_nb_driver.c * @Author :QDIES PLATFORM TEAM * @Version :V1.0 * @Date :2017-03-01 * @Description : ************************************************************************************/ #include "sys_config.h" #ifdef MODULE_ML307A_TCP #ifdef __cplusplus extern "C" { #endif #include "nb_uart_driver_ml307a.h" #include "nb_driver_ml307a.h" #include "stdio.h" #include #include "UWater_timer1uS_driver.h" #include "UWater_uart_driver.h" #include "UWater_Rtcc_Driver.h" #include "UWater_frame_app.h" #include "nb_upload_monitor.h" /********************************变量定义************************************/ //模组信息、网络配置、连接状态相关参数 NBIOT_PARA Nbiot_Para; //模组数据发送指针 NBIOT_SEND_DATA Nbiot_Send_Data; //AT指令拼接缓存 static char stringbuffer_temp[UP_BUF_SIZE * 2]; //AT指令发送缓存 static char AT_BUF[50 + UP_BUF_SIZE * 2]; //任务完成情况 TYP_TASK_RESULT g_s_nbiot_task_flag = TASK_INIT; //数据发送通道 u8 g_s_nbiot_send_type; //模组上电标志 u8 nb_power_flag = FALSE; //AT指令查询失败次数 u8 at_requestErrorCount = 0; //AT指令执行结果 TYP_RESULT_CODE g_at_request_res; //AT指令索引 int g_at_index = 0; //TCP要发送数据的长度 u16 tcp_send_len = 0; char tcp_send_len_buf[8]; u8 tcp_send_len_buf_len = 0; //UDP要发送数据的长度 u16 udp_send_len = 0; char udp_send_len_buf[8]; u8 udp_send_len_buf_len = 0; //IP地址 unsigned char *coap_ip; u16 coap_port; unsigned char *udp_ip1; u16 udp_port1; unsigned char *udp_ip2; u16 udp_port2; u8 nbiot_temp_connect_type = NBIOT_CONNECT_COAP; //AT指令集 static STRUCT_AT_CMD AtCmdBuf[AT_CMD_COUNT] = { /*****模组初始化指令********************/ {AT_CODE_AT, "AT", WT_2S, RETRY_5, cst_AT_No_AT},//AT指令 {AT_CODE_CGSN, "AT+CGSN=1", WT_2S, RETRY_5, cst_AT_No_AT_IMEI},//查询IMEI {AT_CODE_CPIN, "AT+CPIN?", WT_2S, RETRY_5, cst_AT_No_AT_CPIN},//查询SIM卡状态,READY表示SIM卡正常识别运行。 {AT_CODE_CIMI, "AT+CIMI", WT_2S, RETRY_5, cst_AT_No_AT_CIMI},//查询IMSI {AT_CODE_MCCID, "AT+MCCID", WT_5S, RETRY_5, cst_AT_No_AT_ICCID},//查询ICCID {AT_CODE_CFUN_CK, "AT+CFUN?", WT_2S, RETRY_5, cst_AT_No_AT_CFUN_CK},//查询协议栈是否打开 {AT_CODE_CFUN0, "AT+CFUN=0", WT_2S, RETRY_5, cst_AT_No_AT_CFUN},// {AT_CODE_CFUN1, "AT+CFUN=1", WT_20S, RETRY_3, cst_AT_No_AT_CFUN},// {AT_CODE_CSQ, "AT+CSQ", WT_2S, RETRY_2, cst_AT_No_AT_CSQ},//查询信号质量 {AT_CODE_MUESTATS, "AT+MUESTATS=\"cell\"", WT_2S, RETRY_2, cst_AT_No_AT_MUESTATS},//查询信号状态 {AT_CODE_SBAND, "AT+MUESTATS=\"sband\"", WT_2S, RETRY_2, cst_AT_No_AT_SBAND},//查询频段 {AT_CODE_CGDCONT, "AT+CGDCONT=1,\"IPV4V6\",\"", WT_2S, RETRY_1, cst_AT_No_AT},//设置APN,配置PDP上下文 {AT_CODE_MIPCALL_CK, "AT+MIPCALL?", WT_2S, RETRY_2, cst_AT_No_AT_MIPCALL_how}, //查询拨号状态 {AT_CODE_CEREG, "AT+CEREG?", WT_2S, RETRY_10, cst_AT_No_AT_CEREG}, //查询网络注册状态 {AT_CODE_MIPCALL, "AT+MIPCALL=1,1", WT_2S, RETRY_5, cst_AT_No_AT_MIPCALL},//激活PDP {AT_CODE_CCLK, "AT+CCLK?", WT_5S, RETRY_3, cst_AT_No_AT_CCLK},//查询模组时间 /*****TCP连接指令***********************/ {AT_CODE_MIPCFG_ACK1, "AT+MIPCFG=\"ackmode\",1,1", WT_2S, RETRY_5, cst_AT_No_AT}, //接收ACK包时上报URC {AT_CODE_MIPCFG_ACK0, "AT+MIPCFG=\"ackmode\",1,0", WT_2S, RETRY_5, cst_AT_No_AT}, //接收ACK包时不上报URC //{AT_CODE_MIPOPEN, "AT+MIPOPEN=0,\"TCP\",\"",WT_5S, RETRY_5, cst_AT_No_AT_MIPOPEN},// AT+MIPOPEN=0,"TCP","58.59.6.130",21628 {AT_CODE_MIPCFG_TCP, "AT+MIPCFG=\"encoding\",1,1,1", WT_2S, RETRY_5, cst_AT_No_AT}, //发送接收数据格式为HEX {AT_CODE_MIPOPEN, "AT+MIPOPEN=1,\"TCP\",\"", WT_40S, RETRY_1, cst_AT_No_AT_MIPOPEN}, // AT+MIPOPEN=1,"TCP","58.59.6.130",21628 /*****TCP数据发送***********************/ {AT_CODE_TCPSEND_ACK, "AT+MIPSEND=1,", WT_5S, RETRY_2, cst_AT_No_AT_TCPSEND_ACK}, //发送 {AT_CODE_TCPSEND, "AT+MIPSEND=1,", WT_5S, RETRY_2, cst_AT_No_AT_TCPSEND},// //关闭TCP连接 {AT_CODE_MIPCLOSE, "AT+MIPCLOSE=1", WT_5S, RETRY_2, cst_AT_No_AT_MIPCLOSE},//AT+MIPCLOSE=1 /*****UDP1连接指令**********************/ {AT_CODE_MIPCFG_UDP1, "AT+MIPCFG=\"encoding\",2,1,1", WT_2S, RETRY_5, cst_AT_No_AT}, //发送接收数据格式为HEX {AT_CODE_MIPOPEN_UDP1, "AT+MIPOPEN=2,\"UDP\",\"", WT_5S, RETRY_5, cst_AT_No_AT_MIPOPEN}, // AT+MIPOPEN=1,"UDP","60.208.16.58",7833 /*****UDP1数据发送***********************/ // {AT_CODE_MIPSENDCOUNT_UDP1, "AT+MIPSEND=2,", WT_5S, RETRY_2, cst_AT_No_AT_MIPSENDCOUNT}, //设置发送字节数 {AT_CODE_UDPSEND1, "AT+MIPSEND=2,", WT_5S, RETRY_0, cst_AT_No_AT_TCPSEND},// //关闭UDP1连接 {AT_CODE_MIPCLOSE_UDP1, "AT+MIPCLOSE=2", WT_5S, RETRY_2, cst_AT_No_AT_MIPCLOSE},//AT+MIPCLOSE=0 /*****UDP2连接指令**********************/ {AT_CODE_MIPCFG_UDP2, "AT+MIPCFG=\"encoding\",3,1,1", WT_2S, RETRY_5, cst_AT_No_AT}, //发送接收数据格式为HEX {AT_CODE_MIPOPEN_UDP2, "AT+MIPOPEN=3,\"UDP\",\"", WT_5S, RETRY_5, cst_AT_No_AT_MIPOPEN}, // AT+MIPOPEN=1,"UDP","60.208.16.58",7833 /*****UDP2数据发送***********************/ // {AT_CODE_MIPSENDCOUNT_UDP2, "AT+MIPSEND=3,", WT_5S, RETRY_2, cst_AT_No_AT_MIPSENDCOUNT}, //设置发送字节数 {AT_CODE_UDPSEND2, "AT+MIPSEND=3,", WT_5S, RETRY_0, cst_AT_No_AT_TCPSEND},// //关闭UDP2连接 {AT_CODE_MIPCLOSE_UDP2, "AT+MIPCLOSE=3", WT_5S, RETRY_2, cst_AT_No_AT_MIPCLOSE},//AT+MIPCLOSE=0 //关机 {AT_CODE_MPOF, "AT+MPOF=0", WT_20S, RETRY_2, cst_AT_No_AT},//模组关机 }; /*****************************内部功能状态定义*********************************/ //主状态 TYP_STATE_MAIN_CONNECT g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; //开机状态 TYP_STEP_MODULE_POWERON s_power_on_state = MODULE_IDLE; //关机状态 TYP_STATE_POWER_OFF s_power_off_state = S_PWOFF_IDLE; //AT指令查询状态 TYP_STATE_AT_REQUEST s_at_requeset_state = AT_REQUEST_IDLE; //模组初始化状态 TYP_MODULE_INIT s_init_state = S_MODULE_INIT_IDLE; //TCP连接状态 TYP_TCP_CONNECT s_tcp_connect_state = S_TCP_CONNECT_IDLE; //TCP发送数据状态 TYP_TCP_SEND s_tcp_send_state; //UDP连接状态 TYP_UDP_CONNECT s_udp_connect_state = S_UDP_CONNECT_IDLE; //UDP发送数据状态 TYP_UDP_SEND s_udp_send_state; /*****************************内部功能状态机函数*********************************/ void NbiotInitMachine(void); void NbiotPowerOffMachine(void); void UdpReadDataMachine(void); //TCP连接 void TcpStartConnect(void); void TcpConnectMachine(void); //TCP发送 void StartTcpSendData(void); void TcpSendDataMachine(void); //UDP连接 void UdpStartConnect(u8 udp_num); void UdpConnectMachine(void); //UDP发送 void StartUdpSendData(void); void UdpSendDataMachine(void); /*****************************内部定时器接口**********************************/ void set_timer_1s(u16 time); u16 check_timer_1s(void); void set_timer_1ms(u16 time); u16 check_timer_1ms(void); void StartNbiotInit(void); /*****************************外部接口****************************************/ void NB_Power_Disable(void) { Gpio_WriteOutputIO(BAT_NB_PORT, BAT_NB_PIN, FALSE); nb_power_flag = FALSE; } void NB_Power_Enable(void) { Gpio_WriteOutputIO(BAT_NB_PORT, BAT_NB_PIN, TRUE); nb_power_flag = TRUE; } u8 If_NB_Poweron(void) { return nb_power_flag; } /*************************************************************************** * @fun_name void NbModuleIOInit(void) * @brief 模块供电IO、模块复位、电源、PSM唤醒引脚初始化 ***************************************************************************/ void NbModuleIOInit(void) { stc_gpio_cfg_t stcGpioCfg; DDL_ZERO_STRUCT(stcGpioCfg); stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置 stcGpioCfg.enDrv = GpioDrvL; ///< 端口驱动能力配置->低驱动能力 stcGpioCfg.enPu = GpioPuDisable; ///< 端口上下拉配置->无 stcGpioCfg.enPd = GpioPdDisable; stcGpioCfg.enOD = GpioOdDisable; ///< 端口开漏输出配置 stcGpioCfg.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHB Gpio_Init(BAT_NB_PORT, BAT_NB_PIN, &stcGpioCfg); //模块供电IO Gpio_Init(RSTN_NB_PORT, RSTN_NB_PIN, &stcGpioCfg); Gpio_Init(NB_PSM_WAKE_PORT, NB_PSM_WAKE_PIN, &stcGpioCfg); Gpio_Init(PWR_NB_PORT, PWR_NB_PIN, &stcGpioCfg); //电源控制脚 Gpio_WriteOutputIO(BAT_NB_PORT, BAT_NB_PIN, FALSE); Gpio_WriteOutputIO(PWR_NB_PORT, PWR_NB_PIN, FALSE); Gpio_WriteOutputIO(RSTN_NB_PORT, RSTN_NB_PIN, FALSE); Gpio_WriteOutputIO(NB_PSM_WAKE_PORT, NB_PSM_WAKE_PIN, FALSE); } /*模组端串口调试配置*/ void NB_UartInitForGPIO(void)//debug { stc_gpio_cfg_t stcGpioCfg; DDL_ZERO_STRUCT(stcGpioCfg); //PA0,PA1:配置为数字输入 stcGpioCfg.enDir = GpioDirIn; ///< 端口方向配置->输入 stcGpioCfg.enDrv = GpioDrvL; ///< 端口驱动能力配置->低驱动能力 stcGpioCfg.enPu = GpioPuDisable; ///< 端口上下拉配置->无 stcGpioCfg.enPd = GpioPdDisable; stcGpioCfg.enOD = GpioOdDisable; ///< 端口开漏输出配置->开漏输出关闭 stcGpioCfg.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHB Gpio_Init(GpioPortA, GpioPin0, &stcGpioCfg); Gpio_Init(GpioPortA, GpioPin1, &stcGpioCfg); } /*************************************************************************** * @fun_name void NbiotMainMachine() * @brief NBIOT主任务机,放在主程序空间的主循环中,进行NBIOT任务处理 ***************************************************************************/ void NbiotMainMachine(void) { switch (g_s_nbiot_main_state) { case S_NBIOT_MAIN_IDLE: { } break; case S_NBIOT_MAIN_POWER_INIT: { if (TASK_INIT == g_s_nbiot_task_flag) //如果是初始状态 { NbiotInitMachine(); //模块初始化状态机 } else { if (TASK_SUCCESS == g_s_nbiot_task_flag) //任务成功 { Nbiot_Para.net_state = NB_ON_LINE; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; } else //任务失败 { *Nbiot_Send_Data.state = NBIOT_ERROR; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; } g_s_nbiot_task_flag = TASK_INIT; //清标志位 } } break; case S_NBIOT_MAIN_TCP_OPEN: { if (TASK_INIT == g_s_nbiot_task_flag) { TcpConnectMachine(); //与主站建立连接状态机 } else { if (TASK_SUCCESS == g_s_nbiot_task_flag) { Nbiot_Para.coap_state = CONNECT_ON_LINE; } else { Nbiot_Para.coap_state = CONNECT_OFF_LINE; *Nbiot_Send_Data.state = NBIOT_ERROR; } g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; } } break; case S_NBIOT_MAIN_TCP_SEND: { if (CONNECT_ON_LINE == Nbiot_Para.coap_state) { if (TASK_INIT == g_s_nbiot_task_flag) { TcpSendDataMachine(); //数据发送状态机 } else//发送数据任务成功和失败都回到空闲 { *Nbiot_Send_Data.state = NBIOT_SUCCESS; g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; } } else { g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; } } break; case S_NBIOT_MAIN_UDP_OPEN: { if (TASK_INIT == g_s_nbiot_task_flag) { UdpConnectMachine(); //与主站建立连接状态机 } else { if (TASK_SUCCESS == g_s_nbiot_task_flag) { if (nbiot_temp_connect_type == NBIOT_CONNECT_UDP1) { Nbiot_Para.udp1_state = CONNECT_ON_LINE; } else if (nbiot_temp_connect_type == NBIOT_CONNECT_UDP2) { Nbiot_Para.udp2_state = CONNECT_ON_LINE; } } g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; } } break; case S_NBIOT_MAIN_UDP_SEND: { if (CONNECT_ON_LINE == Nbiot_Para.udp1_state) { if (TASK_INIT == g_s_nbiot_task_flag) { UdpSendDataMachine(); //数据发送状态机 } else//发送数据任务成功和失败都回到空闲 { g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; } } else { g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; } } break; case S_NBIOT_MAIN_POWER_OFF: { if (TASK_INIT == g_s_nbiot_task_flag) { NbiotPowerOffMachine(); //断电关机 } else { g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; Nbiot_Para.net_state = NB_OFF_LINE; Nbiot_Para.coap_state = CONNECT_OFF_LINE; Nbiot_Para.udp1_state = CONNECT_OFF_LINE; Nbiot_Para.udp2_state = CONNECT_OFF_LINE; } } break; default: { g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; } break; } } /*************************************************************************** * @fun_name u8 NbiotIfIdle() * @brief 查询模块的空闲状态 ***************************************************************************/ u8 NbiotIfIdle(void) { if (S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state) { return TASK_IDLE; } else { return TASK_BUSY; } } /*************************************************************************** * @fun_name u8 NbiotIfOnline() * @brief 查询NBIOT是否在线 ***************************************************************************/ u8 NbiotIfOnline(void) { if (NB_ON_LINE == Nbiot_Para.net_state) { return TRUE; } else { return FALSE; } } /*************************************************************************** * @fun_name u8 UdpIfOnline() * @brief 查询UDP连接是否建立 ***************************************************************************/ //u8 UdpIfOnline(void) //{ // if (CONNECT_ON_LINE == Nbiot_Para.udp1_state) // { // return TRUE; // } // else // { // return FALSE; // } //} /*************************************************************************** * @fun_name u8 ConncetIfOnline() * @brief 查询连接是否在线 ***************************************************************************/ u8 ConncetIfOnline(u8 connect_type) { if (connect_type == NBIOT_CONNECT_COAP) { if (CONNECT_ON_LINE == Nbiot_Para.coap_state) { return TRUE; } else { return FALSE; } } else if (connect_type == NBIOT_CONNECT_UDP1) { if (CONNECT_ON_LINE == Nbiot_Para.udp1_state) { return TRUE; } else { return FALSE; } } else if (connect_type == NBIOT_CONNECT_UDP2) { if (CONNECT_ON_LINE == Nbiot_Para.udp2_state) { return TRUE; } else { return FALSE; } } return FALSE; } /*************************************************************************** * @fun_name void NbiotOnlineTask(u8 *state) * @brief NBIOT上线任务 * @param[in] state:状态信息 ***************************************************************************/ void NbiotOnlineTask(u8 *state) { if (S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state) { if (!NbiotIfOnline()) { if (S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state) { Nbiot_Send_Data.state = state; //地址拷贝 *state = NBIOT_ING; g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_POWER_INIT; StartNbiotInit(); } } else { *state = NBIOT_ONLINE; } } else { *state = NBIOT_ERROR; } } /*************************************************************************** * @fun_name void NB_NetConnectStart * @brief 根据连接类型建立连接 * @param[in] state:状态信息 ***************************************************************************/ void NB_NetConnectStart(unsigned char *temp_ip, u16 temp_port, u8 connect_type) { if (connect_type == NBIOT_CONNECT_COAP) { coap_ip = temp_ip; coap_port = temp_port; TcpStartConnect(); nbiot_temp_connect_type = NBIOT_CONNECT_COAP; g_s_nbiot_main_state = S_NBIOT_MAIN_TCP_OPEN; } else if (connect_type == NBIOT_CONNECT_UDP1) { udp_ip1 = temp_ip; udp_port1 = temp_port; UdpStartConnect(connect_type); g_s_nbiot_main_state = S_NBIOT_MAIN_UDP_OPEN; } else if (connect_type == NBIOT_CONNECT_UDP2) { udp_ip2 = temp_ip; udp_port2 = temp_port; UdpStartConnect(connect_type); g_s_nbiot_main_state = S_NBIOT_MAIN_UDP_OPEN; } g_s_nbiot_task_flag = TASK_INIT; } /*************************************************************************** * @fun_name void NbiotSendTask(u8 *addr, u16 len, u8 send_type,u8 *state) * @brief NBIOT数据发送任务 * @param[in] addr:内容的首地址 len:长度 * @param[out] state:状态信息 * @retval None * @other state(NBIOT_ING:查询中, NBIOT_SUCCES:成功 其他:异常) ***************************************************************************/ void NbiotSendTask(u8 *addr, u16 len, u8 send_type, u8 *state) { if ((S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state) && (len > 0) && (len <= UP_BUF_SIZE)) { Nbiot_Send_Data.buf = addr; //地址拷贝 Nbiot_Send_Data.len = len; //值拷贝 Nbiot_Send_Data.state = state; //地址拷贝 *state = NBIOT_ING; g_s_nbiot_send_type = send_type; g_s_nbiot_task_flag = TASK_INIT; if ((SEND_TYPE_UDP1 == g_s_nbiot_send_type) || (SEND_TYPE_UDP2 == g_s_nbiot_send_type)) { g_s_nbiot_main_state = S_NBIOT_MAIN_UDP_SEND; StartUdpSendData(); } else { StartTcpSendData(); g_s_nbiot_main_state = S_NBIOT_MAIN_TCP_SEND; //发送NBIOT数据 } } else { *state = NBIOT_ERROR; } } //获取发送类型 u8 GetNbiotSendType(void) { return g_s_nbiot_send_type; } /*************************************************************************** * @fun_name void NbiotReadCsqTask(u8 *out_csq,u8 *state) * @brief NBIOT查询信号值任务 * @param[in] out_csq:存放数据地址 * @param[out] state:状态信息 * @retval None * @other state(CSQ_ING:查询中, CSQ_SUCCES:成功 其他:异常) ***************************************************************************/ //void NbiotUdpOpenTask(void) //{ // if (S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state) // { // if(!UdpIfOnline()) // { // g_s_nbiot_task_flag = TASK_INIT; // g_s_nbiot_main_state = S_NBIOT_MAIN_UDP_OPEN; // UdpStartConnect(); // } // } //} /*************************************************************************** * @fun_name u8 NbiotIfSleep() * @brief 是否允许休眠 * @param[in] None * @param[out] None * @retval TRUE: 允许 FALSE:不允许 * @other None ***************************************************************************/ u8 NbiotIfSleep(void) { if (S_NBIOT_MAIN_IDLE == g_s_nbiot_main_state) { return TRUE; } else { return FALSE; } } /*************************************************************************** * @fun_name void NbiotPreSleep() * @brief 休眠前操作 * @param[in] None * @param[out] None * @retval None * @other None ***************************************************************************/ void NbiotPreSleep(void) { NB_Power_Disable(); //切断电源 UartPreSleep(NB_UART_COM); g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; Nbiot_Para.net_state = NB_OFF_LINE; Nbiot_Para.coap_state = CONNECT_OFF_LINE; Nbiot_Para.udp1_state = CONNECT_OFF_LINE; Nbiot_Para.udp2_state = CONNECT_OFF_LINE; //配置NB相关引脚 stc_gpio_cfg_t stcGpioCfg; DDL_ZERO_STRUCT(stcGpioCfg); stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置 stcGpioCfg.enDrv = GpioDrvL; ///< 端口驱动能力配置->低驱动能力 stcGpioCfg.enPu = GpioPuDisable; ///< 端口上下拉配置->无 stcGpioCfg.enPd = GpioPdDisable; stcGpioCfg.enOD = GpioOdDisable; ///< 端口开漏输出配置 stcGpioCfg.enCtrlMode = GpioAHB; ///< 端口输入/输出值寄存器总线控制模式配置->AHB Gpio_Init(BAT_NB_PORT, BAT_NB_PIN, &stcGpioCfg); //模块供电IO Gpio_Init(RSTN_NB_PORT, RSTN_NB_PIN, &stcGpioCfg); Gpio_Init(NB_PSM_WAKE_PORT, NB_PSM_WAKE_PIN, &stcGpioCfg); Gpio_Init(PWR_NB_PORT, PWR_NB_PIN, &stcGpioCfg); //电源控制脚 Gpio_WriteOutputIO(BAT_NB_PORT, BAT_NB_PIN, FALSE); Gpio_WriteOutputIO(PWR_NB_PORT, PWR_NB_PIN, FALSE); Gpio_WriteOutputIO(RSTN_NB_PORT, RSTN_NB_PIN, FALSE); Gpio_WriteOutputIO(NB_PSM_WAKE_PORT, NB_PSM_WAKE_PIN, FALSE); Gpio_Init(LPUART1_TX_PORT, LPUART1_TX_PIN, &stcGpioCfg); Gpio_WriteOutputIO(LPUART1_TX_PORT, LPUART1_TX_PIN, FALSE); //TX也配置为输出低 stcGpioCfg.enDir = GpioDirIn; //RX输入 Gpio_Init(LPUART1_RX_PORT, LPUART1_RX_PIN, &stcGpioCfg); } /*************************************************************************** * @fun_name void NbiotWakeSleep() * @brief 休眠后唤醒 * @param[in] None * @param[out] None * @retval None * @other None ***************************************************************************/ void NbiotWakeSleep(void) { } /******************************内部状态机***********************************/ /*************************************************************************** * @fun_name void NetModulePowerOn_Proc() * @brief 模组开机状态 * @param[in] None * @param[out] None * @retval None * @other None ***************************************************************************/ TYP_RESULT_CODE NetModulePowerOn_Proc(void) { switch (s_power_on_state) { case MODULE_IDLE://模块送电 { } break; case MODULE_POWERON://模块送电 { NbModuleIOInit(); //初始化默认模块断电 UartInit(NB_UART_COM, BAUD9600, DATA_BIT_8, STOPBIT_1, UART_NONE_PARITY, UART_LPUART_Disable); RSTN_NB_HIG(); PWR_NB_HIG(); NB_Power_Enable(); //打开电源,延时1S,等待上电稳定 set_timer_1ms(MODULE_POWER_DELAY_TIME); s_power_on_state = MODULE_POWERON_WT; } break; case MODULE_POWERON_WT://NB模块送电 { if (!check_timer_1ms()) { PWR_NB_LOW(); set_timer_1ms(MODULE_POWERKEY_DELAY_TIME); s_power_on_state = MODULE_POWER_KEY_ON_WT; } } break; case MODULE_POWER_KEY_ON_WT://NB模块送电 { if (!check_timer_1ms()) { PWR_NB_HIG(); s_power_on_state = MODULE_IDLE; return ResultOk; } } break; default: { s_power_on_state = MODULE_IDLE; } break; } return ResultBusy; } /*************************************************************************** * @fun_name void AT_Common_Requeset_Proc() * @brief AT指令集通用查询函数 * @param[in] None * @param[out] None * @retval None * @other 中国移动的为:898600;898602;898604;898607 中国电信898603;898611 ***************************************************************************/ int getAtIndexFromCode(TYP_AT_CMDCODE atCode) { for (int i = 0; i < AT_CMD_COUNT; i++) { if (AtCmdBuf[i].AtCode == atCode) { return i; } } return 0; } TYP_RESULT_CODE AT_Common_Requeset_Proc(TYP_AT_CMDCODE atCode, char addFlag, char *addBuf, int addLen) { switch (s_at_requeset_state) { case AT_REQUEST_IDLE: { g_at_index = getAtIndexFromCode(atCode); at_requestErrorCount = 0; set_timer_1ms(500); s_at_requeset_state = AT_REQUEST_WT; } break; case AT_REQUEST_WT: { if (!check_timer_1ms()) { set_timer_1s(0); s_at_requeset_state = AT_REQUEST_SEND; } } break; case AT_REQUEST_SEND: { if (!check_timer_1s()) { memset(AT_BUF, 0, sizeof(AT_BUF)); int i = 0; int all_len = 0; int str_len = strlen(AtCmdBuf[g_at_index].pAtCmdStr); const char *p; p = AtCmdBuf[g_at_index].pAtCmdStr; for (i = 0; i < str_len; i++) { AT_BUF[i] = *p++; all_len++; } if (addFlag == 1) { for (i = 0; i < addLen; i++) { AT_BUF[str_len + i] = *addBuf++; all_len++; } } AT_BUF[all_len++] = '\r'; /*strcpy(AT_BUF, AtCmdBuf[g_at_index].pAtCmdStr);//不能使用strcpy,否则取数据只能到0x00 if(addFlag==1) { strcat(AT_BUF, addBuf); } strcat(AT_BUF, "\r");*/ NbiotUartSend((u8 *)AT_BUF, all_len, AtCmdBuf[g_at_index].CaseAtNum); //不能用strlen(AT_BUF),否则只能发送到0x00 set_timer_1s(AtCmdBuf[g_at_index].WaitTime); s_at_requeset_state = AT_REQUEST_CHECK; } } break; case AT_REQUEST_CHECK: { if (NbiotCheckAtAck() == UART_OK)//返回正确的应答 { s_at_requeset_state = AT_REQUEST_IDLE; return ResultOk; } else if ((!check_timer_1s()) || (NbiotCheckAtAck() == UART_ERROR)) //应答超时或者错误 { if (at_requestErrorCount >= AtCmdBuf[g_at_index].ErrorLimit) { s_at_requeset_state = AT_REQUEST_IDLE; return ResultFail; } else { at_requestErrorCount++; set_timer_1s(AtCmdBuf[g_at_index].WaitTime); s_at_requeset_state = AT_REQUEST_SEND; } } } break; default: { s_at_requeset_state = AT_REQUEST_IDLE; return ResultFail; } } return ResultBusy; } /*************************************************************************** * @fun_name void NbiotInitMachine() * @brief 模组初始化状态机 * @param[in] None * @param[out] None * @retval None * @other ***************************************************************************/ void StartNbiotInit(void) { s_init_state = S_MODULE_INIT_POWER_ON; s_power_on_state = MODULE_POWERON;//模块送电 } void NbiotInitMachine_ML307A(void) { switch (s_init_state) { case S_MODULE_INIT_IDLE: { break; } case S_MODULE_INIT_POWER_ON://NB模块送电 { g_at_request_res = NetModulePowerOn_Proc(); if (g_at_request_res == ResultOk) { //NB_UartInitForGPIO();//debug //初始化可调参数 u8 NB_login_ask_times = (FrameCheckParaApp(FramePara_NbParaLoginAckTimes) / 3); if (NB_login_ask_times < NET_CEREG_MIN_TIMES) { NB_login_ask_times = NET_CEREG_MIN_TIMES; } if (NB_login_ask_times > NET_CEREG_MAX_TIMES) { NB_login_ask_times = NET_CEREG_MAX_TIMES; } AtCmdBuf[getAtIndexFromCode(AT_CODE_CEREG)].ErrorLimit = NB_login_ask_times;//查询网络注册状态次数 if(getUploadControlPara(UP_AT_SIMPLE)!=AT_SIMPLE_NULL) { s_init_state = S_MODULE_INIT_CEREG_CK; } else { s_init_state = S_MODULE_INIT_AT; } } } break; case S_MODULE_INIT_AT: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_AT, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CGSN; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败 s_init_state = S_MODULE_INIT_IDLE; } } break; // case S_MODULE_INIT_CMEE: // { // g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CMEE, 0, NULL, 0); // if (g_at_request_res == ResultOk) // { // s_init_state = S_MODULE_INIT_CGSN; // } // else if (g_at_request_res == ResultFail) // { // g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败 // s_init_state = S_MODULE_INIT_IDLE; // } // } // break; case S_MODULE_INIT_CGSN: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGSN, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CPIN; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败 s_init_state = S_MODULE_INIT_IDLE; } } break; case S_MODULE_INIT_CPIN: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CPIN, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CIMI; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败 s_init_state = S_MODULE_INIT_IDLE; } } break; case S_MODULE_INIT_CIMI: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CIMI, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_MCCID; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败 s_init_state = S_MODULE_INIT_IDLE; } } break; case S_MODULE_INIT_MCCID: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MCCID, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CFUN_CK; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败 s_init_state = S_MODULE_INIT_IDLE; } } break; case S_MODULE_INIT_CFUN_CK: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CFUN_CK, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CEREG_CK; } else if (g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_CFUN1; } } break; case S_MODULE_INIT_CFUN1: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CFUN1, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CEREG_CK; } else if (g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_CEREG_CK; } } break; // case S_MODULE_INIT_VERCTRL://查询激活方式 // { // g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_VERCTRL, 0, NULL, 0); // if (g_at_request_res == ResultOk) //如果是自动激活 // { // s_init_state = S_MODULE_INIT_CSQ; // } // else if (g_at_request_res == ResultFail) // { // s_init_state = S_MODULE_INIT_VERCTRL1; // } // } // break; // case S_MODULE_INIT_VERCTRL1://设置自动激活(注意,重启后才能生效,PCBA测试不需要激活成功) // { // g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_VERCTRL1, 0, NULL, 0); // if (g_at_request_res == ResultOk) // { // s_init_state = S_MODULE_INIT_CSQ; // } // else if (g_at_request_res == ResultFail) // { // g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败 // s_init_state = S_MODULE_INIT_IDLE; // } // } // break; /* case S_MODULE_INIT_CTEC_CK: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CTEC_CK, 0, NULL,0); if(g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CCED_CK; } else if(g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_CCED_CK; } } break; case S_MODULE_INIT_CCED_CK: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CCED_CK, 0, NULL,0); if(g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CEREG_CK; } else if(g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_CEREG_CK; } } break; */ /*case S_MODULE_INIT_CGDCONT: { //获取APN参数 memset(stringbuffer_temp,0,sizeof(stringbuffer_temp)); for(int i = 0; i < Sys_data_object.P1.apn[1]; i++) { stringbuffer_temp[i] = Sys_data_object.P1.apn[2 + i]; } stringbuffer_temp[Sys_data_object.P1.apn[1]] = '\"'; g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGDCONT, 1, stringbuffer_temp, Sys_data_object.P1.apn[1]+1); if(g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CGACT; } else if(g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_CGACT; } } break; case S_MODULE_INIT_CGACT: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGACT, 0, NULL,0); if(g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CEREG_CK; } else if(g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_CEREG_CK; } } break; */ case S_MODULE_INIT_CEREG_CK: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CEREG, 0, NULL, 0); if (g_at_request_res == ResultOk) { if(getUploadControlPara(UP_AT_SIMPLE)!=AT_SIMPLE_NULL) { g_s_nbiot_task_flag = TASK_SUCCESS; //初始化任务成功 s_init_state = S_MODULE_INIT_IDLE; } else { s_init_state = S_MODULE_INIT_CSQ; } } else if (g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_CSQ; } } break; case S_MODULE_INIT_CSQ: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CSQ, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_MUESTATS; } else if (g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_MUESTATS; } } break; case S_MODULE_INIT_MUESTATS: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MUESTATS, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_SBAND; } else if (g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_SBAND; } } break; case S_MODULE_INIT_SBAND: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_SBAND, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_MIPCALL_CK; } else if (g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_MIPCALL_CK; } } break; case S_MODULE_INIT_MIPCALL_CK: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCALL_CK, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CCLK; } else if (g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_CGDCONT; } } break; case S_MODULE_INIT_CGDCONT: { //获取APN参数 memset(stringbuffer_temp, 0, sizeof(stringbuffer_temp)); for (int i = 0; i < Sys_data_object.P1.apn[1]; i++) { stringbuffer_temp[i] = Sys_data_object.P1.apn[2 + i]; } stringbuffer_temp[Sys_data_object.P1.apn[1]] = '\"'; g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CGDCONT, 1, stringbuffer_temp, Sys_data_object.P1.apn[1] + 1); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_MIPCALL; } else if (g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_MIPCALL; } } break; case S_MODULE_INIT_MIPCALL: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCALL, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_init_state = S_MODULE_INIT_CCLK; } else if (g_at_request_res == ResultFail) { s_init_state = S_MODULE_INIT_CCLK; } } break; case S_MODULE_INIT_CCLK: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_CCLK, 0, NULL, 0); if (g_at_request_res == ResultOk) { g_s_nbiot_task_flag = TASK_SUCCESS; //初始化任务成功 s_init_state = S_MODULE_INIT_IDLE; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_SUCCESS; //初始化任务成功 s_init_state = S_MODULE_INIT_IDLE; } } break; default: { g_s_nbiot_task_flag = TASK_FAIL; //初始化任务失败 s_init_state = S_MODULE_INIT_IDLE; } break; } } void NbiotInitMachine(void) { NbiotInitMachine_ML307A(); } /*************************************************************************** * @fun_name void TcpConnectMachine() * @brief TCP连接状态机 * @param[in] None * @param[out] None * @retval None * @other ***************************************************************************/ void TcpStartConnect(void) { s_tcp_connect_state = S_TCP_CONNECT_START; } void TcpConnectMachine_ML307A(void) { unsigned char *nbiot_ip; u16 nbiot_port; static int ip_len = 0; switch (s_tcp_connect_state) { case S_TCP_CONNECT_IDLE: { break; } case S_TCP_CONNECT_START: { if (1) { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCFG_ACK1, 0, NULL, 0); } else { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCFG_ACK0, 0, NULL, 0); } if (g_at_request_res == ResultOk) { s_tcp_connect_state = S_TCP_CONNECT_MIPCFG; } else if (g_at_request_res == ResultFail) { s_tcp_connect_state = S_TCP_CONNECT_MIPCFG; } break; } case S_TCP_CONNECT_MIPCFG: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCFG_TCP, 0, NULL, 0); if (g_at_request_res == ResultOk) { ip_len = 0; nbiot_port = coap_port;//Sys_data_object.P1.server_port.datas; nbiot_ip = coap_ip;//Sys_data_object.P1.server_ip; memset(stringbuffer_temp, 0, sizeof(stringbuffer_temp)); //IP 的存储仍然使用水表原来格式,不保存“.”号,使用时加入 int i; for (i = 0; i < 4; i++) { if (nbiot_ip[i] < 10) { stringbuffer_temp[ip_len++] = nbiot_ip[i] + 0x30; } else if (nbiot_ip[i] < 100) { stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 10) + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] % 10) + 0x30; } else { stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 100) + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 10) % 10 + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] % 10) + 0x30; } stringbuffer_temp[ip_len++] = '.'; } ip_len--; //消除多余的点号 stringbuffer_temp[ip_len++] = '\"'; stringbuffer_temp[ip_len++] = ','; stringbuffer_temp[ip_len++] = ((nbiot_port) / 10000) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 10000) / 1000) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 1000) / 100) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 100) / 10) + 0x30; stringbuffer_temp[ip_len++] = ((nbiot_port) % 10) + 0x30; stringbuffer_temp[ip_len++] = ','; stringbuffer_temp[ip_len++] = '6'; stringbuffer_temp[ip_len++] = '0'; stringbuffer_temp[ip_len++] = ','; stringbuffer_temp[ip_len++] = '0'; stringbuffer_temp[ip_len++] = '\r'; s_tcp_connect_state = S_TCP_CONNECT_MIPOPEN; } else if (g_at_request_res == ResultFail) { ip_len = 0; nbiot_port = coap_port;//Sys_data_object.P1.server_port.datas; nbiot_ip = coap_ip;//Sys_data_object.P1.server_ip; memset(stringbuffer_temp, 0, sizeof(stringbuffer_temp)); //IP 的存储仍然使用水表原来格式,不保存“.”号,使用时加入 int i; for (i = 0; i < 4; i++) { if (nbiot_ip[i] < 10) { stringbuffer_temp[ip_len++] = nbiot_ip[i] + 0x30; } else if (nbiot_ip[i] < 100) { stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 10) + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] % 10) + 0x30; } else { stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 100) + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 10) % 10 + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] % 10) + 0x30; } stringbuffer_temp[ip_len++] = '.'; } ip_len--; //消除多余的点号 stringbuffer_temp[ip_len++] = '\"'; stringbuffer_temp[ip_len++] = ','; stringbuffer_temp[ip_len++] = ((nbiot_port) / 10000) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 10000) / 1000) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 1000) / 100) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 100) / 10) + 0x30; stringbuffer_temp[ip_len++] = ((nbiot_port) % 10) + 0x30; stringbuffer_temp[ip_len++] = ','; stringbuffer_temp[ip_len++] = '6'; stringbuffer_temp[ip_len++] = '0'; stringbuffer_temp[ip_len++] = ','; stringbuffer_temp[ip_len++] = '0'; stringbuffer_temp[ip_len++] = '\r'; s_tcp_connect_state = S_TCP_CONNECT_MIPOPEN; } } break; case S_TCP_CONNECT_MIPOPEN: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPOPEN, 1, stringbuffer_temp, ip_len); if (g_at_request_res == ResultOk) { g_s_nbiot_task_flag = TASK_SUCCESS; //成功 s_tcp_connect_state = S_TCP_CONNECT_IDLE; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_FAIL; //任务失败 s_tcp_connect_state = S_TCP_CONNECT_IDLE; } } break; default: { g_s_nbiot_task_flag = TASK_FAIL; s_tcp_connect_state = S_TCP_CONNECT_IDLE; break; } } } void TcpConnectMachine(void) { TcpConnectMachine_ML307A(); } /*************************************************************************** * @fun_name void TcpSendDataMachine() * @brief TCP发送数据状态机 * @param[in] None * @param[out] None * @retval None * @other [15:27:39.342]收←◆AT+MIPSEND=1,0352 > [15:27:43.341]收←◆AT+MIPSEND=1,0352 [15:27:47.357]收←◆AT+MIPSEND=1,0352 [15:27:51.356]收←◆AT+MIPSEND=1,0352 [15:27:55.371]收←◆AT+MIPSEND=1,0352 注意,如果设置了发送数据长度,但没有发送数据,再设置长度无反应 ***************************************************************************/ void StartTcpSendData(void) { s_tcp_send_state = S_TCP_SEND_START; } void TcpSendDataMachine_ML307A(void) { switch (s_tcp_send_state) { case S_TCP_SEND_IDLE: { } break; case S_TCP_SEND_START: { NbiotClearMsg(); memset(stringbuffer_temp, 0, sizeof(stringbuffer_temp)); //内容 tcp_send_len = 0; // memset(tcp_send_len_buf, 0, sizeof(tcp_send_len_buf)); tcp_send_len = Nbiot_Send_Data.len; //发送数据长度 if (tcp_send_len < 10) { stringbuffer_temp[0] = tcp_send_len + 0x30; tcp_send_len_buf_len = 1; } else if (tcp_send_len < 100) { stringbuffer_temp[0] = (tcp_send_len / 10) + 0x30; stringbuffer_temp[1] = (tcp_send_len % 10) + 0x30; tcp_send_len_buf_len = 2; } else { stringbuffer_temp[0] = (tcp_send_len / 100) + 0x30; stringbuffer_temp[1] = (tcp_send_len / 10) % 10 + 0x30; stringbuffer_temp[2] = (tcp_send_len % 10) + 0x30; tcp_send_len_buf_len = 3; } tcp_send_len = tcp_send_len_buf_len ; stringbuffer_temp[tcp_send_len++] = ','; stringbuffer_temp[tcp_send_len++] = '\"'; // for (int i = 0; i < Nbiot_Send_Data.len; i++)//获取发送数据内容 // { // stringbuffer_temp[tcp_send_len++] = *(Nbiot_Send_Data.buf + i);//数据发送十六进制格式 // } for (int i = 0; i < Nbiot_Send_Data.len; i++)//获取发送数据内容 { if ((*(Nbiot_Send_Data.buf + i) >> 4) >= 0x0A) { stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x37; } else { stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x30; } if ((*(Nbiot_Send_Data.buf + i) & 0x0F) >= 0x0A) { stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x37; } else { stringbuffer_temp[tcp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x30; } } stringbuffer_temp[tcp_send_len++] = '\"'; s_tcp_send_state = S_TCP_SEND_DATA; } break; // case S_TCP_SEND_DATALEN://发送数据长度 // { // g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPSENDCOUNT, 1, tcp_send_len_buf, tcp_send_len_buf_len); // if (g_at_request_res == ResultOk) // { // s_tcp_send_state = S_TCP_SEND_DATA; // } // else if (g_at_request_res == ResultFail) // { // g_s_nbiot_task_flag = TASK_FAIL; //失败 // s_tcp_send_state = S_TCP_SEND_IDLE; // } // } // break; case S_TCP_SEND_DATA://发送数据 { if (1) { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_TCPSEND_ACK, 1, stringbuffer_temp, tcp_send_len); } else { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_TCPSEND, 1, stringbuffer_temp, tcp_send_len); } if (g_at_request_res == ResultOk) { g_s_nbiot_task_flag = TASK_SUCCESS; //成功 s_tcp_send_state = S_TCP_SEND_IDLE; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_FAIL; //失败 s_tcp_send_state = S_TCP_SEND_IDLE; } } break; default: { g_s_nbiot_task_flag = TASK_FAIL; //失败 s_tcp_send_state = S_TCP_SEND_IDLE; } break; } } void TcpSendDataMachine(void) { TcpSendDataMachine_ML307A(); } //启动连接UDP void UdpStartConnect(u8 udp_num) { nbiot_temp_connect_type = udp_num; s_udp_connect_state = S_UDP_CONNECT_START; } /*************************************************************************** * @fun_name void UdpConnectMachine(void) * @brief 连接UDP状态机 ***************************************************************************/ void UdpConnectMachine_ML307A(void) { unsigned char *nbiot_ip; u16 nbiot_port; static int ip_len = 0; switch (s_udp_connect_state) { case S_UDP_CONNECT_IDLE: { break; } case S_UDP_CONNECT_START: { ip_len = 0; if (nbiot_temp_connect_type == NBIOT_CONNECT_UDP1) { nbiot_port = udp_port1;//Sys_data_object.P2.server_port.datas; nbiot_ip = udp_ip1;//Sys_data_object.P2.server_ip; g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCFG_UDP1, 0, NULL, 0); } else if (nbiot_temp_connect_type == NBIOT_CONNECT_UDP2) { nbiot_port = udp_port2; nbiot_ip = udp_ip2; g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCFG_UDP2, 0, NULL, 0); } if (g_at_request_res == ResultOk) { memset(stringbuffer_temp, 0, sizeof(stringbuffer_temp)); //IP 的存储仍然使用水表原来格式,不保存“.”号,使用时加入 int i; for (i = 0; i < 4; i++) { if (nbiot_ip[i] < 10) { stringbuffer_temp[ip_len++] = nbiot_ip[i] + 0x30; } else if (nbiot_ip[i] < 100) { stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 10) + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] % 10) + 0x30; } else { stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 100) + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 10) % 10 + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] % 10) + 0x30; } stringbuffer_temp[ip_len++] = '.'; } ip_len--; //消除多余的点号 stringbuffer_temp[ip_len++] = '\"'; stringbuffer_temp[ip_len++] = ','; stringbuffer_temp[ip_len++] = ((nbiot_port) / 10000) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 10000) / 1000) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 1000) / 100) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 100) / 10) + 0x30; stringbuffer_temp[ip_len++] = ((nbiot_port) % 10) + 0x30; stringbuffer_temp[ip_len++] = '\r'; s_udp_connect_state = S_UDP_CONNECT_MIPOPEN; } else if (g_at_request_res == ResultFail) { memset(stringbuffer_temp, 0, sizeof(stringbuffer_temp)); //IP 的存储仍然使用水表原来格式,不保存“.”号,使用时加入 int i; for (i = 0; i < 4; i++) { if (nbiot_ip[i] < 10) { stringbuffer_temp[ip_len++] = nbiot_ip[i] + 0x30; } else if (nbiot_ip[i] < 100) { stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 10) + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] % 10) + 0x30; } else { stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 100) + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] / 10) % 10 + 0x30; stringbuffer_temp[ip_len++] = (nbiot_ip[i] % 10) + 0x30; } stringbuffer_temp[ip_len++] = '.'; } ip_len--; //消除多余的点号 stringbuffer_temp[ip_len++] = '\"'; stringbuffer_temp[ip_len++] = ','; stringbuffer_temp[ip_len++] = ((nbiot_port) / 10000) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 10000) / 1000) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 1000) / 100) + 0x30; stringbuffer_temp[ip_len++] = (((nbiot_port) % 100) / 10) + 0x30; stringbuffer_temp[ip_len++] = ((nbiot_port) % 10) + 0x30; stringbuffer_temp[ip_len++] = '\r'; s_udp_connect_state = S_UDP_CONNECT_MIPOPEN; } } break; case S_UDP_CONNECT_MIPOPEN: { if (nbiot_temp_connect_type == NBIOT_CONNECT_UDP1) { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPOPEN_UDP1, 1, stringbuffer_temp, ip_len); } else if (nbiot_temp_connect_type == NBIOT_CONNECT_UDP2) { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPOPEN_UDP2, 1, stringbuffer_temp, ip_len); } if (g_at_request_res == ResultOk) { g_s_nbiot_task_flag = TASK_SUCCESS; //成功 s_udp_connect_state = S_UDP_CONNECT_IDLE; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_FAIL; //任务失败 s_udp_connect_state = S_UDP_CONNECT_IDLE; } } break; default: { g_s_nbiot_task_flag = TASK_FAIL; s_udp_connect_state = S_UDP_CONNECT_IDLE; break; } } } void UdpConnectMachine(void) { UdpConnectMachine_ML307A(); } // void StartUdpSendData(void) { s_udp_send_state = S_UDP_SEND_START; } // void UdpSendDataMachine_ML307A(void) { switch (s_udp_send_state) { case S_UDP_SEND_IDLE: { } break; case S_UDP_SEND_START: { NbiotClearMsg(); memset(stringbuffer_temp, 0, sizeof(stringbuffer_temp)); //内容 udp_send_len = 0; // memset(udp_send_len_buf, 0, sizeof(udp_send_len_buf)); udp_send_len = Nbiot_Send_Data.len; if (udp_send_len < 10) { stringbuffer_temp[0] = udp_send_len + 0x30; udp_send_len_buf_len = 1; } else if (udp_send_len < 100) { stringbuffer_temp[0] = (udp_send_len / 10) + 0x30; stringbuffer_temp[1] = (udp_send_len % 10) + 0x30; udp_send_len_buf_len = 2; } else { stringbuffer_temp[0] = (udp_send_len / 100) + 0x30; stringbuffer_temp[1] = (udp_send_len / 10) % 10 + 0x30; stringbuffer_temp[2] = (udp_send_len % 10) + 0x30; udp_send_len_buf_len = 3; } udp_send_len = udp_send_len_buf_len ; stringbuffer_temp[udp_send_len++] = ','; stringbuffer_temp[udp_send_len++] = '\"'; for (int i = 0; i < Nbiot_Send_Data.len; i++)//获取发送数据内容 { if ((*(Nbiot_Send_Data.buf + i) >> 4) >= 0x0A) { stringbuffer_temp[udp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x37; } else { stringbuffer_temp[udp_send_len++] = (*(Nbiot_Send_Data.buf + i) >> 4) + 0x30; } if ((*(Nbiot_Send_Data.buf + i) & 0x0F) >= 0x0A) { stringbuffer_temp[udp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x37; } else { stringbuffer_temp[udp_send_len++] = (*(Nbiot_Send_Data.buf + i) & 0x0F) + 0x30; } } stringbuffer_temp[udp_send_len++] = '\"'; s_udp_send_state = S_UDP_SEND_DATA; } break; case S_UDP_SEND_DATA://发送数据 { if (g_s_nbiot_send_type == SEND_TYPE_UDP1) { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_UDPSEND1, 1, stringbuffer_temp, udp_send_len); } else if (g_s_nbiot_send_type == SEND_TYPE_UDP2) { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_UDPSEND2, 1, stringbuffer_temp, udp_send_len); } if (g_at_request_res == ResultOk) { g_s_nbiot_task_flag = TASK_SUCCESS; //成功 s_udp_send_state = S_UDP_SEND_IDLE; } else if (g_at_request_res == ResultFail) { g_s_nbiot_task_flag = TASK_FAIL; //失败 s_udp_send_state = S_UDP_SEND_IDLE; } } break; default: { g_s_nbiot_task_flag = TASK_FAIL; //失败 s_udp_send_state = S_UDP_SEND_IDLE; } break; } } void UdpSendDataMachine(void) { UdpSendDataMachine_ML307A(); } /*************************************************************************** * @fun_name static void NbiotPowerOffMachine() * @brief 关机状态机 ***************************************************************************/ //模组关机状态号 void NbiotPowerOffMachine(void) //先注销网络然后断电关机 { switch (s_power_off_state) { case S_PWOFF_IDLE: { } break; case S_PWOFF_TCP_CLOSE: { if (ConncetIfOnline(NBIOT_CONNECT_COAP) == TRUE) { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCLOSE, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_power_off_state = S_PWOFF_UDP1_CLOSE; } else if (g_at_request_res == ResultFail) { s_power_off_state = S_PWOFF_UDP1_CLOSE; } } else { s_power_off_state = S_PWOFF_UDP1_CLOSE; } } break; case S_PWOFF_UDP1_CLOSE: { if (ConncetIfOnline(NBIOT_CONNECT_UDP1) == TRUE) { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCLOSE_UDP1, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_power_off_state = S_PWOFF_UDP2_CLOSE; } else if (g_at_request_res == ResultFail) { s_power_off_state = S_PWOFF_UDP2_CLOSE; } } else { s_power_off_state = S_PWOFF_UDP2_CLOSE; } } break; case S_PWOFF_UDP2_CLOSE: { if (ConncetIfOnline(NBIOT_CONNECT_UDP2) == TRUE) { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MIPCLOSE_UDP2, 0, NULL, 0); if (g_at_request_res == ResultOk) { s_power_off_state = S_PWOFF_MPOF; } else if (g_at_request_res == ResultFail) { s_power_off_state = S_PWOFF_MPOF; } } else { s_power_off_state = S_PWOFF_MPOF; } } break; case S_PWOFF_MPOF: { g_at_request_res = AT_Common_Requeset_Proc(AT_CODE_MPOF, 0, NULL, 0); if (g_at_request_res == ResultOk) { set_timer_1s(1); s_power_off_state = S_PWOFF_PW_DOWN; } else if (g_at_request_res == ResultFail) { s_power_off_state = S_PWOFF_PW_DOWN; } } break; case S_PWOFF_PW_DOWN: { if (!check_timer_1s()) { NB_Power_Disable(); //切断电源 set_timer_1s(1); s_power_off_state = S_PWOFF_PW_DOWN_WAIT; Nbiot_Para.net_state = NB_OFF_LINE; Nbiot_Para.coap_state = CONNECT_OFF_LINE; Nbiot_Para.udp1_state = CONNECT_OFF_LINE; Nbiot_Para.udp2_state = CONNECT_OFF_LINE; } } break; case S_PWOFF_PW_DOWN_WAIT: { if (!check_timer_1s()) { NbiotPreSleep(); g_s_nbiot_task_flag = TASK_SUCCESS; s_power_off_state = S_PWOFF_IDLE; } } break; default: { s_power_off_state = S_PWOFF_IDLE; } break; } } /*************************************************************************** * @fun_name 定时器资源 * @brief 该内部接口主要为了方便记忆及使用 ***************************************************************************/ void set_timer_1s(u16 time) { Set100msTimer(TIMER_100MS_NBIOT, time * 10); } u16 check_timer_1s(void) { return Check100msTimer(TIMER_100MS_NBIOT); } void set_timer_1ms(u16 time) { Set5msTimer(TIMER_5MS_NBIOT, time / 5); } u16 check_timer_1ms(void) { return Check5msTimer(TIMER_5MS_NBIOT); } /*************************************************************************** * @fun_name void StartPowerOffTask() * @brief 关机接口 ***************************************************************************/ void StartPowerOffTask(void) { g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_POWER_OFF; s_power_off_state = S_PWOFF_TCP_CLOSE; } //NB强制关机 void NbForcePowerOff(void) { NB_Power_Disable(); Nbiot_Para.net_state = NB_OFF_LINE; Nbiot_Para.coap_state = CONNECT_OFF_LINE; Nbiot_Para.udp1_state = CONNECT_OFF_LINE; Nbiot_Para.udp2_state = CONNECT_OFF_LINE; g_s_nbiot_task_flag = TASK_INIT; g_s_nbiot_main_state = S_NBIOT_MAIN_IDLE; s_at_requeset_state = AT_REQUEST_IDLE; } UNION_4U8TOU32 net_state_data; u32 sys_get_net_state(void) { s16 s_temp_data = 0; if (g_s_nbiot_main_state == S_NBIOT_MAIN_POWER_INIT) { net_state_data.data_buf[0] = 1; net_state_data.data_buf[1] = s_init_state; //net_state_buf[2]CEREG //net_state_buf[3]cgatt } else if (g_s_nbiot_main_state == S_NBIOT_MAIN_TCP_OPEN) { net_state_data.data_buf[0] = 2; net_state_data.data_buf[1] = s_tcp_connect_state; } else if (If_NB_Poweron() == FALSE) { net_state_data.data_buf[0] = 3; //rsrp NbiotGetRSRP(&s_temp_data); net_state_data.data_buf[1] = -(s_temp_data / 10); //SNR NbiotGetSNR(&s_temp_data); if (s_temp_data < 0) { net_state_data.data_buf[2] = (-s_temp_data / 10) | 0x80; } else { net_state_data.data_buf[2] = s_temp_data / 10; } //CSQ NbiotGetCSQ(&net_state_data.data_buf[3]); } return net_state_data.datas; } void sys_set_net_state(u8 state, u8 data) { net_state_data.data_buf[state] = data; } /**NB接口**/ TYP_PSM_STATE getPsmState(void) { return PSM_STATE_OUT;//不进入PSM模式 } void NbiotPsmWakeupTask(void) { } void NbiotPsmSleepTask(void) { } void NbiotPsmCheckTask(void) { } #ifdef __cplusplus } #endif #endif