mirror of
https://github.com/apache/nuttx.git
synced 2026-10-02 11:48:02 +00:00
arch/arm/imxrt: Add support for IOMUXC and rgpio for imxrt118x
- Add imxrt118x compatible IOMUX definitions, named as IOMUX_VER3. This is the same IP as what is used for example for IMX9. Instead of directly copying the support from imx9, pack the padconfig into the same 32-bit value used for GPIO for easy use. - Add imxrt118x compatible rgpio driver. This is the same GPIO block as what has been used in imx9. Instead of directly copying the support from IMX9, add pin muxing directly into GPIO driver as well, to keep the usage compatible with existing IMXRT boards. Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
This commit is contained in:
parent
5137e583d6
commit
80d6f34cd7
17 changed files with 3426 additions and 14 deletions
|
|
@ -84,6 +84,11 @@
|
|||
/* MIMXRT1170DVMA TODO
|
||||
*/
|
||||
# define IMXRT_GPIO_NPORTS 13 /* Thirteen total ports */
|
||||
#elif defined(CONFIG_ARCH_CHIP_MIMXRT1189CVM8C) || \
|
||||
defined(CONFIG_ARCH_CHIP_MIMXRT1189CVM8C_CM33)
|
||||
/* MIMXRT1189CVM8C - Dual-core Cortex-M33 + Cortex-M7 */
|
||||
|
||||
# define IMXRT_GPIO_NPORTS 6 /* Six general purpose GPIO ports */
|
||||
#else
|
||||
# error "Unknown i.MX RT chip type"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -24,7 +24,11 @@
|
|||
|
||||
# Required i.MX RT files
|
||||
|
||||
set(SRCS imxrt_allocateheap.c imxrt_start.c imxrt_periphclks.c)
|
||||
set(SRCS imxrt_allocateheap.c imxrt_start.c)
|
||||
|
||||
if(NOT CONFIG_IMXRT_RGPIO)
|
||||
list(APPEND SRCS imxrt_periphclks.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_IMXRT_PROGMEM)
|
||||
list(APPEND SRCS imxrt_flash.c)
|
||||
|
|
@ -35,14 +39,18 @@ list(
|
|||
SRCS
|
||||
imxrt_irq.c
|
||||
imxrt_clrpend.c
|
||||
imxrt_gpio.c
|
||||
imxrt_daisy.c
|
||||
imxrt_wdog.c
|
||||
imxrt_serial.c
|
||||
imxrt_xbar.c
|
||||
imxrt_ocotp.c
|
||||
imxrt_lowputc.c)
|
||||
|
||||
if(CONFIG_IMXRT_RGPIO)
|
||||
list(APPEND SRCS imxrt_rgpio.c)
|
||||
else()
|
||||
list(APPEND SRCS imxrt_gpio.c imxrt_daisy.c)
|
||||
endif()
|
||||
|
||||
# Configuration-dependent i.MX RT files
|
||||
|
||||
if(CONFIG_IMXRT_CLOCKCONFIG_VER3)
|
||||
|
|
@ -53,7 +61,9 @@ else()
|
|||
list(APPEND SRCS imxrt_clockconfig_ver1.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_IMXRT_IOMUX_VER2)
|
||||
if(CONFIG_IMXRT_IOMUX_VER3)
|
||||
list(APPEND SRCS imxrt_iomuxc_ver3.c)
|
||||
elseif(CONFIG_IMXRT_IOMUX_VER2)
|
||||
list(APPEND SRCS imxrt_iomuxc_ver2.c)
|
||||
else()
|
||||
list(APPEND SRCS imxrt_iomuxc_ver1.c)
|
||||
|
|
@ -70,7 +80,11 @@ else()
|
|||
endif()
|
||||
|
||||
if(CONFIG_IMXRT_GPIO_IRQ)
|
||||
list(APPEND SRCS imxrt_gpioirq.c)
|
||||
if(CONFIG_IMXRT_RGPIO)
|
||||
list(APPEND SRCS imxrt_rgpioirq.c)
|
||||
else()
|
||||
list(APPEND SRCS imxrt_gpioirq.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_ARM_MPU)
|
||||
|
|
|
|||
|
|
@ -235,6 +235,8 @@ config ARCH_FAMILY_IMXRT118x
|
|||
select IMXRT_HAVE_LPUART11
|
||||
select IMXRT_HAVE_LPUART12
|
||||
select IMXRT_CLOCKCONFIG_VER3
|
||||
select IMXRT_IOMUX_VER3
|
||||
select IMXRT_RGPIO
|
||||
---help---
|
||||
i.MX RT1180 dual-core Crossover Processors (Cortex-M33 + Cortex-M7).
|
||||
|
||||
|
|
@ -417,6 +419,19 @@ config IMXRT_IOMUX_VER2
|
|||
bool
|
||||
default n
|
||||
|
||||
config IMXRT_IOMUX_VER3
|
||||
bool
|
||||
default n
|
||||
---help---
|
||||
Selects the "generation 3" IOMUXC driver used by RT118x.
|
||||
|
||||
config IMXRT_RGPIO
|
||||
bool
|
||||
default n
|
||||
---help---
|
||||
Selects the RGPIO driver (arch/arm/src/imxrt/imxrt_rgpio.c) that
|
||||
targets the RGPIO IP block used on RT118x.
|
||||
|
||||
config IMXRT_TRDC
|
||||
bool
|
||||
default n
|
||||
|
|
@ -2451,42 +2466,52 @@ if IMXRT_GPIO_IRQ
|
|||
config IMXRT_GPIO1_0_15_IRQ
|
||||
bool "GPIO1 Pins 0-15 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO1_16_31_IRQ
|
||||
bool "GPIO1 Pins 16-31 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO2_0_15_IRQ
|
||||
bool "GPIO2 Pins 0-15 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO2_16_31_IRQ
|
||||
bool "GPIO2 Pins 16-31 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO3_0_15_IRQ
|
||||
bool "GPIO3 Pins 0-15 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO3_16_31_IRQ
|
||||
bool "GPIO3 Pins 16-31 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO4_0_15_IRQ
|
||||
bool "GPIO4 Pins 0-15 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO4_16_31_IRQ
|
||||
bool "GPIO4 Pins 16-31 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO5_0_15_IRQ
|
||||
bool "GPIO5 Pins 0-15 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO5_16_31_IRQ
|
||||
bool "GPIO5 Pins 16-31 interrupts"
|
||||
default n
|
||||
depends on !IMXRT_RGPIO
|
||||
|
||||
config IMXRT_GPIO6_0_15_IRQ
|
||||
bool "GPIO6 Pins 0-15 interrupts"
|
||||
|
|
|
|||
|
|
@ -30,13 +30,22 @@ endif
|
|||
|
||||
# Required i.MX RT files
|
||||
|
||||
CHIP_CSRCS = imxrt_allocateheap.c imxrt_start.c imxrt_periphclks.c
|
||||
CHIP_CSRCS = imxrt_allocateheap.c imxrt_start.c
|
||||
ifneq ($(CONFIG_IMXRT_RGPIO),y)
|
||||
CHIP_CSRCS += imxrt_periphclks.c
|
||||
endif
|
||||
ifeq ($(CONFIG_IMXRT_PROGMEM),y)
|
||||
CHIP_CSRCS += imxrt_flash.c
|
||||
endif
|
||||
CHIP_CSRCS += imxrt_irq.c imxrt_clrpend.c imxrt_gpio.c
|
||||
CHIP_CSRCS += imxrt_daisy.c imxrt_wdog.c imxrt_serial.c
|
||||
CHIP_CSRCS += imxrt_xbar.c imxrt_ocotp.c imxrt_lowputc.c
|
||||
CHIP_CSRCS += imxrt_irq.c imxrt_clrpend.c
|
||||
ifeq ($(CONFIG_IMXRT_RGPIO),y)
|
||||
CHIP_CSRCS += imxrt_rgpio.c
|
||||
else
|
||||
CHIP_CSRCS += imxrt_gpio.c
|
||||
CHIP_CSRCS += imxrt_daisy.c
|
||||
endif
|
||||
CHIP_CSRCS += imxrt_wdog.c imxrt_serial.c imxrt_xbar.c imxrt_ocotp.c
|
||||
CHIP_CSRCS += imxrt_lowputc.c
|
||||
|
||||
# Configuration-dependent i.MX RT files
|
||||
|
||||
|
|
@ -48,7 +57,9 @@ else
|
|||
CHIP_CSRCS += imxrt_clockconfig_ver1.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IMXRT_IOMUX_VER2),y)
|
||||
ifeq ($(CONFIG_IMXRT_IOMUX_VER3),y)
|
||||
CHIP_CSRCS += imxrt_iomuxc_ver3.c
|
||||
else ifeq ($(CONFIG_IMXRT_IOMUX_VER2),y)
|
||||
CHIP_CSRCS += imxrt_iomuxc_ver2.c
|
||||
else
|
||||
CHIP_CSRCS += imxrt_iomuxc_ver1.c
|
||||
|
|
@ -65,8 +76,12 @@ CHIP_CSRCS += imxrt_tickless.c
|
|||
endif
|
||||
|
||||
ifeq ($(CONFIG_IMXRT_GPIO_IRQ),y)
|
||||
ifeq ($(CONFIG_IMXRT_RGPIO),y)
|
||||
CHIP_CSRCS += imxrt_rgpioirq.c
|
||||
else
|
||||
CHIP_CSRCS += imxrt_gpioirq.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARM_MPU),y)
|
||||
CHIP_CSRCS += imxrt_mpuinit.c
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
# include "hardware/rt106x/imxrt106x_gpio.h"
|
||||
#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x)
|
||||
# include "hardware/rt117x/imxrt117x_gpio.h"
|
||||
#elif defined(CONFIG_ARCH_FAMILY_IMXRT118x)
|
||||
# include "hardware/imxrt_memorymap.h"
|
||||
#else
|
||||
# error Unrecognized i.MX RT architecture
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,10 +30,13 @@
|
|||
#include <nuttx/config.h>
|
||||
|
||||
/* IMXRT117X IOMUX Differs too much from IMXRT10XX
|
||||
* hence we use a VER2 driver
|
||||
* hence we use a VER2 driver. IMXRT118x uses another (generation 3)
|
||||
* IOMUXC IP; that is IMXRT_IOMUX_VER3.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_IMXRT_IOMUX_VER2
|
||||
#ifdef CONFIG_IMXRT_IOMUX_VER3
|
||||
#include "imxrt_iomuxc_ver3.h"
|
||||
#elif defined(CONFIG_IMXRT_IOMUX_VER2)
|
||||
#include "imxrt_iomuxc_ver2.h"
|
||||
#else
|
||||
#include "imxrt_iomuxc_ver1.h"
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
# include "hardware/rt106x/imxrt106x_pinmux.h"
|
||||
#elif defined(CONFIG_ARCH_FAMILY_IMXRT117x)
|
||||
# include "hardware/rt117x/imxrt117x_pinmux.h"
|
||||
#elif defined(CONFIG_ARCH_FAMILY_IMXRT118x)
|
||||
# include "hardware/rt118x/imxrt118x_pinmux.h"
|
||||
#else
|
||||
# error Unrecognized i.MX RT architecture
|
||||
#endif
|
||||
|
|
|
|||
119
arch/arm/src/imxrt/hardware/rt118x/imxrt118x_gpio.h
Normal file
119
arch/arm/src/imxrt/hardware/rt118x/imxrt118x_gpio.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/hardware/rt118x/imxrt118x_gpio.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_GPIO_H
|
||||
#define __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_GPIO_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/imxrt_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* RGPIO register offsets (IMXRT1180RM chapter 16) **************************/
|
||||
|
||||
#define IMXRT_GPIO_VERID_OFFSET (0x0000) /* Version ID */
|
||||
#define IMXRT_GPIO_PARAM_OFFSET (0x0004) /* Parameter */
|
||||
#define IMXRT_GPIO_LOCK_OFFSET (0x000c) /* Lock */
|
||||
#define IMXRT_GPIO_PCNS_OFFSET (0x0010) /* Pin Control Nonsecure */
|
||||
#define IMXRT_GPIO_ICNS_OFFSET (0x0014) /* Interrupt Control Nonsecure */
|
||||
#define IMXRT_GPIO_PCNP_OFFSET (0x0018) /* Pin Control Nonprivilege */
|
||||
#define IMXRT_GPIO_ICNP_OFFSET (0x001c) /* Interrupt Control Nonprivilege */
|
||||
#define IMXRT_GPIO_PDOR_OFFSET (0x0040) /* Port Data Output */
|
||||
#define IMXRT_GPIO_PSOR_OFFSET (0x0044) /* Port Set Output */
|
||||
#define IMXRT_GPIO_PCOR_OFFSET (0x0048) /* Port Clear Output */
|
||||
#define IMXRT_GPIO_PTOR_OFFSET (0x004c) /* Port Toggle Output */
|
||||
#define IMXRT_GPIO_PDIR_OFFSET (0x0050) /* Port Data Input */
|
||||
#define IMXRT_GPIO_PDDR_OFFSET (0x0054) /* Port Data Direction */
|
||||
#define IMXRT_GPIO_PIDR_OFFSET (0x0058) /* Port Input Disable */
|
||||
#define IMXRT_GPIO_P0DR_OFFSET (0x0060) /* Pin Data (0-31 at n * 4h) */
|
||||
#define IMXRT_GPIO_ICR0_OFFSET (0x0080) /* Interrupt Control (0-31 at n * 4h) */
|
||||
#define IMXRT_GPIO_GICLR_OFFSET (0x0100) /* Global Interrupt Control Low */
|
||||
#define IMXRT_GPIO_GICHR_OFFSET (0x0104) /* Global Interrupt Control High */
|
||||
#define IMXRT_GPIO_ISFR0_OFFSET (0x0120) /* Interrupt Status Flag 0 (0..15) */
|
||||
#define IMXRT_GPIO_ISFR1_OFFSET (0x0124) /* Interrupt Status Flag 1 (16..31) */
|
||||
|
||||
/* GPIO port enumeration ****************************************************/
|
||||
|
||||
#define GPIO1 0
|
||||
#define GPIO2 1
|
||||
#define GPIO3 2
|
||||
#define GPIO4 3
|
||||
#define GPIO5 4
|
||||
#define GPIO6 5
|
||||
|
||||
#define IMXRT_GPIO_NPORTS 6
|
||||
#define IMXRT_GPIO_NPINS 32
|
||||
|
||||
/* Register bit definitions *************************************************/
|
||||
|
||||
/* Most registers are laid out simply with one bit per pin */
|
||||
|
||||
#define GPIO_PIN(n) (1u << (n)) /* Bit n: Pin n, n=0-31 */
|
||||
|
||||
/* ICRN register (per-pin interrupt configuration) */
|
||||
|
||||
#define IMXRT_GPIO_ICRN_ISF (1u << 24) /* Bit 24: Interrupt Status Flag */
|
||||
#define IMXRT_GPIO_ICRN_LK (1u << 23) /* Bit 23: Lock */
|
||||
#define IMXRT_GPIO_ICRN_IRQS (1u << 20) /* Bit 20: Selects the interrupt/DMA channel */
|
||||
#define IMXRT_GPIO_ICRN_SHIFT (16) /* Bits 16-19: Interrupt Configuration */
|
||||
#define IMXRT_GPIO_ICRN_MASK (0xfu << IMXRT_GPIO_ICRN_SHIFT)
|
||||
# define IMXRT_GPIO_ICRN_DISABLED (0u << IMXRT_GPIO_ICRN_SHIFT) /* ISF disabled */
|
||||
# define IMXRT_GPIO_ICRN_DMARISING (1u << IMXRT_GPIO_ICRN_SHIFT) /* DMA rising */
|
||||
# define IMXRT_GPIO_ICRN_DMAFALLING (2u << IMXRT_GPIO_ICRN_SHIFT) /* DMA falling */
|
||||
# define IMXRT_GPIO_ICRN_DMABOTH (3u << IMXRT_GPIO_ICRN_SHIFT) /* DMA both */
|
||||
# define IMXRT_GPIO_ICRN_ISFRISING (5u << IMXRT_GPIO_ICRN_SHIFT) /* ISF-only rising */
|
||||
# define IMXRT_GPIO_ICRN_ISFFALLING (6u << IMXRT_GPIO_ICRN_SHIFT) /* ISF-only falling */
|
||||
# define IMXRT_GPIO_ICRN_ISFBOTH (7u << IMXRT_GPIO_ICRN_SHIFT) /* ISF-only both */
|
||||
# define IMXRT_GPIO_ICRN_ZERO (8u << IMXRT_GPIO_ICRN_SHIFT) /* IRQ when 0 */
|
||||
# define IMXRT_GPIO_ICRN_RISING (9u << IMXRT_GPIO_ICRN_SHIFT) /* IRQ rising */
|
||||
# define IMXRT_GPIO_ICRN_FALLING (10u << IMXRT_GPIO_ICRN_SHIFT) /* IRQ falling */
|
||||
# define IMXRT_GPIO_ICRN_BOTH (11u << IMXRT_GPIO_ICRN_SHIFT) /* IRQ both */
|
||||
# define IMXRT_GPIO_ICRN_ONE (12u << IMXRT_GPIO_ICRN_SHIFT) /* IRQ when 1 */
|
||||
|
||||
/* Global Interrupt Control Low (pins 0..15) */
|
||||
|
||||
#define IMXRT_GPIO_GICLR_GIWD_SHIFT (0)
|
||||
#define IMXRT_GPIO_GICLR_GIWD_MASK (0xffffu << IMXRT_GPIO_GICLR_GIWD_SHIFT)
|
||||
# define IMXRT_GPIO_GICLR_GIWD_PIN(n) ((uint32_t)(n) << IMXRT_GPIO_GICLR_GIWD_SHIFT)
|
||||
#define IMXRT_GPIO_GICLR_GIWE_SHIFT (16)
|
||||
#define IMXRT_GPIO_GICLR_GIWE_MASK (0xffffu << IMXRT_GPIO_GICLR_GIWE_SHIFT)
|
||||
# define IMXRT_GPIO_GICLR_GIWE_PIN(n) ((uint32_t)(n) << IMXRT_GPIO_GICLR_GIWE_SHIFT)
|
||||
|
||||
/* Global Interrupt Control High (pins 16..31) */
|
||||
|
||||
#define IMXRT_GPIO_GICHR_GIWD_SHIFT (0)
|
||||
#define IMXRT_GPIO_GICHR_GIWD_MASK (0xffffu << IMXRT_GPIO_GICHR_GIWD_SHIFT)
|
||||
# define IMXRT_GPIO_GICHR_GIWD_PIN(n) ((uint32_t)((n) - 16) << IMXRT_GPIO_GICHR_GIWD_SHIFT)
|
||||
#define IMXRT_GPIO_GICHR_GIWE_SHIFT (16)
|
||||
#define IMXRT_GPIO_GICHR_GIWE_MASK (0xffffu << IMXRT_GPIO_GICHR_GIWE_SHIFT)
|
||||
# define IMXRT_GPIO_GICHR_GIWE_PIN(n) ((uint32_t)((n) - 16) << IMXRT_GPIO_GICHR_GIWE_SHIFT)
|
||||
|
||||
/* Interrupt Status Flag Register */
|
||||
|
||||
#define IMXRT_GPIO_ISFR(n) (1u << (n)) /* Interrupt Status Flag, n=0-31 */
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_GPIO_H */
|
||||
220
arch/arm/src/imxrt/hardware/rt118x/imxrt118x_iomuxc.h
Normal file
220
arch/arm/src/imxrt/hardware/rt118x/imxrt118x_iomuxc.h
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/hardware/rt118x/imxrt118x_iomuxc.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_IOMUXC_H
|
||||
#define __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_IOMUXC_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* IOMUXC register bit-fields (IMXRT1180RM chapter 17)
|
||||
*
|
||||
* SW_MUX_CTL_PAD register:
|
||||
* [3:0] MUX_MODE (alternate function 0..12)
|
||||
* [4] SION (force input path)
|
||||
*
|
||||
* SW_PAD_CTL_PAD register:
|
||||
* [1] PDRV (0 = high driver, 1 = normal driver)
|
||||
* [3:2] PULL (00 = keep, 01 = pull-up, 10 = pull-down, 11 = disabled)
|
||||
* [4] ODE (open drain enable)
|
||||
* [5] HYS (Schmitt trigger / hysteresis enable)
|
||||
* [6] FSEL_APC (fast/slow slew select)
|
||||
* [7] DDR_MODE (DDR input mode; only implemented on selected pads)
|
||||
*/
|
||||
|
||||
/* MUX_CTL fields */
|
||||
|
||||
#define IOMUXC_MUX_MODE_SHIFT (0)
|
||||
#define IOMUXC_MUX_MODE_MASK (0x0fu << IOMUXC_MUX_MODE_SHIFT)
|
||||
# define IOMUXC_MUX_MODE_ALT(n) (((n) & 0x0fu) << IOMUXC_MUX_MODE_SHIFT)
|
||||
# define IOMUXC_MUX_MODE_ALT0 IOMUXC_MUX_MODE_ALT(0)
|
||||
# define IOMUXC_MUX_MODE_ALT1 IOMUXC_MUX_MODE_ALT(1)
|
||||
# define IOMUXC_MUX_MODE_ALT2 IOMUXC_MUX_MODE_ALT(2)
|
||||
# define IOMUXC_MUX_MODE_ALT3 IOMUXC_MUX_MODE_ALT(3)
|
||||
# define IOMUXC_MUX_MODE_ALT4 IOMUXC_MUX_MODE_ALT(4)
|
||||
# define IOMUXC_MUX_MODE_ALT5 IOMUXC_MUX_MODE_ALT(5)
|
||||
# define IOMUXC_MUX_MODE_ALT6 IOMUXC_MUX_MODE_ALT(6)
|
||||
# define IOMUXC_MUX_MODE_ALT7 IOMUXC_MUX_MODE_ALT(7)
|
||||
# define IOMUXC_MUX_MODE_ALT8 IOMUXC_MUX_MODE_ALT(8)
|
||||
# define IOMUXC_MUX_MODE_ALT9 IOMUXC_MUX_MODE_ALT(9)
|
||||
# define IOMUXC_MUX_MODE_ALT10 IOMUXC_MUX_MODE_ALT(10)
|
||||
# define IOMUXC_MUX_MODE_ALT11 IOMUXC_MUX_MODE_ALT(11)
|
||||
# define IOMUXC_MUX_MODE_ALT12 IOMUXC_MUX_MODE_ALT(12)
|
||||
|
||||
#define IOMUXC_MUX_SION_SHIFT (4)
|
||||
#define IOMUXC_MUX_SION_MASK (0x01u << IOMUXC_MUX_SION_SHIFT)
|
||||
# define IOMUXC_MUX_SION_OFF (0u << IOMUXC_MUX_SION_SHIFT)
|
||||
# define IOMUXC_MUX_SION_ON (1u << IOMUXC_MUX_SION_SHIFT)
|
||||
|
||||
/* PAD_CTL fields */
|
||||
|
||||
#define IOMUXC_PAD_PDRV_SHIFT (1)
|
||||
#define IOMUXC_PAD_PDRV_MASK (0x01u << IOMUXC_PAD_PDRV_SHIFT)
|
||||
# define IOMUXC_PAD_PDRV_HIGH (0u << IOMUXC_PAD_PDRV_SHIFT)
|
||||
# define IOMUXC_PAD_PDRV_NORMAL (1u << IOMUXC_PAD_PDRV_SHIFT)
|
||||
|
||||
#define IOMUXC_PAD_PULL_SHIFT (2)
|
||||
#define IOMUXC_PAD_PULL_MASK (0x03u << IOMUXC_PAD_PULL_SHIFT)
|
||||
# define IOMUXC_PAD_PULL_KEEP (0u << IOMUXC_PAD_PULL_SHIFT)
|
||||
# define IOMUXC_PAD_PULL_UP (1u << IOMUXC_PAD_PULL_SHIFT)
|
||||
# define IOMUXC_PAD_PULL_DOWN (2u << IOMUXC_PAD_PULL_SHIFT)
|
||||
# define IOMUXC_PAD_PULL_NONE (3u << IOMUXC_PAD_PULL_SHIFT)
|
||||
|
||||
#define IOMUXC_PAD_ODE_SHIFT (4)
|
||||
#define IOMUXC_PAD_ODE_MASK (0x01u << IOMUXC_PAD_ODE_SHIFT)
|
||||
# define IOMUXC_PAD_ODE_OFF (0u << IOMUXC_PAD_ODE_SHIFT)
|
||||
# define IOMUXC_PAD_ODE_ON (1u << IOMUXC_PAD_ODE_SHIFT)
|
||||
|
||||
#define IOMUXC_PAD_HYS_SHIFT (5)
|
||||
#define IOMUXC_PAD_HYS_MASK (0x01u << IOMUXC_PAD_HYS_SHIFT)
|
||||
# define IOMUXC_PAD_HYS_OFF (0u << IOMUXC_PAD_HYS_SHIFT)
|
||||
# define IOMUXC_PAD_HYS_ON (1u << IOMUXC_PAD_HYS_SHIFT)
|
||||
|
||||
#define IOMUXC_PAD_FSEL_SHIFT (6)
|
||||
#define IOMUXC_PAD_FSEL_MASK (0x01u << IOMUXC_PAD_FSEL_SHIFT)
|
||||
# define IOMUXC_PAD_FSEL_SLOW (0u << IOMUXC_PAD_FSEL_SHIFT)
|
||||
# define IOMUXC_PAD_FSEL_FAST (1u << IOMUXC_PAD_FSEL_SHIFT)
|
||||
|
||||
#define IOMUXC_PAD_DDR_SHIFT (7)
|
||||
#define IOMUXC_PAD_DDR_MASK (0x01u << IOMUXC_PAD_DDR_SHIFT)
|
||||
# define IOMUXC_PAD_DDR_OFF (0u << IOMUXC_PAD_DDR_SHIFT)
|
||||
# define IOMUXC_PAD_DDR_ON (1u << IOMUXC_PAD_DDR_SHIFT)
|
||||
|
||||
/****************************************************************************
|
||||
* IMXRT_PADCFG packed encoding
|
||||
****************************************************************************
|
||||
*
|
||||
* The (mux/pad/daisy) register addresses for every RT1180 pin/alt combo can
|
||||
* be derived from a single uint32_t using pure arithmetic, without any run-
|
||||
* time look-up tables. The two IOMUXC instances on RT1180 (main IOMUXC at
|
||||
* 0x42a1_0000 and AON IOMUXC at 0x443c_0000) each expose:
|
||||
*
|
||||
* MUX_CTL[i] = base + ctl_first + i * 4 (contiguous, verified)
|
||||
* PAD_CTL[i] = MUX_CTL[i] + pad_delta (constant offset per bank)
|
||||
* DAISY[j] = base + dsy_first + j * 4 (base offset differs; j
|
||||
* may be sparse but is
|
||||
* still expressible as an
|
||||
* index into the daisy
|
||||
* region)
|
||||
*
|
||||
* Constants per bank (from IMXRT1180RM Ch. 17):
|
||||
*
|
||||
* +---------------+---------+-----------+-----------+-----------+
|
||||
* | bank | ctl_bit | ctl_first | pad_delta | dsy_first |
|
||||
* +---------------+---------+-----------+-----------+-----------+
|
||||
* | main IOMUXC | 0 | 0x010 | 0x248 | 0x4A0 |
|
||||
* | AON IOMUXC | 1 | 0x000 | 0x074 | 0x0E8 |
|
||||
* +---------------+---------+-----------+-----------+-----------+
|
||||
*
|
||||
* PADCFG bit layout (LSB..MSB):
|
||||
*
|
||||
* bits 0- 2 dsy_val (3 b) value written to DAISY register
|
||||
* bits 3- 8 reserved (6 b) must be zero
|
||||
* bits 9-17 dsy_idx (9 b) DAISY[j]; IMXRT_PADCFG_NO_DSYIDX = none
|
||||
* bits 18-21 mux_mode (4 b) ALT 0..12
|
||||
* bits 22-29 pad_idx (8 b) MUX_CTL[i] where i = pad_idx
|
||||
* bit 30 dsy_bank (1 b) 0 = main IOMUXC, 1 = AON IOMUXC
|
||||
* bit 31 pad_bank (1 b) 0 = main IOMUXC, 1 = AON IOMUXC
|
||||
*
|
||||
* Together with a two-entry bank descriptor (see imxrt_iomuxc.c) this
|
||||
* encoding suffices to compute all three register addresses at run time
|
||||
* with only shifts, masks, and a single indexed load of the descriptor
|
||||
* struct. There is no per-pin ROM table.
|
||||
*/
|
||||
|
||||
#define IMXRT_PADCFG_PADBANK_SHIFT (31)
|
||||
#define IMXRT_PADCFG_PADBANK_MASK (0x1u << IMXRT_PADCFG_PADBANK_SHIFT)
|
||||
|
||||
#define IMXRT_PADCFG_DSYBANK_SHIFT (30)
|
||||
#define IMXRT_PADCFG_DSYBANK_MASK (0x1u << IMXRT_PADCFG_DSYBANK_SHIFT)
|
||||
|
||||
#define IMXRT_PADCFG_PADIDX_SHIFT (22)
|
||||
#define IMXRT_PADCFG_PADIDX_MASK (0xffu << IMXRT_PADCFG_PADIDX_SHIFT)
|
||||
|
||||
#define IMXRT_PADCFG_MUX_SHIFT (18)
|
||||
#define IMXRT_PADCFG_MUX_MASK (0xfu << IMXRT_PADCFG_MUX_SHIFT)
|
||||
|
||||
#define IMXRT_PADCFG_DSYIDX_SHIFT (9)
|
||||
#define IMXRT_PADCFG_DSYIDX_MASK (0x1ffu << IMXRT_PADCFG_DSYIDX_SHIFT)
|
||||
|
||||
/* Sentinel dsy_idx meaning "this pin/alt has no input daisy". */
|
||||
|
||||
#define IMXRT_PADCFG_NO_DSYIDX (0x1ffu)
|
||||
|
||||
#define IMXRT_PADCFG_DSY_SHIFT (0)
|
||||
#define IMXRT_PADCFG_DSY_MASK (0x7u << IMXRT_PADCFG_DSY_SHIFT)
|
||||
|
||||
/* Compile-time packer used by the auto-generated imxrt118x_pinmux.h. */
|
||||
|
||||
#define IMXRT_PADCFG(_padbank, _padidx, _mux, _dsybank, _dsyidx, _dsy) \
|
||||
((((uint32_t)(_padbank) & 0x1u) << IMXRT_PADCFG_PADBANK_SHIFT) | \
|
||||
(((uint32_t)(_dsybank) & 0x1u) << IMXRT_PADCFG_DSYBANK_SHIFT) | \
|
||||
(((uint32_t)(_padidx) & 0xffu) << IMXRT_PADCFG_PADIDX_SHIFT) | \
|
||||
(((uint32_t)(_mux) & 0xfu) << IMXRT_PADCFG_MUX_SHIFT) | \
|
||||
(((uint32_t)(_dsyidx) & 0x1ffu) << IMXRT_PADCFG_DSYIDX_SHIFT) | \
|
||||
(((uint32_t)(_dsy) & 0x7u) << IMXRT_PADCFG_DSY_SHIFT))
|
||||
|
||||
/* Field extraction helpers (used by the runtime driver). */
|
||||
|
||||
#define IMXRT_PADCFG_PADBANK(_v) \
|
||||
(((_v) & IMXRT_PADCFG_PADBANK_MASK) >> IMXRT_PADCFG_PADBANK_SHIFT)
|
||||
#define IMXRT_PADCFG_DSYBANK(_v) \
|
||||
(((_v) & IMXRT_PADCFG_DSYBANK_MASK) >> IMXRT_PADCFG_DSYBANK_SHIFT)
|
||||
#define IMXRT_PADCFG_PADIDX(_v) \
|
||||
(((_v) & IMXRT_PADCFG_PADIDX_MASK) >> IMXRT_PADCFG_PADIDX_SHIFT)
|
||||
#define IMXRT_PADCFG_MUX(_v) \
|
||||
(((_v) & IMXRT_PADCFG_MUX_MASK) >> IMXRT_PADCFG_MUX_SHIFT)
|
||||
#define IMXRT_PADCFG_DSYIDX(_v) \
|
||||
(((_v) & IMXRT_PADCFG_DSYIDX_MASK) >> IMXRT_PADCFG_DSYIDX_SHIFT)
|
||||
#define IMXRT_PADCFG_DSY(_v) \
|
||||
(((_v) & IMXRT_PADCFG_DSY_MASK) >> IMXRT_PADCFG_DSY_SHIFT)
|
||||
|
||||
/****************************************************************************
|
||||
* Bank descriptor type
|
||||
****************************************************************************/
|
||||
|
||||
#define IMXRT_PADCFG_NBANKS (2)
|
||||
#define IMXRT_PADCFG_BANK_MAIN (0)
|
||||
#define IMXRT_PADCFG_BANK_AON (1)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct imxrt_iomux_bank_s
|
||||
{
|
||||
uint32_t base; /* IOMUXC instance base address */
|
||||
uint16_t ctl_first; /* Offset of MUX_CTL[0] within the bank */
|
||||
uint16_t pad_delta; /* pad_reg = mux_reg + pad_delta */
|
||||
uint16_t dsy_first; /* Offset of DAISY[0] within the bank */
|
||||
};
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_IOMUXC_H */
|
||||
1842
arch/arm/src/imxrt/hardware/rt118x/imxrt118x_pinmux.h
Normal file
1842
arch/arm/src/imxrt/hardware/rt118x/imxrt118x_pinmux.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -33,6 +33,17 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
#ifdef CONFIG_IMXRT_RGPIO
|
||||
|
||||
/* The RGPIO IP block (used by RT118x) has its public interface in a
|
||||
* separate header and driver source.
|
||||
*/
|
||||
|
||||
# include "imxrt_rgpio.h"
|
||||
|
||||
#else
|
||||
|
||||
#include "hardware/imxrt_gpio.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -380,4 +391,6 @@ int imxrt_dump_gpio(uint32_t pinset, const char *msg);
|
|||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_IMXRT_RGPIO */
|
||||
#endif /* __ARCH_ARM_SRC_IMXRT_IMXRT_GPIO_H */
|
||||
|
|
|
|||
|
|
@ -30,10 +30,13 @@
|
|||
#include <nuttx/config.h>
|
||||
|
||||
/* IMXRT117X IOMUX Differs too much from IMXRT10XX
|
||||
* hence we use a VER2 driver
|
||||
* hence we use a VER2 driver. IMXRT118x uses another (generation 3)
|
||||
* IOMUXC IP; that is IMXRT_IOMUX_VER3.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_IMXRT_IOMUX_VER2
|
||||
#ifdef CONFIG_IMXRT_IOMUX_VER3
|
||||
#include "imxrt_iomuxc_ver3.h"
|
||||
#elif defined(CONFIG_IMXRT_IOMUX_VER2)
|
||||
#include "imxrt_iomuxc_ver2.h"
|
||||
#else
|
||||
#include "imxrt_iomuxc_ver1.h"
|
||||
|
|
|
|||
194
arch/arm/src/imxrt/imxrt_iomuxc_ver3.c
Normal file
194
arch/arm/src/imxrt/imxrt_iomuxc_ver3.c
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_iomuxc_ver3.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "hardware/imxrt_memorymap.h"
|
||||
#include "imxrt_iomuxc_ver3.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Descriptors for the two IOMUXC instances on RT1180. These four numbers
|
||||
* per bank are all we need to derive MUX_CTL, PAD_CTL and DAISY register
|
||||
* addresses from a packed IMXRT_PADCFG value using pure arithmetic.
|
||||
*
|
||||
* ctl_first : offset of MUX_CTL[0] within the bank
|
||||
* pad_delta : PAD_CTL[i] = MUX_CTL[i] + pad_delta (constant per bank)
|
||||
* dsy_first : offset of DAISY[0] within the bank
|
||||
*/
|
||||
|
||||
static const struct imxrt_iomux_bank_s g_bank[IMXRT_PADCFG_NBANKS] =
|
||||
{
|
||||
[IMXRT_PADCFG_BANK_MAIN] =
|
||||
{
|
||||
.base = IMXRT_IOMUXC_WKUP_BASE, /* 0x42a1_0000 */
|
||||
.ctl_first = 0x010u,
|
||||
.pad_delta = 0x248u,
|
||||
.dsy_first = 0x4a0u,
|
||||
},
|
||||
[IMXRT_PADCFG_BANK_AON] =
|
||||
{
|
||||
.base = IMXRT_IOMUXC_AON_BASE, /* 0x443c_0000 */
|
||||
.ctl_first = 0x000u,
|
||||
.pad_delta = 0x074u,
|
||||
.dsy_first = 0x0e8u,
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_iomux_ctlreg
|
||||
*
|
||||
* Description:
|
||||
* Compute the SW_MUX_CTL register address for a packed padcfg value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uintptr_t imxrt_iomux_ctlreg(uint32_t padcfg)
|
||||
{
|
||||
const struct imxrt_iomux_bank_s *b = &g_bank[IMXRT_PADCFG_PADBANK(padcfg)];
|
||||
|
||||
return (uintptr_t)b->base + b->ctl_first +
|
||||
IMXRT_PADCFG_PADIDX(padcfg) * 4u;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_iomux_padreg
|
||||
*
|
||||
* Description:
|
||||
* Compute the SW_PAD_CTL register address for a packed padcfg value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uintptr_t imxrt_iomux_padreg(uint32_t padcfg)
|
||||
{
|
||||
const struct imxrt_iomux_bank_s *b = &g_bank[IMXRT_PADCFG_PADBANK(padcfg)];
|
||||
|
||||
return imxrt_iomux_ctlreg(padcfg) + b->pad_delta;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_iomux_dsyreg
|
||||
*
|
||||
* Description:
|
||||
* Compute the DAISY (input) register address for a packed padcfg value,
|
||||
* or 0 if the pad/alt has no input daisy. Note that the daisy bank
|
||||
* may differ from the pad bank (a pin on one IOMUXC can route to a
|
||||
* peripheral whose input mux lives on the other IOMUXC).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uintptr_t imxrt_iomux_dsyreg(uint32_t padcfg)
|
||||
{
|
||||
uint32_t dsy_idx = IMXRT_PADCFG_DSYIDX(padcfg);
|
||||
const struct imxrt_iomux_bank_s *b;
|
||||
|
||||
if (dsy_idx == IMXRT_PADCFG_NO_DSYIDX)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
b = &g_bank[IMXRT_PADCFG_DSYBANK(padcfg)];
|
||||
return (uintptr_t)b->base + b->dsy_first + dsy_idx * 4u;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_iomux_configure
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_iomux_configure(imxrt_pinset_t pinset)
|
||||
{
|
||||
uint32_t padcfg = IMXRT_PINSET_PADCFG(pinset);
|
||||
uintptr_t ctlreg = imxrt_iomux_ctlreg(padcfg);
|
||||
uintptr_t padreg = imxrt_iomux_padreg(padcfg);
|
||||
uintptr_t dsyreg = imxrt_iomux_dsyreg(padcfg);
|
||||
uint32_t mux = IMXRT_PADCFG_MUX(padcfg);
|
||||
uint32_t mux_side = IMXRT_PINSET_MUXSIDE(pinset);
|
||||
|
||||
/* Write MUX_CTL: ALT | mux side-band bits (currently only SION) */
|
||||
|
||||
putreg32(IOMUXC_MUX_MODE_ALT(mux) | mux_side, ctlreg);
|
||||
|
||||
/* Write PAD_CTL */
|
||||
|
||||
putreg32(IMXRT_PINSET_PADCTL(pinset), padreg);
|
||||
|
||||
/* Route the peripheral input mux (daisy) if this alt uses one */
|
||||
|
||||
if (dsyreg != 0)
|
||||
{
|
||||
putreg32(IMXRT_PADCFG_DSY(padcfg), dsyreg);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_iomux_gpio
|
||||
*
|
||||
* Description:
|
||||
* Force a pad to GPIO mode. On RT1180 dedicated GPIO_IOxx pads on the
|
||||
* main IOMUXC take ALT0 for GPIO; all other pads (including AON pads)
|
||||
* use ALT5.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_iomux_gpio(imxrt_pinset_t pinset, bool sion)
|
||||
{
|
||||
uint32_t padcfg = IMXRT_PINSET_PADCFG(pinset);
|
||||
uintptr_t ctlreg = imxrt_iomux_ctlreg(padcfg);
|
||||
uintptr_t padreg = imxrt_iomux_padreg(padcfg);
|
||||
uint32_t reg_sion = sion ? IOMUXC_MUX_SION_ON : 0;
|
||||
uint32_t alt;
|
||||
|
||||
/* On the main IOMUXC, the dedicated GPIO_IO<n> pads (there is no other
|
||||
* function on ALT0) select GPIO via ALT0. Every other pad selects GPIO
|
||||
* via ALT5. The IOMUXC_PAD_..._GPIOx_IOn macros generated from the SDK
|
||||
* already carry the correct ALT (0 or 5) in the padcfg field, so we
|
||||
* simply write the pre-encoded ALT and SION.
|
||||
*/
|
||||
|
||||
alt = IMXRT_PADCFG_MUX(padcfg);
|
||||
|
||||
putreg32(IOMUXC_MUX_MODE_ALT(alt) | reg_sion, ctlreg);
|
||||
putreg32(IMXRT_PINSET_PADCTL(pinset), padreg);
|
||||
|
||||
return OK;
|
||||
}
|
||||
159
arch/arm/src/imxrt/imxrt_iomuxc_ver3.h
Normal file
159
arch/arm/src/imxrt/imxrt_iomuxc_ver3.h
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_iomuxc_ver3.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_IMXRT_IMXRT_IOMUXC_VER3_H
|
||||
#define __ARCH_ARM_SRC_IMXRT_IMXRT_IOMUXC_VER3_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "hardware/rt118x/imxrt118x_iomuxc.h"
|
||||
#include "hardware/rt118x/imxrt118x_pinmux.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* imxrt_pinset_t is a 64-bit descriptor packing all four sub-fields
|
||||
* needed to fully program a physical pad:
|
||||
*
|
||||
* bits 0..31 : padcfg IMXRT_PADCFG(...) constant (pad_bank,
|
||||
* pad_idx, ALT, dsy_bank, dsy_idx, dsy_val).
|
||||
* bits 32..39 : pad_ctl SW_PAD_CTL byte.
|
||||
* bits 40..47 : mux_side SW_MUX_CTL side-band bits in register order
|
||||
* (currently only SION at bit 4).
|
||||
* bits 48..63 : gpio 16-bit gpio pinset (port | pin | mode |
|
||||
* output value | int cfg | int both).
|
||||
*/
|
||||
|
||||
#define IMXRT_PINSET_PADCFG_SHIFT (0)
|
||||
#define IMXRT_PINSET_PADCTL_SHIFT (32)
|
||||
#define IMXRT_PINSET_MUXSIDE_SHIFT (40)
|
||||
#define IMXRT_PINSET_GPIO_SHIFT (48)
|
||||
|
||||
#define IMXRT_PINSET_PADCFG(_p) ((uint32_t)(_p))
|
||||
#define IMXRT_PINSET_PADCTL(_p) ((uint8_t)((_p) >> IMXRT_PINSET_PADCTL_SHIFT))
|
||||
#define IMXRT_PINSET_MUXSIDE(_p) ((uint8_t)((_p) >> IMXRT_PINSET_MUXSIDE_SHIFT))
|
||||
#define IMXRT_PINSET_GPIO(_p) ((uint16_t)((_p) >> IMXRT_PINSET_GPIO_SHIFT))
|
||||
|
||||
/* Compose a full 64-bit pinset from its four sub-fields. See
|
||||
* IOMUX_PIN and IOMUX_GPIO below for the convenient wrappers.
|
||||
*/
|
||||
|
||||
#define IOMUX_CFG(_padcfg, _pad_ctl, _mux_side, _gpio) \
|
||||
(((uint64_t)(uint32_t)(_padcfg)) | \
|
||||
(((uint64_t)(uint8_t)(_pad_ctl)) << IMXRT_PINSET_PADCTL_SHIFT) | \
|
||||
(((uint64_t)(uint8_t)(_mux_side)) << IMXRT_PINSET_MUXSIDE_SHIFT) | \
|
||||
(((uint64_t)(uint16_t)(_gpio)) << IMXRT_PINSET_GPIO_SHIFT))
|
||||
|
||||
/* Peripheral pin: no GPIO fields. `mux_side' is OR'd into SW_MUX_CTL
|
||||
* verbatim; the only defined bit is IOMUXC_MUX_SION_ON.
|
||||
*/
|
||||
|
||||
#define IOMUX_PIN(_padcfg, _pad_ctl, _mux_side) \
|
||||
IOMUX_CFG(_padcfg, _pad_ctl, _mux_side, 0xc000u)
|
||||
|
||||
/* GPIO pin: caller supplies pad_ctl and a 16-bit gpio pinset built from
|
||||
* GPIO_INPUT / GPIO_OUTPUT / GPIO_PORTn / GPIO_PINn / etc. SION is 0
|
||||
* because a GPIO output only needs to sample the pad when the ALT is
|
||||
* routed elsewhere.
|
||||
*/
|
||||
|
||||
#define IOMUX_GPIO(_padcfg, _pad_ctl, _gpio) \
|
||||
IOMUX_CFG(_padcfg, _pad_ctl, 0, _gpio)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Packed 64-bit pad + GPIO descriptor. See IOMUX_CFG above for the
|
||||
* bit layout. Peripheral drivers and board files should treat this
|
||||
* type as opaque and use the IOMUX_PIN / IOMUX_GPIO macros to build
|
||||
* values and the IMXRT_PINSET_* macros (or the driver entry points) to
|
||||
* consume them.
|
||||
*/
|
||||
|
||||
typedef uint64_t imxrt_pinset_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_iomux_configure
|
||||
*
|
||||
* Description:
|
||||
* Program a pad's SW_MUX_CTL, SW_PAD_CTL and (if applicable) input
|
||||
* DAISY select register from a packed pinset.
|
||||
*
|
||||
* Input Parameters:
|
||||
* pinset - the pad configuration built with IOMUX_PIN() or IOMUX_GPIO()
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_iomux_configure(imxrt_pinset_t pinset);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_iomux_gpio
|
||||
*
|
||||
* Description:
|
||||
* Forcibly set a pad to GPIO mode. This overrides and disconnects any
|
||||
* peripheral that was previously routed through the pad. The GPIO ALT
|
||||
* is selected automatically based on the pad (ALT5 for most pads, ALT0
|
||||
* for dedicated GPIO_IO pads on the main IOMUXC).
|
||||
*
|
||||
* Input Parameters:
|
||||
* pinset - the pad configuration. Only the padcfg and pad_ctl fields
|
||||
* are used to identify the pad and program SW_PAD_CTL.
|
||||
* sion - if true; sets SION, otherwise clears it.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_iomux_gpio(imxrt_pinset_t pinset, bool sion);
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_IMXRT_IMXRT_IOMUXC_VER3_H */
|
||||
275
arch/arm/src/imxrt/imxrt_rgpio.c
Normal file
275
arch/arm/src/imxrt/imxrt_rgpio.c
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_rgpio.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "arm_internal.h"
|
||||
#include "imxrt_rgpio.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Look-up table that maps GPIO1..GPIOn indexes into RGPIO base addresses.
|
||||
* GPIO1 lives in the AON domain; GPIO2..GPIO6 are in the WAKEUPMIX.
|
||||
*/
|
||||
|
||||
const uintptr_t g_gpio_base[IMXRT_GPIO_NPORTS] =
|
||||
{
|
||||
IMXRT_GPIO1_BASE,
|
||||
IMXRT_GPIO2_BASE,
|
||||
IMXRT_GPIO3_BASE,
|
||||
IMXRT_GPIO4_BASE,
|
||||
IMXRT_GPIO5_BASE,
|
||||
IMXRT_GPIO6_BASE,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_dirout
|
||||
****************************************************************************/
|
||||
|
||||
static inline void imxrt_gpio_dirout(uint32_t port, uint32_t pin)
|
||||
{
|
||||
uint32_t regval = getreg32(IMXRT_GPIO_PDDR(port));
|
||||
|
||||
regval |= GPIO_PIN(pin);
|
||||
putreg32(regval, IMXRT_GPIO_PDDR(port));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_dirin
|
||||
****************************************************************************/
|
||||
|
||||
static inline void imxrt_gpio_dirin(uint32_t port, uint32_t pin)
|
||||
{
|
||||
uint32_t regval = getreg32(IMXRT_GPIO_PDDR(port));
|
||||
|
||||
regval &= ~GPIO_PIN(pin);
|
||||
putreg32(regval, IMXRT_GPIO_PDDR(port));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_setoutput
|
||||
****************************************************************************/
|
||||
|
||||
static void imxrt_gpio_setoutput(uint32_t port, uint32_t pin, bool value)
|
||||
{
|
||||
uintptr_t regaddr = value ? IMXRT_GPIO_PSOR(port) : IMXRT_GPIO_PCOR(port);
|
||||
|
||||
putreg32(GPIO_PIN(pin), regaddr);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_get_pinstatus
|
||||
****************************************************************************/
|
||||
|
||||
static inline bool imxrt_gpio_get_pinstatus(uint32_t port, uint32_t pin)
|
||||
{
|
||||
uintptr_t regaddr = IMXRT_GPIO_PDOR(port);
|
||||
uint32_t regval;
|
||||
|
||||
regval = getreg32(regaddr);
|
||||
return ((regval & GPIO_PIN(pin)) != 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_getinput
|
||||
****************************************************************************/
|
||||
|
||||
static inline bool imxrt_gpio_getinput(uint32_t port, uint32_t pin)
|
||||
{
|
||||
uintptr_t regaddr = IMXRT_GPIO_PDIR(port);
|
||||
uint32_t regval;
|
||||
|
||||
regval = getreg32(regaddr);
|
||||
return ((regval & GPIO_PIN(pin)) != 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_configinput
|
||||
****************************************************************************/
|
||||
|
||||
static int imxrt_gpio_configinput(uint16_t gpio)
|
||||
{
|
||||
uint32_t port = (gpio & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint32_t pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
|
||||
DEBUGASSERT(port < IMXRT_GPIO_NPORTS);
|
||||
|
||||
imxrt_gpio_dirin(port, pin);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_configoutput
|
||||
****************************************************************************/
|
||||
|
||||
static inline int imxrt_gpio_configoutput(uint16_t gpio)
|
||||
{
|
||||
uint32_t port = (gpio & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint32_t pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
bool value = ((gpio & GPIO_OUTPUT_ONE) != 0);
|
||||
|
||||
DEBUGASSERT(port < IMXRT_GPIO_NPORTS);
|
||||
|
||||
imxrt_gpio_setoutput(port, pin, value);
|
||||
imxrt_gpio_dirout(port, pin);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_config_gpio
|
||||
*
|
||||
* Description:
|
||||
* Configure a GPIO pin based on pin-encoded description of the pin.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_config_gpio(gpio_pinset_t pinset)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint16_t gpio = IMXRT_PINSET_GPIO(pinset);
|
||||
int ret;
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
ret = imxrt_iomux_configure(pinset);
|
||||
if (ret < 0)
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (gpio & GPIO_MODE_MASK)
|
||||
{
|
||||
case GPIO_INPUT:
|
||||
{
|
||||
ret = imxrt_gpio_configinput(gpio);
|
||||
}
|
||||
break;
|
||||
|
||||
case GPIO_OUTPUT:
|
||||
{
|
||||
ret = imxrt_gpio_configinput(gpio);
|
||||
if (ret >= 0)
|
||||
{
|
||||
ret = imxrt_gpio_configoutput(gpio);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_IMXRT_GPIO_IRQ
|
||||
case GPIO_INTERRUPT:
|
||||
{
|
||||
ret = imxrt_gpio_configinput(gpio);
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = imxrt_gpioirq_configure(pinset);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ret = OK;
|
||||
break;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_write
|
||||
*
|
||||
* Description:
|
||||
* Write one or zero to the selected GPIO pin
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void imxrt_gpio_write(gpio_pinset_t pinset, bool value)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint16_t gpio = IMXRT_PINSET_GPIO(pinset);
|
||||
uint32_t port = (gpio & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint32_t pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
|
||||
DEBUGASSERT(port < IMXRT_GPIO_NPORTS);
|
||||
|
||||
flags = enter_critical_section();
|
||||
imxrt_gpio_setoutput(port, pin, value);
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_read
|
||||
*
|
||||
* Description:
|
||||
* Read one or zero from the selected GPIO pin
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool imxrt_gpio_read(gpio_pinset_t pinset)
|
||||
{
|
||||
irqstate_t flags;
|
||||
uint16_t gpio = IMXRT_PINSET_GPIO(pinset);
|
||||
uint32_t port = (gpio & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint32_t pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
bool value;
|
||||
|
||||
DEBUGASSERT(port < IMXRT_GPIO_NPORTS);
|
||||
|
||||
flags = enter_critical_section();
|
||||
if ((gpio & GPIO_MODE_MASK) == GPIO_OUTPUT)
|
||||
{
|
||||
value = imxrt_gpio_get_pinstatus(port, pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = imxrt_gpio_getinput(port, pin);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return value;
|
||||
}
|
||||
253
arch/arm/src/imxrt/imxrt_rgpio.h
Normal file
253
arch/arm/src/imxrt/imxrt_rgpio.h
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_rgpio.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_IMXRT_IMXRT_RGPIO_H
|
||||
#define __ARCH_ARM_SRC_IMXRT_IMXRT_RGPIO_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "hardware/rt118x/imxrt118x_gpio.h"
|
||||
#include "imxrt_iomuxc_ver3.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* 16-bit gpio pinset bit layout (lives in bits 48..63 of imxrt_pinset_t):
|
||||
*
|
||||
* 1111 1100 0000 0000
|
||||
* 5432 1098 7654 3210
|
||||
* ENCODING MMVX BEEG GGGP PPPP
|
||||
* GPIO INPUT 00.. BEEG GGGP PPPP
|
||||
* INT INPUT 11.. BEEG GGGP PPPP
|
||||
* GPIO OUTPUT 01V. ...G GGGP PPPP
|
||||
*/
|
||||
|
||||
/* Input/Output Selection: bits 14-15 */
|
||||
|
||||
#define GPIO_MODE_SHIFT (14)
|
||||
#define GPIO_MODE_MASK (0x3u << GPIO_MODE_SHIFT)
|
||||
# define GPIO_INPUT (0u << GPIO_MODE_SHIFT)
|
||||
# define GPIO_OUTPUT (1u << GPIO_MODE_SHIFT)
|
||||
# define GPIO_INTERRUPT (2u << GPIO_MODE_SHIFT)
|
||||
# define GPIO_NONE (3u << GPIO_MODE_SHIFT)
|
||||
|
||||
/* Initial Output Value: bit 13 (only meaningful for GPIO_OUTPUT) */
|
||||
|
||||
#define GPIO_OUTPUT_SHIFT (13)
|
||||
#define GPIO_OUTPUT_MASK (0x1u << GPIO_OUTPUT_SHIFT)
|
||||
# define GPIO_OUTPUT_ZERO (0u << GPIO_OUTPUT_SHIFT)
|
||||
# define GPIO_OUTPUT_ONE (1u << GPIO_OUTPUT_SHIFT)
|
||||
|
||||
/* Interrupt "both edges" flag: bit 11 (only for GPIO_INTERRUPT) */
|
||||
|
||||
#define GPIO_INTBOTHCFG_SHIFT (11)
|
||||
#define GPIO_INTBOTHCFG_MASK (1u << GPIO_INTBOTHCFG_SHIFT)
|
||||
# define GPIO_INTBOTH_EDGES (1u << GPIO_INTBOTHCFG_SHIFT)
|
||||
|
||||
/* Interrupt edge/level configuration: bits 9-10 (only for GPIO_INTERRUPT) */
|
||||
|
||||
#define GPIO_INTCFG_SHIFT (9)
|
||||
#define GPIO_INTCFG_MASK (0x3u << GPIO_INTCFG_SHIFT)
|
||||
# define GPIO_INT_LOWLEVEL (0u << GPIO_INTCFG_SHIFT)
|
||||
# define GPIO_INT_HIGHLEVEL (1u << GPIO_INTCFG_SHIFT)
|
||||
# define GPIO_INT_RISINGEDGE (2u << GPIO_INTCFG_SHIFT)
|
||||
# define GPIO_INT_FALLINGEDGE (3u << GPIO_INTCFG_SHIFT)
|
||||
|
||||
/* GPIO Port Number: bits 5-8 (GPIO1..GPIO6) */
|
||||
|
||||
#define GPIO_PORT_SHIFT (5)
|
||||
#define GPIO_PORT_MASK (0xfu << GPIO_PORT_SHIFT)
|
||||
# define GPIO_PORT1 (GPIO1 << GPIO_PORT_SHIFT)
|
||||
# define GPIO_PORT2 (GPIO2 << GPIO_PORT_SHIFT)
|
||||
# define GPIO_PORT3 (GPIO3 << GPIO_PORT_SHIFT)
|
||||
# define GPIO_PORT4 (GPIO4 << GPIO_PORT_SHIFT)
|
||||
# define GPIO_PORT5 (GPIO5 << GPIO_PORT_SHIFT)
|
||||
# define GPIO_PORT6 (GPIO6 << GPIO_PORT_SHIFT)
|
||||
|
||||
/* GPIO Pin Number: bits 0-4 */
|
||||
|
||||
#define GPIO_PIN_SHIFT (0)
|
||||
#define GPIO_PIN_MASK (0x1fu << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN0 (0u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN1 (1u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN2 (2u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN3 (3u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN4 (4u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN5 (5u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN6 (6u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN7 (7u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN8 (8u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN9 (9u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN10 (10u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN11 (11u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN12 (12u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN13 (13u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN14 (14u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN15 (15u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN16 (16u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN17 (17u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN18 (18u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN19 (19u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN20 (20u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN21 (21u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN22 (22u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN23 (23u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN24 (24u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN25 (25u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN26 (26u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN27 (27u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN28 (28u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN29 (29u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN30 (30u << GPIO_PIN_SHIFT)
|
||||
# define GPIO_PIN31 (31u << GPIO_PIN_SHIFT)
|
||||
|
||||
#define GPIO_SION_ENABLE (((imxrt_pinset_t)IOMUXC_MUX_SION_ON) << IMXRT_PINSET_MUXSIDE_SHIFT)
|
||||
|
||||
/* Port access via global LUT */
|
||||
|
||||
#define IMXRT_GPIO_BASE(n) g_gpio_base[n]
|
||||
|
||||
#define IMXRT_GPIO_VERID(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_VERID_OFFSET)
|
||||
#define IMXRT_GPIO_PARAM(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PARAM_OFFSET)
|
||||
#define IMXRT_GPIO_LOCK(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_LOCK_OFFSET)
|
||||
#define IMXRT_GPIO_PCNS(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PCNS_OFFSET)
|
||||
#define IMXRT_GPIO_ICNS(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_ICNS_OFFSET)
|
||||
#define IMXRT_GPIO_PCNP(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PCNP_OFFSET)
|
||||
#define IMXRT_GPIO_ICNP(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_ICNP_OFFSET)
|
||||
#define IMXRT_GPIO_PDOR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PDOR_OFFSET)
|
||||
#define IMXRT_GPIO_PSOR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PSOR_OFFSET)
|
||||
#define IMXRT_GPIO_PCOR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PCOR_OFFSET)
|
||||
#define IMXRT_GPIO_PTOR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PTOR_OFFSET)
|
||||
#define IMXRT_GPIO_PDIR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PDIR_OFFSET)
|
||||
#define IMXRT_GPIO_PDDR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PDDR_OFFSET)
|
||||
#define IMXRT_GPIO_PIDR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_PIDR_OFFSET)
|
||||
#define IMXRT_GPIO_GICLR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_GICLR_OFFSET)
|
||||
#define IMXRT_GPIO_GICHR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_GICHR_OFFSET)
|
||||
|
||||
/* Interrupt status flag registers (two channels). Channel selected via
|
||||
* ICRN.IRQS.
|
||||
*/
|
||||
|
||||
#define IMXRT_GPIO_ISFR0(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_ISFR0_OFFSET)
|
||||
#define IMXRT_GPIO_ISFR1(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_ISFR1_OFFSET)
|
||||
|
||||
/* Per-pin ICR and PDR at n*4 offsets */
|
||||
|
||||
#define IMXRT_GPIO_P0DR(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_P0DR_OFFSET)
|
||||
#define IMXRT_GPIO_PNDR(n, p) (IMXRT_GPIO_P0DR(n) + ((p) * 0x4))
|
||||
#define IMXRT_GPIO_ICR0(n) (IMXRT_GPIO_BASE(n) + IMXRT_GPIO_ICR0_OFFSET)
|
||||
#define IMXRT_GPIO_ICRN(n, p) (IMXRT_GPIO_ICR0(n) + ((p) * 0x4))
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef imxrt_pinset_t gpio_pinset_t;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* Look-up table that maps GPIO1..GPIOn indexes into RGPIO instance base
|
||||
* addresses.
|
||||
*/
|
||||
|
||||
EXTERN const uintptr_t g_gpio_base[IMXRT_GPIO_NPORTS];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpioirq_initialize
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_IMXRT_GPIO_IRQ
|
||||
void imxrt_gpioirq_initialize(void);
|
||||
#else
|
||||
# define imxrt_gpioirq_initialize()
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_config_gpio
|
||||
*
|
||||
* Description:
|
||||
* Configure the pad routing and (for GPIO pins) the RGPIO direction,
|
||||
* initial output value and interrupt configuration.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_config_gpio(gpio_pinset_t pinset);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_write
|
||||
****************************************************************************/
|
||||
|
||||
void imxrt_gpio_write(gpio_pinset_t pinset, bool value);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_read
|
||||
****************************************************************************/
|
||||
|
||||
bool imxrt_gpio_read(gpio_pinset_t pinset);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpioirq_attach / imxrt_gpioirq_configure /
|
||||
* imxrt_gpioirq_enable / imxrt_gpioirq_disable
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_IMXRT_GPIO_IRQ
|
||||
int imxrt_gpioirq_attach(gpio_pinset_t pinset, xcpt_t isr, void *arg);
|
||||
int imxrt_gpioirq_configure(gpio_pinset_t pinset);
|
||||
int imxrt_gpioirq_enable(gpio_pinset_t pinset);
|
||||
int imxrt_gpioirq_disable(gpio_pinset_t pinset);
|
||||
#else
|
||||
# define imxrt_gpioirq_attach(pinset, isr, arg) 0
|
||||
# define imxrt_gpioirq_configure(pinset) 0
|
||||
# define imxrt_gpioirq_enable(pinset) 0
|
||||
# define imxrt_gpioirq_disable(pinset) 0
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_IMXRT_IMXRT_RGPIO_H */
|
||||
268
arch/arm/src/imxrt/imxrt_rgpioirq.c
Normal file
268
arch/arm/src/imxrt/imxrt_rgpioirq.c
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt_rgpioirq.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "imxrt_gpio.h"
|
||||
|
||||
#ifdef CONFIG_IMXRT_GPIO_IRQ
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct imxrt_portisr_s
|
||||
{
|
||||
struct
|
||||
{
|
||||
xcpt_t isr;
|
||||
void *arg;
|
||||
}
|
||||
pins[IMXRT_GPIO_NPINS];
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct imxrt_portisr_s g_isrtab[IMXRT_GPIO_NPORTS];
|
||||
|
||||
/* NVIC IRQ per RGPIO instance (channel 0). RGPIO1..3 also expose a
|
||||
* second interrupt (channel 1) at IMXRT_IRQ_GPIOn_1; the driver uses
|
||||
* channel 0 for all pins by leaving ICRN.IRQS at reset (0).
|
||||
*/
|
||||
|
||||
static const int g_gpio_irq[IMXRT_GPIO_NPORTS] =
|
||||
{
|
||||
IMXRT_IRQ_GPIO1_0,
|
||||
IMXRT_IRQ_GPIO2_0,
|
||||
IMXRT_IRQ_GPIO3_0,
|
||||
IMXRT_IRQ_GPIO4,
|
||||
IMXRT_IRQ_GPIO5,
|
||||
IMXRT_IRQ_GPIO6,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpio_interrupt
|
||||
*
|
||||
* Description:
|
||||
* Common ISR shared by every RGPIO instance. Scans the port's ISFR0
|
||||
* flag word and dispatches per-pin user handlers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int imxrt_gpio_interrupt(int irq, void *context, void *arg)
|
||||
{
|
||||
uint32_t port = (uint32_t)((uintptr_t)arg);
|
||||
uint32_t status;
|
||||
uint32_t pin;
|
||||
uintptr_t regaddr;
|
||||
|
||||
regaddr = IMXRT_GPIO_ISFR0(port);
|
||||
status = getreg32(regaddr);
|
||||
|
||||
for (pin = 0; pin < IMXRT_GPIO_NPINS && status != 0; pin++)
|
||||
{
|
||||
uint32_t mask = (1u << pin);
|
||||
|
||||
if ((status & mask) != 0)
|
||||
{
|
||||
struct imxrt_portisr_s *isrtab;
|
||||
|
||||
putreg32(mask, regaddr);
|
||||
status &= ~mask;
|
||||
|
||||
isrtab = &g_isrtab[port];
|
||||
if (isrtab->pins[pin].isr != NULL)
|
||||
{
|
||||
isrtab->pins[pin].isr(irq, context, isrtab->pins[pin].arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpioirq_initialize
|
||||
****************************************************************************/
|
||||
|
||||
void imxrt_gpioirq_initialize(void)
|
||||
{
|
||||
uint32_t port;
|
||||
uint32_t pin;
|
||||
|
||||
/* Reset every pin's ICR so no interrupt configuration survives across
|
||||
* a warm reset from the M33.
|
||||
*/
|
||||
|
||||
for (port = 0; port < IMXRT_GPIO_NPORTS; port++)
|
||||
{
|
||||
for (pin = 0; pin < IMXRT_GPIO_NPINS; pin++)
|
||||
{
|
||||
putreg32(0, IMXRT_GPIO_ICRN(port, pin));
|
||||
}
|
||||
}
|
||||
|
||||
/* Attach the common ISR to every RGPIO NVIC line. */
|
||||
|
||||
for (port = 0; port < IMXRT_GPIO_NPORTS; port++)
|
||||
{
|
||||
up_disable_irq(g_gpio_irq[port]);
|
||||
DEBUGVERIFY(irq_attach(g_gpio_irq[port],
|
||||
imxrt_gpio_interrupt,
|
||||
(void *)(uintptr_t)port));
|
||||
up_enable_irq(g_gpio_irq[port]);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpioirq_attach
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_gpioirq_attach(gpio_pinset_t pinset, xcpt_t isr, void *arg)
|
||||
{
|
||||
uint16_t gpio = IMXRT_PINSET_GPIO(pinset);
|
||||
uint32_t port = (gpio & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint32_t pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
irqstate_t flags;
|
||||
|
||||
DEBUGASSERT(port < IMXRT_GPIO_NPORTS && pin < IMXRT_GPIO_NPINS);
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
g_isrtab[port].pins[pin].isr = isr;
|
||||
g_isrtab[port].pins[pin].arg = arg;
|
||||
|
||||
leave_critical_section(flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpioirq_configure
|
||||
*
|
||||
* Description:
|
||||
* Reset ICRN for the pin. Interrupt is enabled by imxrt_gpioirq_enable().
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_gpioirq_configure(gpio_pinset_t pinset)
|
||||
{
|
||||
uint16_t gpio = IMXRT_PINSET_GPIO(pinset);
|
||||
uint32_t port = (gpio & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint32_t pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
|
||||
DEBUGASSERT(port < IMXRT_GPIO_NPORTS && pin < IMXRT_GPIO_NPINS);
|
||||
|
||||
putreg32(0, IMXRT_GPIO_ICRN(port, pin));
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpioirq_enable
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_gpioirq_enable(gpio_pinset_t pinset)
|
||||
{
|
||||
uint16_t gpio = IMXRT_PINSET_GPIO(pinset);
|
||||
uint32_t port = (gpio & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint32_t pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
uint32_t both = (gpio & GPIO_INTBOTHCFG_MASK) >> GPIO_INTBOTHCFG_SHIFT;
|
||||
uint32_t icr = (gpio & GPIO_INTCFG_MASK);
|
||||
uint32_t regval;
|
||||
uintptr_t regaddr;
|
||||
|
||||
DEBUGASSERT(port < IMXRT_GPIO_NPORTS && pin < IMXRT_GPIO_NPINS);
|
||||
|
||||
regaddr = IMXRT_GPIO_ICRN(port, pin);
|
||||
regval = getreg32(regaddr);
|
||||
regval &= ~IMXRT_GPIO_ICRN_MASK;
|
||||
|
||||
if (both)
|
||||
{
|
||||
regval |= IMXRT_GPIO_ICRN_BOTH;
|
||||
}
|
||||
else if (icr == GPIO_INT_LOWLEVEL)
|
||||
{
|
||||
regval |= IMXRT_GPIO_ICRN_ZERO;
|
||||
}
|
||||
else if (icr == GPIO_INT_HIGHLEVEL)
|
||||
{
|
||||
regval |= IMXRT_GPIO_ICRN_ONE;
|
||||
}
|
||||
else if (icr == GPIO_INT_RISINGEDGE)
|
||||
{
|
||||
regval |= IMXRT_GPIO_ICRN_RISING;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval |= IMXRT_GPIO_ICRN_FALLING;
|
||||
}
|
||||
|
||||
putreg32(regval, regaddr);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt_gpioirq_disable
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt_gpioirq_disable(gpio_pinset_t pinset)
|
||||
{
|
||||
uint16_t gpio = IMXRT_PINSET_GPIO(pinset);
|
||||
uint32_t port = (gpio & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
uint32_t pin = (gpio & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
uint32_t regval;
|
||||
uintptr_t regaddr;
|
||||
|
||||
DEBUGASSERT(port < IMXRT_GPIO_NPORTS && pin < IMXRT_GPIO_NPINS);
|
||||
|
||||
regaddr = IMXRT_GPIO_ICRN(port, pin);
|
||||
regval = getreg32(regaddr);
|
||||
regval &= ~IMXRT_GPIO_ICRN_MASK;
|
||||
|
||||
putreg32(regval, regaddr);
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_IMXRT_GPIO_IRQ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue