ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_modem_at.h File Reference

Cellular modem AT command/response driver layered on UART. More...

#include <stddef.h>
#include <stdint.h>
#include "ra8_err.h"
Include dependency graph for ra8_modem_at.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_modem_at_io_t
 Byte-level transport injected into the AT driver (DIP). More...
struct  ra8_modem_at_cfg_t
 Configuration handed to ra8_modem_at_init. More...

Typedefs

typedef void(* ra8_modem_at_urc_fn_t) (const char *line, void *ctx)
 Unsolicited result-code (URC) handler signature.

Enumerations

enum  ra8_modem_at_limits_t : uint8_t {
  k_ra8_modem_at_max_unsolicited = 8U ,
  k_ra8_modem_at_max_prefix_len
}
 Compile-time tunables. More...
enum  ra8_modem_at_timeouts_t : uint16_t { k_ra8_modem_at_default_timeout_ms = 1000U }
 Default per-command timeout when caller passes 0 ms. More...

Functions

ra8_err_t ra8_modem_at_init (const ra8_modem_at_cfg_t *cfg)
 Bind transport, buffer and timeout policy.
ra8_err_t ra8_modem_at_send_cmd (const char *cmd, const char *expected_response, uint16_t timeout_ms)
 Send an AT command and wait for OK/ERROR/expected.
ra8_err_t ra8_modem_at_send_cmd_capture (const char *cmd, char *out_buf, size_t buf_len, uint16_t timeout_ms)
 Send an AT command and capture the response payload.
ra8_err_t ra8_modem_at_register_unsolicited_handler (const char *prefix, ra8_modem_at_urc_fn_t fn, void *ctx)
 Register a URC (unsolicited result code) handler.
ra8_err_t ra8_modem_at_poll (void)
 Pump the RX path without sending a command.

Detailed Description

Cellular modem AT command/response driver layered on UART.

Tag
[Ring 4 / PAL] {World: NS}

Tiny AT-command transport for SIM7600 / Quectel BG95 / similar 3GPP modems. Sits on top of a UART-like byte transport and provides:

  • ra8_modem_at_init: bind a byte transport, response buffer, and default per-command timeout configuration.
  • ra8_modem_at_send_cmd: write an AT command terminated with "\r" and block until the modem replies with OK, ERROR or a caller-specified expected prefix.
  • ra8_modem_at_send_cmd_capture: same as send_cmd but copy any response payload lines (everything between echo and final result code) into a caller buffer.
  • ra8_modem_at_register_unsolicited_handler: register a callback for unsolicited result codes (URCs) such as +CMTI: (SMS arrival) or +CREG: (network registration change). The driver scans every received line; lines that do not belong to a pending command are dispatched to the matching handler.

State machine

The line accumulator runs as:

Lines are accumulated byte-by-byte from the byte transport. CR/LF pairs split the stream into discrete lines. Each line is either

  • the command echo (silently dropped),
  • a final result code (OK, ERROR, +CME ERROR: ...),
  • the caller-specified expected_response prefix, or
  • a URC (dispatched if a registered prefix matches).

Anything else is treated as response payload and (optionally) captured into the user buffer.

Memory

NASA Power-of-10 Rule 3 compliant – zero dynamic allocation. The line accumulator buffer is owned by the caller and passed in via ra8_modem_at_cfg_t. Unsolicited-handler slots live in a fixed-size table inside the module.

Definition in file ra8_modem_at.h.

Typedef Documentation

◆ ra8_modem_at_urc_fn_t

typedef void(* ra8_modem_at_urc_fn_t) (const char *line, void *ctx)

Unsolicited result-code (URC) handler signature.

