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

NSC veneers for the communications drivers. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_i3c.h"
#include "ra8_nsc_veneer.h"
#include "ra8_sci.h"
#include "ra8_spi.h"
#include "ra8_usb.h"
Include dependency graph for ra8_nsc_comms.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  ra8_nsc_spi_pack_const_t : uint32_t {
  k_ra8_nsc_spi_byte_msk = 0x000000FFU ,
  k_ra8_nsc_spi_bw_shift = 8U
}
 Bit layout for ra8_nsc_spi_ch_bw() packed argument. More...

Functions

ra8_err_t ra8_nsc_sci_init (uint8_t channel, const ra8_sci_cfg_t *cfg)
 NSC veneer: bring up an SCI channel from NS code.
ra8_err_t ra8_nsc_sci_putc (uint8_t channel, uint8_t byte)
 NSC veneer: blocking single-byte SCI write.
ra8_err_t ra8_nsc_sci_getc (uint8_t channel, uint8_t *out_byte)
 NSC veneer: blocking single-byte SCI read.
ra8_err_t ra8_nsc_iic_init (uint8_t channel, const ra8_i3c_cfg_t *cfg)
 NSC veneer: bring up an IIC channel.
ra8_err_t ra8_nsc_iic_write (uint8_t channel, uint8_t target_7b, const uint8_t *data, uint32_t len)
 NSC veneer: blocking I2C write to a 7-bit target.
ra8_err_t ra8_nsc_iic_read (uint8_t channel, uint8_t target_7b, uint8_t *out_buf, uint32_t len)
 NSC veneer: blocking I2C read from a 7-bit target.
ra8_err_t ra8_nsc_spi_init (uint8_t channel, const ra8_spi_cfg_t *cfg)
 NSC veneer: bring up an SPI controller channel.
ra8_err_t ra8_nsc_spi_xfer8 (uint8_t channel, uint8_t tx, uint8_t *rx)
 NSC veneer: full-duplex single-byte SPI exchange.
ra8_err_t ra8_nsc_spi_write (uint8_t channel, const void *tx, uint32_t len, ra8_spi_bit_width_t bit_width)
 NSC veneer: multi-frame TX-only polling SPI write.
ra8_err_t ra8_nsc_spi_read (uint8_t channel, void *rx, uint32_t len, ra8_spi_bit_width_t bit_width)
 NSC veneer: multi-frame RX-only polling SPI read.
static uint32_t ra8_nsc_spi_ch_bw (uint8_t channel, ra8_spi_bit_width_t bit_width)
 Pack channel + bit_width into a single 32-bit argument.
ra8_err_t ra8_nsc_spi_write_read (uint32_t ch_bw, const void *tx, void *rx, uint32_t len)
 NSC veneer: multi-frame full-duplex polling SPI exchange.
ra8_err_t ra8_nsc_usb_init (ra8_usb_speed_t speed)
 NSC veneer: bring up the USB device controller.
ra8_err_t ra8_nsc_usb_attach (ra8_usb_speed_t speed, bool attached)
 NSC veneer: raise / drop USB D+ pull-up.

Detailed Description

NSC veneers for the communications drivers.

Tag
[Ring 4 / NSC] {World: NSC}

Retrofit veneers for the comms drivers (ra8_sci, ra8_iic, ra8_spi, ra8_usb). Each function here is a Non-Secure Callable entry point that validates pointer arguments via cmse_check_address_range (under TrustZone) and forwards to the matching Ring-3 driver primitive in the secure world.

This layer ships a representative subset – init + the most common transfer primitive per driver. The remaining surface (interrupt callbacks, DMA paths, error introspection) is straightforward to add by following the same pattern; it is deferred to land alongside the first NS-world consumer that actually exercises those paths.

Coverage

