ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_net_pal.c
Go to the documentation of this file.
1
18
19#include "ra8_net_pal.h"
20
21#include <stdint.h>
22
23#include "ra8_attributes.h"
24#include "ra8_check.h"
25#include "ra8_err.h"
26#include "ra8_eth.h"
27#include "ra8_log.h"
28
51static void internal_copy_bytes(uint8_t* dst, const uint8_t* src, uint16_t len)
52{
53 for (uint16_t i = 0U; i < len; ++i) {
54 dst[i] = src[i];
55 }
56}
57
77static void internal_zero_bytes(uint8_t* dst, uint16_t len)
78{
79 for (uint16_t i = 0U; i < len; ++i) {
80 dst[i] = 0U;
81 }
82}
83
84static const char* s_tag = "NETPAL";
85
86/* =============================================================================
87 * Ring buffer sizing
88 * =============================================================================
89 */
90
91typedef enum : uint16_t {
94
95/* =============================================================================
96 * Per-PAL state (single instance -- one ESWM per chip)
97 * =============================================================================
98 */
99
104typedef struct {
105 uint16_t len;
108
124
126
127/* =============================================================================
128 * Internal helpers
129 * =============================================================================
130 */
131
149static void internal_ring_reset(void)
150{
151 s_state.head = 0U;
152 s_state.tail = 0U;
153 s_state.count = 0U;
154 for (uint16_t i = 0U; i < k_ra8_net_pal_ring_slots; ++i) {
155 s_state.ring[i].len = 0U;
156 }
157}
158
182static uint32_t internal_translate_event(uint32_t eth_mask)
183{
184 if (eth_mask != 0U) {
186 }
188}
189
212static void internal_eth_event(void* ctx, uint32_t status_mask)
213{
214 (void)ctx;
215 if (!s_state.initialized) {
216 return;
217 }
218 const uint32_t pal_mask = internal_translate_event(status_mask);
219 // mcdc-deactivated: TU-local helper internal_eth_event dispatch gate; tests/net/src/test_ra8_net_pal.c covers each branch outcome but the MC/DC vector that flips event_fn while holding pal_mask non-empty (or vice-versa) is not reachable through the public-API surface -- callbacks are registered/unregistered before any event mask can become non-zero.
220 if ((s_state.event_fn != nullptr) && (pal_mask != k_ra8_net_pal_event_none)) {
221 s_state.event_fn(s_state.event_ctx, pal_mask);
222 }
223}
224
225/* =============================================================================
226 * Public API
227 * =============================================================================
228 */
229
257{
258 const ra8_err_t eth_err = ra8_eth_init();
259 if (eth_err != k_ra8_ok) {
260 ra8_log_error_val(s_tag, "ra8_eth_init failed", (uint32_t)eth_err);
262 }
263
265 s_state.link_state = k_ra8_net_pal_link_down;
266 s_state.event_fn = nullptr;
267 s_state.event_ctx = nullptr;
268 s_state.initialized = true;
270
271 if (mac != nullptr) {
273 }
274
276
277 ra8_log_info(s_tag, "PAL ready");
278 return k_ra8_ok;
279}
280
303{
304 if (!s_state.initialized) {
306 }
307 ra8_eth_attach_handler(nullptr, nullptr);
308 const ra8_err_t err = ra8_eth_deinit();
309 s_state.initialized = false;
310 s_state.event_fn = nullptr;
311 s_state.event_ctx = nullptr;
312 s_state.link_state = k_ra8_net_pal_link_down;
314 return err;
315}
316
340{
341 RA8_CHECK_NULL_PTR(mac, s_tag, "set_mac_addr: mac");
342 if (!s_state.initialized) {
344 }
346 return k_ra8_ok;
347}
348
370{
371 RA8_CHECK_NULL_PTR(out_mac, s_tag, "get_mac_addr: out_mac");
372 if (!s_state.initialized) {
374 }
376 return k_ra8_ok;
377}
378
409ra8_err_t ra8_net_pal_send_frame(const uint8_t* frame, uint16_t len)
410{
411 RA8_CHECK_NULL_PTR(frame, s_tag, "send_frame: frame");
412 if (!s_state.initialized) {
414 }
415 if ((len == 0U) || (len > k_ra8_net_pal_frame_max)) {
417 }
418 if (s_state.count >= k_ra8_net_pal_ring_slots) {
419 return k_ra8_err_no_mem;
420 }
421 ra8_net_pal_slot_t* slot = &s_state.ring[s_state.tail];
422 internal_copy_bytes(slot->data, frame, len);
423 slot->len = len;
424 s_state.tail = (uint16_t)((s_state.tail + 1U) % k_ra8_net_pal_ring_slots);
425 ++s_state.count;
426 if ((s_state.event_fn != nullptr)) {
427 s_state.event_fn(s_state.event_ctx, k_ra8_net_pal_event_tx_done);
428 }
429 return k_ra8_ok;
430}
431
462ra8_err_t ra8_net_pal_recv_frame(uint8_t* out_buf, uint16_t* inout_len)
463{
464 RA8_CHECK_NULL_PTR(out_buf, s_tag, "recv_frame: out_buf");
465 RA8_CHECK_NULL_PTR(inout_len, s_tag, "recv_frame: inout_len");
466 if (!s_state.initialized) {
468 }
469 if (*inout_len < k_ra8_net_pal_frame_max) {
471 }
472 if (s_state.count == 0U) {
473 return k_ra8_err_no_data;
474 }
475 ra8_net_pal_slot_t* slot = &s_state.ring[s_state.head];
476 const uint16_t n = slot->len;
477 internal_copy_bytes(out_buf, slot->data, n);
478 *inout_len = n;
479 slot->len = 0U;
480 s_state.head = (uint16_t)((s_state.head + 1U) % k_ra8_net_pal_ring_slots);
481 --s_state.count;
482 return k_ra8_ok;
483}
484
486{
487 RA8_CHECK_NULL_PTR(out_state, s_tag, "link_status: out_state");
488 if (!s_state.initialized) {
490 }
491 *out_state = s_state.link_state;
492 return k_ra8_ok;
493}
494
519{
520 if (!s_state.initialized) {
522 }
523 s_state.event_fn = fn;
524 s_state.event_ctx = ctx;
525 return k_ra8_ok;
526}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_hw_init_failed
Hardware peripheral failed to initialise.
Definition ra8_err.h:290
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_err_no_data
No application data available (e.g.
Definition ra8_err.h:202
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Ethernet Switch Module (ESWM) + frame TX/RX driver.
void ra8_eth_attach_handler(ra8_eth_event_fn_t fn, void *ctx)
Replace the shared Ethernet event callback.
Definition ra8_eth.c:532
ra8_err_t ra8_eth_deinit(void)
Tear down the ESWM block.
Definition ra8_eth.c:504
ra8_err_t ra8_eth_init(void)
Initialise the ESWM block (MSTP enable + reset regs).
Definition ra8_eth.c:486
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_error_val(tag, message, value)
RA8 log error val.
Definition ra8_log.h:337
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
ra8_err_t ra8_net_pal_link_status(ra8_net_pal_link_state_t *out_state)
Read the current link state.
ra8_err_t ra8_net_pal_send_frame(const uint8_t *frame, uint16_t len)
Hand a complete ethernet frame to the MAC for transmit.
ra8_err_t ra8_net_pal_deinit(void)
Tear down the network PAL singleton.
ra8_err_t ra8_net_pal_recv_frame(uint8_t *out_buf, uint16_t *inout_len)
Pull the next received ethernet frame, if any, into a buffer.
static void internal_ring_reset(void)
Reset the software ring to empty.
static uint32_t internal_translate_event(uint32_t eth_mask)
Translate ra8_eth status bits into PAL event bits.
static void internal_copy_bytes(uint8_t *dst, const uint8_t *src, uint16_t len)
Copy len bytes byte-by-byte (string.h-free implementation).
Definition ra8_net_pal.c:51
ra8_err_t ra8_net_pal_get_mac_addr(ra8_net_pal_mac_t *out_mac)
Read the currently programmed MAC address.
ra8_err_t ra8_net_pal_set_event_handler(ra8_net_pal_event_fn_t fn, void *ctx)
Install a single event handler for link / RX / TX events.
ra8_err_t ra8_net_pal_set_mac_addr(const ra8_net_pal_mac_t *mac)
Programme the PAL MAC address.
static void internal_eth_event(void *ctx, uint32_t status_mask)
ra8_eth event handler – translate + forward to the PAL callback.
ra8_net_pal_ring_dim_t
Definition ra8_net_pal.c:91
@ k_ra8_net_pal_ring_slots
Number of in-flight frames.
Definition ra8_net_pal.c:92
static void internal_zero_bytes(uint8_t *dst, uint16_t len)
Zero len bytes (project-local replacement for memset).
Definition ra8_net_pal.c:77
ra8_err_t ra8_net_pal_init(const ra8_net_pal_mac_t *mac)
Bring up the network PAL singleton.
Network Platform Abstraction Layer for the RA8D2 ESWM block.
void(* ra8_net_pal_event_fn_t)(void *ctx, uint32_t event_mask)
Async event callback shape (link change, RX ready, error).
ra8_net_pal_link_state_t
Possible link-up states surfaced to the stack.
@ k_ra8_net_pal_link_down
Cable unplugged or PHY not up.
@ k_ra8_net_pal_frame_max
MTU + header + FCS.
Definition ra8_net_pal.h:97
@ k_ra8_net_pal_mac_addr_len
48-bit Ethernet MAC.
Definition ra8_net_pal.h:95
@ k_ra8_net_pal_event_tx_done
TX descriptor freed.
@ k_ra8_net_pal_event_error
MAC reported a fault.
@ k_ra8_net_pal_event_none
RA8 net pal event none.
static uint32_t s_state
48-bit MAC address container.
uint8_t bytes[k_ra8_net_pal_mac_addr_len]
Bytes.
One ring slot holding a single frame plus its byte length.
uint16_t len
0 == slot empty.
uint8_t data[k_ra8_net_pal_frame_max]
Up to 1518 bytes.
Singleton PAL state.
ra8_net_pal_mac_t mac
Stored MAC address.
uint16_t tail
Next slot to push (send).
uint16_t head
Next slot to pop (recv).
ra8_net_pal_link_state_t link_state
Last observed link state.
void * event_ctx
Callback context.
ra8_net_pal_event_fn_t event_fn
Async event callback.
uint16_t count
In-flight frame count.
ra8_net_pal_slot_t ring[k_ra8_net_pal_ring_slots]
RX/TX ring.
bool initialized
True after ra8_net_pal_init.