288 lines
6.8 KiB
C
288 lines
6.8 KiB
C
/*
|
||
*********************************************************************************************************
|
||
* IAR Development Kits
|
||
* on the
|
||
*
|
||
* M451
|
||
*
|
||
* Filename : uart_Ethernet.h
|
||
* Version : V1.00
|
||
* Programmer(s) : Qian Xianghong
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* INCLUDE FILES
|
||
*********************************************************************************************************
|
||
*/
|
||
#include <includes.h>
|
||
|
||
// ETHERNET串口接收的循环缓冲
|
||
#define ETHERNET_DATA_COUNT 200
|
||
loopbuff_t Ethernet_Buff;
|
||
uint8_t Ethernet_Buff_Data[sizeof(uint8_t) * (ETHERNET_DATA_COUNT + 1)] = {0};
|
||
// ETHERNET串口接收的消息通知
|
||
SemaphoreHandle_t Ethernet_semQ = NULL;
|
||
|
||
// ETHERNET串口AT命令接收的循环缓冲
|
||
#define ETHERNET_ATDATA_COUNT 50
|
||
loopbuff_t Ethernet_ATBuff;
|
||
uint8_t Ethernet_ATBuff_Data[sizeof(uint8_t) * (ETHERNET_ATDATA_COUNT + 1)] = {0};
|
||
|
||
// 网口初始化状态
|
||
uint8_t Ethernet_initStatus = 0, Ethernet_connected = 0;
|
||
|
||
static void Ethernet_IRQHandler(USART_Handle *huart)
|
||
{
|
||
BaseType_t xHigherPriorityTaskWoken;
|
||
|
||
uint8_t c = (uint8_t) huart->Instance->DR;
|
||
// 加入缓冲
|
||
LoopBuff_PutItem(&Ethernet_Buff, &c);
|
||
// 发消息给任务
|
||
xSemaphoreGiveFromISR(Ethernet_semQ, &xHigherPriorityTaskWoken);
|
||
}
|
||
|
||
static void Ethernet_ATHandler(USART_Handle *huart)
|
||
{
|
||
uint8_t c = (uint8_t) huart->Instance->DR;
|
||
// 加入缓冲
|
||
LoopBuff_PutItem(&Ethernet_ATBuff, &c);
|
||
}
|
||
|
||
void Ethernet_Send(char *buf)
|
||
{
|
||
UART_Transmit(&huart3, (uint8_t *) buf, strlen(buf));
|
||
}
|
||
|
||
// 非中断方式,直接从串口接收数据
|
||
uint16_t Ethernet_Recv(char *buf, uint16_t wait_cnt)
|
||
{
|
||
uint16_t recv_cnt = 0;
|
||
uint32_t stop_seconds;
|
||
char c;
|
||
|
||
stop_seconds = rf_get_seconds() + 2;
|
||
while(rf_get_seconds() < stop_seconds)
|
||
{
|
||
if(LoopBuff_GetCount(&Ethernet_ATBuff) > 0)
|
||
{
|
||
c = *(uint8_t *) LoopBuff_GetDataPtr(&Ethernet_ATBuff, Ethernet_ATBuff.info.rdPtr);
|
||
LoopBuff_RemoveItems(&Ethernet_ATBuff, 1);
|
||
printf("%c", c);
|
||
if(c != '\r' && c != '\n')
|
||
{
|
||
buf[recv_cnt++] = c;
|
||
if(recv_cnt == wait_cnt)
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return recv_cnt;
|
||
}
|
||
|
||
// 进入AT命令模式
|
||
uint8_t Ethernet_ATMode()
|
||
{
|
||
uint8_t try_cnt;
|
||
char buf[3] = {0};
|
||
|
||
// 进入AT命令模式
|
||
for(try_cnt = 0; try_cnt < 3; try_cnt++)
|
||
{
|
||
// 先进入AT命令模式
|
||
delay_ms(100);
|
||
Ethernet_Send("+++");
|
||
if(Ethernet_Recv(buf, 1) < 1 || buf[0] != 'a')
|
||
continue;
|
||
|
||
Ethernet_Send("a");
|
||
if(Ethernet_Recv(buf, 3) < 3 || strncmp(buf, "+ok", 3) != 0)
|
||
continue;
|
||
|
||
// 成功进入AT命令模式
|
||
delay_ms(100);
|
||
return 1;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
uint8_t Ethernet_ATCmd(char *cmd, char *ok_str, char *err_str)
|
||
{
|
||
char buf[21], c;
|
||
uint8_t try_cnt;
|
||
uint16_t recv_cnt = 0;
|
||
uint32_t stop_seconds;
|
||
|
||
memset(buf, 0, sizeof(buf));
|
||
for(try_cnt = 0; try_cnt < 3; try_cnt++)
|
||
{
|
||
// 清空串口缓冲区
|
||
LoopBuff_Clear(&Ethernet_ATBuff);
|
||
// 发送命令
|
||
Ethernet_Send(cmd);
|
||
Ethernet_Send("\r");
|
||
// 等待返回数据
|
||
stop_seconds = rf_get_seconds() + 2;
|
||
while(rf_get_seconds() < stop_seconds)
|
||
{
|
||
if(LoopBuff_GetCount(&Ethernet_ATBuff) > 0)
|
||
{
|
||
c = *(uint8_t *) LoopBuff_GetDataPtr(&Ethernet_ATBuff, Ethernet_ATBuff.info.rdPtr);
|
||
LoopBuff_RemoveItems(&Ethernet_ATBuff, 1);
|
||
printf("%c", c);
|
||
if(c != '\r' && c != '\n')
|
||
{
|
||
buf[recv_cnt++] = c;
|
||
if(strstr(buf, ok_str) != NULL)
|
||
return 1;
|
||
if(strstr(buf, err_str) != NULL)
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void Ethernet_Open()
|
||
{
|
||
// 创建消息队列
|
||
LoopBuff_Create(&Ethernet_Buff, sizeof(uint8_t), ETHERNET_DATA_COUNT, 0, (uint32_t) Ethernet_Buff_Data);
|
||
LoopBuff_Create(&Ethernet_ATBuff, sizeof(uint8_t), ETHERNET_ATDATA_COUNT, 0, (uint32_t) Ethernet_ATBuff_Data);
|
||
|
||
// 创建信号量
|
||
Ethernet_semQ = xSemaphoreCreateBinary();
|
||
|
||
SET_BIT(USART3->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
|
||
LL_USART_Enable(USART3);
|
||
}
|
||
|
||
// 本函数要用到中断,只能在任务启动以后执行
|
||
void Ethernet_Config()
|
||
{
|
||
huart3.RxISR = Ethernet_ATHandler;
|
||
|
||
delay_ms(100);
|
||
VCC_ETHERNET_ON();
|
||
delay_ms(1000);
|
||
|
||
// 设置状态
|
||
Ethernet_initStatus = 0;
|
||
Ethernet_connected = 0;
|
||
|
||
// 设置Usr_K3工作方式
|
||
#if 1
|
||
// 进入AT命令模式
|
||
if(!Ethernet_ATMode())
|
||
return;
|
||
// 设置命令不回显
|
||
if(!Ethernet_ATCmd("AT+E=OFF", "+OK", "+ERR"))
|
||
return;
|
||
// 设置DHCP
|
||
if(!Ethernet_ATCmd("AT+WANN=DHCP", "+OK", "+ERR"))
|
||
// if(!Ethernet_ATCmd("AT+WANN=STATIC,192.168.0.3,255.255.255.0,192.168.0.1", "+OK", "+ERR"))
|
||
return;
|
||
// 设置DNS(如DHCP配置可不设DNS)
|
||
// if(!Ethernet_ATCmd("AT+DNS=202.106.0.20", "+OK", "+ERR"))
|
||
// return;
|
||
// 设置TCP模式、服务器、端口
|
||
if(RF_APP == RF_APP_AJH)
|
||
{
|
||
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,171.88.5.52,8061", "+OK", "+ERR")) // 公司路由器
|
||
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,extra.cd-ls.cn,8061", "+OK", "+ERR"))
|
||
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,121.89.205.240,41001", "+OK", "+ERR"))
|
||
if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,data.ajhiot.com,8088", "+OK", "+ERR"))
|
||
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,114.55.209.85,8088", "+OK", "+ERR")) // data.ajhiot.com
|
||
// if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,192.168.0.2,8061", "+OK", "+ERR")) // 直连电脑
|
||
return;
|
||
}
|
||
else if(RF_APP == RF_APP_PRAX)
|
||
{
|
||
if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,tts.praxair.com.cn,7005", "+OK", "+ERR"))
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
if(!Ethernet_ATCmd("AT+SOCKA1=TCPC,data.cd-ls.cn,8088", "+OK", "+ERR"))
|
||
return;
|
||
}
|
||
|
||
// 关闭串口心跳包
|
||
if(!Ethernet_ATCmd("AT+HEARTEN1=OFF", "+OK", "+ERR"))
|
||
return;
|
||
// 关闭串口注册包
|
||
if(!Ethernet_ATCmd("AT+REGEN1=OFF", "+OK", "+ERR"))
|
||
return;
|
||
// 关闭短连接功能
|
||
if(!Ethernet_ATCmd("AT+SOCKSL1=OFF", "+OK", "+ERR"))
|
||
return;
|
||
// 设置超时重启时间:60秒
|
||
if(!Ethernet_ATCmd("AT+RSTIM=60", "+OK", "+ERR"))
|
||
return;
|
||
// 连接前是否清理串口缓存?
|
||
if(!Ethernet_ATCmd("AT+UARTCLBUF=ON", "+OK", "+ERR"))
|
||
return;
|
||
// 设为默认参数
|
||
if(!Ethernet_ATCmd("AT+CFGTF", "saved", "+ERR"))
|
||
return;
|
||
// 重启模块
|
||
if(!Ethernet_ATCmd("AT+Z", "OK", "+ERR"))
|
||
return;
|
||
#endif
|
||
|
||
/* Enable UART3 interrupt */
|
||
huart3.RxISR = Ethernet_IRQHandler;
|
||
|
||
// 设置状态
|
||
Ethernet_initStatus = 1;
|
||
}
|
||
|
||
// 检查服务器连接情况
|
||
uint8_t Ethernet_IsConnected()
|
||
{
|
||
u8 try_count;
|
||
u8 atMode = 0, connected = 0, tranMode = 0;
|
||
|
||
huart3.RxISR = Ethernet_ATHandler;
|
||
|
||
// 清除串口缓冲数据
|
||
LoopBuff_Clear(&Ethernet_ATBuff);
|
||
|
||
// 进入AT命令模式,3次不成功则复位
|
||
for(try_count = 0; try_count < 3; try_count++)
|
||
{
|
||
if(Ethernet_ATMode())
|
||
{
|
||
atMode = 1;
|
||
break;
|
||
}
|
||
osDelay(500);
|
||
}
|
||
|
||
if(atMode)
|
||
{
|
||
// 检查是否连上网络
|
||
connected = Ethernet_ATCmd("AT+SOCKLKA1", "+OK=CONNECTED", "+OK=CONNECTING");
|
||
|
||
// 进入透传模式,3次不成功则复位
|
||
for(try_count = 0; try_count < 3; try_count++)
|
||
{
|
||
if(Ethernet_ATCmd("AT+ENTM", "+OK", "+ERR"))
|
||
{
|
||
tranMode = 1;
|
||
break;
|
||
}
|
||
osDelay(500);
|
||
}
|
||
}
|
||
|
||
huart3.RxISR = Ethernet_IRQHandler;
|
||
|
||
return (atMode && connected && tranMode);
|
||
}
|