ra8_nsc_sci_init wraps ra8_sci_init ra8_nsc_sci_putc wraps ra8_sci_putc_polling ra8_nsc_sci_getc wraps ra8_sci_getc_polling ra8_nsc_iic_init wraps ra8_i3c_init ra8_nsc_iic_write wraps ra8_i3c_write ra8_nsc_iic_read wraps ra8_i3c_read ra8_nsc_spi_init wraps ra8_spi_init ra8_nsc_spi_xfer8 wraps ra8_spi_xfer8 ra8_nsc_usb_init wraps ra8_usb_device_init ra8_nsc_usb_attach wraps ra8_usb_device_attach

TrustZone Safety:
  • Validates: every config struct pointer + every byte buffer is in NS-readable / NS-writable memory.
  • Trusts: the secure-side driver state machines.
  • Denies: raw struct pass-by-value crossing the boundary (the cfg pointers stay opaque to the secure side until the veneer copies what it needs).

Definition in file ra8_nsc_comms.h.

Enumeration Type Documentation

◆ ra8_nsc_spi_pack_const_t

enum ra8_nsc_spi_pack_const_t : uint32_t

Bit layout for ra8_nsc_spi_ch_bw() packed argument.

Enumerator
k_ra8_nsc_spi_byte_msk 

Byte mask within the packed word.

k_ra8_nsc_spi_bw_shift 

Bit position of bit_width.

Definition at line 181 of file ra8_nsc_comms.h.

Function Documentation

◆ ra8_nsc_iic_init()

ra8_err_t ra8_nsc_iic_init ( uint8_t channel,
const ra8_i3c_cfg_t * cfg )
nodiscard

NSC veneer: bring up an IIC channel.

Since
0.1.0

NSC veneer: bring up an IIC channel.

Validates the NS pointer to cfg then forwards to ra8_i3c_init.

Parameters
[in]channelIIC channel index.
[in]cfgCaller-supplied configuration in NS memory.
Returns
ra8_err_t outcome.
Return values
k_ra8_okChannel programmed.
k_ra8_err_null_ptrcfg was NULL.
k_ra8_err_invalid_argcfg not in NS region or channel bad.
Precondition
TrustZone substrate up.
cfg lies entirely within NS data region.
Postcondition
On success the IIC hardware is ready for I/O.
On failure no module state was mutated.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. cfg is range-checked so a hostile NS pointer cannot leak secure-region bytes.
Note
Thread-safe: serialised by the secure IIC driver lock.
Since
0.1.0

Definition at line 167 of file ra8_nsc_comms.c.

References k_ra8_i3c_mode_i2c, ra8_i3c_cfg_t::mode, RA8_CHECK_NULL_PTR, ra8_i3c_init(), RA8_NSC_CHECK_NS_RANGE_R, RA8_NSC_VENEER, and s_tag.

◆ ra8_nsc_iic_read()

ra8_err_t ra8_nsc_iic_read ( uint8_t channel,
uint8_t target_7b,
uint8_t * out_buf,
uint32_t len )
nodiscard

NSC veneer: blocking I2C read from a 7-bit target.

Since
0.1.0

Validates [out_buf, out_buf+len) lies in writable NS memory then forwards to ra8_i3c_read.

Parameters
[in]channelIIC channel index.
[in]target_7b7-bit peripheral address.
[out]out_bufNS destination buffer.
[in]lenByte count to read.
Returns
ra8_err_t outcome.
Return values
k_ra8_okBytes received into out_buf.
k_ra8_err_null_ptrout_buf was NULL.
k_ra8_err_invalid_argRange outside NS region.
Precondition
ra8_nsc_iic_init succeeded for channel.
[out_buf, out_buf+len) lies in NS data region.
Postcondition
On success out_buf holds len received bytes.
On failure out_buf content is undefined.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. cmse_check_address_range guarantees the secure driver only writes to NS memory.
Note
Thread-safe: serialised by the secure IIC driver lock.
Since
0.1.0

Definition at line 244 of file ra8_nsc_comms.c.

References RA8_CHECK_NULL_PTR, ra8_i3c_read(), RA8_NSC_CHECK_NS_RANGE_RW, RA8_NSC_VENEER, and s_tag.

◆ ra8_nsc_iic_write()

