#ifdef GPRS
#include "stm32f10x_gpio.h"
#include "stm32f10x_usart.h"
#include <stdarg.h>
#include "fifo.h"
#include "debug.h"
#include "kernel.h"
#include "macro.h"
#include "gprs.h"
#include "timer.h"
#define UART1_BUF_SIZE 256
static TIMER *gprs_csq_timer = NULL;
static uint8_t rx_buf[UART1_BUF_SIZE], tx_buf[UART1_BUF_SIZE];
static fifo_t gprs_rx_fifo = {
(void *)rx_buf,
NULL,
NULL,
NULL,
1,
UART1_BUF_SIZE,
};
static fifo_t gprs_tx_fifo = {
(void *)tx_buf,
NULL,
NULL,
NULL,
1,
UART1_BUF_SIZE,
};
static bool uart_fifo_push(uint8_t *data, uint8_t len)
{
uint8_t i;
if(fifo_is_full(&gprs_tx_fifo))
{
fifo_flush(&gprs_tx_fifo);
}
for(i = 0; i < len; i ++)
{
fifo_push(&gprs_tx_fifo, &data[i]);
}
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
return TRUE;
}
static int uart_at_cmd_frame_send(char *cmd, ...)
{
char cmd_str[64] = "AT+";
uint8_t len;
char *arg;
va_list ap;
va_start(ap, cmd);
strcat(cmd_str, cmd);
if(strcmp(arg = va_arg(ap, char *), VA_PARAM_END))
{
strcat(cmd_str, "=");
strcat(cmd_str, arg);
while(strcmp(arg = va_arg(ap, char *), VA_PARAM_END))
{
strcat(cmd_str, ",");
strcat(cmd_str, arg);
}
}
len = strlen(cmd_str);
cmd_str[len ++] = 0x0D;
cmd_str[len ++] = 0x0A;
uart_fifo_push(cmd_str, len);
return 0;
}
static bool uart_at_cmd_result_read(uint8_t data[])
{
uint8_t len = 0, i, result[256] = {0};
char *sub_str;
len = fifo_get_len(&gprs_rx_fifo);
if(len > 6)
{
for(i = 0; i < len; i ++)
{
fifo_peek_at(&gprs_rx_fifo, &result[i], i);
}
if(strstr(result, "\r\n"))
{
fifo_flush(&gprs_rx_fifo);
memcpy(data, result, len);
return true;
}
return false;
}
else
return false;
return true;
}
static bool at_cmd_result_get(uint8_t data[], int32_t timeout)
{
timeout = knlGetTargetTime(timeout);
while(!knlIsTimeOut(timeout))
{
OSMaskEventPend(ANYEVENT);
if(uart_at_cmd_result_read(data))
{
return TRUE;
}
}
fifo_flush(&gprs_rx_fifo);
return FALSE;
}
static void gprs_power_ctrl(void)
{
int32_t timeout;
GPRS_2G_HIGH();
GPRS_2G_LOW();
timeout = knlGetTargetTime(2000);
while(!knlIsTimeOut(timeout))
{
OSMaskEventPend(ANYEVENT);
}
GPRS_2G_HIGH();
timeout = knlGetTargetTime(10000);
while(!knlIsTimeOut(timeout))
{
OSMaskEventPend(ANYEVENT);
}
}
#define AT_ERROR_CHECK(result, expect) do{ \
if(!at_cmd_result_get(result, 1000) && strstr(result, expect)) \
goto reset; \
}while(0)
static void gprs_reset(void)
{
uint8_t result[256] = {0}, times = 0;
timer_stop(gprs_csq_timer);
reset:
RTT_LOG(APP_WARNING"gprs reset %s\r\n", result);
gprs_power_ctrl();
fifo_flush(&gprs_rx_fifo);
fifo_flush(&gprs_tx_fifo);
uart_at_cmd_frame_send("IPR", "115200", VA_PARAM_END);
AT_ERROR_CHECK(result,"OK");
knlDelayTime(1000);
uart_at_cmd_frame_send("QISDE", "0", VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
uart_at_cmd_frame_send("CPIN?", VA_PARAM_END);
AT_ERROR_CHECK(result, "READY");
knlDelayTime(50);
uart_at_cmd_frame_send("CREG?", VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
uart_at_cmd_frame_send("QIFGCNT", "1", VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
uart_at_cmd_frame_send("QIDNSIP", "0", VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
uart_at_cmd_frame_send("QIMODE", "0", VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
uart_at_cmd_frame_send("QIHEAD", "0", VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
uart_at_cmd_frame_send("QINDI", "0", VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
uart_at_cmd_frame_send("QIMUX", "1", VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
uart_at_cmd_frame_send("QIREGAPP",VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
retry:
uart_at_cmd_frame_send("QIACT",VA_PARAM_END);
if(!(at_cmd_result_get(result, 1000) && strstr(result, "OK")))
{
times ++;
if(times > 60)
{
times = 0;
goto reset;
}
goto retry;
}
knlDelayTime(50);
uart_at_cmd_frame_send("QIOPEN","0", "\"TCP\"", "\"119.23.237.22\"", "\"14322\"", VA_PARAM_END);
AT_ERROR_CHECK(result, "OK");
knlDelayTime(50);
timer_start(gprs_csq_timer, _SEC_, 15);
RTT_LOG(APP_WARNING"gprs reset success\r\n");
}
#undef AT_ERROR_CHECK
static void csq_get(void)
{
char result[256];
int pos;
uart_at_cmd_frame_send("CSQ", VA_PARAM_END);
if(at_cmd_result_get(result, 1000))
{
if(pos = strstr(result, "+CSQ: "))
{
if(((char *)pos)[6] < '0' || ((char *)pos)[7] > '9')
return ;
else
gprs.csq = (((char *)pos)[6] - '0') * 10 + (((char *)pos)[7] - '0');
RTT_LOG(APP_NOTICE"csq get:%d\r\n", gprs.csq);
}
return ;
}
gprs.csq = 99;
return ;
}
static bool gprs_data_send(uint8_t *data, uint16_t len)
{
uint8_t slen[6];
uint8_t result[256];
sprintf(slen, "%d", len);
uart_at_cmd_frame_send("QISEND", "0", slen, VA_PARAM_END);
if(at_cmd_result_get(result, 1000) && strstr(result, "> "))
{
uart_fifo_push(data, len);
if(at_cmd_result_get(result, 2000) && strstr(result, "SEND OK"))
return TRUE;
}
return TRUE;
}
static void gprs_init(void)
{
fifo_init(&gprs_rx_fifo);
fifo_init(&gprs_tx_fifo);
if(!gprs_csq_timer)
{
gprs_csq_timer = timer_add(csq_get, "gprs csq get");
timer_start(gprs_csq_timer, _SEC_, 15);
}
}
static bool gprs_rx_proc(void)
{
uint8_t data;
if(fifo_is_full(&gprs_rx_fifo))
{
fifo_flush(&gprs_rx_fifo);
}
data = USART_ReceiveData(USART1);
fifo_push(&gprs_rx_fifo, &data);
return FALSE;
}
static void gprs_tx_proc()
{
uint8_t data;
if(fifo_pop(&gprs_tx_fifo, (void *)&data) == FIFO_SUCCESS)
{
USART_SendData(USART1, data);
}
else
{
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
void USART1_IRQHandler(void)
{
OS_ENTER_CRITICAL();
OSIntNesting++;
OS_EXIT_CRITICAL();
if(USART_GetITStatus(USART1,USART_IT_RXNE)!= RESET)
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
gprs_rx_proc();
}
if (USART_GetITStatus(USART1, USART_IT_TXE)!= RESET)
{
USART_ClearITPendingBit(USART1,USART_IT_TXE);
gprs_tx_proc();
}
if(USART_GetITStatus(USART1, USART_IT_TC) != RESET)
{
USART_ClearITPendingBit(USART1,USART_IT_TC);
}
if (USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_ORE);
USART_ReceiveData(USART1);
}
if (USART_GetFlagStatus(USART1,USART_FLAG_NE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_NE);
USART_ReceiveData(USART1);
}
if (USART_GetFlagStatus(USART1,USART_FLAG_FE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_FE);
USART_ReceiveData(USART1);
}
OSIntExit();
}
struct gprs_driver gprs = {
99,
&gprs_rx_fifo,
gprs_init,
gprs_reset,
gprs_data_send,
};
#endif