ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
board_periph_modem.c
Go to the documentation of this file.
1
30
31#include "board_periph_modem.h"
32
33#include <stdint.h>
34#include <stdio.h>
35#include <string.h>
36
38
43typedef enum : uint32_t {
47 k_modem_cr = 13U,
48 k_modem_lf = 10U,
50
55typedef struct {
56 const char* cmd;
57 const char* resp;
59
71 {"AT", "\r\nOK\r\n"},
72 {"ATE0", "\r\nOK\r\n"},
73 {"AT+CMEE=1", "\r\nOK\r\n"},
74 {"AT+CPIN?", "\r\n+CPIN: READY\r\n\r\nOK\r\n"},
75 {"AT+CSQ", "\r\n+CSQ: 17,99\r\n\r\nOK\r\n"},
76 {"AT+CREG=1", "\r\nOK\r\n\r\n+CREG: 1\r\n"},
77 {"AT+CREG?", "\r\n+CREG: 1,1\r\n\r\nOK\r\n"},
78 {"AT+CGATT?", "\r\n+CGATT: 1\r\n\r\nOK\r\n"},
79};
80
82static const char s_k_modem_cme_error[] = "\r\n+CME ERROR: 4\r\n";
83
88typedef struct {
89 bool attached;
91 uint32_t cmd_len;
92 uint32_t answered;
93 uint32_t errors;
95
98
113RA8_INTERNAL static uint32_t internal_modem_emit(const char* resp, uint8_t* out, uint32_t out_cap)
114{
115 uint32_t n = 0U;
116 while ((n < out_cap) && (resp[n] != '\0')) {
117 out[n] = (uint8_t)resp[n];
118 n++;
119 }
120 return n;
121}
122
136RA8_INTERNAL static uint32_t internal_modem_answer_line(uint8_t* out, uint32_t out_cap)
137{
138 s_modem.cmd[s_modem.cmd_len] = '\0';
139 const uint32_t count = (uint32_t)(sizeof(s_k_modem_script) / sizeof(s_k_modem_script[0]));
140 for (uint32_t i = 0U; i < count; i++) {
141 if (strcmp(s_modem.cmd, s_k_modem_script[i].cmd) == 0) {
142 s_modem.answered++;
143 return internal_modem_emit(s_k_modem_script[i].resp, out, out_cap);
144 }
145 }
146 s_modem.errors++;
147 return internal_modem_emit(s_k_modem_cme_error, out, out_cap);
148}
149
151{
152 s_modem.attached = true;
154 return true;
155}
156
158{
159 return s_modem.attached;
160}
161
163{
164 return (uint8_t)k_modem_channel;
165}
166
167uint32_t board_modem_feed_tx(uint8_t tx, uint8_t* out, uint32_t out_cap)
168{
169 if ((out == nullptr) || (out_cap == 0U)) {
170 return 0U;
171 }
172 if (tx == (uint8_t)k_modem_lf) {
173 return 0U; /* modems terminate on CR; LF (if any) is not a delimiter */
174 }
175 if (tx == (uint8_t)k_modem_cr) {
176 const uint32_t n = internal_modem_answer_line(out, out_cap);
177 s_modem.cmd_len = 0U;
178 return n;
179 }
180 if (s_modem.cmd_len < (uint32_t)(k_modem_cmd_cap - 1U)) {
181 s_modem.cmd[s_modem.cmd_len] = (char)tx;
182 s_modem.cmd_len++;
183 }
184 return 0U;
185}
186
188{
189 s_modem.cmd_len = 0U;
190 s_modem.cmd[0] = '\0';
191}
192
194{
195 if (!s_modem.attached) {
196 return;
197 }
198 if ((s_modem.answered == 0U) && (s_modem.errors == 0U)) {
199 return;
200 }
201 (void)priv_emu_io_errf(" AT modem : %u command(s) answered, %u +CME ERROR\n",
202 s_modem.answered,
203 s_modem.errors);
204}
void board_modem_reset(void)
Clear the modem's parser state (keeps the attached flag).
static RA8_INTERNAL uint32_t internal_modem_emit(const char *resp, uint8_t *out, uint32_t out_cap)
Copy a NUL-terminated response into out, bounded by out_cap.
uint8_t board_modem_channel(void)
SCI channel the modem is wired to (RXD7 / TXD7 = SCI7).
static RA8_INTERNAL uint32_t internal_modem_answer_line(uint8_t *out, uint32_t out_cap)
Answer the completed command line in s_modem.cmd.
uint32_t board_modem_feed_tx(uint8_t tx, uint8_t *out, uint32_t out_cap)
Feed one firmware-transmitted byte into the modem and drain a reply.
bool board_modem_attached(void)
Report whether the AT modem model is currently attached.
static const char s_k_modem_cme_error[]
Response for a command not present in s_k_modem_script.
modem_geom_t
Sizing constants for the modem line model (no magic numbers).
@ k_modem_cr
Carriage return (line terminator).
@ k_modem_resp_cap
Longest scripted response.
@ k_modem_lf
Line feed (dropped from the line).
@ k_modem_cmd_cap
Longest AT command line accepted.
@ k_modem_channel
RXD7/TXD7 = SCI7 (MikroBUS UART).
static modem_model_t s_modem
The single modelled modem.
static const modem_reply_t s_k_modem_script[]
The AT script the modelled modem answers.
void board_modem_report(void)
Print a one-line end-of-run summary if the modem was exercised.
bool board_modem_attach(void)
Attach (arm) the modelled AT cellular modem.
Cellular AT-modem device model for ra8_emulator (attached to SCI7 UART).
Bounded raw-descriptor I/O seam for the RA8 emulator.
emu_io_result_t priv_emu_io_errf(const char *format,...)
Format bounded text and write it to the injected error descriptor.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
int strcmp(const char *s1, const char *s2)
Compare two null-terminated strings.
The modelled modem's whole state.
char cmd[k_modem_cmd_cap]
Command-line accumulator.
bool attached
–modem armed the modem.
uint32_t cmd_len
Bytes buffered in cmd.
uint32_t answered
Commands answered OK/URC.
uint32_t errors
Commands answered +CME ERROR.
One scripted (command -> response) pair.
const char * resp
Bytes the modem returns (CRLF-framed).
const char * cmd
AT command WITHOUT the trailing CR.