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

High-level GPIO helpers on top of the PORT + PFS register layer. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_gpio_constants.h"
#include "ra8_icu_regs.h"
#include "ra8_isr.h"
#include "ra8_pfs_regs.h"
#include "ra8_port_constants.h"
Include dependency graph for ra8_port_utils.h:

Go to the source code of this file.

Data Structures

struct  ra8_gpio_irq_cfg_t
 Configuration descriptor for ra8_gpio_attach_irq. More...

Functions

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.
ra8_err_t ra8_gpio_input_init (ra8_port_pin_t pin, ra8_pin_pull_t pull)
 Configure a pin as a digital input.
ra8_err_t ra8_gpio_write (ra8_port_pin_t pin, ra8_level_t level)
 Drive a previously-configured output to the given level.
ra8_err_t ra8_gpio_toggle (ra8_port_pin_t pin)
 Toggle a previously-configured output.
ra8_err_t ra8_gpio_read (ra8_port_pin_t pin, ra8_level_t *out_level)
 Read a previously-configured input.
ra8_err_t ra8_gpio_release (ra8_port_pin_t pin)
 Release a GPIO pin claim.
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.
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.
ra8_err_t ra8_gpio_attach_irq (ra8_port_pin_t pin, uint8_t irq_num, const ra8_gpio_irq_cfg_t *cfg, ra8_isr_handler_t handler, void *ctx)
 Wire a pin as an external IRQ input and install a handler.
ra8_err_t ra8_gpio_detach_irq (ra8_port_pin_t pin, uint8_t irq_num)
 Tear down a previously attached external IRQ.

Detailed Description

High-level GPIO helpers on top of the PORT + PFS register layer.

Thin convenience API that takes ra8_port_pin_t values and wraps the PORT and PFS register writes with the correct PWPR unlock / lock sequence. Drivers should prefer these helpers over hand-coding the PFS dance at every callsite.

Pattern

#define RA8_ERROR_CHECK(err)
Halt on fatal error.
Definition ra8_check.h:147
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
@ k_ra8_pin_led1
LED1 on P6_00 – (port 6 << 8) | pin 0.
@ k_ra8_level_high
Drive or read 1.
@ k_ra8_level_low
Drive or read 0.
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

Every helper claims ownership of the pin through ra8_pin_validator_claim() under the tag "GPIO". If a different driver later tries to claim the same pin, it gets k_ra8_err_gpio_conflict.

Definition in file ra8_port_utils.h.

Function Documentation

◆ ra8_gpio_attach_irq()

ra8_err_t ra8_gpio_attach_irq ( ra8_port_pin_t pin,
uint8_t irq_num,
const ra8_gpio_irq_cfg_t * cfg,
ra8_isr_handler_t handler,
void * ctx )
nodiscard

Wire a pin as an external IRQ input and install a handler.

One-call convenience that:

  • configures the pin as GPIO input with the requested pull,
  • programmes IRQCRi edge / filter fields,
  • registers handler against the matching ICU IRQ event in the ra8_isr table (which also enables the NVIC line and sets priority).
Parameters
[in]pinPacked port/pin identifier for the IRQ input.
[in]irq_numExternal IRQ pin number 0..15.
[in]cfgNon-NULL configuration descriptor.
[in]handlerNon-NULL handler invoked on IRQ firing.
[in]ctxOpaque context forwarded to the handler.
Returns
ra8_err_t error code.
Return values
k_ra8_okPin, IRQCR, ISR all programmed.
k_ra8_err_null_ptrcfg or handler was NULL.
k_ra8_err_invalid_argirq_num out of range.
k_ra8_err_gpio_invalid_*Pin port/pin out of range.
k_ra8_err_existsIRQ event already registered.
Precondition
ra8_infrastructure_init and ra8_icu_init / ra8_isr_init have run.
Postcondition
On success the pin is input-configured, IRQCR[irq_num] matches cfg, and the NVIC line is enabled.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 341 of file gpio.c.

References ra8_gpio_irq_cfg_t::filter_div, ra8_gpio_irq_cfg_t::filter_en, internal_event_for_irq(), k_ra8_err_invalid_arg, k_ra8_gpio_irq_num_max, k_ra8_ok, pin, ra8_gpio_irq_cfg_t::priority, ra8_gpio_irq_cfg_t::pull, RA8_CHECK_NULL_PTR, ra8_gpio_input_init(), ra8_icu_configure_irq_pin(), ra8_isr_register(), ra8_log_info_val, ra8_pin_validator_release(), s_tag, and ra8_gpio_irq_cfg_t::sense.

Referenced by internal_attach_hardware().

◆ ra8_gpio_detach_irq()

ra8_err_t ra8_gpio_detach_irq ( ra8_port_pin_t pin,
uint8_t irq_num )
nodiscard

