ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_mpc.c
Go to the documentation of this file.
1
16
17#include "ra8_mpc.h"
18
19#include <stdint.h>
20
21#include "ra8_attributes.h"
22#include "ra8_check.h"
23#include "ra8_err.h"
24#include "ra8_log.h"
25#include "ra8_pfs_regs.h"
26
27static const char* s_tag = "MPC";
28
47{
48 if ((uint8_t)port > k_ra8_port_max) {
50 }
51 if ((uint8_t)pin > k_ra8_pin_max) {
53 }
54 return k_ra8_ok;
55}
56
76RA8_INTERNAL static void
77internal_update_pfs(ra8_port_t port, ra8_pin_t pin, uint32_t clear_mask, uint32_t set_mask)
78{
79 volatile uint32_t* pfs = ra8_pfs_pmn(port, pin);
80 if (pfs == nullptr) { /* GCOVR_EXCL_BR_LINE -- bounds already validated by caller */
81 return;
82 }
84 /* HUM Ch 20.2 "PmnPFS : Pin Function Select Register", p 837 */
85 const uint32_t cur = *pfs;
86 const uint32_t masked = cur & ~clear_mask;
87 *pfs = masked | set_mask;
89}
90
111RA8_INTERNAL static void internal_reset_pfs(ra8_port_t port, ra8_pin_t pin, uint32_t set_mask)
112{
113 volatile uint32_t* pfs = ra8_pfs_pmn(port, pin);
114 if (pfs == nullptr) { /* GCOVR_EXCL_BR_LINE -- bounds already validated by caller */
115 return;
116 }
118 *pfs = set_mask;
120}
121
123{
124 const ra8_err_t err = internal_check(port, pin);
125 if (err != k_ra8_ok) {
126 return err;
127 }
128 const uint32_t psel_bits = ((uint32_t)psel << k_ra8_pfs_bit_psel0) & k_ra8_pfs_mask_psel;
129 const uint32_t pmr = k_ra8_pfs_mask_pmr;
130
131 /* HUM Ch 20.2.4 "Notes on the PmnPFS Register Setting" p 859 -- PMR
132 * must be cleared before a new PSEL is programmed. Three-step write:
133 * 1. PMR := 0 (return pin to GPIO mode)
134 * 2. PFS := new PSEL (programme function while PMR is still 0)
135 * 3. PFS := PSEL | PMR (hand pin to the peripheral)
136 * Single combined write is what FSP r_ioport_pfs_write avoids; doing
137 * it would let the pin briefly drive whatever the *previous* PSEL
138 * decoded to with PMR already 1.
139 * @note PMSAR resets to all-Secure on RA8D2; we hold the unlock
140 * across the whole sequence so no extra PWPR write storms. */
141 volatile uint32_t* pfs = ra8_pfs_pmn(port, pin);
142 if (pfs == nullptr) { /* GCOVR_EXCL_BR_LINE -- bounds already validated */
144 }
146 /* HUM Ch 20.2.4 "Notes on the PmnPFS Register Setting" p 859 */
147 *pfs = 0U; /* step 1: PMR = 0. */
148 *pfs = psel_bits; /* step 2: PSEL, PMR=0. */
149 *pfs = psel_bits | pmr; /* step 3: PSEL | PMR=1. */
151
152 ra8_log_info_val(s_tag, "route", (uint32_t)psel);
153 return k_ra8_ok;
154}
155
157{
158 const ra8_err_t err = internal_check(port, pin);
159 if (err != k_ra8_ok) {
160 return err;
161 }
162 const uint32_t pdr = (dir == k_ra8_mpc_dir_output) ? k_ra8_pfs_mask_pdr : 0U;
163 internal_reset_pfs(port, pin, pdr);
164 return k_ra8_ok;
165}
166
168{
169 const ra8_err_t err = internal_check(port, pin);
170 if (err != k_ra8_ok) {
171 return err;
172 }
174 return k_ra8_ok;
175}
176
178{
179 const ra8_err_t err = internal_check(port, pin);
180 if (err != k_ra8_ok) {
181 return err;
182 }
184 return k_ra8_ok;
185}
186
188{
189 const ra8_err_t err = internal_check(port, pin);
190 if (err != k_ra8_ok) {
191 return err;
192 }
193 const uint32_t set = (pull == k_ra8_mpc_pull_up) ? k_ra8_pfs_mask_pcr : 0U;
195 return k_ra8_ok;
196}
197
199{
200 const ra8_err_t err = internal_check(port, pin);
201 if (err != k_ra8_ok) {
202 return err;
203 }
204 uint32_t set = 0U;
205 if (enable) {
207 }
209 return k_ra8_ok;
210}
211
213{
214 RA8_CHECK_NULL_PTR(out_val, s_tag, "out_val must not be NULL");
215 const ra8_err_t err = internal_check(port, pin);
216 if (err != k_ra8_ok) {
217 return err;
218 }
219 volatile const uint32_t* pfs = ra8_pfs_pmn(port, pin);
220 if (pfs == nullptr) { /* GCOVR_EXCL_BR_LINE -- bounds already validated */
222 }
223 *out_val = *pfs;
224 return k_ra8_ok;
225}
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).
ra8_board_eth_pin_t pin
Pin.
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_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_gpio_invalid_pin
GPIO pin index out of range within its port (valid: 0..15).
Definition ra8_err.h:331
@ k_ra8_err_gpio_invalid_port
GPIO port index out of range for this MCU.
Definition ra8_err.h:325
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_info_val(tag, message, value)
RA8 log info val.
Definition ra8_log.h:366
ra8_err_t ra8_mpc_set_open_drain(ra8_port_t port, ra8_pin_t pin, bool enable)
Enable or disable N-channel open-drain on a pin.
Definition ra8_mpc.c:198
static ra8_err_t internal_check(ra8_port_t port, ra8_pin_t pin)
Bounds-check a (port, pin) pair.
Definition ra8_mpc.c:46
ra8_err_t ra8_mpc_set_gpio(ra8_port_t port, ra8_pin_t pin, ra8_mpc_dir_t dir)
Reset a pin to plain GPIO with a chosen direction.
Definition ra8_mpc.c:156
ra8_err_t ra8_mpc_set_irq(ra8_port_t port, ra8_pin_t pin)
Mark a pin as an external IRQ input (ISEL = 1).
Definition ra8_mpc.c:177
static void internal_update_pfs(ra8_port_t port, ra8_pin_t pin, uint32_t clear_mask, uint32_t set_mask)
Update a single field of PmnPFS under PWPR unlock.
Definition ra8_mpc.c:77
ra8_err_t ra8_mpc_route_peripheral(ra8_port_t port, ra8_pin_t pin, ra8_mpc_psel_t psel)
Route a pin to a peripheral function.
Definition ra8_mpc.c:122
ra8_err_t ra8_mpc_read_pfs(ra8_port_t port, ra8_pin_t pin, uint32_t *out_val)
Read the raw 32-bit PmnPFS register for diagnostic use.
Definition ra8_mpc.c:212
static void internal_reset_pfs(ra8_port_t port, ra8_pin_t pin, uint32_t set_mask)
All-fields reset + new-fields write under PWPR unlock.
Definition ra8_mpc.c:111
ra8_err_t ra8_mpc_set_pull(ra8_port_t port, ra8_pin_t pin, ra8_mpc_pull_t pull)
Enable or disable the internal pull-up on a pin.
Definition ra8_mpc.c:187
ra8_err_t ra8_mpc_set_analog(ra8_port_t port, ra8_pin_t pin)
Put a pin in analog-input mode (ASEL = 1).
Definition ra8_mpc.c:167
Multi-function Pin Controller (MPC) facade.
ra8_mpc_pull_t
Pull-up enable for ra8_mpc_set_pull.
Definition ra8_mpc.h:114
@ k_ra8_mpc_pull_up
RA8 mpc pull up.
Definition ra8_mpc.h:116
ra8_mpc_psel_t
Peripheral function select values for the PMR/PSEL path.
Definition ra8_mpc.h:66
ra8_mpc_dir_t
Pin direction for ra8_mpc_set_gpio.
Definition ra8_mpc.h:105
@ k_ra8_mpc_dir_output
Output direction (PDR = 1).
Definition ra8_mpc.h:107
Pin Function Select (PFS) register layout for the Renesas RA8D2.
@ 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).
@ k_ra8_pfs_mask_isel
RA8 PFS mask isel.
@ k_ra8_pfs_mask_ncodr
RA8 PFS mask ncodr.
@ k_ra8_pfs_mask_pdr
RA8 PFS mask pdr.
@ k_ra8_pfs_mask_pcr
RA8 PFS mask pcr.
@ k_ra8_pfs_bit_psel0
Peripheral select bit 0.
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.
ra8_port_t
Port indices for the RA8D2 IOPORT module.
@ k_ra8_port_max
Highest valid port index.
ra8_pin_t
Pin indices within an IOPORT port (0..15).
@ k_ra8_pin_max
Highest valid pin index.