This repository has been archived on 2023-07-17. You can view files and clone it, but cannot push or open issues or pull requests.
bl_mcu_sdk/examples/at_client/at.c

204 lines
5.8 KiB
C

#include "bflb_platform.h"
#include "hal_uart.h"
#include "at.h"
#include "ring_buffer.h"
#define UART_SEND_BUF_SZIE 1024
char send_buf[UART_SEND_BUF_SZIE] = { 0 };
#define UART_RX_RINGBUFFER_SIZE (1 * 1024)
uint8_t uart_rx_mem[UART_RX_RINGBUFFER_SIZE];
struct device *uart1;
Ring_Buffer_Type uart1_rx_rb;
static void uart1_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
Ring_Buffer_Write(&uart1_rx_rb, (uint8_t *)args, size);
}
uint32_t at_vprintfln(const char *format, va_list args)
{
uint32_t len;
len = vsnprintf(send_buf, sizeof(send_buf) - 2, format, args);
if (len > sizeof(send_buf) - 2)
len = sizeof(send_buf) - 2;
memcpy(send_buf + len, "\r\n", 2);
len = len + 2;
MSG("%s\r\n", send_buf);
device_control(uart1, DEVICE_CTRL_CLR_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
uart1->oflag &= ~DEVICE_OFLAG_INT_RX;
return device_write(uart1, 0, (uint8_t *)send_buf, len);
}
int at_read_line(struct at_client *client)
{
uint32_t read_len = 0;
uint32_t start_time = 0;
char ch = 0, last_ch = 0;
memset(client->recv_line_buf, 0, client->recv_bufsz);
client->recv_line_len = 0;
start_time = bflb_platform_get_time_ms();
while (1) {
while (device_read(uart1, 0, &ch, 1) == 0) {
if ((bflb_platform_get_time_ms() - start_time) > client->timeout) {
client->resp_status = AT_RESP_TIMEOUT;
return AT_RESP_TIMEOUT;
}
}
if (read_len < client->recv_bufsz) {
client->recv_line_buf[read_len++] = ch;
client->recv_line_len = read_len;
} else {
MSG("buf full\r\n");
client->resp_status = AT_RESP_BUFF_FULL;
return AT_RESP_BUFF_FULL;
}
if (ch == '\n' && last_ch == '\r') {
if (strstr((const char *)client->recv_line_buf, (const char *)client->resp_succ)) {
client->resp_status = AT_RESP_OK;
goto match_out;
} else if (client->resp_err && strstr((const char *)client->recv_line_buf, (const char *)client->resp_err)) {
client->resp_status = AT_RESP_ERROR;
goto match_out;
}
}
last_ch = ch;
}
match_out:
MSG("%s", client->recv_line_buf);
return read_len;
}
int at_exe_cmd(struct at_client *client, char *cmd_expr, ...)
{
va_list ap;
va_start(ap, cmd_expr);
at_vprintfln(cmd_expr, ap);
va_end(ap);
return at_read_line(client);
}
int at_write_recv(uint8_t *send_buffer, uint32_t send_len, uint8_t *recv_buffer, uint32_t *recv_len, uint32_t timeout)
{
int ret = 0;
uint8_t found = 0;
uint32_t read_len = 0;
uint32_t start_time = 0;
uint8_t ch = 0, last_ch = 0;
uint8_t tmp_buf[32] = { 0 };
const char *found_string = "+IPD:0,";
uint8_t found_index = 0;
struct at_client static_client;
static_client.recv_line_buf = tmp_buf;
static_client.recv_bufsz = 32;
static_client.resp_succ = ">";
static_client.resp_err = "FAIL";
static_client.timeout = 1000;
ret = at_exe_cmd(&static_client, "AT+CIPSEND=0,%d", 114);
if (ret < 0) {
return -1;
}
Ring_Buffer_Reset(&uart1_rx_rb);
device_control(uart1, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
device_write(uart1, 0, (uint8_t *)send_buffer, send_len);
if (recv_buffer == NULL) {
return 0;
}
uint8_t *p = recv_buffer;
start_time = bflb_platform_get_time_ms();
while (1) {
while (Ring_Buffer_Read_Byte(&uart1_rx_rb, &ch) == 0) {
if ((bflb_platform_get_time_ms() - start_time) > timeout) {
return AT_RESP_TIMEOUT;
}
}
if (found == 0) {
tmp_buf[found_index++] = ch;
if (strstr((const char *)tmp_buf, found_string)) {
found = 1;
found_index = 0;
}
} else if (found == 1) {
tmp_buf[found_index++] = ch;
if (ch == '\n' && last_ch == '\r') {
if (found_index == 3) {
read_len = (tmp_buf[0] - '0');
} else if (found_index == 4) {
read_len = (tmp_buf[0] - '0') * 10 + (tmp_buf[1] - '0');
} else if (found_index == 5) {
read_len = (tmp_buf[0] - '0') * 100 + (tmp_buf[1] - '0') * 10 + (tmp_buf[2] - '0');
}
*recv_len = read_len;
found = 2;
}
last_ch = ch;
} else {
*p++ = ch;
read_len--;
if (read_len == 0) {
return 0;
}
}
}
return 0;
}
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
void at_dump_hex(const void *ptr, uint32_t buflen)
{
unsigned char *buf = (unsigned char *)ptr;
int i, j;
for (i = 0; i < buflen; i += 16) {
MSG("%08X:", i);
for (j = 0; j < 16; j++)
if (i + j < buflen) {
if ((j % 8) == 0) {
MSG(" ");
}
MSG("%02X ", buf[i + j]);
} else
MSG(" ");
MSG(" ");
for (j = 0; j < 16; j++)
if (i + j < buflen)
MSG("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
MSG("\n");
}
}
void at_client_init()
{
Ring_Buffer_Init(&uart1_rx_rb, uart_rx_mem, UART_RX_RINGBUFFER_SIZE, cpu_global_irq_disable, cpu_global_irq_enable);
uart_register(UART1_INDEX, "uart1");
uart1 = device_find("uart1");
if (uart1) {
UART_DEV(uart1)->baudrate = 115200;
device_open(uart1, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_INT_RX);
device_set_callback(uart1, uart1_irq_callback);
device_control(uart1, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
Ring_Buffer_Reset(&uart1_rx_rb);
}
}