ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
c6_xfer.c
Go to the documentation of this file.
1
20
21#include <stdint.h>
22
23#include "c6_probe.h"
24#include "ra8_board_ek_ra8d2.h"
25#include "ra8_err.h"
26#include "ra8_port_utils.h"
27#include "ra8_sci_spi.h"
28#include "ra8_spi.h"
29#include "ra8_time.h"
30
41
51
71static void internal_fill_idle_tx(void)
72{
73 for (uint16_t i = 0U; i < (uint16_t)k_c6_proto_buf_size; i++) {
74 s_c6_tx[i] = 0U;
75 s_c6_rx[i] = 0U;
76 }
78}
79
98
125static bool internal_sample_ready(const c6_sideband_sample_t* s, uint8_t hs_idx)
126{
127 if (s == nullptr) {
128 return false;
129 }
130 if (hs_idx < (uint8_t)k_c6_sb_count) {
131 return s->level[hs_idx] != 0U;
132 }
133 for (uint8_t i = 0U; i < (uint8_t)k_c6_sb_count; i++) {
134 if (s->level[i] != 0U) {
135 return true;
136 }
137 }
138 return false;
139}
140
159static bool internal_wait_ready(uint8_t hs_idx)
160{
161 for (uint8_t poll = 0U; poll < (uint8_t)k_c6_probe_hs_poll_max; poll++) {
164 if (internal_sample_ready(&s, hs_idx)) {
165 return true;
166 }
168 }
169 return false;
170}
171
192static ra8_err_t
194{
195 if (pre == nullptr || mid == nullptr || post == nullptr) {
196 return k_ra8_err_null_ptr;
197 }
198 const uint8_t channel = (uint8_t)k_ra8_board_pmod1_sci_channel;
200
205 if (err == k_ra8_ok) {
206 err =
207 ra8_sci_spi_xfer(channel,
210 (uint32_t)((uint16_t)k_c6_proto_buf_size - (uint16_t)k_c6_proto_hdr_size));
211 }
215 return err;
216}
217
245{
246 if (st == nullptr) {
247 return k_c6_frame_garbage;
248 }
249 c6_hdr_t hdr = {};
252 const c6_frame_kind_t kind = c6_probe_classify(&hdr);
253 if (kind == k_c6_frame_idle) {
254 st->idle_frames++;
255 c6_probe_puts(" frame: idle filler from the C6\r\n");
256 } else if (kind == k_c6_frame_data) {
257 st->data_frames++;
258 c6_probe_puts(" frame: data, checksum ok\r\n");
260 } else if (kind == k_c6_frame_bad_csum) {
261 st->bad_csum_frames++;
262 c6_probe_puts(" frame: header sane, checksum mismatch\r\n");
264 } else {
265 c6_probe_puts(" frame: no esp-hosted structure\r\n");
266 }
267 return kind;
268}
269
292static c6_frame_kind_t internal_one_xfer(uint32_t index, uint8_t hs_idx, c6_probe_stats_t* st)
293{
294 if (st == nullptr) {
295 return k_c6_frame_garbage;
296 }
297 c6_probe_puts(" xfer ");
298 c6_probe_put_u32(index);
299 c6_probe_puts("\r\n");
300 if (!internal_wait_ready(hs_idx)) {
301 c6_probe_puts(" skipped: no side-band pin asserted\r\n");
302 return k_c6_frame_garbage;
303 }
304
305 c6_sideband_sample_t pre = {};
306 c6_sideband_sample_t mid = {};
307 c6_sideband_sample_t post = {};
308 const ra8_err_t err = internal_transfer(&pre, &mid, &post);
309 st->attempts++;
310 c6_probe_print_sideband(" pre ", &pre);
311 c6_probe_print_sideband(" mid ", &mid);
312 c6_probe_print_sideband(" post", &post);
313 c6_probe_vote(&pre, &mid, &post, st);
314 if (err != k_ra8_ok) {
315 c6_probe_puts(" spi transfer error\r\n");
316 return k_c6_frame_garbage;
317 }
318
319 return internal_report_frame(st);
320}
321
323{
326 "c6probe.sck");
327 if (err != k_ra8_ok) {
328 return err;
329 }
332 "c6probe.cipo");
333 if (err != k_ra8_ok) {
334 return err;
335 }
338 "c6probe.copi");
339 if (err != k_ra8_ok) {
340 return err;
341 }
343}
344
346 uint32_t pclka_hz,
348 uint8_t* hs_idx)
349{
350 if (st == nullptr || hs_idx == nullptr) {
351 return false;
352 }
353 const ra8_sci_spi_cfg_t cfg = {
354 .baud_hz = (uint32_t)k_c6_probe_sck_hz,
355 .pclk_hz = pclka_hz,
356 .mode = mode,
357 .lsb_first = false,
358 };
359 c6_probe_puts("c6_probe: spi mode=");
360 c6_probe_put_u32((uint32_t)mode);
361 c6_probe_puts(" sck_hz=");
363 c6_probe_puts("\r\n");
365 c6_probe_puts("c6_probe: sci spi init failed\r\n");
366 return false;
367 }
368
369 bool decoded = false;
370 for (uint8_t i = 0U; i < (uint8_t)k_c6_probe_xfer_per_mode; i++) {
371 const c6_frame_kind_t kind = internal_one_xfer((uint32_t)i + 1U, *hs_idx, st);
372 if (kind == k_c6_frame_idle || kind == k_c6_frame_data) {
373 decoded = true;
374 }
375 *hs_idx = c6_probe_best(st->hs_vote, (uint8_t)k_c6_sb_count, (uint32_t)k_c6_probe_min_votes);
377 }
379 return decoded;
380}
Shared contract for the EK-RA8D2 <-> ESP32-C6 esp-hosted SPI probe.
@ k_c6_sb_count
Side-band pin count.
Definition c6_probe.h:177
void c6_probe_vote(const c6_sideband_sample_t *pre, const c6_sideband_sample_t *mid, const c6_sideband_sample_t *post, c6_probe_stats_t *st)
Fold one transaction's three samples into the classification votes.
@ k_c6_probe_gap_ms
Gap between transactions.
Definition c6_probe.h:75
@ k_c6_probe_settle_ms
Post-transfer side-band settle.
Definition c6_probe.h:74
@ k_c6_probe_sck_hz
Conservative first-light SCK rate.
Definition c6_probe.h:72
@ k_c6_probe_cs_hold_ms
Chip-select setup / hold.
Definition c6_probe.h:76
void c6_probe_puts(const char *text)
Emit a bounded, NUL-terminated ASCII literal on the console.
Definition c6_console.c:25
void c6_probe_put_u32(uint32_t value)
Emit an unsigned integer in decimal.
Definition c6_console.c:38
void c6_probe_sample_sideband(c6_sideband_sample_t *out)
Read every Pmod1 side-band pin into one sample.
void c6_probe_print_sideband(const char *label, const c6_sideband_sample_t *s)
Print a labelled side-band sample as label P006=1 P402=0 ....
@ k_c6_probe_hs_poll_ms
Delay between handshake polls.
Definition c6_probe.h:109
@ k_c6_probe_min_votes
Votes required to claim a mapping.
Definition c6_probe.h:114
@ k_c6_probe_xfer_per_mode
Transactions attempted per SPI mode.
Definition c6_probe.h:106
@ k_c6_probe_hs_poll_max
Handshake polls before giving up.
Definition c6_probe.h:108
uint8_t c6_probe_best(const uint32_t *votes, uint8_t ignore, uint32_t min_votes)
Pick the side-band pin that won the vote outright, or report none.
void c6_probe_decode_header(const uint8_t *buf, c6_hdr_t *out)
Unpack the twelve-byte esp-hosted payload header.
Definition c6_frame.c:72
void c6_probe_print_header(const c6_hdr_t *h)
Print the decoded header fields on one console line.
Definition c6_frame.c:116
@ k_c6_hdr_off_iface
if_type[3:0] | if_num[7:4].
Definition c6_proto.h:96
void c6_probe_dump_payload(const uint8_t *buf, uint16_t len)
Hex-dump the leading payload bytes of a received frame.
Definition c6_frame.c:142
@ k_c6_proto_buf_size
Bytes clocked per transaction.
Definition c6_proto.h:68
@ k_c6_proto_hdr_size
sizeof(struct esp_payload_header).
Definition c6_proto.h:69
c6_frame_kind_t
Classification of one received 1600-byte transaction.
Definition c6_proto.h:224
@ k_c6_frame_data
Real frame, checksum verified.
Definition c6_proto.h:227
@ k_c6_frame_bad_csum
Header shape sane, checksum mismatched.
Definition c6_proto.h:228
@ k_c6_frame_garbage
No recognisable esp-hosted structure.
Definition c6_proto.h:225
@ k_c6_frame_idle
The C6's idle filler frame.
Definition c6_proto.h:226
c6_frame_kind_t c6_probe_classify(const c6_hdr_t *h)
Judge a decoded header against the upstream receive rules.
Definition c6_frame.c:95
@ k_c6_if_max
Idle filler marker.
Definition c6_proto.h:139
ra8_err_t c6_probe_spi_pins_init(void)
Route the Pmod1 SPI pins to SCI2 and own the chip-select as GPIO.
Definition c6_xfer.c:322
static void internal_fill_idle_tx(void)
Stamp the transmit buffer as an esp-hosted idle host frame.
Definition c6_xfer.c:71
static void internal_cs(ra8_level_t level)
Drive the chip-select and let the line settle.
Definition c6_xfer.c:93
static bool internal_sample_ready(const c6_sideband_sample_t *s, uint8_t hs_idx)
Decide whether one side-band sample says the C6 is ready.
Definition c6_xfer.c:125
static c6_frame_kind_t internal_report_frame(c6_probe_stats_t *st)
Decode, classify, tally and narrate the frame in the receive buffer.
Definition c6_xfer.c:244
bool c6_probe_sweep_mode(ra8_spi_mode_t mode, uint32_t pclka_hz, c6_probe_stats_t *st, uint8_t *hs_idx)
Run the transaction burst for one SPI mode.
Definition c6_xfer.c:345
static c6_frame_kind_t internal_one_xfer(uint32_t index, uint8_t hs_idx, c6_probe_stats_t *st)
Clock one transaction and report everything it revealed.
Definition c6_xfer.c:292
static ra8_err_t internal_transfer(c6_sideband_sample_t *pre, c6_sideband_sample_t *mid, c6_sideband_sample_t *post)
Clock one full esp-hosted transaction, sampling the side-band pins.
Definition c6_xfer.c:193
static uint8_t s_c6_tx[k_c6_proto_buf_size]
Transmit buffer: one full esp-hosted SPI transaction.
Definition c6_xfer.c:40
static bool internal_wait_ready(uint8_t hs_idx)
Wait, with a bounded poll, for the peripheral-ready condition.
Definition c6_xfer.c:159
static uint8_t s_c6_rx[k_c6_proto_buf_size]
Receive buffer: one full esp-hosted SPI transaction.
Definition c6_xfer.c:50
Board-support layer for the Renesas EK-RA8D2 v1 evaluation kit.
@ k_ra8_board_pmod1_sci_channel
Pmod1 (J26) Simple-SPI is SCI2.
@ k_ra8_board_pmod1_spi_copi
Pmod1.2 COPI (MOSI2/TXD2 per UM),P801.
@ k_ra8_board_pmod1_spi_sck
Pmod1.4 SCK (SCK2), P803.
@ k_ra8_board_pmod1_spi_cs
Pmod1.1 CS (SS2/IRQ14), P804.
@ k_ra8_board_pmod1_spi_cipo
Pmod1.3 CIPO (MISO2/RXD2 per UM),P802.
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
@ k_ra8_psel_sci_async
00100b: SCI async serial (UART).
ra8_port_pin_t
Packed (port << 8) | pin pin identifier.
ra8_level_t
Digital output / input level.
@ k_ra8_level_high
Drive or read 1.
@ k_ra8_level_low
Drive or read 0.
High-level GPIO helpers on top of the PORT + PFS register layer.
ra8_err_t ra8_gpio_output_init(ra8_port_pin_t pin, ra8_level_t init_level)
Configure a pin as a digital output and drive it to an initial level.
Definition gpio.c:88
ra8_err_t ra8_gpio_write(ra8_port_pin_t pin, ra8_level_t level)
Drive a previously-configured output to the given level.
Definition gpio.c:154
ra8_err_t ra8_pfs_route_peripheral(ra8_port_pin_t pin, ra8_psel_t psel, const char *owner)
Route a pin to a non-IRQ peripheral function via PFS.PSEL.
Definition gpio.c:238
SCI Simple-SPI controller-mode driver (polling, full-duplex).
ra8_err_t ra8_sci_spi_xfer(uint8_t channel, const uint8_t *tx, uint8_t *rx, uint32_t len)
Full-duplex multi-byte transfer.
ra8_err_t ra8_sci_spi_init(uint8_t channel, const ra8_sci_spi_cfg_t *cfg)
Bring an SCI channel up as a Simple-SPI controller.
ra8_err_t ra8_sci_spi_deinit(uint8_t channel)
Disable the channel and release its MSTP gate.
SPI_B controller driver (RA8D2 Type-B SPI peripheral).
ra8_spi_mode_t
CPOL / CPHA combinations.
Definition ra8_spi.h:61
SysTick-based tick counter, delay and timestamp helpers.
void ra8_delay_ms(uint32_t ms)
Busy-wait for at least ms milliseconds.
Definition ra8_time.c:129
Decoded esp-hosted payload header plus the locally recomputed sum.
Definition c6_proto.h:246
uint16_t len
Payload length claimed by the sender.
Definition c6_proto.h:250
Running evidence gathered across every transaction.
Definition c6_probe.h:280
uint32_t hs_vote[k_c6_sb_count]
Pin dropped while CS was asserted.
Definition c6_probe.h:285
uint32_t attempts
Transactions clocked.
Definition c6_probe.h:281
uint32_t idle_frames
Idle filler frames decoded.
Definition c6_probe.h:282
uint32_t data_frames
Real frames with a good checksum.
Definition c6_probe.h:283
uint32_t bad_csum_frames
Sane shape, checksum mismatched.
Definition c6_probe.h:284
One simultaneous reading of every side-band pin.
Definition c6_probe.h:194
uint8_t level[k_c6_sb_count]
Per-pin logic level (0 or 1).
Definition c6_probe.h:195
Configuration descriptor for ra8_sci_spi_init.
Definition ra8_sci_spi.h:49