Tear down a previously attached external IRQ.

Unregisters the ISR slot (disables the NVIC line, clears IELSR), zeroes IRQCR[irq_num], and releases the pin claim so another driver can reuse it.

Parameters
[in]pinPacked port/pin identifier previously attached.
[in]irq_numExternal IRQ number 0..15.
Returns
ra8_err_t error code.
Return values
k_ra8_okPin and IRQ torn down.
k_ra8_err_invalid_argirq_num out of range.
k_ra8_err_not_foundNo handler registered for this IRQ.
Precondition
ra8_gpio_attach_irq was called for the same irq_num.
Postcondition
NVIC line disabled, IRQCR == 0, pin validator released.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 388 of file gpio.c.

References internal_event_for_irq(), k_ra8_err_invalid_arg, k_ra8_gpio_irq_num_max, k_ra8_ok, pin, ra8_icu_configure_irq_pin(), ra8_isr_unregister(), ra8_log_info_val, ra8_pin_validator_release(), and s_tag.

Referenced by internal_teardown_gpio_interrupt().

◆ ra8_gpio_input_init()

ra8_err_t ra8_gpio_input_init ( ra8_port_pin_t pin,
ra8_pin_pull_t pull )
nodiscard

Configure a pin as a digital input.

Parameters
[in]pinPacked port/pin identifier.
[in]pullk_ra8_pull_none / k_ra8_pull_up. The RA8D2 PFS has a pull-up bit only, so k_ra8_pull_down is accepted but configures no pull.
Returns
ra8_err_t error code.
Return values
k_ra8_okPin configured as a digital input.
k_ra8_err_gpio_invalid_portPort out of range.
k_ra8_err_gpio_invalid_pinPin out of range.
k_ra8_err_gpio_conflictPin already owned.
k_ra8_err_hw_unmappedThe port/pin pair has no PFS register on this device.
Precondition
ra8_infrastructure_init() has run (pin validator ready).
The IOPORT module clock is on (always-on after reset).
Postcondition
On success, the pin is a digital input owned by this driver.
On any failure, pin ownership is unchanged (see ra8_gpio_output_init()).
Note
Not thread-safe; same PFS/PWPR caveat as ra8_gpio_output_init().
Since
0.1.0

Definition at line 121 of file gpio.c.

References internal_claim(), k_ra8_err_hw_unmapped, k_ra8_ok, k_ra8_pfs_mask_pcr, k_ra8_pin_0, k_ra8_port_0, k_ra8_pull_up, pin, ra8_log_error_val, ra8_log_info_val, ra8_pfs_pmn(), ra8_pfs_pwpr_lock(), ra8_pfs_pwpr_unlock(), ra8_pin_validator_release(), and s_tag.

Referenced by c6_probe_sideband_init(), cam_claim_probe_pins(), ep_bringup_panel_bus(), internal_config_gpio(), internal_io_expander_bus_recover(), internal_kick_net(), internal_pull_gpio(), internal_pull_read(), priv_ra8_esp_hosted_gpio_edge_register(), ra8_board_arduino_pin_init(), ra8_board_sw_init(), and ra8_gpio_attach_irq().

◆ ra8_gpio_output_init()

ra8_err_t ra8_gpio_output_init ( ra8_port_pin_t pin,
ra8_level_t init_level )
nodiscard

Configure a pin as a digital output and drive it to an initial level.

Parameters
[in]pinPacked port/pin identifier.
[in]init_levelInitial output level (k_ra8_level_low or k_ra8_level_high).
Returns
ra8_err_t error code.
Return values
k_ra8_okPin configured and driven.
k_ra8_err_gpio_invalid_portPort out of range.
k_ra8_err_gpio_invalid_pinPin out of range.
k_ra8_err_gpio_conflictPin already owned.
k_ra8_err_hw_unmappedThe port/pin pair has no PFS register on this device.
Precondition
ra8_infrastructure_init() has run (pin validator ready).
The IOPORT module clock is on (IOPORT is one of the "always on" blocks, so this is satisfied automatically after reset).
Postcondition
On success, the pin is in GPIO-output mode driving init_level.
On success, the pin is owned by this driver ("GPIO" tag).
On any failure, pin ownership is unchanged: a claim taken while configuring is handed back before returning, so a failed call never strands the pin. Callers may retry or fall through without leaking it.
Note
Not thread-safe: reads / modifies / writes the PFS register and touches PWPR. Protect with IRQ masking or run during single-threaded init.
Since
0.1.0

Definition at line 88 of file gpio.c.

References internal_claim(), k_ra8_err_hw_unmapped, k_ra8_level_high, k_ra8_ok, k_ra8_pfs_mask_pdr, k_ra8_pfs_mask_podr, k_ra8_pin_0, k_ra8_port_0, pin, ra8_log_error_val, ra8_log_info_val, ra8_pfs_pmn(), ra8_pfs_pwpr_lock(), ra8_pfs_pwpr_unlock(), ra8_pin_validator_release(), and s_tag.

