|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Cellular AT-modem bring-up + query demo over the MikroBUS UART (SCI7). More...
#include <stddef.h>#include <stdint.h>#include "ra8_board_ek_ra8d2.h"#include "ra8_boot_entry.h"#include "ra8_cgc.h"#include "ra8_err.h"#include "ra8_gpio_constants.h"#include "ra8_isr.h"#include "ra8_modem_at.h"#include "ra8_mstp.h"#include "ra8_port_utils.h"#include "ra8_sci.h"#include "ra8_time.h"Go to the source code of this file.
Enumerations | |
| enum | modem_const_t : uint32_t { k_modem_baud = 115200U , k_modem_console_baud = 115200U , k_modem_heartbeat_ms = 500U , k_modem_dec_base = 10U , k_modem_uart_channel = (uint32_t)k_ra8_board_mikrobus_uart_sci_channel } |
| App-wide numeric tunables (typed enum – no magic numbers). More... | |
| enum | modem_timeout_t : uint16_t { k_modem_cmd_timeout_ms = 2000U } |
| Per-command timeout handed to ra8_modem_at (ms). More... | |
| enum | modem_cap_t : uint32_t { k_modem_dec_cap = 10U , k_modem_capture_cap = 64U , k_modem_scan_max = 64U } |
| Small fixed buffer capacities. More... | |
| enum | modem_csq_t : uint8_t { k_modem_csq_min_bars = 5U , k_modem_csq_max = 31U , k_modem_csq_unknown = 99U } |
| CSQ (signal-quality) sentinels: RSSI range 0..31, 99 = unknown. More... | |
| enum | modem_creg_stat_t : uint8_t { k_modem_creg_not_registered = 0U , k_modem_creg_home = 1U , k_modem_creg_searching = 2U , k_modem_creg_denied = 3U , k_modem_creg_unknown = 4U , k_modem_creg_roaming = 5U } |
| +CREG registration-status codes (3GPP 27.007). More... | |
| enum | modem_cgatt_t : uint8_t { k_modem_cgatt_detached = 0U , k_modem_cgatt_attached = 1U } |
| CGATT PS-attach flag values. More... | |
Functions | |
| static bool | modem_creg_registered (uint32_t stat) |
| Is the modem registered on a network (home or roaming)? | |
| static bool | modem_signal_valid (uint32_t rssi) |
| Is a CSQ RSSI reading a known, usable signal? | |
| static bool | modem_step_passed (bool is_cme_probe, ra8_err_t err) |
| Did an AT step return the outcome the app expected? | |
| static bool | modem_run_ok (bool sim_ready, bool signal_ok, bool registered, bool attached, bool cme_ok) |
| Overall run verdict: every probed condition must hold. | |
| static bool | modem_parse_first_uint (const char *line, uint32_t *out) |
| Parse the first unsigned integer after the : in an AT reply line. | |
| static bool | modem_parse_last_uint (const char *line, uint32_t *out) |
| Parse the LAST unsigned integer anywhere in an AT reply line. | |
| static bool | modem_line_contains (const char *line, const char *needle) |
Does line contain the substring needle? | |
| static uint32_t | modem_u32_to_dec (uint32_t value, uint8_t *out) |
| Convert an unsigned 32-bit int into a decimal ASCII string. | |
| static void | modem_tx (const uint8_t *bytes, uint32_t len) |
| Emit a byte run on the J-Link OB VCOM console (SCI8). | |
| static void | modem_emit_kv (const uint8_t *label, uint32_t label_len, uint32_t value) |
| Emit a labelled unsigned integer: <label><value>. | |
| static ra8_err_t | modem_tx_byte (void *ctx, uint8_t byte) |
| static ra8_err_t | modem_rx_byte (void *ctx, uint8_t *out_byte) |
| static uint32_t | modem_now_ms (void *ctx) |
| static void | modem_on_creg_urc (const char *line, void *ctx) |
| URC handler for unsolicited + solicited +CREG lines. | |
| static void | modem_panic_halt (void) |
| Park forever after a fatal error. | |
| static void | modem_clocks_or_halt (uint32_t *out_pclka_hz) |
Bring CGC + SysTick + MSTP up; publish PCLKA via out_pclka_hz. | |
| static void | modem_pfs_or_halt (void) |
| Route the MikroBUS UART pins (TXD7 / RXD7) via PFS. | |
| static void | modem_setup_or_halt (void) |
| Bring CGC + console (SCI8) + modem UART (SCI7) + LEDs up. | |
| static ra8_err_t | modem_bind (uint8_t *line_buf, uint16_t line_buf_len) |
| Bind ra8_modem_at to the SCI7 transport + register the URC handler. | |
| static ra8_err_t | modem_cmd_ok (const char *cmd) |
| Send an AT command and require a bare OK. | |
| static ra8_err_t | modem_query (const char *cmd, char *buf, size_t cap) |
| Send an AT query and capture its response payload. | |
| static void | modem_fail (const uint8_t *step, uint32_t step_len) |
| Print a modem: <step> FAIL banner, latch LED2, and park. | |
| static void | modem_phase_sync (void) |
| Sync phase: probe (AT), disable echo (ATE0), numeric CME errors. | |
| static bool | modem_phase_sim (void) |
| SIM phase: query AT+CPIN? and confirm READY. | |
| static bool | modem_phase_signal (uint32_t *out_rssi) |
| Signal phase: query AT+CSQ and parse + print the RSSI. | |
| static bool | modem_phase_registration (void) |
| Registration phase: enable +CREG URCs, poll one, then query. | |
| static bool | modem_phase_attach (void) |
| Attach phase: query AT+CGATT? and parse + print the flag. | |
| static bool | modem_phase_error (void) |
| Error-path phase: send an unsupported command, expect +CME ERROR. | |
| void | main (void) |
| Application entry: bring up SCI7 + the AT driver, walk the state machine. | |
Variables | |
| static uint8_t | s_creg_stat |
| Latest registration status parsed from a +CREG line. | |
| static bool | s_creg_seen |
| True once at least one +CREG line has been parsed. | |
| static const uint8_t | k_modem_banner_prefix [] = "modem: rssi=" |
| static const uint8_t | k_modem_str_reg [] = " reg=" |
| static const uint8_t | k_modem_str_attach [] = " attach=" |
| static const uint8_t | k_modem_str_cme [] = " cme=" |
| static const uint8_t | k_modem_str_ok [] = "ok" |
| static const uint8_t | k_modem_str_no [] = "no" |
| static const uint8_t | k_modem_str_pass [] = " PASS\r\n" |
| static const uint8_t | k_modem_str_fail [] = " FAIL\r\n" |
Cellular AT-modem bring-up + query demo over the MikroBUS UART (SCI7).
Stand-alone EK-RA8D2 application that drives libs/ra8_modem_at against a 3GPP AT-command cellular modem (SIM7600 / Quectel BG95 class) presented on the MikroBUS UART – RXD7 / TXD7, i.e. SCI channel 7 (k_ra8_board_mikrobus_uart_sci_channel). A MikroE cellular Click (LTE IoT / 4G LTE / NB-IoT) exposes its modem on exactly these MikroBUS pads.
TODO(real modem): the physical RF link + a populated MikroBUS cellular Click with a live SIM are external hardware this repo cannot carry, so the app is hw_pending. ra8_emulator answers the AT script faithfully with the SCI7 modem model (tools/ra8_emulator/src/periph/board_periph_modem.c, --modem), so the app boots and walks its whole state machine 0-skip in EIL (EIL == HIL for the AT protocol; only the antenna is unmodelled).
State machine (each step is one blocking ra8_modem_at command):
On success the app prints (SCI8 console, scraped by ra8_emulator / a HIL rig):
modem: rssi=17 reg=1 attach=1 cme=ok PASS
On any unexpected step failure it prints modem: <step> FAIL, latches LED2 and parks. The compound decisions (registration OK, signal valid, per-step expected outcome, overall verdict) are host-tested with MC/DC in tests/mocks/src/test_app_modem_at_demo.c.
Definition in file main.c.
| enum modem_cap_t : uint32_t |
| enum modem_cgatt_t : uint8_t |
| enum modem_const_t : uint32_t |
| enum modem_creg_stat_t : uint8_t |
+CREG registration-status codes (3GPP 27.007).
| enum modem_csq_t : uint8_t |
| enum modem_timeout_t : uint16_t |
| void main | ( | void | ) |
Application entry: bring up SCI7 + the AT driver, walk the state machine.
The application entry point Reset_Handler hands control to.
Definition at line 891 of file main.c.
References k_modem_capture_cap, k_modem_csq_unknown, k_modem_heartbeat_ms, k_modem_str_cme, k_modem_str_fail, k_modem_str_no, k_modem_str_ok, k_modem_str_pass, k_ra8_board_led1, k_ra8_ok, modem_bind(), modem_fail(), modem_panic_halt(), modem_phase_attach(), modem_phase_error(), modem_phase_registration(), modem_phase_signal(), modem_phase_sim(), modem_phase_sync(), modem_run_ok(), modem_setup_or_halt(), modem_tx(), ra8_board_led_toggle(), ra8_delay_ms(), and ra8_isr_globals_enable().
|
static |
Bind ra8_modem_at to the SCI7 transport + register the URC handler.
| [in] | line_buf | Caller-owned line accumulator for the driver. |
| [in] | line_buf_len | Capacity of line_buf. |
| k_ra8_ok | Bound and the +CREG handler is installed. |
| other | The first non-OK code from init / registration. |
line_buf is non-NULL and line_buf_len >= 16. Definition at line 651 of file main.c.
References k_modem_cmd_timeout_ms, k_ra8_ok, modem_now_ms(), modem_on_creg_urc(), modem_rx_byte(), modem_tx_byte(), ra8_modem_at_init(), and ra8_modem_at_register_unsolicited_handler().
Referenced by main().
|
static |
Bring CGC + SysTick + MSTP up; publish PCLKA via out_pclka_hz.
| [out] | out_pclka_hz | Receives the live PCLKA frequency on success. |
out_pclka_hz is non-NULL. Definition at line 555 of file main.c.
References k_ra8_clock_id_cpuclk0, k_ra8_clock_id_pclka, k_ra8_ok, modem_panic_halt(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), ra8_mstp_init(), and ra8_time_init().
Referenced by modem_setup_or_halt().
|
static |
Send an AT command and require a bare OK.
| [in] | cmd | NUL-terminated AT command (no trailing CR). |
cmd is NUL-terminated. Definition at line 682 of file main.c.
References k_modem_cmd_timeout_ms, and ra8_modem_at_send_cmd().
Referenced by modem_phase_error(), modem_phase_registration(), and modem_phase_sync().
|
static |
Is the modem registered on a network (home or roaming)?
| [in] | stat | A +CREG status code (modem_creg_stat_t value). |
stat is "registered, home" or "registered, roaming". | true | stat == 1 or stat == 5. |
| false | Any other status (not registered / searching / denied / unknown). |
stat is a 3GPP 27.007 +CREG status code. stat.Definition at line 170 of file main.c.
References k_modem_creg_home, and k_modem_creg_roaming.
Referenced by modem_phase_registration().
|
static |
Emit a labelled unsigned integer: <label><value>.
| [in] | label | NUL-terminated label bytes. |
| [in] | label_len | Length of label in bytes. |
| [in] | value | Value to print in decimal. |
label is non-NULL. Definition at line 462 of file main.c.
References k_modem_dec_cap, modem_tx(), and modem_u32_to_dec().
Referenced by modem_phase_attach(), modem_phase_registration(), and modem_phase_signal().
|
static |
Print a modem: <step> FAIL banner, latch LED2, and park.
| [in] | step | NUL-terminated failing-step label. |
| [in] | step_len | Length of step in bytes. |
Definition at line 719 of file main.c.
References k_ra8_board_led2, modem_panic_halt(), modem_tx(), and ra8_board_led_on().
Referenced by main(), modem_phase_attach(), modem_phase_registration(), modem_phase_signal(), modem_phase_sim(), and modem_phase_sync().
|
static |
Does line contain the substring needle?
| [in] | line | NUL-terminated line to search (may be NULL -> false). |
| [in] | needle | NUL-terminated substring (may be NULL -> false). |
needle occurs within line. | true | A match was found. |
| false | No match, or a NULL argument. |
Definition at line 373 of file main.c.
References k_modem_scan_max.
Referenced by modem_phase_sim().
|
static |
|
static |
URC handler for unsolicited + solicited +CREG lines.
Parses the registration status (last integer field) and latches it for the run verdict. Registered with ra8_modem_at_register_unsolicited_handler so both the AT+CREG=1 enable URC and the AT+CREG? reply route here.
| [in] | line | NUL-terminated +CREG ... line (non-NULL from the driver). |
| [in] | ctx | Unused opaque context. |
line is a NUL-terminated modem line beginning with +CREG:. Definition at line 511 of file main.c.
References modem_parse_last_uint(), s_creg_seen, and s_creg_stat.
Referenced by modem_bind().
|
static |
Park forever after a fatal error.
Definition at line 536 of file main.c.
Referenced by main(), modem_clocks_or_halt(), modem_fail(), modem_pfs_or_halt(), and modem_setup_or_halt().
|
static |
Parse the first unsigned integer after the : in an AT reply line.
Used for +CSQ: 17,99 (-> 17) and +CGATT: 1 (-> 1). Every scan loop is bounded by k_modem_scan_max (NASA P10 Rule 2).
| [in] | line | NUL-terminated reply line (may be NULL -> failure). |
| [out] | out | Parsed value on success (may be NULL -> failure). |
| true | out holds the first integer after the colon. |
| false | No colon, no digit, or a NULL argument. |
line is NUL-terminated within k_modem_scan_max bytes. out points to writable storage when non-NULL. out is written only on success. Definition at line 282 of file main.c.
References k_modem_dec_base, and k_modem_scan_max.
Referenced by modem_phase_attach(), and modem_phase_signal().
|
static |
Parse the LAST unsigned integer anywhere in an AT reply line.
The +CREG status is the last field in both forms the modem sends: the URC +CREG: <stat> and the solicited +CREG: <n>,<stat>. Scanning for the last digit run yields stat for both. Bounded by k_modem_scan_max.
| [in] | line | NUL-terminated reply line (may be NULL -> failure). |
| [out] | out | Parsed value on success (may be NULL -> failure). |
| true | out holds the value of the last digit run. |
| false | No digit found, or a NULL argument. |
line is NUL-terminated within k_modem_scan_max bytes. out points to writable storage when non-NULL. out is written only on success. Definition at line 331 of file main.c.
References k_modem_dec_base, and k_modem_scan_max.
Referenced by modem_on_creg_urc().
|
static |
Route the MikroBUS UART pins (TXD7 / RXD7) via PFS.
Definition at line 584 of file main.c.
References k_ra8_board_mikrobus_rx, k_ra8_board_mikrobus_tx, k_ra8_ok, k_ra8_psel_sci_async, modem_panic_halt(), and ra8_pfs_route_peripheral().
Referenced by modem_setup_or_halt().
|
static |
Attach phase: query AT+CGATT? and parse + print the flag.
Definition at line 846 of file main.c.
References k_modem_capture_cap, k_modem_cgatt_attached, k_modem_cgatt_detached, k_modem_str_attach, k_ra8_ok, modem_emit_kv(), modem_fail(), modem_parse_first_uint(), and modem_query().
Referenced by main().
|
static |
Error-path phase: send an unsupported command, expect +CME ERROR.
Definition at line 870 of file main.c.
References modem_cmd_ok(), and modem_step_passed().
Referenced by main().
|
static |
Registration phase: enable +CREG URCs, poll one, then query.
Definition at line 820 of file main.c.
References k_modem_str_reg, k_ra8_ok, modem_cmd_ok(), modem_creg_registered(), modem_emit_kv(), modem_fail(), ra8_modem_at_poll(), s_creg_seen, and s_creg_stat.
Referenced by main().
|
static |
Signal phase: query AT+CSQ and parse + print the RSSI.
| [out] | out_rssi | Receives the parsed RSSI (or 99 if unparsed). |
out_rssi is non-NULL. Definition at line 795 of file main.c.
References k_modem_banner_prefix, k_modem_capture_cap, k_modem_csq_unknown, k_ra8_ok, modem_emit_kv(), modem_fail(), modem_parse_first_uint(), modem_query(), and modem_signal_valid().
Referenced by main().
|
static |
SIM phase: query AT+CPIN? and confirm READY.
| true | SIM is ready. |
| false | SIM not ready (query error path parks via modem_fail). |
Definition at line 773 of file main.c.
References k_modem_capture_cap, k_ra8_ok, modem_fail(), modem_line_contains(), and modem_query().
Referenced by main().
|
static |
Sync phase: probe (AT), disable echo (ATE0), numeric CME errors.
Any non-OK here parks via modem_fail (the modem is absent / dead).
Definition at line 746 of file main.c.
References k_ra8_ok, modem_cmd_ok(), and modem_fail().
Referenced by main().
|
static |
Send an AT query and capture its response payload.
| [in] | cmd | NUL-terminated AT command (no trailing CR). |
| [out] | buf | Capture buffer for the payload lines. |
| [in] | cap | Capacity of buf. |
buf is non-NULL and cap >= 1. buf is NUL-terminated with the captured payload. Definition at line 702 of file main.c.
References k_modem_cmd_timeout_ms, and ra8_modem_at_send_cmd_capture().
Referenced by modem_phase_attach(), modem_phase_signal(), and modem_phase_sim().
|
static |
Overall run verdict: every probed condition must hold.
| [in] | sim_ready | SIM reported +CPIN: READY. |
| [in] | signal_ok | CSQ RSSI was a valid reading. |
| [in] | registered | +CREG status was home or roaming. |
| [in] | attached | CGATT reported attached. |
| [in] | cme_ok | The error-probe step returned the expected CME error. |
| true | Every condition held. |
| false | Any one condition failed. |
Definition at line 252 of file main.c.
Referenced by main().
|
static |
Definition at line 481 of file main.c.
References k_modem_uart_channel, and ra8_sci_getc_polling().
Referenced by modem_bind().
|
static |
Bring CGC + console (SCI8) + modem UART (SCI7) + LEDs up.
Definition at line 607 of file main.c.
References k_modem_baud, k_modem_console_baud, k_modem_uart_channel, k_ra8_board_led1, k_ra8_board_led2, k_ra8_ok, k_ra8_sci_data_8, k_ra8_sci_parity_none, k_ra8_sci_stop_1, modem_clocks_or_halt(), modem_panic_halt(), modem_pfs_or_halt(), ra8_board_led_init(), ra8_board_uart_console_init(), and ra8_sci_init().
Referenced by main().
|
static |
Is a CSQ RSSI reading a known, usable signal?
Two independent conditions: the reading must be a real measurement (not the 99 "unknown" sentinel) AND at least k_modem_csq_min_bars of strength. The two are genuinely independent – 99 (unknown) is above the strength floor, so either can fail alone – which is what makes the compound MC/DC-testable.
| [in] | rssi | A CSQ RSSI index parsed from +CSQ: <rssi>,<ber>. |
rssi is a real reading with usable strength. | true | rssi != 99 and rssi >= k_modem_csq_min_bars. |
| false | rssi == 99 (unknown) or rssi below the usable floor. |
rssi is the first field of a +CSQ response. rssi.Definition at line 197 of file main.c.
References k_modem_csq_min_bars, and k_modem_csq_unknown.
Referenced by modem_phase_signal().
|
static |
Did an AT step return the outcome the app expected?
Every step but the deliberate error probe expects k_ra8_ok. The error probe sends an unsupported command and EXPECTS the modem's +CME ERROR (which the driver surfaces as k_ra8_err_hw_error): for that step a plain OK would actually be a failure. This inverts the pass condition on the probe step, which is the interesting compound decision.
| [in] | is_cme_probe | true for the intentional unsupported-command step. |
| [in] | err | The ra8_modem_at return code for that step. |
err is the expected outcome for the step. | true | (probe and err == hw_error) or (non-probe and err == ok). |
| false | Otherwise. |
err came from a completed ra8_modem_at_send_cmd* call. is_cme_probe and err.Definition at line 226 of file main.c.
References k_ra8_err_hw_error, and k_ra8_ok.
Referenced by modem_phase_error().
|
static |
Emit a byte run on the J-Link OB VCOM console (SCI8).
| [in] | bytes | Byte array to transmit (non-NULL when len > 0). |
| [in] | len | Number of bytes. |
bytes is non-NULL when len > 0. len bytes have been handed to SCI8. Definition at line 443 of file main.c.
References ra8_board_uart_console_write().
Referenced by main(), modem_emit_kv(), and modem_fail().
|
static |
Definition at line 475 of file main.c.
References k_modem_uart_channel, and ra8_sci_putc_polling().
Referenced by modem_bind().
|
static |
Convert an unsigned 32-bit int into a decimal ASCII string.
| [in] | value | Integer to convert. |
| [out] | out | Destination buffer (>= k_modem_dec_cap bytes). |
out is non-NULL and >= k_modem_dec_cap bytes. out holds the decimal digits, most-significant first. out buffer. Definition at line 410 of file main.c.
References k_modem_dec_base, and k_modem_dec_cap.
Referenced by modem_emit_kv().
|
static |
Definition at line 140 of file main.c.
Referenced by modem_phase_signal().
|
static |
Definition at line 142 of file main.c.
Referenced by modem_phase_attach().
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
Definition at line 141 of file main.c.
Referenced by modem_phase_registration().
|
static |
True once at least one +CREG line has been parsed.
Definition at line 135 of file main.c.
Referenced by modem_on_creg_urc(), and modem_phase_registration().
|
static |
Latest registration status parsed from a +CREG line.
Definition at line 126 of file main.c.
Referenced by modem_on_creg_urc(), and modem_phase_registration().