ra8_err_t ra8_nsc_iic_write ( uint8_t channel,
uint8_t target_7b,
const uint8_t * data,
uint32_t len )
nodiscard

NSC veneer: blocking I2C write to a 7-bit target.

Since
0.1.0

Validates [data, data+len) lies in NS memory then forwards to ra8_i3c_write.

Parameters
[in]channelIIC channel index.
[in]target_7b7-bit peripheral address.
[in]dataNS source buffer.
[in]lenByte count.
Returns
ra8_err_t outcome.
Return values
k_ra8_okBytes transmitted (or ACK-checked).
k_ra8_err_null_ptrdata was NULL.
k_ra8_err_invalid_argRange outside NS region or len bogus.
Precondition
ra8_nsc_iic_init succeeded for channel.
[data, data+len) lies in NS data region.
Postcondition
On success the bus completed a START-WRITE-STOP transaction.
On failure the bus has been released.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. cmse_check_address_range rejects buffers that overlap secure memory before the secure driver reads them.
Note
Thread-safe: serialised by the secure IIC driver lock.
Since
0.1.0

Definition at line 206 of file ra8_nsc_comms.c.

References RA8_CHECK_NULL_PTR, ra8_i3c_write(), RA8_NSC_CHECK_NS_RANGE_R, RA8_NSC_VENEER, and s_tag.

◆ ra8_nsc_sci_getc()

ra8_err_t ra8_nsc_sci_getc ( uint8_t channel,
uint8_t * out_byte )
nodiscard

NSC veneer: blocking single-byte SCI read.

Parameters
[in]channelSCI channel 0..9.
[out]out_byteDestination in NS memory.
Returns
ra8_err_t error code.
Since
0.1.0

Validates out_byte is in the NS region and forwards to ra8_sci_getc_polling.

Parameters
[in]channelSCI channel index.
[out]out_byteDestination byte (in NS memory).
Returns
ra8_err_t outcome.
Return values
k_ra8_okOne byte stored at *out_byte.
k_ra8_err_null_ptrout_byte was NULL.
k_ra8_err_invalid_argPointer not in NS region.
Precondition
ra8_nsc_sci_init succeeded for channel.
out_byte lies in NS data region.
Postcondition
On success *out_byte reflects the received byte.
On failure *out_byte unchanged.
TrustZone:
Crosses NS->S via cmse_nonsecure_entry. out_byte is cmse_check_address_range-validated so the secure driver cannot be tricked into writing into secure memory.
Note
Thread-safe: serialised by the secure SCI driver lock.
Since
0.1.0

Definition at line 129 of file ra8_nsc_comms.c.

References RA8_CHECK_NULL_PTR, RA8_NSC_CHECK_NS_RANGE_RW, RA8_NSC_VENEER, ra8_sci_getc_polling(), and s_tag.

◆ ra8_nsc_sci_init()

ra8_err_t ra8_nsc_sci_init ( uint8_t channel,
const ra8_sci_cfg_t * cfg )
nodiscard

NSC veneer: bring up an SCI channel from NS code.

Parameters
[in]channelSCI channel 0..9.
[in]cfgConfiguration descriptor in NS memory.
Returns
ra8_err_t error code from the underlying ra8_sci_init.
TrustZone Safety:
  • Validates the cfg pointer covers sizeof(ra8_sci_cfg_t) of NS-readable memory before forwarding.
Since
0.1.0

NSC veneer: bring up an SCI channel from NS code.

Validates cfg lies inside the NS region (TZ builds) and forwards to the secure ra8_sci_init driver.

Parameters
[in]channelSCI channel index (0..k_ra8_sci_channel_max-1).
[in]cfgCaller-supplied configuration in NS memory.
Returns
ra8_err_t outcome.
Return values
k_ra8_okChannel programmed and ready.
k_ra8_err_null_ptrcfg was NULL.
k_ra8_err_invalid_argcfg outside NS range or channel bad.
Precondition
TrustZone substrate has been initialized.
cfg lies entirely within the NS data region.
Postcondition
On success the SCI hardware is ready for I/O.
On failure no module state was mutated.
TrustZone:
Crosses the NS->S boundary via cmse_nonsecure_entry. The caller pointer is checked with cmse_check_address_range so a malicious NS pointer cannot trick the secure SCI driver into reading secure memory.
Note
Thread-safe: serialised by the secure SCI driver lock.
Since
0.1.0

