G-CAMS-DATU/applications/AIR820/LTE.c
2024-05-13 16:08:47 +08:00

398 lines
9.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-05-06 lijian the first version
*/
#include <LTE.h>
#define AT_UART_NAME "uart3"
LTE_t LTE;
static rt_device_t AT_serial; /* 串口设备句柄 */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */
/* 串口接收消息结构*/
struct rx_msg
{
rt_device_t dev;
rt_size_t size;
};
/* 消息队列控制块 */
static struct rt_messagequeue rx_mq;
rt_uint8_t rx_length;
rt_uint8_t check_flag;
rt_err_t result;
static char line_buffer[60];
void set_check_flag(rt_uint8_t flag){
check_flag = flag;
}
//AT指令发送
void AT_send(const char * cmd)
{
rt_device_write(AT_serial, 0, cmd, rt_strlen(cmd));
}
/* 接收数据回调函数 */
static rt_err_t uart_callback(rt_device_t dev, rt_size_t size)
{
struct rx_msg msg;
rt_err_t result;
msg.dev = dev;
msg.size = size;
//rt_kprintf("in uart_callback\n");
result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
if (result == -RT_EFULL)
{
/* 消息队列满 */
rt_kprintf("message queue full\n");
}
return result;
}
//接收数据线程
static void rx_serial_thread_entry(void *parameter)
{
struct rx_msg msg;
static char rx_buffer[RT_SERIAL_RB_BUFSZ + 1];
rt_uint8_t line_pos = 0;
while (1)
{
rt_memset(&msg, 0, sizeof(msg));
/* 从消息队列中读取消息*/
result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
if (result > 0)
{
// rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
// rx_buffer[rx_length] = '\0';
// /* 打印数据 */
// rt_kprintf("%s\n", rx_buffer);
rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
for (int i = 0; i < rx_length; i++)
{
// 如果收到了换行符或回车符,就认为是一行的结束
if (rx_buffer[i] == '\n' || rx_buffer[i] == '\r')
{
line_buffer[line_pos] = '\0'; // 添加字符串结束符
if (line_pos > 0) // 如果这一行至少有一个字符
{
if (check_flag == 1) //1检测MQTT
{
//+MQTTSTATU :0 离线 1 已经登陆认证过 2 还没认证,需要发送 MCONNECT
char * ch_pos = rt_strstr(line_buffer, "+MQTTSTATU :");
// rt_kprintf("ch_pos c: %s\n", ch_pos);
if (ch_pos != RT_NULL)
{
ch_pos = ch_pos + 12;
set_MQTT_STATUS((rt_uint8_t) *ch_pos - '0');
//break;
}
}
else if (check_flag == 2) //2检测LTE
{
//判断两个.为有IP即联网成功
char *ch_pos2 = strchr(line_buffer, '.');
if (ch_pos2 != NULL) {
// 计算点字符的位置
rt_uint8_t position = ch_pos2 - line_buffer; // 指针减法得到索引
if (line_buffer[position+2] == '.' || line_buffer[position+3] == '.' || line_buffer[position+4] == '.') {
set_LTE_Status(1);
}
}
else
{
//+CME ERROR:联网失败
ch_pos2 = rt_strstr(line_buffer, "+CME ERROR:");
if (ch_pos2 != RT_NULL)
{
set_LTE_Status(0);
}
}
}
if (LTE.log) {
rt_kprintf("Received line: %s\n", line_buffer);
}
// rt_kprintf("Received line: %s , %d\n", line_buffer, line_pos);
}
line_pos = 0; // 重置行缓冲区位置
}
else if (line_pos < sizeof(line_buffer) - 1)
{
// 否则,将字符添加到行缓冲区
line_buffer[line_pos++] = rx_buffer[i];
}
}
}
}
}
//AT串口初始化
rt_uint8_t AT_device_init()
{
// rt_pin_mode(WAK, PIN_MODE_OUTPUT);
// // 默认为高电平
// rt_pin_write(WAK, PIN_HIGH);
// rt_pin_mode(GPS, PIN_MODE_OUTPUT);
// // 默认为高电平
// rt_pin_write(GPS, PIN_LOW);
rt_pin_mode(RST, PIN_MODE_OUTPUT);
// 默认为高电平
rt_pin_write(RST, PIN_HIGH);
rt_thread_mdelay(200);
rt_pin_write(RST, PIN_LOW);
rt_err_t ret = RT_EOK;
static char msg_pool[256];
// char str[] = "AT\r\n";
AT_serial = rt_device_find(AT_UART_NAME);
if (!AT_serial)
{
rt_kprintf("find %s failed!\n", AT_UART_NAME);
return RT_ERROR;
}
config.baud_rate = BAUD_RATE_115200; //修改波特率为 115200
config.data_bits = DATA_BITS_8; //数据位 8
config.stop_bits = STOP_BITS_1; //停止位 1
config.bufsz = 128; //修改缓冲区 buff size 为 128
config.parity = PARITY_NONE; //无奇偶校验位
/* 初始化消息队列 */
rt_mq_init(&rx_mq, "rx_mq", msg_pool, /* 存放消息的缓冲区 */
sizeof(struct rx_msg), /* 一条消息的最大长度 */
sizeof(msg_pool), /* 存放消息的缓冲区大小 */
RT_IPC_FLAG_FIFO); /* 如果有多个线程等待,按照先来先得到的方法分配消息 */
/* 串口设备控制参数 */
rt_device_control(AT_serial, RT_DEVICE_CTRL_CONFIG, &config);
/* 打开串口设备。 DMA 接收及轮询发送模式打开串口设备 RT_DEVICE_FLAG_DMA_RX */
ret = rt_device_open(AT_serial, RT_DEVICE_FLAG_DMA_RX);
if (ret != RT_EOK)
{
rt_kprintf("open AT_serial fail!\n");
return RT_ERROR;
}
// AT_send("ATE0\r\n");
/* 设置接收回调函数 */
rt_device_set_rx_indicate(AT_serial, uart_callback);
/* 发送字符串 */
/* 创建 serial 线程 */
rt_thread_t rx_thread = rt_thread_create("rx_serial", rx_serial_thread_entry, RT_NULL, 1024, 25, 10);
/* 创建成功则启动线程 */
if (rx_thread != RT_NULL)
{
rt_thread_startup(rx_thread);
}
else
{
ret = RT_ERROR;
}
rt_kprintf("open AT_serial ok!\n");
return ret;
}
//LTE初始化
rt_uint8_t LTE_init()
{
AT_send("AT\r\n");
AT_send("ATE0\r\n");
rt_thread_mdelay(1000);
// AT_send("AT+CGMI\r\n"); //模块厂商信息
// rt_thread_mdelay(500);
//
// AT_send("AT+CPIN?\r\n"); //查询卡是否插好
// rt_thread_mdelay(500);
//
// AT_send("AT+CSQ\r\n"); //信号质量
// rt_thread_mdelay(500);
//
// AT_send("AT+CREG?\r\n"); //网络注册状态
// rt_thread_mdelay(500);
//
// AT_send("AT+CGATT?\r\n"); //附着GPRS
// rt_thread_mdelay(500);
AT_send("AT+CSTT=\"\",\"\",\"\"\r\n"); //自动APN
rt_thread_mdelay(500);
// AT_send("AT+CSTT?\r\n");
// rt_thread_mdelay(500);
AT_send("AT+CIICR\r\n"); //激活移动场景
rt_thread_mdelay(500);
AT_send("AT+CIFSR\r\n"); //查询IP
rt_thread_mdelay(500);
// AT_send("ATI\r\n");
// rt_thread_mdelay(500);
//AT_send("ATD15612696324;\r\n");
return RT_EOK;
}
//获取LTE状态
rt_uint8_t get_LTE_status_flag()
{
set_check_flag(2);
rt_uint8_t i = 0;
AT_send("AT+CIFSR\r\n");
while (!get_LTE_Status())
{
rt_thread_mdelay(200);
if (i > 3)
{
break;
}
i++;
}
if (LTE.log) {
rt_kprintf("LTE status:%d\n" , get_LTE_Status());
}
return get_LTE_Status();
}
void set_LTE_log(rt_uint8_t log){
LTE.log = log;
}
//LTE重新初始化
void LTE_Re_Init()
{
rt_pin_write(RST, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(RST, PIN_LOW);
AT_send("AT+CSTT=\"\",\"\",\"\"\r\n"); //自动APN
rt_thread_mdelay(500);
// AT_send("AT+CSTT?\r\n");
// rt_thread_mdelay(500);
AT_send("AT+CIICR\r\n"); //激活移动场景
rt_thread_mdelay(500);
AT_send("AT+CIFSR\r\n"); //查询IP
}
//检测MQTT与LTE联网状态
void check_LTE_MQTT(){
if (LTE.toggle)
{
if (get_LTE_status_flag() != 1)
{
LTE.LTE_re++;
}
else
{
LTE.LTE_re = 0;
}
if (LTE.LTE_re == 3)
{
LTE_Re_Init();
}
LTE.toggle = 0;
}
else
{
if (get_MQTT_Status_flag() != 1)
{
LTE.MQTT_re++;
}
else
{
LTE.MQTT_re = 0;
}
if (LTE.LTE_re == 0 && LTE.MQTT_re == 3)
{
MQTT_RE_init();
}
LTE.toggle = 1;
}
}
/**
* @brief 设置/获取LTE使用键值
* @param rt_uint8_t key 要设置的Key值
* @return rt_uint8_t 返回当前的Key值
*/
void set_LTE_Key(rt_uint8_t key)
{
LTE.Key = key;
}
rt_uint8_t get_LTE_Key()
{
return LTE.Key;
}
/**
* @brief 设置/获取LTE状态键值
* @param rt_uint8_t key 要设置的Key值
* @return rt_uint8_t 返回当前的Key值
*/
void set_LTE_Status(rt_uint8_t Status_t)
{
LTE.Status = Status_t;
}
rt_uint8_t get_LTE_Status()
{
return LTE.Status;
}
rt_uint8_t get_LTE_re()
{
return LTE.LTE_re;
}
rt_uint8_t get_L_MQTT_re()
{
return LTE.MQTT_re;
}