Referenced by blc_route_usb_or_halt(), c6_probe_spi_pins_init(), cdc_route_usb_or_halt(), demo_pins_init(), dfu_route_usb_or_halt(), eoh_spi_pins_init(), ep_bringup_panel_bus(), etoc_spi_pins_init(), fileops_route_usb_or_halt(), fs_fmt_spi_pins_init(), hid_route_usb_or_halt(), internal_bringup_spi(), internal_cs_try(), internal_eth_phy_hw_reset(), internal_io_expander_bus_recover(), internal_io_expander_enable_pullups(), internal_kick_net(), internal_pc_spi_pins_init(), internal_pin_if_output_init(), internal_sci_transport_bringup(), internal_usbhs_role_select_device(), microsd_route_usb_or_halt(), microsd_sd_spi_open(), mlun_route_usb_or_halt(), ospirw_route_usb_or_halt(), ra8_board_arduino_pin_init(), ra8_board_camera_reset(), ra8_board_lcd_panel_power_on(), ra8_board_led_init(), ra8_board_xspi_pins_init(), sd_demo_spi_pins_init(), sdmsc_route_usb_or_halt(), selftest_route_usb_or_halt(), sh_sd_bus_init(), and wlun_route_usb_or_halt().

◆ ra8_gpio_read()

◆ ra8_gpio_release()

ra8_err_t ra8_gpio_release ( ra8_port_pin_t pin)
nodiscard

Release a GPIO pin claim.

Parameters
[in]pinPacked port/pin identifier previously claimed by a GPIO init call.
Returns
ra8_err_t error code from the pin validator.
Since
0.1.0

Definition at line 233 of file gpio.c.

References pin, and ra8_pin_validator_release().

Referenced by cam_release_probe_pins(), internal_cs_try(), internal_io_expander_bus_recover(), internal_kick_net(), internal_pull_gpio(), internal_pull_read(), internal_release_pins(), priv_ra8_esp_hosted_gpio_edge_register(), and priv_ra8_esp_hosted_gpio_edge_unregister().

◆ ra8_gpio_toggle()

ra8_err_t ra8_gpio_toggle ( ra8_port_pin_t pin)
nodiscard

Toggle a previously-configured output.

Parameters
[in]pinPacked port/pin identifier.
Returns
ra8_err_t error code.
Since
0.1.0

Definition at line 182 of file gpio.c.

References k_ra8_err_gpio_invalid_pin, k_ra8_err_gpio_invalid_port, k_ra8_err_hw_unmapped, k_ra8_ok, k_ra8_pcntr_high_half_shift, k_ra8_pin_max, k_ra8_port_max, r_port_regs_t::PCNTR1, r_port_regs_t::PCNTR3, pin, RA8_PIN_PIN, RA8_PIN_PORT, and ra8_port().

Referenced by internal_pin_if_toggle(), and ra8_board_led_toggle().

◆ ra8_gpio_write()

◆ ra8_pfs_route_peripheral()

ra8_err_t ra8_pfs_route_peripheral ( ra8_port_pin_t pin,
ra8_psel_t psel,
const char * owner )
nodiscard

Route a pin to a non-IRQ peripheral function via PFS.PSEL.

Claims the pin through the validator, unlocks PWPR, writes PMR=1 plus the requested PSEL code into the pin's PFS register, relocks PWPR, and logs the routing. Use for SCI / IIC / SPI / GPT / xSPI / GLCDC / etc. – any peripheral whose pin selection is encoded in the PFS PSEL field. External IRQ inputs go through ra8_gpio_attach_irq instead, which combines the PFS write with the ICU + NVIC configuration in one call.

Parameters
[in]pinPacked port/pin identifier (see RA8_PIN(...)).
[in]pselPFS PSEL code (ra8_psel_t from ra8_gpio_constants.h).
[in]ownerNon-NULL static string used for the validator ownership log.
Returns
ra8_err_t error code.
Return values
k_ra8_okPin is now in peripheral mode.
k_ra8_err_null_ptrowner was nullptr.
k_ra8_err_gpio_invalid_portPort index out of range.
k_ra8_err_gpio_invalid_pinPin index out of range.
k_ra8_err_gpio_conflictPin is already claimed by another owner.
k_ra8_err_hw_unmappedPin has no PFS mapping (host-test fake only).
Precondition
IOPORT module is reachable.
Caller is single-threaded init context.
Postcondition
On success the pin's PFS holds PMR=1 | (psel << PSEL0).
On success the pin is claimed by owner.
Note
Not thread-safe; intended for boot.
Since
0.1.0