Definition at line 65 of file ra8_nsc_comms.c.

References RA8_CHECK_NULL_PTR, RA8_NSC_CHECK_NS_RANGE_R, RA8_NSC_VENEER, ra8_sci_init(), and s_tag.

◆ ra8_nsc_sci_putc()

ra8_err_t ra8_nsc_sci_putc ( uint8_t channel,
uint8_t byte )
nodiscard

NSC veneer: blocking single-byte SCI write.

Parameters
[in]channelSCI channel 0..9.
[in]byteByte to send.
Returns
ra8_err_t error code.
Since
0.1.0

Forwards directly to ra8_sci_putc_polling; no pointer crosses the boundary so no NS-range check is needed.

Parameters
[in]channelSCI channel index.
[in]byteByte to transmit.
Returns
ra8_err_t outcome.
Return values
k_ra8_okByte queued for TX.
k_ra8_err_invalid_argBad channel index.
Precondition
ra8_nsc_sci_init succeeded for channel.
TrustZone substrate up.
Postcondition
On success one byte was transmitted.
On failure the bus state is unchanged.
TrustZone:
Crosses NS->S via cmse_nonsecure_entry. Scalar-only signature; nothing leaks across the boundary.
Note
Thread-safe: serialised by the secure SCI driver lock.
Since
0.1.0

Definition at line 97 of file ra8_nsc_comms.c.

References RA8_NSC_VENEER, and ra8_sci_putc_polling().

◆ ra8_nsc_spi_ch_bw()

uint32_t ra8_nsc_spi_ch_bw ( uint8_t channel,
ra8_spi_bit_width_t bit_width )
inlinestatic

Pack channel + bit_width into a single 32-bit argument.

ra8_nsc_spi_write_read would naturally have five arguments (channel, tx, rx, len, bit_width) but cmse_nonsecure_entry requires every parameter to fit in a register (AAPCS R0..R3). Five args spill to the stack and the compiler rejects the attribute. We encode channel in bits [7:0] and bit_width in bits [15:8] so the veneer takes four register-sized arguments.

Parameters
[in]channelSPI channel id.
[in]bit_widthBus bit width enum value.
Returns
Packed ch_bw value suitable for ra8_nsc_spi_write_read.
Return values
value(channel & 0xFF) | (bit_width << 8).
Precondition
None.
None.
Postcondition
Returned value round-trips: (v & 0xFF) == channel and ((v >> 8) & 0xFF) == (uint8_t)bit_width.
No side effects.
Note
Pure function; safe from any context.
Since
0.1.0

Definition at line 212 of file ra8_nsc_comms.h.

References k_ra8_nsc_spi_bw_shift, and k_ra8_nsc_spi_byte_msk.

◆ ra8_nsc_spi_init()

ra8_err_t ra8_nsc_spi_init ( uint8_t channel,
const ra8_spi_cfg_t * cfg )
nodiscard

NSC veneer: bring up an SPI controller channel.

Since
0.1.0

NSC veneer: bring up an SPI controller channel.

Validates the NS pointer to cfg then forwards to ra8_spi_init.

Parameters
[in]channelSPI channel index.
[in]cfgCaller-supplied configuration in NS memory.
Returns
ra8_err_t outcome.
Return values
k_ra8_okChannel programmed.
k_ra8_err_null_ptrcfg was NULL.
k_ra8_err_invalid_argcfg not in NS region or channel bad.
Precondition
TrustZone substrate up.
cfg lies in NS data region.
Postcondition
On success the SPI hardware is ready for transfers.
On failure no module state was mutated.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. cfg is range-checked prior to the secure-side read.
Note
Thread-safe: serialised by the secure SPI driver lock.
Since
0.1.0

