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