Definition at line 238 of file gpio.c.

References k_ra8_err_gpio_invalid_pin, k_ra8_err_gpio_invalid_port, k_ra8_err_hw_unmapped, k_ra8_ok, k_ra8_pfs_bit_psel0, k_ra8_pfs_mask_pmr, k_ra8_pin_max, k_ra8_port_max, owner, pin, RA8_CHECK_NULL_PTR, ra8_log_error_val, ra8_log_info_val, ra8_pfs_pmn(), ra8_pfs_pwpr_lock(), ra8_pfs_pwpr_unlock(), RA8_PIN_PIN, RA8_PIN_PORT, ra8_pin_validator_claim(), ra8_pin_validator_release(), and s_tag.

Referenced by blc_route_usb_or_halt(), blc_setup_or_halt(), bm_pins_init(), c6_probe_spi_pins_init(), cdc_route_usb_or_halt(), combo_pfs_or_halt(), demo_pins_init(), demo_setup_or_halt(), dfu_route_usb_or_halt(), eoh_spi_pins_init(), etoc_spi_pins_init(), fileops_route_usb_or_halt(), fs_fmt_spi_pins_init(), gpt_ecc_route_pins_or_halt(), hid_route_usb_or_halt(), i3c_demo_pfs_or_halt(), imu_demo_pfs_or_halt(), internal_audio_route_pins(), internal_bringup_spi(), internal_demo_setup_or_halt(), internal_eth_route_alt_pins(), internal_io_expander_route_pins(), internal_motor_3phase_pins_init(), internal_pc_spi_pins_init(), internal_route_data_pins(), internal_sci_transport_bringup(), internal_sdramc_route_pins(), lin_hil_setup_or_halt(), microsd_route_usb_or_halt(), microsd_sd_spi_open(), mlun_route_usb_or_halt(), modem_pfs_or_halt(), ospirw_route_usb_or_halt(), ra8_board_camera_route_parallel_pins(), ra8_board_camera_xclk_start(), ra8_board_glcdc_init(), ra8_board_pdm_mic_route(), ra8_board_sdhi_pins_init(), ra8_board_uart_console_init(), ra8_board_xspi_pins_init(), sd_demo_spi_pins_init(), sd_pins_init(), sdmsc_route_usb_or_halt(), selftest_route_usb_or_halt(), sh_sd_bus_init(), uart_irq_pins_init(), and wlun_route_usb_or_halt().

◆ ra8_pfs_set_drive_strength()

ra8_err_t ra8_pfs_set_drive_strength ( ra8_port_pin_t pin,
ra8_pfs_dscr_t dscr )
nodiscard

Set the output drive strength (PmnPFS.DSCR) of an already-routed pin.

Read-modify-write of the PmnPFS.DSCR[1:0] field for one pin under a PWPR write-protect unlock. Only the DSCR field is touched – the pin's PSEL / PMR / direction are preserved – so this is meant to be called AFTER ra8_pfs_route_peripheral (or ra8_gpio_output_init) has already configured the pin's function.

High-speed peripheral outputs need more than the reset-default low drive: HUM Ch 20.2.6 requires DSCR = 01b for RGMII/3.3 V transmit pins (and 11b for RGMII/2.5 V). Leaving an RGMII transmit pin at the default 00b leaves its edge timing out of spec – bench- confirmed to corrupt the majority of transmitted frames.

Parameters
[in]pinPacked port/pin identifier (RA8_PIN).
[in]dscrTarget drive-capability code (ra8_pfs_dscr_t).
Returns
ra8_err_t Error code.
Return values
k_ra8_okDSCR updated.
k_ra8_err_gpio_invalid_portport index out of range.
k_ra8_err_gpio_invalid_pinpin index out of range.
k_ra8_err_hw_unmappedpin has no PFS register.
Precondition
The pin has already been routed / configured by the caller.
Caller is single-threaded init context.
Postcondition
On success the pin's PmnPFS.DSCR equals dscr.
PSEL / PMR / direction bits are unchanged.
Note
Not thread-safe; intended for boot.
Since
0.1.0

Definition at line 287 of file gpio.c.

References k_ra8_err_gpio_invalid_pin, k_ra8_err_gpio_invalid_port, k_ra8_err_hw_unmapped, k_ra8_ok, k_ra8_pfs_bit_dscr0, k_ra8_pfs_mask_dscr, k_ra8_pin_max, k_ra8_port_max, pin, ra8_log_info_val, ra8_pfs_pmn(), ra8_pfs_pwpr_lock(), ra8_pfs_pwpr_unlock(), RA8_PIN_PIN, RA8_PIN_PORT, and s_tag.

Referenced by internal_eth_route_alt_pins(), internal_sdramc_route_pins(), and ra8_board_camera_xclk_start().