Parameters
[in]lineNUL-terminated full line received from the modem (e.g. "+CMTI: \"SM\\",3\").
[in]ctxOpaque pointer registered with the handler.

Definition at line 168 of file ra8_modem_at.h.

Enumeration Type Documentation

◆ ra8_modem_at_limits_t

enum ra8_modem_at_limits_t : uint8_t

Compile-time tunables.

All limits are typed C23 enums so the compiler picks an exact width and the values appear by name in the debugger.

Enumerator
k_ra8_modem_at_max_unsolicited 

Maximum number of registered URC handlers.

k_ra8_modem_at_max_prefix_len 

Maximum bytes of a URC prefix (including + and :).

Definition at line 81 of file ra8_modem_at.h.

◆ ra8_modem_at_timeouts_t

enum ra8_modem_at_timeouts_t : uint16_t

Default per-command timeout when caller passes 0 ms.

Enumerator
k_ra8_modem_at_default_timeout_ms 

RA8 modem at default timeout ms.

Definition at line 90 of file ra8_modem_at.h.

Function Documentation

◆ ra8_modem_at_init()

ra8_err_t ra8_modem_at_init ( const ra8_modem_at_cfg_t * cfg)
nodiscard

Bind transport, buffer and timeout policy.

Resets all internal state and copies cfg into module-static storage. Must be called once before any other API. Re-calling is legal – previous URC handlers are cleared.

Parameters
[in]cfgPointer to a fully populated configuration.
Returns
ra8_err_t error code.
Return values
k_ra8_okInitialized successfully.
k_ra8_err_null_ptrcfg, cfg->line_buf or any IO function pointer is NULL.
k_ra8_err_invalid_sizeline_buf_len smaller than 16.
Precondition
cfg != NULL.
All members of cfg->io non-NULL.
Postcondition
Internal state reset to k_ra8_modem_at_state_idle.
URC table empty.
Note
Not thread-safe; the AT driver assumes a single owner.
Example:
static uint8_t s_at_line[256];
.io = {
.tx_byte = my_uart_tx, .rx_byte = my_uart_rx, .now_ms = my_now,
.ctx = (void*)1U,
},
.line_buf = s_at_line,
.line_buf_len = sizeof s_at_line,
.default_timeout_ms = 2000U,
};
(void)ra8_modem_at_init(&cfg);
ra8_err_t ra8_modem_at_init(const ra8_modem_at_cfg_t *cfg)
Bind transport, buffer and timeout policy.
Configuration handed to ra8_modem_at_init.
See also
ra8_modem_at_send_cmd()
ra8_modem_at_register_unsolicited_handler()
Since
0.1.0

Definition at line 821 of file ra8_modem_at.c.

References internal_clear_urc_table(), internal_reset_line(), internal_validate_init_cfg(), k_ra8_modem_at_state_idle, k_ra8_ok, and s_mod.

Referenced by modem_bind().

◆ ra8_modem_at_poll()

ra8_err_t ra8_modem_at_poll ( void )
nodiscard

Pump the RX path without sending a command.

Drains any queued bytes, dispatches URC handlers, and returns. Useful when the application is otherwise idle but wants to service unsolicited modem traffic. Does not block beyond a single drain pass.

Returns
ra8_err_t error code.
Return values
k_ra8_okDrain completed.
k_ra8_err_not_initializedModule not initialized.
Precondition
ra8_modem_at_init returned k_ra8_ok.
Postcondition
RX FIFO drained for the current call.
Since
0.1.0

Definition at line 974 of file ra8_modem_at.c.

References internal_accumulate(), k_ra8_err_not_initialized, k_ra8_ok, priv_modem_classify(), and s_mod.

Referenced by modem_phase_registration().

◆ ra8_modem_at_register_unsolicited_handler()

ra8_err_t ra8_modem_at_register_unsolicited_handler ( const char * prefix,
ra8_modem_at_urc_fn_t fn,
void * ctx )
nodiscard

Register a URC (unsolicited result code) handler.

Whenever the line accumulator emits a complete line that starts with prefix and the driver is not currently expecting that prefix as a command response, fn(line, ctx) is invoked. Registration order is preserved, but only one handler per distinct prefix is permitted – duplicate registration replaces the previous handler.

Parameters
[in]prefixNUL-terminated prefix string (e.g. "+CMTI:"). Must be shorter than k_ra8_modem_at_max_prefix_len.
[in]fnHandler function (must be non-NULL).
[in]ctxOpaque pointer passed to fn on every match.
Returns
ra8_err_t error code.
Return values
k_ra8_okHandler installed (or replaced).
k_ra8_err_null_ptrprefix or fn NULL.
k_ra8_err_invalid_sizeprefix too long or empty.
k_ra8_err_no_memHandler table full.
k_ra8_err_not_initializedModule not initialized.
Precondition
ra8_modem_at_init returned k_ra8_ok.
Postcondition
Future matching lines invoke fn exactly once each.
Note
Not thread-safe with concurrent ra8_modem_at_send_cmd.
Since
0.1.0

