Merge pull request #7084 from kaspar030/add_at_parser
drivers: initial commit of generic AT parser module
This commit is contained in:
commit
84874e61d3
@ -21,6 +21,13 @@ ifneq (,$(filter apa102,$(USEMODULE)))
|
|||||||
FEATURES_REQUIRED += periph_gpio
|
FEATURES_REQUIRED += periph_gpio
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter at,$(USEMODULE)))
|
||||||
|
FEATURES_REQUIRED += periph_uart
|
||||||
|
USEMODULE += fmt
|
||||||
|
USEMODULE += xtimer
|
||||||
|
USEMODULE += isrpipe
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter at30tse75x,$(USEMODULE)))
|
ifneq (,$(filter at30tse75x,$(USEMODULE)))
|
||||||
USEMODULE += xtimer
|
USEMODULE += xtimer
|
||||||
FEATURES_REQUIRED += periph_i2c
|
FEATURES_REQUIRED += periph_i2c
|
||||||
|
|||||||
1
drivers/at/Makefile
Normal file
1
drivers/at/Makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
248
drivers/at/at.c
Normal file
248
drivers/at/at.c
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "at.h"
|
||||||
|
#include "fmt.h"
|
||||||
|
#include "isrpipe.h"
|
||||||
|
#include "periph/uart.h"
|
||||||
|
#include "xtimer.h"
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
#ifndef AT_PRINT_INCOMING
|
||||||
|
#define AT_PRINT_INCOMING (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int at_dev_init(at_dev_t *dev, uart_t uart, uint32_t baudrate, char *buf, size_t bufsize)
|
||||||
|
{
|
||||||
|
dev->uart = uart;
|
||||||
|
isrpipe_init(&dev->isrpipe, buf, bufsize);
|
||||||
|
uart_init(uart, baudrate, (uart_rx_cb_t) isrpipe_write_one,
|
||||||
|
&dev->isrpipe);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int at_expect_bytes(at_dev_t *dev, const char *bytes, uint32_t timeout)
|
||||||
|
{
|
||||||
|
while (*bytes) {
|
||||||
|
char c;
|
||||||
|
int res;
|
||||||
|
if ((res = isrpipe_read_timeout(&dev->isrpipe, &c, 1, timeout)) == 1) {
|
||||||
|
if (AT_PRINT_INCOMING) {
|
||||||
|
print(&c, 1);
|
||||||
|
}
|
||||||
|
if (c != *bytes++) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void at_send_bytes(at_dev_t *dev, const char *bytes, size_t len)
|
||||||
|
{
|
||||||
|
uart_write(dev->uart, (const uint8_t *)bytes, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int at_send_cmd(at_dev_t *dev, const char *command, uint32_t timeout)
|
||||||
|
{
|
||||||
|
size_t cmdlen = strlen(command);
|
||||||
|
|
||||||
|
uart_write(dev->uart, (const uint8_t *)command, cmdlen);
|
||||||
|
uart_write(dev->uart, (const uint8_t *)AT_SEND_EOL, AT_SEND_EOL_LEN);
|
||||||
|
|
||||||
|
if (AT_SEND_ECHO) {
|
||||||
|
if (at_expect_bytes(dev, command, timeout)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (at_expect_bytes(dev, AT_SEND_EOL "\r\n", timeout)) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void at_drain(at_dev_t *dev)
|
||||||
|
{
|
||||||
|
char _tmp[16];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
do {
|
||||||
|
/* consider no character within 10ms "drained" */
|
||||||
|
res = isrpipe_read_timeout(&dev->isrpipe, _tmp, sizeof(_tmp), 10000U);
|
||||||
|
} while (res > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t at_send_cmd_get_resp(at_dev_t *dev, const char *command,
|
||||||
|
char *resp_buf, size_t len, uint32_t timeout)
|
||||||
|
{
|
||||||
|
ssize_t res;
|
||||||
|
|
||||||
|
at_drain(dev);
|
||||||
|
|
||||||
|
res = at_send_cmd(dev, command, timeout);
|
||||||
|
if (res) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = at_readline(dev, resp_buf, len, timeout);
|
||||||
|
if (res == 0) {
|
||||||
|
/* skip possible empty line */
|
||||||
|
res = at_readline(dev, resp_buf, len, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t at_send_cmd_get_lines(at_dev_t *dev, const char *command,
|
||||||
|
char *resp_buf, size_t len, uint32_t timeout)
|
||||||
|
{
|
||||||
|
ssize_t res;
|
||||||
|
size_t bytes_left = len - 1;
|
||||||
|
char *pos = resp_buf;
|
||||||
|
|
||||||
|
memset(resp_buf, '\0', len);
|
||||||
|
|
||||||
|
at_drain(dev);
|
||||||
|
|
||||||
|
res = at_send_cmd(dev, command, timeout);
|
||||||
|
if (res) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
res = at_readline(dev, pos, bytes_left, timeout);
|
||||||
|
if (res == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (res > 0) {
|
||||||
|
bytes_left -= res;
|
||||||
|
if ((res == 2) && (strncmp(pos, "OK", 2) == 0)) {
|
||||||
|
res = len - bytes_left;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if ((res == 5) && (strncmp(pos, "ERROR", 5) == 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (strncmp(pos, "+CME ERROR:", 11) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (strncmp(pos, "+CMS ERROR:", 11) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pos += res;
|
||||||
|
if (bytes_left) {
|
||||||
|
*pos++ = '\n';
|
||||||
|
bytes_left--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout)
|
||||||
|
{
|
||||||
|
unsigned cmdlen = strlen(command);
|
||||||
|
|
||||||
|
at_drain(dev);
|
||||||
|
|
||||||
|
uart_write(dev->uart, (const uint8_t *)command, cmdlen);
|
||||||
|
uart_write(dev->uart, (const uint8_t *)AT_SEND_EOL, AT_SEND_EOL_LEN);
|
||||||
|
|
||||||
|
if (at_expect_bytes(dev, command, timeout)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (at_expect_bytes(dev, AT_SEND_EOL "\n", timeout)) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (at_expect_bytes(dev, ">", timeout)) {
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int at_send_cmd_wait_ok(at_dev_t *dev, const char *command, uint32_t timeout)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
char resp_buf[64];
|
||||||
|
|
||||||
|
res = at_send_cmd_get_resp(dev, command, resp_buf, sizeof(resp_buf), timeout);
|
||||||
|
if (res > 0) {
|
||||||
|
if (strcmp(resp_buf, "OK") == 0) {
|
||||||
|
res = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t at_readline(at_dev_t *dev, char *resp_buf, size_t len, uint32_t timeout)
|
||||||
|
{
|
||||||
|
ssize_t res = -1;
|
||||||
|
char *resp_pos = resp_buf;
|
||||||
|
|
||||||
|
memset(resp_buf, 0, len);
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
int read_res;
|
||||||
|
if ((read_res = isrpipe_read_timeout(&dev->isrpipe, resp_pos, 1, timeout)) == 1) {
|
||||||
|
if (AT_PRINT_INCOMING) {
|
||||||
|
print(resp_pos, read_res);
|
||||||
|
}
|
||||||
|
if (*resp_pos == '\r') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (*resp_pos == '\n') {
|
||||||
|
*resp_pos = '\0';
|
||||||
|
res = resp_pos - resp_buf;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
resp_pos += read_res;
|
||||||
|
len -= read_res;
|
||||||
|
}
|
||||||
|
else if (read_res == -ETIMEDOUT) {
|
||||||
|
res = -ETIMEDOUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (res < 0) {
|
||||||
|
*resp_buf = '\0';
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
210
drivers/include/at.h
Normal file
210
drivers/include/at.h
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup drivers_at AT (Hayes) command set library
|
||||||
|
* @ingroup drivers
|
||||||
|
* @brief AT (Hayes) command set library
|
||||||
|
*
|
||||||
|
* This module provides functions to interact with devices using AT commands.
|
||||||
|
*
|
||||||
|
* Most functions compare the bytes echoed by the device with what they
|
||||||
|
* intended to send, and bail out if there's no match.
|
||||||
|
*
|
||||||
|
* Furthermore, the library tries to cope with difficulties regarding different
|
||||||
|
* line endings. It usually sends "<command><CR>", but expects
|
||||||
|
* "<command>\LF\CR" as echo.
|
||||||
|
*
|
||||||
|
* As a debugging aid, when compiled with "-DAT_PRINT_INCOMING=1", every input
|
||||||
|
* byte gets printed.
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @brief AT (Hayes) library interface
|
||||||
|
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AT_H
|
||||||
|
#define AT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "isrpipe.h"
|
||||||
|
#include "periph/uart.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AT_SEND_EOL
|
||||||
|
/** End of line character to send after the AT command */
|
||||||
|
#define AT_SEND_EOL "\r"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AT_SEND_ECHO
|
||||||
|
/** Enable/disable the expected echo after an AT command is sent */
|
||||||
|
#define AT_SEND_ECHO 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Shortcut for getting send end of line length */
|
||||||
|
#define AT_SEND_EOL_LEN (sizeof(AT_SEND_EOL) - 1)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief AT device structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
isrpipe_t isrpipe; /**< isrpipe used for getting data from uart */
|
||||||
|
uart_t uart; /**< UART device where the AT device is attached */
|
||||||
|
} at_dev_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize AT device struct
|
||||||
|
*
|
||||||
|
* @param[in] dev struct to initialize
|
||||||
|
* @param[in] uart UART the device is connected to
|
||||||
|
* @param[in] baudrate baudrate of the device
|
||||||
|
* @param[in] buf input buffer
|
||||||
|
* @param[in] bufsize size of @p buf
|
||||||
|
*
|
||||||
|
* @returns 0 on success
|
||||||
|
* @returns <0 otherwise
|
||||||
|
*/
|
||||||
|
int at_dev_init(at_dev_t *dev, uart_t uart, uint32_t baudrate, char *buf, size_t bufsize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Simple command helper
|
||||||
|
*
|
||||||
|
* This function sends an AT command to the device and waits for "OK".
|
||||||
|
*
|
||||||
|
* @param[in] dev device to operate on
|
||||||
|
* @param[in] command command string to send
|
||||||
|
* @param[in] timeout timeout (in usec)
|
||||||
|
*
|
||||||
|
* @returns 0 when device answers "OK"
|
||||||
|
* @returns <0 otherwise
|
||||||
|
*/
|
||||||
|
int at_send_cmd_wait_ok(at_dev_t *dev, const char *command, uint32_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send AT command, wait for a prompt
|
||||||
|
*
|
||||||
|
* This function sends the supplied @p command, then waits for the prompt (>)
|
||||||
|
* character and returns
|
||||||
|
*
|
||||||
|
* @param[in] dev device to operate on
|
||||||
|
* @param[in] command command string to send
|
||||||
|
* @param[in] timeout timeout (in usec)
|
||||||
|
*
|
||||||
|
* @return 0 when prompt is received
|
||||||
|
* @return <0 otherwise
|
||||||
|
*/
|
||||||
|
int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send AT command, wait for response
|
||||||
|
*
|
||||||
|
* This function sends the supplied @p command, then waits and returns one
|
||||||
|
* line of response.
|
||||||
|
*
|
||||||
|
* A possible empty line will be skipped.
|
||||||
|
*
|
||||||
|
* @param[in] dev device to operate on
|
||||||
|
* @param[in] command command to send
|
||||||
|
* @param[out] resp_buf buffer for storing response
|
||||||
|
* @param[in] len len of @p buffer
|
||||||
|
* @param[in] timeout timeout (in usec)
|
||||||
|
*
|
||||||
|
* @returns length of response on success
|
||||||
|
* @returns <0 on error
|
||||||
|
*/
|
||||||
|
ssize_t at_send_cmd_get_resp(at_dev_t *dev, const char *command, char *resp_buf, size_t len, uint32_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send AT command, wait for multiline response
|
||||||
|
*
|
||||||
|
* This function sends the supplied @p command, then returns all response
|
||||||
|
* lines until the device sends "OK".
|
||||||
|
*
|
||||||
|
* If a line starts with "ERROR" or "+CME ERROR:", or the buffer is full, the
|
||||||
|
* function returns -1.
|
||||||
|
*
|
||||||
|
* @param[in] dev device to operate on
|
||||||
|
* @param[in] command command to send
|
||||||
|
* @param[out] resp_buf buffer for storing response
|
||||||
|
* @param[in] len len of @p buffer
|
||||||
|
* @param[in] timeout timeout (in usec)
|
||||||
|
*
|
||||||
|
* @returns length of response on success
|
||||||
|
* @returns <0 on error
|
||||||
|
*/
|
||||||
|
ssize_t at_send_cmd_get_lines(at_dev_t *dev, const char *command, char *resp_buf, size_t len, uint32_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Expect bytes from device
|
||||||
|
*
|
||||||
|
* @param[in] dev device to operate on
|
||||||
|
* @param[in] bytes buffer containing bytes to expect (NULL-terminated)
|
||||||
|
* @param[in] timeout timeout (in usec)
|
||||||
|
*
|
||||||
|
* @returns 0 on success
|
||||||
|
* @returns <0 otherwise
|
||||||
|
*/
|
||||||
|
int at_expect_bytes(at_dev_t *dev, const char *bytes, uint32_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send raw bytes to a device
|
||||||
|
*
|
||||||
|
* @param[in] dev device to operate on
|
||||||
|
* @param[in] bytes buffer containing bytes to send
|
||||||
|
* @param[in] len number of bytes to send
|
||||||
|
*/
|
||||||
|
void at_send_bytes(at_dev_t *dev, const char *bytes, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send command to device
|
||||||
|
*
|
||||||
|
* @param[in] dev device to operate on
|
||||||
|
* @param[in] command command to send
|
||||||
|
* @param[in] timeout timeout (in usec)
|
||||||
|
*
|
||||||
|
* @returns 0 on success
|
||||||
|
* @returns <0 otherwise
|
||||||
|
*/
|
||||||
|
int at_send_cmd(at_dev_t *dev, const char *command, uint32_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a line from device
|
||||||
|
*
|
||||||
|
* @param[in] dev device to operate on
|
||||||
|
* @param[in] resp_buf buffer to store line
|
||||||
|
* @param[in] len size of @p buffer
|
||||||
|
* @param[in] timeout timeout (in usec)
|
||||||
|
*
|
||||||
|
* @returns line length on success
|
||||||
|
* @returns <0 on error
|
||||||
|
*/
|
||||||
|
ssize_t at_readline(at_dev_t *dev, char *resp_buf, size_t len, uint32_t timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Drain device input buffer
|
||||||
|
*
|
||||||
|
* This function drains any possible bytes waiting in the device's input
|
||||||
|
* buffer.
|
||||||
|
*
|
||||||
|
* @param[in] dev device to operate on
|
||||||
|
*/
|
||||||
|
void at_drain(at_dev_t *dev);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AT_H */
|
||||||
|
/** @} */
|
||||||
8
tests/driver_at/Makefile
Normal file
8
tests/driver_at/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
BOARD_INSUFFICIENT_MEMORY += nucleo32-f031
|
||||||
|
|
||||||
|
USEMODULE += shell
|
||||||
|
USEMODULE += at
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
8
tests/driver_at/README.md
Normal file
8
tests/driver_at/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
Expected result
|
||||||
|
===============
|
||||||
|
You should be presented with a RIOT shell that privides commands to
|
||||||
|
initialize an UART and send AT commands to an AT module.
|
||||||
|
|
||||||
|
Background
|
||||||
|
==========
|
||||||
|
Test for the AT command parser driver.
|
||||||
134
tests/driver_at/main.c
Normal file
134
tests/driver_at/main.c
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 OTA keys S.A.
|
||||||
|
* 2018 Inria
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup tests
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief AT module test application
|
||||||
|
*
|
||||||
|
* @author Vincent Dupont <vincent@otakeys.com>
|
||||||
|
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "at.h"
|
||||||
|
#include "shell.h"
|
||||||
|
#include "timex.h"
|
||||||
|
|
||||||
|
#include "periph/uart.h"
|
||||||
|
|
||||||
|
static at_dev_t at_dev;
|
||||||
|
static char buf[256];
|
||||||
|
static char resp[1024];
|
||||||
|
|
||||||
|
static int init(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
printf("Usage: %s <uart> <baudrate>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t uart = atoi(argv[1]);
|
||||||
|
uint32_t baudrate = atoi(argv[2]);
|
||||||
|
|
||||||
|
at_dev_init(&at_dev, UART_DEV(uart), baudrate, buf, sizeof(buf));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Usage: %s <command>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t len;
|
||||||
|
if ((len = at_send_cmd_get_resp(&at_dev, argv[1], resp, sizeof(resp), 10 * US_PER_SEC)) < 0) {
|
||||||
|
puts("Error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Response (len=%d): %s\n", (int)len, resp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_ok(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Usage: %s <command>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (at_send_cmd_wait_ok(&at_dev, argv[1], 10 * US_PER_SEC) < 0) {
|
||||||
|
puts("Error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("OK");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_lines(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Usage: %s <command>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t len;
|
||||||
|
if ((len = at_send_cmd_get_lines(&at_dev, argv[1], resp, sizeof(resp), 10 * US_PER_SEC)) < 0) {
|
||||||
|
puts("Error");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Response (len=%d): %s\n", (int)len, resp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int drain(int argc, char **argv)
|
||||||
|
{
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
|
at_drain(&at_dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const shell_command_t shell_commands[] = {
|
||||||
|
{ "init", "Initialize AT device", init },
|
||||||
|
{ "send", "Send a command and wait response", send },
|
||||||
|
{ "send_ok", "Send a command and wait OK", send_ok },
|
||||||
|
{ "send_lines", "Send a command and wait lines", send_lines },
|
||||||
|
{ "drain", "Drain AT device", drain },
|
||||||
|
{ NULL, NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
puts("AT command test app");
|
||||||
|
|
||||||
|
/* run the shell */
|
||||||
|
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||||
|
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user