Definition at line 285 of file ra8_nsc_comms.c.

References RA8_CHECK_NULL_PTR, RA8_NSC_CHECK_NS_RANGE_R, RA8_NSC_VENEER, ra8_spi_init(), and s_tag.

◆ ra8_nsc_spi_read()

ra8_err_t ra8_nsc_spi_read ( uint8_t channel,
void * rx,
uint32_t len,
ra8_spi_bit_width_t bit_width )
nodiscard

NSC veneer: multi-frame RX-only polling SPI read.

TrustZone Safety:
  • Validates rx covers len * sizeof(unit) bytes of NS-writable memory before forwarding.
Since
0.1.0

Computes the byte span, range-checks rx in NS writable memory, then forwards to ra8_spi_read.

Parameters
[in]channelSPI channel index.
[out]rxNS destination buffer (may be NULL only if len == 0).
[in]lenFrame count.
[in]bit_widthFrame width (8/16/32).
Returns
ra8_err_t outcome.
Return values
k_ra8_okBytes received into rx.
k_ra8_err_null_ptrrx was NULL with non-zero len.
k_ra8_err_invalid_argRange outside NS region or bad width.
Precondition
ra8_nsc_spi_init succeeded for channel.
[rx, rx + bytes_per_frame*len) lies in NS writable memory.
Postcondition
On success rx holds len frames.
On failure rx content is undefined.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. rx is range-checked so the secure driver cannot be tricked into writing into secure RAM.
Note
Thread-safe: serialised by the secure SPI driver lock.
Since
0.1.0

Definition at line 485 of file ra8_nsc_comms.c.

References internal_spi_byte_span(), internal_spi_unit_bytes(), k_ra8_err_invalid_arg, RA8_CHECK_NULL_PTR, RA8_NSC_CHECK_NS_RANGE_RW, RA8_NSC_VENEER, ra8_spi_read(), and s_tag.

◆ ra8_nsc_spi_write()

ra8_err_t ra8_nsc_spi_write ( uint8_t channel,
const void * tx,
uint32_t len,
ra8_spi_bit_width_t bit_width )
nodiscard

NSC veneer: multi-frame TX-only polling SPI write.

TrustZone Safety:
  • Validates tx covers len * sizeof(unit) bytes of NS-readable memory before forwarding.
Since
0.1.0

Computes bytes_per_frame * len, range-checks the source buffer in NS memory, then forwards to ra8_spi_write.

Parameters
[in]channelSPI channel index.
[in]txNS source buffer (may be NULL only if len == 0).
[in]lenFrame count.
[in]bit_widthFrame width (8/16/32).
Returns
ra8_err_t outcome.
Return values
k_ra8_okBytes shifted out.
k_ra8_err_null_ptrtx was NULL with non-zero len.
k_ra8_err_invalid_argRange outside NS region or bad width.
Precondition
ra8_nsc_spi_init succeeded for channel.
[tx, tx + bytes_per_frame*len) lies in NS memory.
Postcondition
On success len frames were transmitted.
On failure no module state was mutated.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. The full byte range spanned by len frames is cmse_check_address_range-validated so the secure driver only reads NS memory.
Note
Thread-safe: serialised by the secure SPI driver lock.
Since
0.1.0

Definition at line 437 of file ra8_nsc_comms.c.

References internal_spi_byte_span(), internal_spi_unit_bytes(), k_ra8_err_invalid_arg, RA8_CHECK_NULL_PTR, RA8_NSC_CHECK_NS_RANGE_R, RA8_NSC_VENEER, ra8_spi_write(), and s_tag.

◆ ra8_nsc_spi_write_read()

ra8_err_t ra8_nsc_spi_write_read ( uint32_t ch_bw,
const void * tx,
void * rx,
uint32_t len )
nodiscard

NSC veneer: multi-frame full-duplex polling SPI exchange.

The veneer takes four register-sized arguments; pack channel and bit_width into ch_bw with ra8_nsc_spi_ch_bw().

