1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 /***********************************************************************************************************************
8  * Includes
9  **********************************************************************************************************************/
10 #include <stdint.h>
11 #include "bsp_api.h"
12 #include "r_ioport.h"
13 #include "r_ioport_api.h"
14 
15 /***********************************************************************************************************************
16  * Macro definitions
17  **********************************************************************************************************************/
18 
19 /* "PORT" in ASCII, used to determine if the module is open */
20 #define IOPORT_OPEN                (0x504F5254U)
21 #define IOPORT_CLOSED              (0x00000000U)
22 
23 /* Shift to get port in bsp_io_port_t and bsp_io_port_pin_t enums. */
24 #define IOPORT_PRV_PORT_OFFSET     (8U)
25 
26 #define IOPORT_PRV_PORT_BITS       (0xFF00U)
27 #define IOPORT_PRV_PIN_BITS        (0x00FFU)
28 
29 #define IOPORT_PRV_8BIT_MASK       (0x00FFU)
30 
31 /* Added definitions */
32 #define IOPORT_PIN_NUM_MUX         (8U)
33 #define IOPORT_REGION_SEL_SAFE     (0U)
34 #define IOPORT_REGION_SEL_NSAFE    (1U)
35 #define IOPORT_RSEL_MASK           (0x01U)
36 #define IOPORT_PM_BIT_MASK         (0x0003U)
37 
38 #if BSP_FEATURE_IOPORT_PIN_PFC_TYPE == 3
39  #define IOPORT_PFC_BIT_MASK       (0x0000003FU)
40 #else
41  #define IOPORT_PFC_BIT_MASK       (0x0000000FU)
42 #endif
43 
44 #define IOPORT_DRTCL_BIT_MASK      (0x000000FFU)
45 #define IOPORT_ELC_PEL_MASK        (0x80)
46 #define IOOPRT_ELC_PGC_MASK        (0x88)
47 #define IOPORT_ELC_PEL_PSM_HIGH    (0x20)
48 
49 /* Switch IOPORT register region either safety or non safety */
50 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
51  #define IOPORT_PRV_PORT_ADDRESS(region_sel)    (region_sel == 1 ? (R_PORT_SRN) : (R_PORT_SRS))
52 #else
53  #define IOPORT_PRV_PORT_ADDRESS(region_sel)    (region_sel == 1 ? (R_PORT_NSR) : (R_PORT_SR))
54 #endif
55 
56 /***********************************************************************************************************************
57  * Typedef definitions
58  **********************************************************************************************************************/
59 #if BSP_FEATURE_IOPORT_PIN_PFC_TYPE == 3
60 typedef struct st_ioport_cfg_data
61 {
62     uint32_t p_reg    : 1;
63     uint32_t pm_reg   : 2;
64     uint32_t pmc_reg  : 1;
65     uint32_t pfc_reg  : 6;
66     uint32_t drct_reg : 6;
67     uint32_t rsel_reg : 1;
68     uint32_t reserved : 15;
69 } ioport_cfg_data_t;
70 #else
71 typedef struct st_ioport_cfg_data
72 {
73     uint32_t p_reg    : 1;
74     uint32_t pm_reg   : 2;
75     uint32_t pmc_reg  : 1;
76     uint32_t pfc_reg  : 4;
77     uint32_t drct_reg : 6;
78     uint32_t rsel_reg : 1;
79     uint32_t reserved : 17;
80 } ioport_cfg_data_t;
81 #endif
82 
83 /***********************************************************************************************************************
84  * Private function prototypes
85  **********************************************************************************************************************/
86 static void r_ioport_pins_config(const ioport_cfg_t * p_cfg);
87 static void r_ioport_pin_set(bsp_io_port_pin_t pin, ioport_cfg_data_t * p_cfg_data);
88 static void r_ioport_event_config(const ioport_extend_cfg_t * p_extend_cfg_data);
89 static void r_ioport_pin_set_safety(R_PORT_COMMON_Type * p_ioport_regs,
90                                     bsp_io_port_pin_t    pin,
91                                     ioport_cfg_data_t  * p_cfg_data);
92 
93 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
94 static void r_ioport_pin_set_non_safety(R_PORT_NS_COMMON_Type * p_ioport_regs,
95                                         bsp_io_port_pin_t       pin,
96                                         ioport_cfg_data_t     * p_cfg_data);
97 
98 #endif
99 
100 /***********************************************************************************************************************
101  * Private global variables
102  **********************************************************************************************************************/
103 
104 /***********************************************************************************************************************
105  * Global Variables
106  **********************************************************************************************************************/
107 
108 /* IOPort Implementation of IOPort Driver  */
109 const ioport_api_t g_ioport_on_ioport =
110 {
111     .open                 = R_IOPORT_Open,
112     .close                = R_IOPORT_Close,
113     .pinsCfg              = R_IOPORT_PinsCfg,
114     .pinCfg               = R_IOPORT_PinCfg,
115     .pinEventInputRead    = R_IOPORT_PinEventInputRead,
116     .pinEventOutputWrite  = R_IOPORT_PinEventOutputWrite,
117     .pinRead              = R_IOPORT_PinRead,
118     .pinWrite             = R_IOPORT_PinWrite,
119     .portDirectionSet     = R_IOPORT_PortDirectionSet,
120     .portEventInputRead   = R_IOPORT_PortEventInputRead,
121     .portEventOutputWrite = R_IOPORT_PortEventOutputWrite,
122     .portRead             = R_IOPORT_PortRead,
123     .portWrite            = R_IOPORT_PortWrite,
124 };
125 
126 /*******************************************************************************************************************//**
127  * @addtogroup IOPORT
128  * @{
129  **********************************************************************************************************************/
130 
131 /***********************************************************************************************************************
132  * Functions
133  **********************************************************************************************************************/
134 
135 /*******************************************************************************************************************//**
136  * Initializes internal driver data, then calls pin configuration function to configure pins.
137  *
138  * @retval FSP_SUCCESS                  Pin configuration data written to the multiple registers
139  * @retval FSP_ERR_ASSERTION            NULL pointer
140  * @retval FSP_ERR_ALREADY_OPEN         Module is already open.
141  **********************************************************************************************************************/
R_IOPORT_Open(ioport_ctrl_t * const p_ctrl,const ioport_cfg_t * p_cfg)142 fsp_err_t R_IOPORT_Open (ioport_ctrl_t * const p_ctrl, const ioport_cfg_t * p_cfg)
143 {
144     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
145 
146 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
147     FSP_ASSERT(NULL != p_instance_ctrl);
148     FSP_ASSERT(NULL != p_cfg);
149     FSP_ASSERT(NULL != p_cfg->p_pin_cfg_data);
150     FSP_ERROR_RETURN(IOPORT_OPEN != p_instance_ctrl->open, FSP_ERR_ALREADY_OPEN);
151 #endif
152 
153     /* Set driver status to open */
154     p_instance_ctrl->open = IOPORT_OPEN;
155 
156     p_instance_ctrl->p_cfg = p_cfg;
157 
158     r_ioport_pins_config(p_cfg);
159 
160     r_ioport_event_config(p_cfg->p_extend);
161 
162     return FSP_SUCCESS;
163 }
164 
165 /*******************************************************************************************************************//**
166  * Resets IOPORT registers. Implements @ref ioport_api_t::close
167  *
168  * @retval FSP_SUCCESS             The IOPORT was successfully uninitialized
169  * @retval FSP_ERR_ASSERTION       p_ctrl was NULL
170  * @retval FSP_ERR_NOT_OPEN        The module has not been opened
171  *
172  **********************************************************************************************************************/
R_IOPORT_Close(ioport_ctrl_t * const p_ctrl)173 fsp_err_t R_IOPORT_Close (ioport_ctrl_t * const p_ctrl)
174 {
175     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
176 
177 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
178     FSP_ASSERT(NULL != p_instance_ctrl);
179     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
180 #else
181     FSP_PARAMETER_NOT_USED(p_ctrl);
182 #endif
183 
184     /* Set state to closed */
185     p_instance_ctrl->open = IOPORT_CLOSED;
186 
187     return FSP_SUCCESS;
188 }
189 
190 /*******************************************************************************************************************//**
191  * Configures the functions of multiple pins by loading configuration data into the multiple registers.
192  * Implements @ref ioport_api_t::pinsCfg.
193  *
194  * This function initializes the supplied list of the multiple registers with the supplied values. This data can be generated
195  * by the Pins tab of the RZ/N2L Configuration editor or manually by the developer. Different pin configurations can be
196  * loaded for different situations such as low power modes and testing.
197  *
198  * @retval FSP_SUCCESS             Pin configuration data written to the multiple registers
199  * @retval FSP_ERR_NOT_OPEN        The module has not been opened
200  * @retval FSP_ERR_ASSERTION       NULL pointer
201  **********************************************************************************************************************/
R_IOPORT_PinsCfg(ioport_ctrl_t * const p_ctrl,const ioport_cfg_t * p_cfg)202 fsp_err_t R_IOPORT_PinsCfg (ioport_ctrl_t * const p_ctrl, const ioport_cfg_t * p_cfg)
203 {
204 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
205     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
206     FSP_ASSERT(NULL != p_instance_ctrl);
207     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
208     FSP_ASSERT(NULL != p_cfg);
209     FSP_ASSERT(NULL != p_cfg->p_pin_cfg_data);
210 #else
211     FSP_PARAMETER_NOT_USED(p_ctrl);
212 #endif
213 
214     r_ioport_pins_config(p_cfg);
215 
216     return FSP_SUCCESS;
217 }
218 
219 /*******************************************************************************************************************//**
220  * Configures the settings of a pin. Implements @ref ioport_api_t::pinCfg.
221  *
222  * @retval FSP_SUCCESS             Pin configured
223  * @retval FSP_ERR_NOT_OPEN        The module has not been opened
224  * @retval FSP_ERR_ASSERTION       NULL pointer
225  *
226  * @note This function is re-entrant for different pins.
227  * This function will change the configuration of the pin with the new configuration. For example it is not possible
228  * with this function to change the drive strength of a pin while leaving all the other pin settings unchanged. To
229  * achieve this the original settings with the required change will need to be written using this function.
230  **********************************************************************************************************************/
R_IOPORT_PinCfg(ioport_ctrl_t * const p_ctrl,bsp_io_port_pin_t pin,uint32_t cfg)231 fsp_err_t R_IOPORT_PinCfg (ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, uint32_t cfg)
232 {
233 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
234     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
235     FSP_ASSERT(NULL != p_instance_ctrl);
236     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
237 #else
238     FSP_PARAMETER_NOT_USED(p_ctrl);
239 #endif
240 
241     R_BSP_PinAccessEnable();
242 
243     r_ioport_pin_set(pin, (ioport_cfg_data_t *) &cfg);
244 
245     R_BSP_PinAccessDisable();
246 
247     return FSP_SUCCESS;
248 }
249 
250 /*******************************************************************************************************************//**
251  * Reads the level on a pin. Implements @ref ioport_api_t::pinRead.
252  *
253  * The level for the specifed pin will be reterned by PINm register.
254  *
255  * @retval FSP_SUCCESS             Pin read
256  * @retval FSP_ERR_ASSERTION       NULL pointer
257  * @retval FSP_ERR_NOT_OPEN        The module has not been opened
258  *
259  * @note This function is re-entrant for different pins.
260  **********************************************************************************************************************/
R_IOPORT_PinRead(ioport_ctrl_t * const p_ctrl,bsp_io_port_pin_t pin,bsp_io_level_t * p_pin_value)261 fsp_err_t R_IOPORT_PinRead (ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, bsp_io_level_t * p_pin_value)
262 {
263 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
264     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
265     FSP_ASSERT(NULL != p_instance_ctrl);
266     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
267     FSP_ASSERT(NULL != p_pin_value);
268 #else
269     FSP_PARAMETER_NOT_USED(p_ctrl);
270 #endif
271 
272     *p_pin_value = (bsp_io_level_t) R_BSP_FastPinRead(R_BSP_IoRegionGet(pin), pin);
273 
274     return FSP_SUCCESS;
275 }
276 
277 /*******************************************************************************************************************//**
278  * Reads the value on an IO port. Implements @ref ioport_api_t::portRead.
279  *
280  * The specified port will be read, and the levels for all the pins will be returned by PINm register.
281  * Each bit in the returned value corresponds to a pin on the port. For example, bit 7 corresponds
282  * to pin 7, bit 6 to pin 6, and so on.
283  *
284  * @retval FSP_SUCCESS             Port read
285  * @retval FSP_ERR_ASSERTION       NULL pointer
286  * @retval FSP_ERR_NOT_OPEN        The module has not been opened
287  *
288  * @note This function is re-entrant for different ports.
289  **********************************************************************************************************************/
R_IOPORT_PortRead(ioport_ctrl_t * const p_ctrl,bsp_io_port_t port,ioport_size_t * p_port_value)290 fsp_err_t R_IOPORT_PortRead (ioport_ctrl_t * const p_ctrl, bsp_io_port_t port, ioport_size_t * p_port_value)
291 {
292 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
293     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
294     FSP_ASSERT(NULL != p_instance_ctrl);
295     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
296     FSP_ASSERT(NULL != p_port_value);
297 #else
298     FSP_PARAMETER_NOT_USED(p_ctrl);
299 #endif
300 
301     R_PORT_COMMON_Type * p_ioport_regs;
302     ioport_size_t        safe_value;
303     ioport_size_t        nsafe_value;
304 
305     /* Get port number */
306     uint32_t port_num = (IOPORT_PRV_PORT_BITS & (ioport_size_t) port) >> IOPORT_PRV_PORT_OFFSET;
307 
308 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
309     if (port_num > BSP_FEATURE_IOPORT_SELECTABLE_PORT_MAX)
310     {
311         /* Read the specified port states */
312         *p_port_value = (ioport_size_t) R_PORT_NSR->PIN[port_num];
313 
314         return FSP_SUCCESS;
315     }
316 #endif
317 
318     /* Get the RSELP register value */
319 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
320     ioport_size_t rselp_value = (ioport_size_t) R_PORT_SRS->RSELP[port_num];
321 #else
322     ioport_size_t rselp_value = (ioport_size_t) R_PTADR->RSELP[port_num];
323 #endif
324 
325     /* Get the port register address in non safety region */
326     p_ioport_regs = IOPORT_PRV_PORT_ADDRESS(IOPORT_REGION_SEL_NSAFE);
327 
328     /* Read the specified port states in non safety region */
329     nsafe_value = (ioport_size_t) (p_ioport_regs->PIN[port_num] & rselp_value);
330 
331     /* Get the port register address in safety region */
332     p_ioport_regs = IOPORT_PRV_PORT_ADDRESS(IOPORT_REGION_SEL_SAFE);
333 
334     /* Read the specified port states in safety region */
335     safe_value = (ioport_size_t) (p_ioport_regs->PIN[port_num] & ~(rselp_value));
336 
337     /* Read the specified port states */
338     *p_port_value = nsafe_value | safe_value;
339 
340     return FSP_SUCCESS;
341 }
342 
343 /*******************************************************************************************************************//**
344  * Writes to multiple pins on a port. Implements @ref ioport_api_t::portWrite.
345  *
346  * The output value will be written to the specified port. Each bit in the value parameter corresponds to a bit
347  * on the port. For example, bit 7 corresponds to pin 7, bit 6 to pin 6, and so on.
348  * Each bit in the mask parameter corresponds to a pin on the port.
349  *
350  * Only the bits with the corresponding bit in the mask value set will be updated.
351  * For example, value = 0x00FF, mask = 0x0003 results in only bits 0 and 1 being updated.
352  *
353  * @retval FSP_SUCCESS                  Port written to
354  * @retval FSP_ERR_INVALID_ARGUMENT     The port and/or mask not valid
355  * @retval FSP_ERR_NOT_OPEN             The module has not been opened
356  * @retval FSP_ERR_ASSERTION            NULL pointerd
357  *
358  * @note This function is re-entrant for different ports. This function makes use of the Pm register to atomically
359  * modify the levels on the specified pins on a port.
360  **********************************************************************************************************************/
R_IOPORT_PortWrite(ioport_ctrl_t * const p_ctrl,bsp_io_port_t port,ioport_size_t value,ioport_size_t mask)361 fsp_err_t R_IOPORT_PortWrite (ioport_ctrl_t * const p_ctrl, bsp_io_port_t port, ioport_size_t value, ioport_size_t mask)
362 {
363 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
364     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
365     FSP_ASSERT(NULL != p_instance_ctrl);
366     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
367     FSP_ERROR_RETURN(mask > (ioport_size_t) 0, FSP_ERR_INVALID_ARGUMENT);
368 #else
369     FSP_PARAMETER_NOT_USED(p_ctrl);
370 #endif
371 
372     R_PORT_COMMON_Type * p_ioport_regs;
373     ioport_size_t        temp_value;
374     ioport_size_t        write_mask;
375 
376     /* mask value: lower word is valid, upper word is invalid */
377     mask &= IOPORT_PRV_8BIT_MASK;
378 
379     /* Get port number */
380     uint32_t port_num = (IOPORT_PRV_PORT_BITS & (ioport_size_t) port) >> IOPORT_PRV_PORT_OFFSET;
381 
382 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
383     if (port_num > BSP_FEATURE_IOPORT_SELECTABLE_PORT_MAX)
384     {
385         /* Output data store of the specified pins sets to low output */
386         temp_value = (ioport_size_t) (R_PORT_NSR->P[port_num] & (~mask));
387 
388         /* Write output data to P register of the specified pins */
389         R_PORT_NSR->P[port_num] = (uint8_t) (temp_value | (value & mask));
390 
391         return FSP_SUCCESS;
392     }
393 #endif
394 
395     /* Get the RSELP register value */
396 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
397     ioport_size_t rselp_value = (ioport_size_t) R_PORT_SRS->RSELP[port_num];
398 #else
399     ioport_size_t rselp_value = (ioport_size_t) R_PTADR->RSELP[port_num];
400 #endif
401 
402     /* Set value to non safety region register */
403     write_mask = rselp_value & mask;
404     if (write_mask)
405     {
406         /* Get the port register address */
407         p_ioport_regs = IOPORT_PRV_PORT_ADDRESS(IOPORT_REGION_SEL_NSAFE);
408 
409         /* Output data store of the specified pins sets to low output */
410         temp_value = (ioport_size_t) (p_ioport_regs->P[port_num] & (~write_mask));
411 
412         /* Write output data to P register of the specified pins */
413         p_ioport_regs->P[port_num] = (uint8_t) (temp_value | (value & write_mask));
414     }
415 
416     /* Set value to safety region register */
417     write_mask = (ioport_size_t) ((~rselp_value) & mask);
418     if (write_mask)
419     {
420         /* Get the port register address */
421         p_ioport_regs = IOPORT_PRV_PORT_ADDRESS(IOPORT_REGION_SEL_SAFE);
422 
423         /* Output data store of the specified pins sets to low output */
424         temp_value = (ioport_size_t) (p_ioport_regs->P[port_num] & (~write_mask));
425 
426         /* Write output data to P register of the specified pins */
427         p_ioport_regs->P[port_num] = (uint8_t) (temp_value | (value & write_mask));
428     }
429 
430     return FSP_SUCCESS;
431 }
432 
433 /*******************************************************************************************************************//**
434  * Sets a pin's output either high or low. Implements @ref ioport_api_t::pinWrite.
435  *
436  * @retval FSP_SUCCESS                  Pin written to
437  * @retval FSP_ERR_INVALID_ARGUMENT     The pin and/or level not valid
438  * @retval FSP_ERR_NOT_OPEN             The module has not been opene
439  * @retval FSP_ERR_ASSERTION            NULL pointerd
440  *
441  * @note This function is re-entrant for different pins. This function makes use of the Pm register to atomically
442  * modify the level on the specified pin on a port.
443  **********************************************************************************************************************/
R_IOPORT_PinWrite(ioport_ctrl_t * const p_ctrl,bsp_io_port_pin_t pin,bsp_io_level_t level)444 fsp_err_t R_IOPORT_PinWrite (ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, bsp_io_level_t level)
445 {
446 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
447     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
448     FSP_ASSERT(NULL != p_instance_ctrl);
449     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
450     FSP_ERROR_RETURN(level <= BSP_IO_LEVEL_HIGH, FSP_ERR_INVALID_ARGUMENT);
451 #else
452     FSP_PARAMETER_NOT_USED(p_ctrl);
453 #endif
454 
455     /* Get port and pin number */
456     uint32_t port_num = (IOPORT_PRV_PORT_BITS & (ioport_size_t) pin) >> IOPORT_PRV_PORT_OFFSET;
457     uint32_t pin_num  = (IOPORT_PRV_PIN_BITS & (ioport_size_t) pin);
458 
459     /* Get the port register address */
460 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
461     if (port_num > BSP_FEATURE_IOPORT_SELECTABLE_PORT_MAX)
462     {
463         /* Get the port register address */
464         R_PORT_NS_COMMON_Type * p_ioport_regs = R_PORT_NSR;
465 
466         /* Set output level to P register of the specified pin */
467         if (BSP_IO_LEVEL_LOW == level)
468         {
469             p_ioport_regs->P[port_num] &= (uint8_t) (~(1U << pin_num));
470         }
471         else
472         {
473             p_ioport_regs->P[port_num] |= (uint8_t) (1U << pin_num);
474         }
475     }
476     else
477     {
478         /* Get the port register address */
479         R_PORT_COMMON_Type * p_ioport_regs =
480             (IOPORT_PRV_PORT_ADDRESS(((uint16_t) (R_PORT_SRS->RSELP[port_num] >> pin_num) &
481                                       IOPORT_RSEL_MASK)));
482 
483         /* Set output level to P register of the specified pin */
484         if (BSP_IO_LEVEL_LOW == level)
485         {
486             p_ioport_regs->P[port_num] &= (uint8_t) (~(1U << pin_num));
487         }
488         else
489         {
490             p_ioport_regs->P[port_num] |= (uint8_t) (1U << pin_num);
491         }
492     }
493 
494 #else
495 
496     /* Get the port register address */
497     R_PORT_COMMON_Type * p_ioport_regs = (IOPORT_PRV_PORT_ADDRESS(((uint16_t) (R_PTADR->RSELP[port_num] >> pin_num) &
498                                                                    IOPORT_RSEL_MASK)));
499 
500     /* Set output level to P register of the specified pin */
501     if (BSP_IO_LEVEL_LOW == level)
502     {
503         p_ioport_regs->P[port_num] &= (uint8_t) (~(1U << pin_num));
504     }
505     else
506     {
507         p_ioport_regs->P[port_num] |= (uint8_t) (1U << pin_num);
508     }
509 #endif
510 
511     return FSP_SUCCESS;
512 }
513 
514 /*******************************************************************************************************************//**
515  * Sets the direction of individual pins on a port. Implements @ref ioport_api_t::portDirectionSet().
516  *
517  * Multiple pins on a port can be set to inputs or outputs at once.
518  * Each bit in the mask parameter corresponds to a pin on the port. For example, bit 7 corresponds to
519  * pin 7, bit 6 to pin 6, and so on. If a mask bit is set to 1 then the corresponding pin will be changed to
520  * an input or an output as specified by the direction values. If a mask bit is set to 0 then the direction of
521  * the pin will not be changed.
522  *
523  * @retval FSP_SUCCESS                 Port direction updated
524  * @retval FSP_ERR_INVALID_ARGUMENT    The port and/or mask not valid
525  * @retval FSP_ERR_NOT_OPEN            The module has not been opened
526  * @retval FSP_ERR_ASSERTION           NULL pointer
527  *
528  * @note This function is re-entrant for different ports.
529  **********************************************************************************************************************/
R_IOPORT_PortDirectionSet(ioport_ctrl_t * const p_ctrl,bsp_io_port_t port,ioport_size_t direction_values,ioport_size_t mask)530 fsp_err_t R_IOPORT_PortDirectionSet (ioport_ctrl_t * const p_ctrl,
531                                      bsp_io_port_t         port,
532                                      ioport_size_t         direction_values,
533                                      ioport_size_t         mask)
534 {
535     uint32_t pin_num;
536 
537 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
538     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
539     FSP_ASSERT(NULL != p_instance_ctrl);
540     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
541     FSP_ERROR_RETURN(mask > (uint16_t) 0, FSP_ERR_INVALID_ARGUMENT);
542 #else
543     FSP_PARAMETER_NOT_USED(p_ctrl);
544 #endif
545 
546     /* mask value: lower word is valid, upper word is invalid */
547     mask &= IOPORT_PRV_8BIT_MASK;
548 
549     for (pin_num = 0U; pin_num < IOPORT_PIN_NUM_MUX; pin_num++)
550     {
551         if (mask & (1U << pin_num))
552         {
553             /* Get port number */
554             uint32_t port_num = (IOPORT_PRV_PORT_BITS & (ioport_size_t) port) >> IOPORT_PRV_PORT_OFFSET;
555 
556 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
557             if (port_num > BSP_FEATURE_IOPORT_SELECTABLE_PORT_MAX)
558             {
559                 /* Get the port register address */
560                 R_PORT_NS_COMMON_Type * p_ioport_regs = R_PORT_NSR;
561 
562                 /* Set  */
563                 uint16_t set_bits = (uint16_t) (direction_values & (IOPORT_PM_BIT_MASK << (pin_num * 2U)));
564 
565                 /* Set the direction value */
566                 uint16_t temp_value =
567                     (uint16_t) (p_ioport_regs->PM[port_num] & ~(IOPORT_PM_BIT_MASK << (pin_num * 2U)));
568                 p_ioport_regs->PM[port_num] = temp_value | set_bits;
569             }
570             else
571             {
572                 /* Get the port register address */
573                 R_PORT_COMMON_Type * p_ioport_regs =
574                     (IOPORT_PRV_PORT_ADDRESS(((uint16_t) (R_PORT_SRS->RSELP[port_num] >> pin_num) &
575                                               IOPORT_RSEL_MASK)));
576 
577                 /* Set  */
578                 uint16_t set_bits = (uint16_t) (direction_values & (IOPORT_PM_BIT_MASK << (pin_num * 2U)));
579 
580                 /* Set the direction value */
581                 uint16_t temp_value =
582                     (uint16_t) (p_ioport_regs->PM[port_num] & ~(IOPORT_PM_BIT_MASK << (pin_num * 2U)));
583                 p_ioport_regs->PM[port_num] = temp_value | set_bits;
584             }
585 
586 #else
587 
588             /* Get the port register address */
589             R_PORT_COMMON_Type * p_ioport_regs =
590                 (IOPORT_PRV_PORT_ADDRESS(((uint16_t) (R_PTADR->RSELP[port_num] >> pin_num) &
591                                           IOPORT_RSEL_MASK)));
592 
593             /* Set  */
594             uint16_t set_bits = (uint16_t) (direction_values & (IOPORT_PM_BIT_MASK << (pin_num * 2U)));
595 
596             /* Set the direction value */
597             uint16_t temp_value = (uint16_t) (p_ioport_regs->PM[port_num] & ~(IOPORT_PM_BIT_MASK << (pin_num * 2U)));
598             p_ioport_regs->PM[port_num] = temp_value | set_bits;
599 #endif
600         }
601     }
602 
603     return FSP_SUCCESS;
604 }
605 
606 /*******************************************************************************************************************//**
607  * Reads the value of the event input data. Implements @ref ioport_api_t::portEventInputRead().
608  *
609  * The event input data for the port will be read. Each bit in the returned value corresponds to a pin on the port.
610  * For example, bit 7 corresponds to pin 7, bit 6 to pin 6, and so on.
611  *
612  * The port event data is captured in response to a trigger from the ELC. This function enables this data to be read.
613  * Using the event system allows the captured data to be stored when it occurs and then read back at a later time.
614  *
615  * @retval FSP_SUCCESS              Port read
616  * @retval FSP_ERR_INVALID_ARGUMENT Port not a valid ELC port
617  * @retval FSP_ERR_ASSERTION        NULL pointer
618  * @retval FSP_ERR_NOT_OPEN         The module has not been opened
619  **********************************************************************************************************************/
R_IOPORT_PortEventInputRead(ioport_ctrl_t * const p_ctrl,bsp_io_port_t port,ioport_size_t * p_event_data)620 fsp_err_t R_IOPORT_PortEventInputRead (ioport_ctrl_t * const p_ctrl, bsp_io_port_t port, ioport_size_t * p_event_data)
621 {
622     uint8_t portgroup = 0U;
623     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
624 
625 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
626     FSP_ASSERT(NULL != p_instance_ctrl);
627     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
628     FSP_ASSERT(NULL != p_event_data);
629     FSP_ERROR_RETURN((port == BSP_FEATURE_ELC_GROUP1_PORT_NUM) || (port == BSP_FEATURE_ELC_GROUP2_PORT_NUM),
630                      FSP_ERR_INVALID_ARGUMENT);
631 #else
632     FSP_PARAMETER_NOT_USED(p_ctrl);
633 #endif
634 
635     const ioport_extend_cfg_t * elc_cfg = p_instance_ctrl->p_cfg->p_extend;
636 
637     /* Get register address */
638 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
639     R_PORT_NS_COMMON_Type * p_ioport_regs = R_PORT_NSR;
640 #else
641     R_PORT_COMMON_Type * p_ioport_regs = R_PORT_NSR;
642 #endif
643 
644     /* Get port group number for the specified port */
645     if (BSP_FEATURE_ELC_GROUP1_PORT_NUM == port)
646     {
647         portgroup = 0U;
648     }
649     else if (BSP_FEATURE_ELC_GROUP2_PORT_NUM == port)
650     {
651         portgroup = 1U;
652     }
653     else
654     {
655         /* Do Nothing */
656     }
657 
658     /* Read current value of buffer value from ELC_PDBF register for the specified port group */
659     *p_event_data =
660         (uint16_t) (p_ioport_regs->ELC_PDBF[portgroup].BY & elc_cfg->port_group_input_cfg[portgroup].pin_select);
661 
662     return FSP_SUCCESS;
663 }
664 
665 /*******************************************************************************************************************//**
666  * Reads the value of the event input data of a specific pin. Implements @ref ioport_api_t::pinEventInputRead.
667  *
668  * The pin event data is captured in response to a trigger from the ELC. This function enables this data to be read.
669  * Using the event system allows the captured data to be stored when it occurs and then read back at a later time.
670  *
671  * @retval FSP_SUCCESS                  Pin read
672  * @retval FSP_ERR_ASSERTION            NULL pointer
673  * @retval FSP_ERR_NOT_OPEN             The module has not been opened
674  * @retval FSP_ERR_INVALID_ARGUMENT     Port is not valid ELC PORT.
675  **********************************************************************************************************************/
R_IOPORT_PinEventInputRead(ioport_ctrl_t * const p_ctrl,bsp_io_port_pin_t pin,bsp_io_level_t * p_pin_event)676 fsp_err_t R_IOPORT_PinEventInputRead (ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, bsp_io_level_t * p_pin_event)
677 {
678     uint8_t portgroup = 0U;
679     uint8_t portvalue;
680     uint8_t mask;
681 
682 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
683     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
684     FSP_ASSERT(NULL != p_instance_ctrl);
685     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
686     FSP_ASSERT(NULL != p_pin_event);
687     uint32_t port_number = pin >> IOPORT_PRV_PORT_OFFSET;
688     FSP_ERROR_RETURN((port_number == BSP_FEATURE_ELC_GROUP1_PORT_NUM >> IOPORT_PRV_PORT_OFFSET) ||
689                      (port_number == BSP_FEATURE_ELC_GROUP2_PORT_NUM >> IOPORT_PRV_PORT_OFFSET),
690                      FSP_ERR_INVALID_ARGUMENT);
691 #else
692     FSP_PARAMETER_NOT_USED(p_ctrl);
693 #endif
694 
695     /* Get port and pin number */
696     uint32_t port_num = (IOPORT_PRV_PORT_BITS & (ioport_size_t) pin);
697     uint32_t pin_num  = (IOPORT_PRV_PIN_BITS & (ioport_size_t) pin);
698 
699     /* Get register address */
700 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
701     R_PORT_NS_COMMON_Type * p_ioport_regs = R_PORT_NSR;
702 #else
703     R_PORT_COMMON_Type * p_ioport_regs = R_PORT_NSR;
704 #endif
705 
706     /* Get port group number for the specified port */
707     if (BSP_FEATURE_ELC_GROUP1_PORT_NUM == port_num)
708     {
709         portgroup = 0U;
710     }
711     else if (BSP_FEATURE_ELC_GROUP2_PORT_NUM == port_num)
712     {
713         portgroup = 1U;
714     }
715     else
716     {
717         /* Do Nothing */
718     }
719 
720     /* Read current value of buffer value from ELC_PDBF register for the specified port group */
721     portvalue = p_ioport_regs->ELC_PDBF[portgroup].BY;
722     mask      = (uint8_t) (1U << pin_num);
723 
724     if ((portvalue & mask) == mask)
725     {
726         *p_pin_event = BSP_IO_LEVEL_HIGH;
727     }
728     else
729     {
730         *p_pin_event = BSP_IO_LEVEL_LOW;
731     }
732 
733     return FSP_SUCCESS;
734 }
735 
736 /*******************************************************************************************************************//**
737  * This function writes the set and reset event output data for a port. Implements
738  * @ref ioport_api_t::portEventOutputWrite.
739  *
740  * Using the event system enables a port state to be stored by this function in advance of being output on the port.
741  * The output to the port will occur when the ELC event occurs.
742  *
743  * The input value will be written to the specified port when an ELC event configured for that port occurs.
744  * Each bit in the value parameter corresponds to a bit on the port. For example, bit 7 corresponds to pin 7,
745  * bit 6 to pin 6, and so on. Each bit in the mask parameter corresponds to a pin on the port.
746  *
747  * @retval FSP_SUCCESS                Port event data written
748  * @retval FSP_ERR_INVALID_ARGUMENT   Port or Mask not valid
749  * @retval FSP_ERR_NOT_OPEN           The module has not been opened
750  * @retval FSP_ERR_ASSERTION          NULL pointer
751  **********************************************************************************************************************/
R_IOPORT_PortEventOutputWrite(ioport_ctrl_t * const p_ctrl,bsp_io_port_t port,ioport_size_t event_data,ioport_size_t mask_value)752 fsp_err_t R_IOPORT_PortEventOutputWrite (ioport_ctrl_t * const p_ctrl,
753                                          bsp_io_port_t         port,
754                                          ioport_size_t         event_data,
755                                          ioport_size_t         mask_value)
756 {
757     uint8_t       portgroup = 0U;
758     ioport_size_t temp_value;
759 
760 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
761     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
762     FSP_ASSERT(NULL != p_instance_ctrl);
763     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
764     FSP_ERROR_RETURN(mask_value > (ioport_size_t) 0, FSP_ERR_INVALID_ARGUMENT);
765     FSP_ERROR_RETURN((port == BSP_FEATURE_ELC_GROUP1_PORT_NUM) || (port == BSP_FEATURE_ELC_GROUP2_PORT_NUM),
766                      FSP_ERR_INVALID_ARGUMENT);
767 #else
768     FSP_PARAMETER_NOT_USED(p_ctrl);
769 #endif
770 
771     R_BSP_PinAccessEnable();           // Unlock Register Write Protection
772 
773     /* Get register address */
774 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
775     R_PORT_NS_COMMON_Type * p_ioport_regs = R_PORT_NSR;
776 #else
777     R_PORT_COMMON_Type * p_ioport_regs = R_PORT_NSR;
778 #endif
779 
780     /* Get port group number for the specified port */
781     if (BSP_FEATURE_ELC_GROUP1_PORT_NUM == port)
782     {
783         portgroup = 0U;
784     }
785     else if (BSP_FEATURE_ELC_GROUP2_PORT_NUM == port)
786     {
787         portgroup = 1U;
788     }
789     else
790     {
791         /* Do Nothing */
792     }
793 
794     temp_value  = p_ioport_regs->ELC_PDBF[portgroup].BY;
795     temp_value &= (ioport_size_t) (~mask_value);
796 
797     p_ioport_regs->ELC_PDBF[portgroup].BY = (uint8_t) (temp_value | event_data);
798 
799     R_BSP_PinAccessDisable();          // Lock Register Write Protection
800 
801     return FSP_SUCCESS;
802 }
803 
804 /**********************************************************************************************************************//**
805  * This function writes the event output data value to a pin. Implements @ref ioport_api_t::pinEventOutputWrite.
806  *
807  * Using the event system enables a pin state to be stored by this function in advance of being output on the pin.
808  * The output to the pin will occur when the ELC event occurs.
809  *
810  * @retval FSP_SUCCESS               Pin event data written
811  * @retval FSP_ERR_INVALID_ARGUMENT  Port or Pin or value not valid
812  * @retval FSP_ERR_NOT_OPEN          The module has not been opened
813  * @retval FSP_ERR_ASSERTION         NULL pointer
814  **********************************************************************************************************************/
R_IOPORT_PinEventOutputWrite(ioport_ctrl_t * const p_ctrl,bsp_io_port_pin_t pin,bsp_io_level_t pin_value)815 fsp_err_t R_IOPORT_PinEventOutputWrite (ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, bsp_io_level_t pin_value)
816 {
817     uint8_t singleport = 0U;
818     uint8_t cnt;
819     ioport_instance_ctrl_t * p_instance_ctrl = (ioport_instance_ctrl_t *) p_ctrl;
820 
821 #if (1 == IOPORT_CFG_PARAM_CHECKING_ENABLE)
822     FSP_ASSERT(NULL != p_instance_ctrl);
823     FSP_ERROR_RETURN(IOPORT_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
824     FSP_ERROR_RETURN((pin_value == BSP_IO_LEVEL_HIGH) || (pin_value == BSP_IO_LEVEL_LOW), FSP_ERR_INVALID_ARGUMENT);
825     uint32_t port_number = pin >> IOPORT_PRV_PORT_OFFSET;
826     FSP_ERROR_RETURN((port_number == BSP_FEATURE_ELC_GROUP1_PORT_NUM >> IOPORT_PRV_PORT_OFFSET) ||
827                      (port_number == BSP_FEATURE_ELC_GROUP2_PORT_NUM >> IOPORT_PRV_PORT_OFFSET),
828                      FSP_ERR_INVALID_ARGUMENT);
829 #endif
830 
831     const ioport_extend_cfg_t * elc_cfg = p_instance_ctrl->p_cfg->p_extend;
832 
833     R_BSP_PinAccessEnable();           // Unlock Register Write Protection
834 
835     /* Get register address */
836 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
837     R_PORT_NS_COMMON_Type * p_ioport_regs = R_PORT_NSR;
838 #else
839     R_PORT_COMMON_Type * p_ioport_regs = R_PORT_NSR;
840 #endif
841 
842     for (cnt = 0; cnt < IOPORT_SINGLE_PORT_NUM; cnt++)
843     {
844         if ((bsp_io_port_pin_t) elc_cfg->single_port_cfg[cnt].port_num == pin)
845         {
846             singleport = cnt;
847         }
848     }
849 
850     if (BSP_IO_LEVEL_HIGH == pin_value)
851     {
852         p_ioport_regs->ELC_PEL[singleport] |= (uint8_t) IOPORT_ELC_PEL_PSM_HIGH;
853     }
854     else
855     {
856         p_ioport_regs->ELC_PEL[singleport] &= (uint8_t) (~IOPORT_ELC_PEL_PSM_HIGH);
857     }
858 
859     R_BSP_PinAccessDisable();          // Lock Register Write Protection
860 
861     return FSP_SUCCESS;
862 }
863 
864 /*******************************************************************************************************************//**
865  * @} (end addtogroup IOPORT)
866  **********************************************************************************************************************/
867 
868 /***********************************************************************************************************************
869  * Private Functions
870  **********************************************************************************************************************/
871 
872 /*******************************************************************************************************************//**
873  * Configures pins.
874  *
875  * @param[in]    p_cfg          Pin configuration data
876  **********************************************************************************************************************/
r_ioport_pins_config(const ioport_cfg_t * p_cfg)877 void r_ioport_pins_config (const ioport_cfg_t * p_cfg)
878 {
879     uint16_t       pin_count;
880     ioport_cfg_t * p_pin_data;
881 
882     p_pin_data = (ioport_cfg_t *) p_cfg;
883 
884     R_BSP_PinAccessEnable();           // Unlock Register Write Protection
885 
886     for (pin_count = 0U; pin_count < p_pin_data->number_of_pins; pin_count++)
887     {
888         r_ioport_pin_set(p_pin_data->p_pin_cfg_data[pin_count].pin,
889                          (ioport_cfg_data_t *) &p_pin_data->p_pin_cfg_data[pin_count].pin_cfg);
890     }
891 
892     R_BSP_PinAccessDisable();          // Lock Register Write Protection
893 }
894 
895 /*******************************************************************************************************************//**
896  * Writes to the specified pin's multiple registers
897  *
898  * @param[in]    pin        Pin to write parameter data for
899  * @param[in]    p_cfg_data Value to be written to the multiple registers
900  *
901  **********************************************************************************************************************/
r_ioport_pin_set(bsp_io_port_pin_t pin,ioport_cfg_data_t * p_cfg_data)902 static void r_ioport_pin_set (bsp_io_port_pin_t pin, ioport_cfg_data_t * p_cfg_data)
903 {
904     /* Get port and pin number */
905     uint32_t port    = (IOPORT_PRV_PORT_BITS & (ioport_size_t) pin) >> IOPORT_PRV_PORT_OFFSET;
906     uint32_t pin_num = (IOPORT_PRV_PIN_BITS & (ioport_size_t) pin);
907 
908     /* Setting for Safety region or Non safety region */
909     if (p_cfg_data->rsel_reg == 1U)    // Setting for Non safety region
910     {
911 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
912         if (port > BSP_FEATURE_IOPORT_SELECTABLE_PORT_MAX)
913         {
914             R_PORT_NS_COMMON_Type * p_ioport_regs = R_PORT_NSR;
915             r_ioport_pin_set_non_safety(p_ioport_regs, pin, p_cfg_data);
916         }
917         else
918         {
919             R_PORT_SRS->RSELP[port] |= (uint8_t) (1U << pin_num);
920             R_PORT_COMMON_Type * p_ioport_regs = IOPORT_PRV_PORT_ADDRESS(IOPORT_REGION_SEL_NSAFE);
921             r_ioport_pin_set_safety(p_ioport_regs, pin, p_cfg_data);
922         }
923 
924 #else
925         R_PTADR->RSELP[port] |= (uint8_t) (1U << pin_num);
926         R_PORT_COMMON_Type * p_ioport_regs = IOPORT_PRV_PORT_ADDRESS(IOPORT_REGION_SEL_NSAFE);
927         r_ioport_pin_set_safety(p_ioport_regs, pin, p_cfg_data);
928 #endif
929     }
930     else                               // Setting for Safety region
931     {
932 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
933         R_PORT_SRS->RSELP[port] &= (uint8_t) (~(1U << pin_num));
934 #else
935         R_PTADR->RSELP[port] &= (uint8_t) (~(1U << pin_num));
936 #endif
937         R_PORT_COMMON_Type * p_ioport_regs = IOPORT_PRV_PORT_ADDRESS(IOPORT_REGION_SEL_SAFE);
938         r_ioport_pin_set_safety(p_ioport_regs, pin, p_cfg_data);
939     }
940 }
941 
942 /*******************************************************************************************************************//**
943  * Writes to the specified pin's multiple registers for safety port
944  *
945  * @param[in]    p_ioport_regs Base address of register to be accessed
946  * @param[in]    pin           Pin to write parameter data for
947  * @param[in]    p_cfg_data    Value to be written to the multiple registers
948  *
949  **********************************************************************************************************************/
r_ioport_pin_set_safety(R_PORT_COMMON_Type * p_ioport_regs,bsp_io_port_pin_t pin,ioport_cfg_data_t * p_cfg_data)950 static void r_ioport_pin_set_safety (R_PORT_COMMON_Type * p_ioport_regs,
951                                      bsp_io_port_pin_t    pin,
952                                      ioport_cfg_data_t  * p_cfg_data)
953 {
954     uint32_t temp_value;
955 
956     /* Get port and pin number */
957     uint32_t port    = (IOPORT_PRV_PORT_BITS & (ioport_size_t) pin) >> IOPORT_PRV_PORT_OFFSET;
958     uint32_t pin_num = (IOPORT_PRV_PIN_BITS & (ioport_size_t) pin);
959 
960     /* Setting DRCTL register */
961     if (3U >= pin_num)
962     {
963         temp_value = p_ioport_regs->DRCTL[port].L & ~(IOPORT_DRTCL_BIT_MASK << (pin_num * 8U));
964         p_ioport_regs->DRCTL[port].L = temp_value | (uint32_t) (p_cfg_data->drct_reg << (pin_num * 8U));
965     }
966     else if (3U < pin_num)
967     {
968         temp_value = p_ioport_regs->DRCTL[port].H & ~(IOPORT_DRTCL_BIT_MASK << ((pin_num - 4U) * 8U));
969         p_ioport_regs->DRCTL[port].H = temp_value | (uint32_t) (p_cfg_data->drct_reg << ((pin_num - 4U) * 8U));
970     }
971     else
972     {
973         /* Do Nothing */
974     }
975 
976     /* Setting for GPIO or peripheral */
977     if (1U == p_cfg_data->pmc_reg)     // Setting for peripheral
978     {
979 #if BSP_FEATURE_IOPORT_PIN_PFC_TYPE == 3
980         if (3U >= pin_num)
981         {
982             /* Setting PFC register */
983             temp_value                 = p_ioport_regs->PFC[port].L & ~(IOPORT_PFC_BIT_MASK << (pin_num * 8U));
984             p_ioport_regs->PFC[port].L = temp_value | (uint32_t) (p_cfg_data->pfc_reg << (pin_num * 8U));
985         }
986         else if (3U < pin_num)
987         {
988             /* Setting PFC register */
989             temp_value                 = p_ioport_regs->PFC[port].H & ~(IOPORT_PFC_BIT_MASK << ((pin_num - 4U) * 8U));
990             p_ioport_regs->PFC[port].H = temp_value | (uint32_t) (p_cfg_data->pfc_reg << ((pin_num - 4U) * 8U));
991         }
992         else
993         {
994             /* Do Nothing */
995         }
996 
997 #else
998 
999         /* Setting PFC register */
1000         temp_value               = p_ioport_regs->PFC[port] & ~(IOPORT_PFC_BIT_MASK << (pin_num * 4U));
1001         p_ioport_regs->PFC[port] = temp_value | (uint32_t) (p_cfg_data->pfc_reg << (pin_num * 4U));
1002 #endif
1003 
1004         /* Setting peripheral for port mode */
1005         p_ioport_regs->PMC[port] |= (uint8_t) (p_cfg_data->pmc_reg << pin_num); // Setting PMC register
1006     }
1007     else // Setting for GPIO
1008     {
1009         /* Setting GPIO for port mode */
1010         p_ioport_regs->PMC[port] &= (uint8_t) (~(1U << pin_num)); // Setting PMC register
1011 
1012         /* Setting for input or output */
1013         if (1U == p_cfg_data->pm_reg)                             // Setting for input
1014         {
1015             /* Setting PM register. */
1016             /* 01b: Input           */
1017             temp_value              = (uint32_t) (p_ioport_regs->PM[port] & ~(IOPORT_PM_BIT_MASK << (pin_num * 2U)));
1018             p_ioport_regs->PM[port] = (uint16_t) (temp_value | (uint32_t) (1U << (pin_num * 2U)));
1019         }
1020         else if (1U < p_cfg_data->pm_reg)     // Setting for two kinds of Output
1021         {
1022             /* Setting P register */
1023             if (0U == p_cfg_data->p_reg)      // Low output setting
1024             {
1025                 p_ioport_regs->P[port] &= (uint8_t) (~(1U << pin_num));
1026             }
1027             else if (1U == p_cfg_data->p_reg) // High output setting
1028             {
1029                 p_ioport_regs->P[port] |= (uint8_t) (1U << pin_num);
1030             }
1031             else
1032             {
1033                 /* Do Nothing */
1034             }
1035 
1036             /* Setting PM register.                              */
1037             /* 10b: Output                                       */
1038             /* 11b: Output(output data is input to input buffer) */
1039             temp_value              = (uint32_t) (p_ioport_regs->PM[port] & ~(IOPORT_PM_BIT_MASK << (pin_num * 2U)));
1040             p_ioport_regs->PM[port] = (uint16_t) (temp_value | (uint32_t) (p_cfg_data->pm_reg << (pin_num * 2U)));
1041         }
1042         else
1043         {
1044             /* Do Nothing */
1045         }
1046     }
1047 }
1048 
1049 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
1050 
1051 /*******************************************************************************************************************//**
1052  * Writes to the specified pin's multiple registers for non safety port
1053  *
1054  * @param[in]    p_ioport_regs Base address of register to be accessed
1055  * @param[in]    pin           Pin to write parameter data for
1056  * @param[in]    p_cfg_data    Value to be written to the multiple registers
1057  *
1058  **********************************************************************************************************************/
r_ioport_pin_set_non_safety(R_PORT_NS_COMMON_Type * p_ioport_regs,bsp_io_port_pin_t pin,ioport_cfg_data_t * p_cfg_data)1059 static void r_ioport_pin_set_non_safety (R_PORT_NS_COMMON_Type * p_ioport_regs,
1060                                          bsp_io_port_pin_t       pin,
1061                                          ioport_cfg_data_t     * p_cfg_data)
1062 {
1063     uint32_t temp_value;
1064 
1065     /* Get port and pin number */
1066     uint32_t port    = (IOPORT_PRV_PORT_BITS & (ioport_size_t) pin) >> IOPORT_PRV_PORT_OFFSET;
1067     uint32_t pin_num = (IOPORT_PRV_PIN_BITS & (ioport_size_t) pin);
1068 
1069     /* Setting DRCTL register */
1070     if (3U >= pin_num)
1071     {
1072         temp_value = p_ioport_regs->DRCTL[port].L & ~(IOPORT_DRTCL_BIT_MASK << (pin_num * 8U));
1073         p_ioport_regs->DRCTL[port].L = temp_value | (uint32_t) (p_cfg_data->drct_reg << (pin_num * 8U));
1074     }
1075     else if (3U < pin_num)
1076     {
1077         temp_value = p_ioport_regs->DRCTL[port].H & ~(IOPORT_DRTCL_BIT_MASK << ((pin_num - 4U) * 8U));
1078         p_ioport_regs->DRCTL[port].H = temp_value | (uint32_t) (p_cfg_data->drct_reg << ((pin_num - 4U) * 8U));
1079     }
1080     else
1081     {
1082         /* Do Nothing */
1083     }
1084 
1085     /* Setting for GPIO or peripheral */
1086     if (1U == p_cfg_data->pmc_reg)     // Setting for peripheral
1087     {
1088  #if BSP_FEATURE_IOPORT_PIN_PFC_TYPE == 3
1089         if (3U >= pin_num)
1090         {
1091             /* Setting PFC register */
1092             temp_value                 = p_ioport_regs->PFC[port].L & ~(IOPORT_PFC_BIT_MASK << (pin_num * 8U));
1093             p_ioport_regs->PFC[port].L = temp_value | (uint32_t) (p_cfg_data->pfc_reg << (pin_num * 8U));
1094         }
1095         else if (3U < pin_num)
1096         {
1097             /* Setting PFC register */
1098             temp_value                 = p_ioport_regs->PFC[port].H & ~(IOPORT_PFC_BIT_MASK << ((pin_num - 4U) * 8U));
1099             p_ioport_regs->PFC[port].H = temp_value | (uint32_t) (p_cfg_data->pfc_reg << ((pin_num - 4U) * 8U));
1100         }
1101         else
1102         {
1103             /* Do Nothing */
1104         }
1105 
1106  #else
1107 
1108         /* Setting PFC register */
1109         temp_value               = p_ioport_regs->PFC[port] & ~(IOPORT_PFC_BIT_MASK << (pin_num * 4U));
1110         p_ioport_regs->PFC[port] = temp_value | (uint32_t) (p_cfg_data->pfc_reg << (pin_num * 4U));
1111  #endif
1112 
1113         /* Setting peripheral for port mode */
1114         p_ioport_regs->PMC[port] |= (uint8_t) (p_cfg_data->pmc_reg << pin_num);
1115     }
1116     else                                                          // Setting for GPIO
1117     {
1118         /* Setting GPIO for port mode */
1119         p_ioport_regs->PMC[port] &= (uint8_t) (~(1U << pin_num)); // Setting PMC register
1120 
1121         /* Setting for input or output */
1122         if (1U == p_cfg_data->pm_reg)                             // Setting for input
1123         {
1124             /* Setting PM register. */
1125             /* 01b: Input           */
1126             temp_value              = (uint32_t) (p_ioport_regs->PM[port] & ~(IOPORT_PM_BIT_MASK << (pin_num * 2U)));
1127             p_ioport_regs->PM[port] = (uint16_t) (temp_value | (uint32_t) (1U << (pin_num * 2U)));
1128         }
1129         else if (1U < p_cfg_data->pm_reg)     // Setting for two kinds of Output
1130         {
1131             /* Setting P register */
1132             if (0U == p_cfg_data->p_reg)      // Low output setting
1133             {
1134                 p_ioport_regs->P[port] &= (uint8_t) (~(1U << pin_num));
1135             }
1136             else if (1U == p_cfg_data->p_reg) // High output setting
1137             {
1138                 p_ioport_regs->P[port] |= (uint8_t) (1U << pin_num);
1139             }
1140             else
1141             {
1142                 /* Do Nothing */
1143             }
1144 
1145             /* Setting PM register.                              */
1146             /* 10b: Output                                       */
1147             /* 11b: Output(output data is input to input buffer) */
1148             temp_value              = (uint32_t) (p_ioport_regs->PM[port] & ~(IOPORT_PM_BIT_MASK << (pin_num * 2U)));
1149             p_ioport_regs->PM[port] = (uint16_t) (temp_value | (uint32_t) (p_cfg_data->pm_reg << (pin_num * 2U)));
1150         }
1151         else
1152         {
1153             /* Do Nothing */
1154         }
1155     }
1156 }
1157 
1158 #endif
1159 
1160 /*******************************************************************************************************************//**
1161  * Writes to the specified pin's multiple registers to generate event link function
1162  *
1163  * @param[in]    p_extend_cfg_data Value to be written to the multiple registers
1164  *
1165  **********************************************************************************************************************/
r_ioport_event_config(const ioport_extend_cfg_t * p_extend_cfg_data)1166 static void r_ioport_event_config (const ioport_extend_cfg_t * p_extend_cfg_data)
1167 {
1168     uint8_t event_num;
1169     uint8_t temp_value    = 0x00;
1170     uint8_t single_enable = 0x00;
1171     uint8_t group_enable  = 0x00;
1172 #if BSP_FEATURE_IOPORT_HAS_NONSAFETY_DEDICATED_PORT
1173     R_PORT_NS_COMMON_Type * p_ioport_regs;
1174 #else
1175     R_PORT_COMMON_Type * p_ioport_regs;
1176 #endif
1177 
1178     ioport_extend_cfg_t * ex_cfg;
1179 
1180     ex_cfg = (ioport_extend_cfg_t *) p_extend_cfg_data;
1181 
1182     R_BSP_PinAccessEnable();           // Unlock Register Write Protection
1183 
1184     /* Get register address */
1185     p_ioport_regs = R_PORT_NSR;
1186 
1187     /* Single port configuration */
1188     for (event_num = 0U; event_num < IOPORT_SINGLE_PORT_NUM; event_num++)
1189     {
1190         uint8_t port =
1191             (uint8_t) ((ex_cfg->single_port_cfg[event_num].port_num & IOPORT_PRV_PORT_BITS) >> IOPORT_PRV_PORT_OFFSET);
1192         uint8_t pin_num = (uint8_t) ex_cfg->single_port_cfg[event_num].port_num & IOPORT_PRV_PIN_BITS;
1193 
1194         temp_value = p_ioport_regs->ELC_PEL[event_num] & IOPORT_ELC_PEL_MASK;
1195 
1196         /* Port selection */
1197         if ((BSP_FEATURE_ELC_GROUP1_PORT_NUM >> IOPORT_PRV_PORT_OFFSET) == port)
1198         {
1199             temp_value |= 1U << 3;
1200         }
1201         else if ((BSP_FEATURE_ELC_GROUP2_PORT_NUM >> IOPORT_PRV_PORT_OFFSET) == port)
1202         {
1203             temp_value |= 1U << 4;
1204         }
1205         else
1206         {
1207             /* Do Nothing */
1208         }
1209 
1210         temp_value |= pin_num;         // Pin number setting
1211 
1212         /* When the pin specified as single input port, Set edge detection */
1213         /* When the pin specified as single output port, Set output operation */
1214         if (IOPORT_EVENT_DIRECTION_INPUT == ex_cfg->single_port_cfg[event_num].direction)
1215         {
1216             temp_value |= (uint8_t) (ex_cfg->single_port_cfg[event_num].edge_detection << 5); // Edge detection
1217 
1218             /* Edge detection enable */
1219             p_ioport_regs->ELC_DPTC |= (uint8_t) (1U << event_num);
1220         }
1221         else
1222         {
1223             temp_value |= (uint8_t) (ex_cfg->single_port_cfg[event_num].operation << 5); // Output operation
1224         }
1225 
1226         /* Set to ELC port setting register */
1227         p_ioport_regs->ELC_PEL[event_num] = temp_value;
1228 
1229         /* Single port event link function enable */
1230         if (IOPORT_EVENT_CONTROL_ENABLE == ex_cfg->single_port_cfg[event_num].event_control)
1231         {
1232             single_enable |= (uint8_t) (1U << event_num);
1233         }
1234     }
1235 
1236     /* Port group configuration */
1237     for (event_num = 0U; event_num < IOPORT_PORT_GROUP_NUM; event_num++)
1238     {
1239         /* Pin selection */
1240         uint8_t group_pin = ex_cfg->port_group_input_cfg[event_num].pin_select |
1241                             ex_cfg->port_group_output_cfg[event_num].pin_select;
1242         p_ioport_regs->ELC_PGR[event_num] = group_pin;
1243 
1244         if (IOPORT_EVENT_CONTROL_ENABLE == ex_cfg->port_group_input_cfg[event_num].event_control)
1245         {
1246             /* Input port group control */
1247             temp_value  = p_ioport_regs->ELC_PGC[event_num] & IOOPRT_ELC_PGC_MASK;
1248             temp_value |= (uint8_t) (ex_cfg->port_group_input_cfg[event_num].edge_detection);          // Edge detection
1249             temp_value |= (uint8_t) (ex_cfg->port_group_input_cfg[event_num].overwrite_control << 2U); // Overwrite setting
1250 
1251             /* Buffer register initialization */
1252             p_ioport_regs->ELC_PDBF[event_num].BY = ex_cfg->port_group_input_cfg[event_num].buffer_init_value;
1253 
1254             /* Input port group event link function enable */
1255             group_enable |= (uint8_t) (1U << event_num);
1256         }
1257 
1258         /* Output port group operation */
1259         temp_value |= (uint8_t) (ex_cfg->port_group_output_cfg[event_num].operation << 4);
1260 
1261         /* Set to port group control register */
1262         p_ioport_regs->ELC_PGC[event_num] = temp_value;
1263     }
1264 
1265     /* Set to ELC port event control register */
1266     p_ioport_regs->ELC_ELSR2 = (uint8_t) ((single_enable << 4) | (group_enable << 2));
1267 
1268     R_BSP_PinAccessDisable();          // Lock Register Write Protection
1269 }
1270