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

Pin Function Select (PFS) register layout for the Renesas RA8D2. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_bit_constants.h"
#include "ra8_port_constants.h"
Include dependency graph for ra8_pfs_regs.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  ra8_pfs_addr_t : uintptr_t {
  k_ra8_pfs_base_addr = 0x40400800UL ,
  k_ra8_pmisc_base_addr = 0x40400D00UL
}
enum  ra8_pmisc_off_t : uint16_t {
  k_ra8_pmisc_off_pfenet = 0x000U ,
  k_ra8_pmisc_off_pwpr = 0x00CU ,
  k_ra8_pmisc_off_pwprs = 0x014U ,
  k_ra8_pmisc_off_pmsar = 0x030U
}
enum  ra8_pfs_bit_t : uint8_t {
  k_ra8_pfs_bit_podr = 0U ,
  k_ra8_pfs_bit_pidr = 1U ,
  k_ra8_pfs_bit_pdr = 2U ,
  k_ra8_pfs_bit_pcr = 4U ,
  k_ra8_pfs_bit_ncodr = 6U ,
  k_ra8_pfs_bit_dscr0 = 10U ,
  k_ra8_pfs_bit_dscr1 = 11U ,
  k_ra8_pfs_bit_eofr0 = 12U ,
  k_ra8_pfs_bit_eofr1 = 13U ,
  k_ra8_pfs_bit_isel = 14U ,
  k_ra8_pfs_bit_asel = 15U ,
  k_ra8_pfs_bit_pmr = 16U ,
  k_ra8_pfs_bit_psel0 = 24U
}
 Bit positions inside the 32-bit PmnPFS register. More...
enum  ra8_pfs_mask_t : uint32_t {
  k_ra8_pfs_mask_podr = 0x00000001UL ,
  k_ra8_pfs_mask_pdr = 0x00000004UL ,
  k_ra8_pfs_mask_pcr = 0x00000010UL ,
  k_ra8_pfs_mask_ncodr = 0x00000040UL ,
  k_ra8_pfs_mask_dscr = 0x00000C00UL ,
  k_ra8_pfs_mask_eofr = 0x00003000UL ,
  k_ra8_pfs_mask_isel = 0x00004000UL ,
  k_ra8_pfs_mask_asel = 0x00008000UL ,
  k_ra8_pfs_mask_pmr = 0x00010000UL ,
  k_ra8_pfs_mask_psel = 0x1F000000UL
}
 Full-width masks for PmnPFS fields. More...
enum  ra8_pfs_dscr_t : uint8_t {
  k_ra8_pfs_dscr_low = 0U ,
  k_ra8_pfs_dscr_middle = 1U ,
  k_ra8_pfs_dscr_high_speed_high = 2U ,
  k_ra8_pfs_dscr_high = 3U
}
 PmnPFS.DSCR[1:0] port drive-capability encodings. More...
enum  ra8_pwpr_bit_t : uint8_t {
  k_ra8_pwpr_bit_pfswe = 6U ,
  k_ra8_pwpr_bit_b0wi = 7U
}
 Bit positions inside the 8-bit PWPR register. More...

Functions

static volatile uint32_t * ra8_pfs_pmn (ra8_port_t port, ra8_pin_t pin)
 Get pointer to the PmnPFS register for a single pin.
static volatile uint8_t * ra8_pfs_pwpr (void)
 Get pointer to the PWPR register (non-secure write-protect).
static volatile uint8_t * ra8_pfs_pwprs (void)
 Get pointer to the PWPRS register (Secure write-protect).
static void ra8_pfs_pwpr_unlock (void)
 Unlock PFS writes.
static void ra8_pfs_pwpr_lock (void)
 Re-lock PFS writes.

Detailed Description

Pin Function Select (PFS) register layout for the Renesas RA8D2.

Every GPIO pin on an RA8D2 has a 32-bit PmnPFS register inside the PFS block at 0x40400800. The register controls direction, output level, pull-up, open-drain, drive strength, IRQ/analog enable and (most importantly) which peripheral function is routed to the pin.

Pins are addressed by a flat (port * 16) + pin index; each entry is 4 bytes. The whole PFS array covers 15 ports x 16 pins x 4 bytes = 960 bytes.

Register field layout (PmnPFS, 32-bit)

Bits Name RW Purpose
0 PODR RW Port output data
1 PIDR R Port input data
2 PDR RW Port direction (0 = in, 1 = out)
4 PCR RW Pull-up control
6 NCODR RW N-channel open-drain
11:10 DSCR RW Drive strength
13:12 EOFR RW Event on falling / rising trigger control
14 ISEL RW IRQ input enable
15 ASEL RW Analog input enable
16 PMR RW Peripheral mode (0 = GPIO, 1 = peripheral)
28:24 PSEL RW Peripheral function select (0..31)

PWPR unlock sequence (MANDATORY)

PmnPFS writes are gated by the PWPR (Write Protect Register). The sequence is:

ra8_pfs_pwpr_unlock(); // clears B0WI, sets PFSWE
ra8_pfs_pmn(port, pin)->PmnPFS = new_value; // programme pin
ra8_pfs_pwpr_lock(); // clears PFSWE
ra8_board_eth_pin_t pin
Pin.
static void ra8_pfs_pwpr_lock(void)
Re-lock PFS writes.
static void ra8_pfs_pwpr_unlock(void)
Unlock PFS writes.
static volatile uint32_t * ra8_pfs_pmn(ra8_port_t port, ra8_pin_t pin)
Get pointer to the PmnPFS register for a single pin.

Skipping the unlock makes the write silently go nowhere.

Definition in file ra8_pfs_regs.h.

Enumeration Type Documentation

◆ ra8_pfs_addr_t

enum ra8_pfs_addr_t : uintptr_t
Enumerator
k_ra8_pfs_base_addr 

PFS array base.

k_ra8_pmisc_base_addr 

PMISC: contains PWPR and PWPRS.

Definition at line 66 of file ra8_pfs_regs.h.

◆ ra8_pfs_bit_t

enum ra8_pfs_bit_t : uint8_t

Bit positions inside the 32-bit PmnPFS register.

Enumerator
k_ra8_pfs_bit_podr 

Output data.

k_ra8_pfs_bit_pidr 

Input data (read-only).

k_ra8_pfs_bit_pdr 

Direction (0=in, 1=out).

k_ra8_pfs_bit_pcr 

Pull-up enable.

k_ra8_pfs_bit_ncodr 

N-channel open-drain enable.

k_ra8_pfs_bit_dscr0 

Drive strength (low bit).

k_ra8_pfs_bit_dscr1 

Drive strength (high bit).

k_ra8_pfs_bit_eofr0 

Event on rising/falling lo.

k_ra8_pfs_bit_eofr1 

Event on rising/falling hi.

k_ra8_pfs_bit_isel 

IRQ input enable.

k_ra8_pfs_bit_asel 

Analog input enable.

k_ra8_pfs_bit_pmr 

0=GPIO, 1=peripheral.

k_ra8_pfs_bit_psel0 

Peripheral select bit 0.

Definition at line 93 of file ra8_pfs_regs.h.

◆ ra8_pfs_dscr_t

enum ra8_pfs_dscr_t : uint8_t

PmnPFS.DSCR[1:0] port drive-capability encodings.

HUM Ch 20.2.6 "PmnPFS" p 845: the DSCR field selects the output pad drive strength. The default after reset is k_ra8_pfs_dscr_low. High-speed peripheral outputs (RGMII transmit data/clock/control, parallel display) need a stronger setting – HUM Ch 20.2.6 explicitly lists DSCR = 01b (middle) for RGMII/3.3 V and 11b (high) for RGMII/2.5 V; any other value for an RGMII pin leaves the electrical characteristics unguaranteed.

@ k_ra8_pfs_dscr_middle
01b: Middle drive.
ra8_err_t ra8_pfs_set_drive_strength(ra8_port_pin_t pin, ra8_pfs_dscr_t dscr)
Set the output drive strength (PmnPFS.DSCR) of an already-routed pin.
Definition gpio.c:287
See also
ra8_pfs_set_drive_strength()
Enumerator
k_ra8_pfs_dscr_low 

00b: Low drive (reset default).

k_ra8_pfs_dscr_middle 

01b: Middle drive.

k_ra8_pfs_dscr_high_speed_high 

10b: High-speed high drive.

k_ra8_pfs_dscr_high 

11b: High drive.

Definition at line 144 of file ra8_pfs_regs.h.

◆ ra8_pfs_mask_t

enum ra8_pfs_mask_t : uint32_t

Full-width masks for PmnPFS fields.

Enumerator
k_ra8_pfs_mask_podr 

RA8 PFS mask podr.

k_ra8_pfs_mask_pdr 

RA8 PFS mask pdr.

k_ra8_pfs_mask_pcr 

RA8 PFS mask pcr.

k_ra8_pfs_mask_ncodr 

RA8 PFS mask ncodr.

k_ra8_pfs_mask_dscr 

bits 11..10.

k_ra8_pfs_mask_eofr 

bits 13..12.

k_ra8_pfs_mask_isel 

RA8 PFS mask isel.

k_ra8_pfs_mask_asel 

RA8 PFS mask asel.

k_ra8_pfs_mask_pmr 

RA8 PFS mask pmr.

k_ra8_pfs_mask_psel 

bits 28..24 (5-bit function select).

Definition at line 113 of file ra8_pfs_regs.h.

◆ ra8_pmisc_off_t

enum ra8_pmisc_off_t : uint16_t
Enumerator
k_ra8_pmisc_off_pfenet 

PFENET: Ethernet Mode Select.

k_ra8_pmisc_off_pwpr 

PWPR: PFS Write Protect (HUM 20.2.5).

k_ra8_pmisc_off_pwprs 

PWPRS: Secure PFS Write Protect.

k_ra8_pmisc_off_pmsar 

PMSAR[0..14]: Port Security Attribution.

Definition at line 71 of file ra8_pfs_regs.h.