TrustZone Safety:
  • Validates both buffer ranges are NS-accessible for the requested direction before forwarding.
Since
0.1.0

Definition at line 505 of file ra8_nsc_comms.c.

References internal_spi_byte_span(), internal_spi_unit_bytes(), k_ra8_err_invalid_arg, k_ra8_nsc_spi_bw_shift, k_ra8_nsc_spi_byte_msk, RA8_CHECK_NULL_PTR, RA8_NSC_CHECK_NS_RANGE_R, RA8_NSC_CHECK_NS_RANGE_RW, RA8_NSC_VENEER, ra8_spi_write_read(), and s_tag.

◆ ra8_nsc_spi_xfer8()

ra8_err_t ra8_nsc_spi_xfer8 ( uint8_t channel,
uint8_t tx,
uint8_t * rx )
nodiscard

NSC veneer: full-duplex single-byte SPI exchange.

Since
0.1.0

Forwards to ra8_spi_xfer8. rx may be NULL (matches the legacy ra8_spi_xfer8 contract); when non-NULL it is range- checked.

Parameters
[in]channelSPI channel index.
[in]txByte to transmit.
[out]rxOptional NS destination for the received byte.
Returns
ra8_err_t outcome.
Return values
k_ra8_okExchange complete.
k_ra8_err_invalid_argrx non-NULL but outside NS region.
Precondition
ra8_nsc_spi_init succeeded for channel.
rx is NULL or in NS data region.
Postcondition
On success and rx non-NULL, *rx reflects the CIPO byte.
On failure the bus state is restored.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. rx (when non-NULL) is cmse_check_address_range-validated.
Note
Thread-safe: serialised by the secure SPI driver lock.
Since
0.1.0

Definition at line 319 of file ra8_nsc_comms.c.

References RA8_NSC_CHECK_NS_RANGE_RW, RA8_NSC_VENEER, and ra8_spi_xfer8().

◆ ra8_nsc_usb_attach()

ra8_err_t ra8_nsc_usb_attach ( ra8_usb_speed_t speed,
bool attached )
nodiscard

NSC veneer: raise / drop USB D+ pull-up.

Since
0.1.0

NSC veneer: raise / drop USB D+ pull-up.

Forwards to ra8_usb_device_attach.

Parameters
[in]speedNegotiated USB speed enum.
[in]attachedTrue to assert pull-up, false to release.
Returns
ra8_err_t outcome.
Return values
k_ra8_okPull-up state set.
k_ra8_err_invalid_argUnknown speed.
Precondition
ra8_nsc_usb_init succeeded.
TrustZone substrate up.
Postcondition
On success the device is visible (or invisible) on the bus.
On failure the pull-up state is unchanged.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. Scalar arguments only.
Note
Thread-safe: no.
Since
0.1.0

Definition at line 589 of file ra8_nsc_comms.c.

References RA8_NSC_VENEER, and ra8_usb_device_attach().

Referenced by internal_usb_audio_usb_or_halt().

◆ ra8_nsc_usb_init()

ra8_err_t ra8_nsc_usb_init ( ra8_usb_speed_t speed)
nodiscard

NSC veneer: bring up the USB device controller.

Since
0.1.0

Forwards to ra8_usb_device_init. Scalar-only signature, so no NS-range check is needed.

Parameters
[in]speedNegotiated USB speed enum.
Returns
ra8_err_t outcome.
Return values
k_ra8_okUSB controller programmed.
k_ra8_err_invalid_argUnknown speed.
Precondition
TrustZone substrate up.
USB clock tree was enabled by ra8_nsc_periph_init.
Postcondition
On success the device controller is in the powered, detached state.
On failure no module state was mutated.
TrustZone:
NS->S boundary via cmse_nonsecure_entry. Scalar enum argument; nothing crosses the boundary that needs range-checking.
Note
Thread-safe: no – USB bring-up is single-threaded.
Since
0.1.0

Definition at line 561 of file ra8_nsc_comms.c.

References RA8_NSC_VENEER, and ra8_usb_device_init().