drivers: at: many improvements
This commit is contained in:
parent
7340e77328
commit
0199f36bb3
@ -22,8 +22,10 @@ ifneq (,$(filter apa102,$(USEMODULE)))
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter at,$(USEMODULE)))
|
ifneq (,$(filter at,$(USEMODULE)))
|
||||||
|
FEATURES_REQUIRED += periph_uart
|
||||||
USEMODULE += fmt
|
USEMODULE += fmt
|
||||||
USEMODULE += xtimer
|
USEMODULE += xtimer
|
||||||
|
USEMODULE += isrpipe
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter at30tse75x,$(USEMODULE)))
|
ifneq (,$(filter at30tse75x,$(USEMODULE)))
|
||||||
|
|||||||
@ -32,19 +32,18 @@ int at_dev_init(at_dev_t *dev, uart_t uart, uint32_t baudrate, char *buf, size_t
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int at_expect_bytes(at_dev_t *dev, const char *bytes, size_t len, uint32_t timeout)
|
int at_expect_bytes(at_dev_t *dev, const char *bytes, uint32_t timeout)
|
||||||
{
|
{
|
||||||
while (len) {
|
while (*bytes) {
|
||||||
char c;
|
char c;
|
||||||
int res;
|
int res;
|
||||||
if ((res = isrpipe_read_timeout(&dev->isrpipe, &c, 1, timeout)) == 1) {
|
if ((res = isrpipe_read_timeout(&dev->isrpipe, &c, 1, timeout)) == 1) {
|
||||||
if (AT_PRINT_INCOMING) {
|
if (AT_PRINT_INCOMING) {
|
||||||
print(&c, 1);
|
print(&c, 1);
|
||||||
}
|
}
|
||||||
if (!(c == *bytes++)) {
|
if (c != *bytes++) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
len--;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return res;
|
return res;
|
||||||
@ -61,18 +60,20 @@ void at_send_bytes(at_dev_t *dev, const char *bytes, size_t len)
|
|||||||
|
|
||||||
int at_send_cmd(at_dev_t *dev, const char *command, uint32_t timeout)
|
int at_send_cmd(at_dev_t *dev, const char *command, uint32_t timeout)
|
||||||
{
|
{
|
||||||
unsigned cmdlen = strlen(command);
|
size_t cmdlen = strlen(command);
|
||||||
|
|
||||||
uart_write(dev->uart, (const uint8_t *)command, cmdlen);
|
uart_write(dev->uart, (const uint8_t *)command, cmdlen);
|
||||||
uart_write(dev->uart, (const uint8_t *)AT_END_OF_LINE, sizeof(AT_END_OF_LINE) - 1);
|
uart_write(dev->uart, (const uint8_t *)AT_SEND_EOL, AT_SEND_EOL_LEN);
|
||||||
|
|
||||||
if (at_expect_bytes(dev, command, cmdlen, timeout)) {
|
if (AT_SEND_ECHO) {
|
||||||
|
if (at_expect_bytes(dev, command, timeout)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at_expect_bytes(dev, AT_END_OF_LINE "\r\n", sizeof(AT_END_OF_LINE) + 1, timeout)) {
|
if (at_expect_bytes(dev, AT_SEND_EOL "\r\n", timeout)) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -83,13 +84,15 @@ void at_drain(at_dev_t *dev)
|
|||||||
int res;
|
int res;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
/* consider no character within 10ms "drained" */
|
||||||
res = isrpipe_read_timeout(&dev->isrpipe, _tmp, sizeof(_tmp), 10000U);
|
res = isrpipe_read_timeout(&dev->isrpipe, _tmp, sizeof(_tmp), 10000U);
|
||||||
} while (res > 0);
|
} 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 at_send_cmd_get_resp(at_dev_t *dev, const char *command,
|
||||||
|
char *resp_buf, size_t len, uint32_t timeout)
|
||||||
{
|
{
|
||||||
ssize_t res = -1;
|
ssize_t res;
|
||||||
|
|
||||||
at_drain(dev);
|
at_drain(dev);
|
||||||
|
|
||||||
@ -108,9 +111,10 @@ out:
|
|||||||
return res;
|
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 at_send_cmd_get_lines(at_dev_t *dev, const char *command,
|
||||||
|
char *resp_buf, size_t len, uint32_t timeout)
|
||||||
{
|
{
|
||||||
ssize_t res = -1;
|
ssize_t res;
|
||||||
size_t bytes_left = len - 1;
|
size_t bytes_left = len - 1;
|
||||||
char *pos = resp_buf;
|
char *pos = resp_buf;
|
||||||
|
|
||||||
@ -123,7 +127,7 @@ ssize_t at_send_cmd_get_lines(at_dev_t *dev, const char *command, char *resp_buf
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1) {
|
while (1) {
|
||||||
res = at_readline(dev, pos, bytes_left, timeout);
|
res = at_readline(dev, pos, bytes_left, timeout);
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
continue;
|
continue;
|
||||||
@ -140,6 +144,9 @@ ssize_t at_send_cmd_get_lines(at_dev_t *dev, const char *command, char *resp_buf
|
|||||||
else if (strncmp(pos, "+CME ERROR:", 11) == 0) {
|
else if (strncmp(pos, "+CME ERROR:", 11) == 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
else if (strncmp(pos, "+CMS ERROR:", 11) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
pos += res;
|
pos += res;
|
||||||
if (bytes_left) {
|
if (bytes_left) {
|
||||||
@ -167,17 +174,17 @@ int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout
|
|||||||
at_drain(dev);
|
at_drain(dev);
|
||||||
|
|
||||||
uart_write(dev->uart, (const uint8_t *)command, cmdlen);
|
uart_write(dev->uart, (const uint8_t *)command, cmdlen);
|
||||||
uart_write(dev->uart, (const uint8_t *)AT_END_OF_LINE, sizeof(AT_END_OF_LINE) - 1);
|
uart_write(dev->uart, (const uint8_t *)AT_SEND_EOL, AT_SEND_EOL_LEN);
|
||||||
|
|
||||||
if (at_expect_bytes(dev, command, cmdlen, timeout)) {
|
if (at_expect_bytes(dev, command, timeout)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at_expect_bytes(dev, AT_END_OF_LINE "\n", sizeof(AT_END_OF_LINE), timeout)) {
|
if (at_expect_bytes(dev, AT_SEND_EOL "\n", timeout)) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at_expect_bytes(dev, ">", 1, timeout)) {
|
if (at_expect_bytes(dev, ">", timeout)) {
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +194,7 @@ int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout
|
|||||||
int at_send_cmd_wait_ok(at_dev_t *dev, const char *command, uint32_t timeout)
|
int at_send_cmd_wait_ok(at_dev_t *dev, const char *command, uint32_t timeout)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
char resp_buf[32];
|
char resp_buf[64];
|
||||||
|
|
||||||
res = at_send_cmd_get_resp(dev, command, resp_buf, sizeof(resp_buf), timeout);
|
res = at_send_cmd_get_resp(dev, command, resp_buf, sizeof(resp_buf), timeout);
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
@ -234,5 +241,8 @@ ssize_t at_readline(at_dev_t *dev, char *resp_buf, size_t len, uint32_t timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (res < 0) {
|
||||||
|
*resp_buf = '\0';
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
* Most functions compare the bytes echoed by the device with what they
|
* Most functions compare the bytes echoed by the device with what they
|
||||||
* intended to send, and bail out if there's no match.
|
* intended to send, and bail out if there's no match.
|
||||||
*
|
*
|
||||||
* Furthermore, the library tries to copy with difficulties regarding different
|
* Furthermore, the library tries to cope with difficulties regarding different
|
||||||
* line endings. It usually sends "<command><CR>", but expects
|
* line endings. It usually sends "<command><CR>", but expects
|
||||||
* "<command>\LF\CR" as echo.
|
* "<command>\LF\CR" as echo.
|
||||||
*
|
*
|
||||||
@ -34,6 +34,7 @@
|
|||||||
#define AT_H
|
#define AT_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "isrpipe.h"
|
#include "isrpipe.h"
|
||||||
#include "periph/uart.h"
|
#include "periph/uart.h"
|
||||||
@ -42,11 +43,19 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef AT_END_OF_LINE
|
#ifndef AT_SEND_EOL
|
||||||
/** End of line character to send after the AT command */
|
/** End of line character to send after the AT command */
|
||||||
#define AT_END_OF_LINE "\r"
|
#define AT_SEND_EOL "\r"
|
||||||
#endif
|
#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
|
* @brief AT device structure
|
||||||
*/
|
*/
|
||||||
@ -55,7 +64,6 @@ typedef struct {
|
|||||||
uart_t uart; /**< UART device where the AT device is attached */
|
uart_t uart; /**< UART device where the AT device is attached */
|
||||||
} at_dev_t;
|
} at_dev_t;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize AT device struct
|
* @brief Initialize AT device struct
|
||||||
*
|
*
|
||||||
@ -71,7 +79,7 @@ typedef struct {
|
|||||||
int at_dev_init(at_dev_t *dev, uart_t uart, uint32_t baudrate, char *buf, size_t bufsize);
|
int at_dev_init(at_dev_t *dev, uart_t uart, uint32_t baudrate, char *buf, size_t bufsize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief simple command helper
|
* @brief Simple command helper
|
||||||
*
|
*
|
||||||
* This function sends an AT command to the device and waits for "OK".
|
* This function sends an AT command to the device and waits for "OK".
|
||||||
*
|
*
|
||||||
@ -85,10 +93,10 @@ int at_dev_init(at_dev_t *dev, uart_t uart, uint32_t baudrate, char *buf, size_t
|
|||||||
int at_send_cmd_wait_ok(at_dev_t *dev, const char *command, uint32_t timeout);
|
int at_send_cmd_wait_ok(at_dev_t *dev, const char *command, uint32_t timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief send AT command, wait for a prompt
|
* @brief Send AT command, wait for a prompt
|
||||||
*
|
*
|
||||||
* This function will send the supplied @p command, then wait for the prompt (>)
|
* This function sends the supplied @p command, then waits for the prompt (>)
|
||||||
* character and return
|
* character and returns
|
||||||
*
|
*
|
||||||
* @param[in] dev device to operate on
|
* @param[in] dev device to operate on
|
||||||
* @param[in] command command string to send
|
* @param[in] command command string to send
|
||||||
@ -100,9 +108,9 @@ int at_send_cmd_wait_ok(at_dev_t *dev, const char *command, uint32_t timeout);
|
|||||||
int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout);
|
int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief send AT command, wait for response
|
* @brief Send AT command, wait for response
|
||||||
*
|
*
|
||||||
* This function will send the supplied @p command, then wait and return one
|
* This function sends the supplied @p command, then waits and returns one
|
||||||
* line of response.
|
* line of response.
|
||||||
*
|
*
|
||||||
* A possible empty line will be skipped.
|
* A possible empty line will be skipped.
|
||||||
@ -113,15 +121,15 @@ int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout
|
|||||||
* @param[in] len len of @p buffer
|
* @param[in] len len of @p buffer
|
||||||
* @param[in] timeout timeout (in usec)
|
* @param[in] timeout timeout (in usec)
|
||||||
*
|
*
|
||||||
* @returns lenght of response on success
|
* @returns length of response on success
|
||||||
* @returns <0 on error
|
* @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);
|
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
|
* @brief Send AT command, wait for multiline response
|
||||||
*
|
*
|
||||||
* This function will send the supplied @p command, then return all response
|
* This function sends the supplied @p command, then returns all response
|
||||||
* lines until the device sends "OK".
|
* lines until the device sends "OK".
|
||||||
*
|
*
|
||||||
* If a line starts with "ERROR" or "+CME ERROR:", or the buffer is full, the
|
* If a line starts with "ERROR" or "+CME ERROR:", or the buffer is full, the
|
||||||
@ -133,7 +141,7 @@ ssize_t at_send_cmd_get_resp(at_dev_t *dev, const char *command, char *resp_buf,
|
|||||||
* @param[in] len len of @p buffer
|
* @param[in] len len of @p buffer
|
||||||
* @param[in] timeout timeout (in usec)
|
* @param[in] timeout timeout (in usec)
|
||||||
*
|
*
|
||||||
* @returns lenght of response on success
|
* @returns length of response on success
|
||||||
* @returns <0 on error
|
* @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);
|
ssize_t at_send_cmd_get_lines(at_dev_t *dev, const char *command, char *resp_buf, size_t len, uint32_t timeout);
|
||||||
@ -142,14 +150,13 @@ ssize_t at_send_cmd_get_lines(at_dev_t *dev, const char *command, char *resp_buf
|
|||||||
* @brief Expect bytes from device
|
* @brief Expect bytes from device
|
||||||
*
|
*
|
||||||
* @param[in] dev device to operate on
|
* @param[in] dev device to operate on
|
||||||
* @param[in] bytes buffer containing bytes to expect
|
* @param[in] bytes buffer containing bytes to expect (NULL-terminated)
|
||||||
* @param[in] len number of bytes to expect
|
|
||||||
* @param[in] timeout timeout (in usec)
|
* @param[in] timeout timeout (in usec)
|
||||||
*
|
*
|
||||||
* @returns 0 on success
|
* @returns 0 on success
|
||||||
* @returns <0 otherwise
|
* @returns <0 otherwise
|
||||||
*/
|
*/
|
||||||
int at_expect_bytes(at_dev_t *dev, const char *bytes, size_t len, uint32_t timeout);
|
int at_expect_bytes(at_dev_t *dev, const char *bytes, uint32_t timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send raw bytes to a device
|
* @brief Send raw bytes to a device
|
||||||
@ -161,7 +168,7 @@ int at_expect_bytes(at_dev_t *dev, const char *bytes, size_t len, uint32_t timeo
|
|||||||
void at_send_bytes(at_dev_t *dev, const char *bytes, size_t len);
|
void at_send_bytes(at_dev_t *dev, const char *bytes, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief send command to device
|
* @brief Send command to device
|
||||||
*
|
*
|
||||||
* @param[in] dev device to operate on
|
* @param[in] dev device to operate on
|
||||||
* @param[in] command command to send
|
* @param[in] command command to send
|
||||||
@ -173,7 +180,7 @@ void at_send_bytes(at_dev_t *dev, const char *bytes, size_t len);
|
|||||||
int at_send_cmd(at_dev_t *dev, const char *command, uint32_t timeout);
|
int at_send_cmd(at_dev_t *dev, const char *command, uint32_t timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief read a line from device
|
* @brief Read a line from device
|
||||||
*
|
*
|
||||||
* @param[in] dev device to operate on
|
* @param[in] dev device to operate on
|
||||||
* @param[in] resp_buf buffer to store line
|
* @param[in] resp_buf buffer to store line
|
||||||
@ -186,7 +193,7 @@ int at_send_cmd(at_dev_t *dev, const char *command, uint32_t timeout);
|
|||||||
ssize_t at_readline(at_dev_t *dev, char *resp_buf, size_t len, uint32_t timeout);
|
ssize_t at_readline(at_dev_t *dev, char *resp_buf, size_t len, uint32_t timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief drain device input buffer
|
* @brief Drain device input buffer
|
||||||
*
|
*
|
||||||
* This function drains any possible bytes waiting in the device's input
|
* This function drains any possible bytes waiting in the device's input
|
||||||
* buffer.
|
* buffer.
|
||||||
@ -200,3 +207,4 @@ void at_drain(at_dev_t *dev);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* AT_H */
|
#endif /* AT_H */
|
||||||
|
/** @} */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user