◆ ra8_pwpr_bit_t

enum ra8_pwpr_bit_t : uint8_t

Bit positions inside the 8-bit PWPR register.

Enumerator
k_ra8_pwpr_bit_pfswe 

1 = PFS writes allowed, 0 = PFS writes blocked.

k_ra8_pwpr_bit_b0wi 

1 = PFSWE write blocked, 0 = PFSWE writable.

Definition at line 183 of file ra8_pfs_regs.h.

Function Documentation

◆ ra8_pfs_pmn()

volatile uint32_t * ra8_pfs_pmn ( ra8_port_t port,
ra8_pin_t pin )
inlinestatic

Get pointer to the PmnPFS register for a single pin.

Parameters
[in]portPort index (0..k_ra8_port_max).
[in]pinPin index within the port (0..k_ra8_pin_max).
Returns
Volatile pointer to the 32-bit PmnPFS register, or nullptr if either index is out of range.

Definition at line 160 of file ra8_pfs_regs.h.

References k_ra8_pfs_base_addr, k_ra8_pin_count, k_ra8_pin_max, k_ra8_port_max, and pin.

Referenced by internal_capture_xspi_pin_state(), internal_glcdc_force_pin_output(), internal_reset_pfs(), internal_update_pfs(), ra8_gpio_input_init(), ra8_gpio_output_init(), ra8_mpc_read_pfs(), ra8_mpc_route_peripheral(), ra8_pfs_route_peripheral(), and ra8_pfs_set_drive_strength().

◆ ra8_pfs_pwpr()

volatile uint8_t * ra8_pfs_pwpr ( void )
inlinestatic

Get pointer to the PWPR register (non-secure write-protect).

Definition at line 190 of file ra8_pfs_regs.h.

References k_ra8_pmisc_base_addr, and k_ra8_pmisc_off_pwpr.

Referenced by ra8_pfs_pwpr_lock(), and ra8_pfs_pwpr_unlock().

◆ ra8_pfs_pwpr_lock()

void ra8_pfs_pwpr_lock ( void )
inlinestatic

Re-lock PFS writes.

Clears PFSWE, then sets B0WI so subsequent accidental writes to PFSWE are silently dropped.

Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 268 of file ra8_pfs_regs.h.

References k_ra8_pwpr_bit_b0wi, ra8_pfs_pwpr(), and ra8_pfs_pwprs().

Referenced by internal_glcdc_force_pin_output(), internal_reset_pfs(), internal_update_pfs(), ra8_gpio_input_init(), ra8_gpio_output_init(), ra8_mpc_route_peripheral(), ra8_pfs_route_peripheral(), and ra8_pfs_set_drive_strength().

◆ ra8_pfs_pwpr_unlock()

void ra8_pfs_pwpr_unlock ( void )
inlinestatic

Unlock PFS writes.

Sequence from HUM section 20.2.6 (PWPR) and 20.2.7 (PWPRS):

  1. Write 0 – clears B0WI (bit 7), allowing PFSWE to be written.
  2. Write 1<<PFSWE – sets PFSWE (bit 6), allowing PmnPFS writes.

Must be called once before a burst of PmnPFS writes, then balanced with ra8_pfs_pwpr_lock().

Note
We touch both PWPR (NS) and PWPRS (S) unconditionally, even though FSP only writes the one matching the current TrustZone build mode. Per HUM Ch 20.2.6 / 20.2.7 the chip silently ignores writes to whichever side does not own the port (the R_PMISC->PMSAR[] bit decides), so writing both is harmless. PMSAR resets to "all ports owned by Secure" on RA8D2, which matches what we currently want; we do not programme PMSAR. If a future bring-up needs NS ports it must (a) write the relevant PMSAR bit Secure-side and (b) the matching PFSWE write will then take effect through the NS path.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Since
0.1.0

Definition at line 241 of file ra8_pfs_regs.h.

References k_ra8_pwpr_bit_pfswe, ra8_pfs_pwpr(), and ra8_pfs_pwprs().

Referenced by internal_glcdc_force_pin_output(), internal_reset_pfs(), internal_update_pfs(), ra8_gpio_input_init(), ra8_gpio_output_init(), ra8_mpc_route_peripheral(), ra8_pfs_route_peripheral(), and ra8_pfs_set_drive_strength().

◆ ra8_pfs_pwprs()

volatile uint8_t * ra8_pfs_pwprs ( void )
inlinestatic

Get pointer to the PWPRS register (Secure write-protect).

On RA8D2 the Cortex-M85 boots in the Secure world. Until the SAU partition is programmed, PFS writes gated only by PWPR are silently dropped because PWPR controls the non-secure path. Secure code must unlock PWPRS as well; both registers share the same bit layout (B0WI / PFSWE) per HUM Ch 20.2.6 / 20.2.7.

Since
0.1.0

Definition at line 208 of file ra8_pfs_regs.h.

References k_ra8_pmisc_base_addr, and k_ra8_pmisc_off_pwprs.

Referenced by ra8_pfs_pwpr_lock(), and ra8_pfs_pwpr_unlock().