Definition at line 952 of file ra8_modem_at.c.

References internal_urc_insert(), internal_urc_replace(), k_ra8_err_invalid_size, k_ra8_err_no_mem, k_ra8_err_not_initialized, k_ra8_modem_at_max_prefix_len, k_ra8_ok, priv_modem_str_len(), RA8_CHECK_NULL_PTR, RA8_MODEM_AT_TAG, and s_mod.

Referenced by modem_bind().

◆ ra8_modem_at_send_cmd()

ra8_err_t ra8_modem_at_send_cmd ( const char * cmd,
const char * expected_response,
uint16_t timeout_ms )
nodiscard

Send an AT command and wait for OK/ERROR/expected.

Writes cmd followed by "\r" byte-by-byte through io.tx_byte, then drives the line accumulator until either:

  • the final result code OK arrives -> k_ra8_ok,
  • the final result code ERROR (or +CME ERROR:, +CMS ERROR:) arrives -> k_ra8_err_hw_error,
  • a line beginning with expected_response arrives (also counts as success and the function continues to drain until OK) -> k_ra8_ok,
  • timeout_ms (or the configured default if 0) elapses -> k_ra8_err_hw_timeout.
Parameters
[in]cmdNUL-terminated AT command without the trailing "\r".
[in]expected_responseOptional NUL-terminated prefix to wait for (e.g. "+CSQ:"). May be NULL when only OK matters.
[in]timeout_msPer-command timeout in ms. 0 selects the configured default.
Returns
ra8_err_t error code.
Return values
k_ra8_okFinal OK (and expected, if set) seen.
k_ra8_err_null_ptrcmd was NULL.
k_ra8_err_not_initializedra8_modem_at_init not yet called.
k_ra8_err_hw_errorModem replied ERROR/+CME ERROR.
k_ra8_err_hw_timeoutNo final result code in time.
Precondition
ra8_modem_at_init returned k_ra8_ok.
cmd NUL-terminated and shorter than line_buf_len.
Postcondition
Driver returned to k_ra8_modem_at_state_idle.
Line accumulator is empty.
Note
Blocking. URC handlers are invoked inline while waiting.
Warning
Not re-entrant.
See also
ra8_modem_at_send_cmd_capture()
Since
0.1.0

Definition at line 836 of file ra8_modem_at.c.

References internal_effective_timeout(), internal_reset_line(), internal_tx_command(), internal_wait_response(), k_ra8_err_not_initialized, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_MODEM_AT_TAG, and s_mod.

Referenced by modem_cmd_ok().

◆ ra8_modem_at_send_cmd_capture()

ra8_err_t ra8_modem_at_send_cmd_capture ( const char * cmd,
char * out_buf,
size_t buf_len,
uint16_t timeout_ms )
nodiscard

Send an AT command and capture the response payload.

Identical wait policy to ra8_modem_at_send_cmd but every non-echo, non-final-result, non-URC line is appended to out_buf with '\n' separators. Truncation past buf_len - 1 bytes is silent; the buffer is always NUL-terminated.

Parameters
[in]cmdNUL-terminated AT command (no trailing CR).
[out]out_bufCaller buffer for captured payload.
[in]buf_lenBytes in out_buf (>= 1).
[in]timeout_msPer-command timeout in ms (0 -> default).
Returns
ra8_err_t error code.
Return values
k_ra8_okCommand finished with OK.
k_ra8_err_null_ptrcmd or out_buf NULL.
k_ra8_err_invalid_sizebuf_len is 0.
k_ra8_err_not_initializedra8_modem_at_init not called.
k_ra8_err_hw_errorModem replied ERROR.
k_ra8_err_hw_timeoutNo final result code in time.
Precondition
out_buf points to writable storage of buf_len bytes.
Postcondition
out_buf is NUL-terminated.
Note
Blocking. Response payload is line-separated with '\n'.
See also
ra8_modem_at_send_cmd()
Since
0.1.0

Definition at line 856 of file ra8_modem_at.c.

References internal_effective_timeout(), internal_reset_line(), internal_tx_command(), internal_wait_response(), k_ra8_err_invalid_size, k_ra8_err_not_initialized, k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_MODEM_AT_TAG, and s_mod.

Referenced by modem_query().