github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_mimxrt1062.go (about) 1 //go:build mimxrt1062 2 3 package machine 4 5 import ( 6 "device/nxp" 7 "math/bits" 8 "runtime/interrupt" 9 "runtime/volatile" 10 ) 11 12 // Peripheral abstraction layer for the MIMXRT1062 13 14 const deviceName = nxp.Device 15 16 func CPUFrequency() uint32 { 17 return 600000000 18 } 19 20 const ( 21 // GPIO 22 PinInput PinMode = iota 23 PinInputPullup 24 PinInputPulldown 25 PinOutput 26 PinOutputOpenDrain 27 PinDisable 28 29 // ADC 30 PinInputAnalog 31 32 // UART 33 PinModeUARTTX 34 PinModeUARTRX 35 36 // SPI 37 PinModeSPISDI 38 PinModeSPISDO 39 PinModeSPICLK 40 PinModeSPICS 41 42 // I2C 43 PinModeI2CSDA 44 PinModeI2CSCL 45 ) 46 47 // Deprecated: use PinInputPullup and PinInputPulldown instead. 48 const ( 49 PinInputPullUp = PinInputPullup 50 PinInputPullDown = PinInputPulldown 51 ) 52 53 type PinChange uint8 54 55 const ( 56 PinRising PinChange = iota + 2 57 PinFalling 58 PinToggle 59 ) 60 61 // pinJumpTable represents a function lookup table for all 128 GPIO pins. 62 // 63 // There are 4 GPIO ports (A-D) and 32 pins (0-31) on each port. The uint8 value 64 // of a Pin is used as table index. The number of pins with a defined (non-nil) 65 // function is recorded in the uint8 field numDefined. 66 type pinJumpTable struct { 67 lut [4 * 32]func(Pin) 68 numDefined uint8 69 } 70 71 // pinISR stores the interrupt callbacks for GPIO pins, and pinInterrupt holds 72 // an interrupt service routine that dispatches the interrupt callbacks. 73 var ( 74 pinISR pinJumpTable 75 pinInterrupt *interrupt.Interrupt 76 ) 77 78 // From the i.MXRT1062 Processor Reference Manual (Chapter 12 - GPIO): 79 // 80 // | High-speed GPIOs exist in this device: 81 // | - GPIO1-5 are standard-speed GPIOs that run off the IPG_CLK_ROOT, while 82 // | GPIO6-9 are high-speed GPIOs that run at the AHB_CLK_ROOT frequency. 83 // | See the table "System Clocks, Gating, and Override" in CCM chapter. 84 // | - Regular GPIO and high speed GPIO are paired (GPIO1 and GPIO6 share the 85 // | same pins, GPIO2 and GPIO7 share, etc). The IOMUXC_GPR_GPR26-29 86 // | registers are used to determine if the regular or high-speed GPIO 87 // | module is used for the GPIO pins on a given port. 88 // 89 // Therefore, we do not even use GPIO1-5 and instead use their high-speed 90 // partner for all pins. This is configured at startup in the runtime package 91 // (func initPins() in `runtime_mimxrt1062.go`). 92 // We cannot declare 32 pins for all available ports (GPIO1-9) anyway, since Pin 93 // is only uint8, and 9*32=288 > 256, so something has to be sacrificed. 94 95 const ( 96 portA Pin = iota * 32 // GPIO1(6) 97 portB // GPIO2(7) 98 portC // GPIO3(8) 99 portD // GPIO4(9) 100 ) 101 102 const ( 103 // [Pad]: Alt Func 0 Alt Func 1 Alt Func 2 Alt Func 3 Alt Func 4 Alt Func 5 Alt Func 6 Alt Func 7 Alt Func 8 Alt Func 9 104 // ---------- --------------- --------------- ------------------- -------------------- -------------------- ----------- -------------------- -------------------- --------------------- ---------------- 105 PA0 = portA + 0 // [AD_B0_00]: FLEXPWM2_PWMA03 XBAR1_INOUT14 REF_CLK_32K USB_OTG2_ID LPI2C1_SCLS GPIO1_IO00 USDHC1_RESET_B LPSPI3_SCK ~ ~ 106 PA1 = portA + 1 // [AD_B0_01]: FLEXPWM2_PWMB03 XBAR1_INOUT15 REF_CLK_24M USB_OTG1_ID LPI2C1_SDAS GPIO1_IO01 EWM_OUT_B LPSPI3_SDO ~ ~ 107 PA2 = portA + 2 // [AD_B0_02]: FLEXCAN2_TX XBAR1_INOUT16 LPUART6_TX USB_OTG1_PWR FLEXPWM1_PWMX00 GPIO1_IO02 LPI2C1_HREQ LPSPI3_SDI ~ ~ 108 PA3 = portA + 3 // [AD_B0_03]: FLEXCAN2_RX XBAR1_INOUT17 LPUART6_RX USB_OTG1_OC FLEXPWM1_PWMX01 GPIO1_IO03 REF_CLK_24M LPSPI3_PCS0 ~ ~ 109 PA4 = portA + 4 // [AD_B0_04]: SRC_BOOT_MODE00 MQS_RIGHT ENET_TX_DATA03 SAI2_TX_SYNC CSI_DATA09 GPIO1_IO04 PIT_TRIGGER00 LPSPI3_PCS1 ~ ~ 110 PA5 = portA + 5 // [AD_B0_05]: SRC_BOOT_MODE01 MQS_LEFT ENET_TX_DATA02 SAI2_TX_BCLK CSI_DATA08 GPIO1_IO05 XBAR1_INOUT17 LPSPI3_PCS2 ~ ~ 111 PA6 = portA + 6 // [AD_B0_06]: JTAG_TMS GPT2_COMPARE1 ENET_RX_CLK SAI2_RX_BCLK CSI_DATA07 GPIO1_IO06 XBAR1_INOUT18 LPSPI3_PCS3 ~ ~ 112 PA7 = portA + 7 // [AD_B0_07]: JTAG_TCK GPT2_COMPARE2 ENET_TX_ER SAI2_RX_SYNC CSI_DATA06 GPIO1_IO07 XBAR1_INOUT19 ENET_1588_EVENT3_OUT ~ ~ 113 PA8 = portA + 8 // [AD_B0_08]: JTAG_MOD GPT2_COMPARE3 ENET_RX_DATA03 SAI2_RX_DATA CSI_DATA05 GPIO1_IO08 XBAR1_IN20 ENET_1588_EVENT3_IN ~ ~ 114 PA9 = portA + 9 // [AD_B0_09]: JTAG_TDI FLEXPWM2_PWMA03 ENET_RX_DATA02 SAI2_TX_DATA CSI_DATA04 GPIO1_IO09 XBAR1_IN21 GPT2_CLK SEMC_DQS4 ~ 115 PA10 = portA + 10 // [AD_B0_10]: JTAG_TDO FLEXPWM1_PWMA03 ENET_CRS SAI2_MCLK CSI_DATA03 GPIO1_IO10 XBAR1_IN22 ENET_1588_EVENT0_OUT FLEXCAN3_TX ARM_TRACE_SWO 116 PA11 = portA + 11 // [AD_B0_11]: JTAG_TRSTB FLEXPWM1_PWMB03 ENET_COL WDOG1_WDOG_B CSI_DATA02 GPIO1_IO11 XBAR1_IN23 ENET_1588_EVENT0_IN FLEXCAN3_RX SEMC_CLK6 117 PA12 = portA + 12 // [AD_B0_12]: LPI2C4_SCL CCM_PMIC_READY LPUART1_TX WDOG2_WDOG_B FLEXPWM1_PWMX02 GPIO1_IO12 ENET_1588_EVENT1_OUT NMI_GLUE_NMI ~ ~ 118 PA13 = portA + 13 // [AD_B0_13]: LPI2C4_SDA GPT1_CLK LPUART1_RX EWM_OUT_B FLEXPWM1_PWMX03 GPIO1_IO13 ENET_1588_EVENT1_IN REF_CLK_24M ~ ~ 119 PA14 = portA + 14 // [AD_B0_14]: USB_OTG2_OC XBAR1_IN24 LPUART1_CTS_B ENET_1588_EVENT0_OUT CSI_VSYNC GPIO1_IO14 FLEXCAN2_TX FLEXCAN3_TX ~ ~ 120 PA15 = portA + 15 // [AD_B0_15]: USB_OTG2_PWR XBAR1_IN25 LPUART1_RTS_B ENET_1588_EVENT0_IN CSI_HSYNC GPIO1_IO15 FLEXCAN2_RX WDOG1_WDOG_RST_B_DEB FLEXCAN3_RX ~ 121 PA16 = portA + 16 // [AD_B1_00]: USB_OTG2_ID QTIMER3_TIMER0 LPUART2_CTS_B LPI2C1_SCL WDOG1_B GPIO1_IO16 USDHC1_WP KPP_ROW07 ENET2_1588_EVENT0_OUT FLEXIO3_FLEXIO00 122 PA17 = portA + 17 // [AD_B1_01]: USB_OTG1_PWR QTIMER3_TIMER1 LPUART2_RTS_B LPI2C1_SDA CCM_PMIC_READY GPIO1_IO17 USDHC1_VSELECT KPP_COL07 ENET2_1588_EVENT0_IN FLEXIO3_FLEXIO01 123 PA18 = portA + 18 // [AD_B1_02]: USB_OTG1_ID QTIMER3_TIMER2 LPUART2_TX SPDIF_OUT ENET_1588_EVENT2_OUT GPIO1_IO18 USDHC1_CD_B KPP_ROW06 GPT2_CLK FLEXIO3_FLEXIO02 124 PA19 = portA + 19 // [AD_B1_03]: USB_OTG1_OC QTIMER3_TIMER3 LPUART2_RX SPDIF_IN ENET_1588_EVENT2_IN GPIO1_IO19 USDHC2_CD_B KPP_COL06 GPT2_CAPTURE1 FLEXIO3_FLEXIO03 125 PA20 = portA + 20 // [AD_B1_04]: FLEXSPIB_DATA03 ENET_MDC LPUART3_CTS_B SPDIF_SR_CLK CSI_PIXCLK GPIO1_IO20 USDHC2_DATA0 KPP_ROW05 GPT2_CAPTURE2 FLEXIO3_FLEXIO04 126 PA21 = portA + 21 // [AD_B1_05]: FLEXSPIB_DATA02 ENET_MDIO LPUART3_RTS_B SPDIF_OUT CSI_MCLK GPIO1_IO21 USDHC2_DATA1 KPP_COL05 GPT2_COMPARE1 FLEXIO3_FLEXIO05 127 PA22 = portA + 22 // [AD_B1_06]: FLEXSPIB_DATA01 LPI2C3_SDA LPUART3_TX SPDIF_LOCK CSI_VSYNC GPIO1_IO22 USDHC2_DATA2 KPP_ROW04 GPT2_COMPARE2 FLEXIO3_FLEXIO06 128 PA23 = portA + 23 // [AD_B1_07]: FLEXSPIB_DATA00 LPI2C3_SCL LPUART3_RX SPDIF_EXT_CLK CSI_HSYNC GPIO1_IO23 USDHC2_DATA3 KPP_COL04 GPT2_COMPARE3 FLEXIO3_FLEXIO07 129 PA24 = portA + 24 // [AD_B1_08]: FLEXSPIA_SS1_B FLEXPWM4_PWMA00 FLEXCAN1_TX CCM_PMIC_READY CSI_DATA09 GPIO1_IO24 USDHC2_CMD KPP_ROW03 FLEXIO3_FLEXIO08 ~ 130 PA25 = portA + 25 // [AD_B1_09]: FLEXSPIA_DQS FLEXPWM4_PWMA01 FLEXCAN1_RX SAI1_MCLK CSI_DATA08 GPIO1_IO25 USDHC2_CLK KPP_COL03 FLEXIO3_FLEXIO09 ~ 131 PA26 = portA + 26 // [AD_B1_10]: FLEXSPIA_DATA03 WDOG1_B LPUART8_TX SAI1_RX_SYNC CSI_DATA07 GPIO1_IO26 USDHC2_WP KPP_ROW02 ENET2_1588_EVENT1_OUT FLEXIO3_FLEXIO10 132 PA27 = portA + 27 // [AD_B1_11]: FLEXSPIA_DATA02 EWM_OUT_B LPUART8_RX SAI1_RX_BCLK CSI_DATA06 GPIO1_IO27 USDHC2_RESET_B KPP_COL02 ENET2_1588_EVENT1_IN FLEXIO3_FLEXIO11 133 PA28 = portA + 28 // [AD_B1_12]: FLEXSPIA_DATA01 ACMP_OUT00 LPSPI3_PCS0 SAI1_RX_DATA00 CSI_DATA05 GPIO1_IO28 USDHC2_DATA4 KPP_ROW01 ENET2_1588_EVENT2_OUT FLEXIO3_FLEXIO12 134 PA29 = portA + 29 // [AD_B1_13]: FLEXSPIA_DATA00 ACMP_OUT01 LPSPI3_SDI SAI1_TX_DATA00 CSI_DATA04 GPIO1_IO29 USDHC2_DATA5 KPP_COL01 ENET2_1588_EVENT2_IN FLEXIO3_FLEXIO13 135 PA30 = portA + 30 // [AD_B1_14]: FLEXSPIA_SCLK ACMP_OUT02 LPSPI3_SDO SAI1_TX_BCLK CSI_DATA03 GPIO1_IO30 USDHC2_DATA6 KPP_ROW00 ENET2_1588_EVENT3_OUT FLEXIO3_FLEXIO14 136 PA31 = portA + 31 // [AD_B1_15]: FLEXSPIA_SS0_B ACMP_OUT03 LPSPI3_SCK SAI1_TX_SYNC CSI_DATA02 GPIO1_IO31 USDHC2_DATA7 KPP_COL00 ENET2_1588_EVENT3_IN FLEXIO3_FLEXIO15 137 138 PB0 = portB + 0 // [B0_00]: LCD_CLK QTIMER1_TIMER0 MQS_RIGHT LPSPI4_PCS0 FLEXIO2_FLEXIO00 GPIO2_IO00 SEMC_CSX01 ENET2_MDC ~ ~ 139 PB1 = portB + 1 // [B0_01]: LCD_ENABLE QTIMER1_TIMER1 MQS_LEFT LPSPI4_SDI FLEXIO2_FLEXIO01 GPIO2_IO01 SEMC_CSX02 ENET2_MDIO ~ ~ 140 PB2 = portB + 2 // [B0_02]: LCD_HSYNC QTIMER1_TIMER2 FLEXCAN1_TX LPSPI4_SDO FLEXIO2_FLEXIO02 GPIO2_IO02 SEMC_CSX03 ENET2_1588_EVENT0_OUT ~ ~ 141 PB3 = portB + 3 // [B0_03]: LCD_VSYNC QTIMER2_TIMER0 FLEXCAN1_RX LPSPI4_SCK FLEXIO2_FLEXIO03 GPIO2_IO03 WDOG2_RESET_B_DEB ENET2_1588_EVENT0_IN ~ ~ 142 PB4 = portB + 4 // [B0_04]: LCD_DATA00 QTIMER2_TIMER1 LPI2C2_SCL ARM_TRACE0 FLEXIO2_FLEXIO04 GPIO2_IO04 SRC_BOOT_CFG00 ENET2_TDATA03 ~ ~ 143 PB5 = portB + 5 // [B0_05]: LCD_DATA01 QTIMER2_TIMER2 LPI2C2_SDA ARM_TRACE1 FLEXIO2_FLEXIO05 GPIO2_IO05 SRC_BOOT_CFG01 ENET2_TDATA02 ~ ~ 144 PB6 = portB + 6 // [B0_06]: LCD_DATA02 QTIMER3_TIMER0 FLEXPWM2_PWMA00 ARM_TRACE2 FLEXIO2_FLEXIO06 GPIO2_IO06 SRC_BOOT_CFG02 ENET2_RX_CLK ~ ~ 145 PB7 = portB + 7 // [B0_07]: LCD_DATA03 QTIMER3_TIMER1 FLEXPWM2_PWMB00 ARM_TRACE3 FLEXIO2_FLEXIO07 GPIO2_IO07 SRC_BOOT_CFG03 ENET2_TX_ER ~ ~ 146 PB8 = portB + 8 // [B0_08]: LCD_DATA04 QTIMER3_TIMER2 FLEXPWM2_PWMA01 LPUART3_TX FLEXIO2_FLEXIO08 GPIO2_IO08 SRC_BOOT_CFG04 ENET2_RDATA03 ~ ~ 147 PB9 = portB + 9 // [B0_09]: LCD_DATA05 QTIMER4_TIMER0 FLEXPWM2_PWMB01 LPUART3_RX FLEXIO2_FLEXIO09 GPIO2_IO09 SRC_BOOT_CFG05 ENET2_RDATA02 ~ ~ 148 PB10 = portB + 10 // [B0_10]: LCD_DATA06 QTIMER4_TIMER1 FLEXPWM2_PWMA02 SAI1_TX_DATA03 FLEXIO2_FLEXIO10 GPIO2_IO10 SRC_BOOT_CFG06 ENET2_CRS ~ ~ 149 PB11 = portB + 11 // [B0_11]: LCD_DATA07 QTIMER4_TIMER2 FLEXPWM2_PWMB02 SAI1_TX_DATA02 FLEXIO2_FLEXIO11 GPIO2_IO11 SRC_BOOT_CFG07 ENET2_COL ~ ~ 150 PB12 = portB + 12 // [B0_12]: LCD_DATA08 XBAR1_INOUT10 ARM_TRACE_CLK SAI1_TX_DATA01 FLEXIO2_FLEXIO12 GPIO2_IO12 SRC_BOOT_CFG08 ENET2_TDATA00 ~ ~ 151 PB13 = portB + 13 // [B0_13]: LCD_DATA09 XBAR1_INOUT11 ARM_TRACE_SWO SAI1_MCLK FLEXIO2_FLEXIO13 GPIO2_IO13 SRC_BOOT_CFG09 ENET2_TDATA01 ~ ~ 152 PB14 = portB + 14 // [B0_14]: LCD_DATA10 XBAR1_INOUT12 ARM_TXEV SAI1_RX_SYNC FLEXIO2_FLEXIO14 GPIO2_IO14 SRC_BOOT_CFG10 ENET2_TX_EN ~ ~ 153 PB15 = portB + 15 // [B0_15]: LCD_DATA11 XBAR1_INOUT13 ARM_RXEV SAI1_RX_BCLK FLEXIO2_FLEXIO15 GPIO2_IO15 SRC_BOOT_CFG11 ENET2_TX_CLK ENET2_REF_CLK2 ~ 154 PB16 = portB + 16 // [B1_00]: LCD_DATA12 XBAR1_INOUT14 LPUART4_TX SAI1_RX_DATA00 FLEXIO2_FLEXIO16 GPIO2_IO16 FLEXPWM1_PWMA03 ENET2_RX_ER FLEXIO3_FLEXIO16 ~ 155 PB17 = portB + 17 // [B1_01]: LCD_DATA13 XBAR1_INOUT15 LPUART4_RX SAI1_TX_DATA00 FLEXIO2_FLEXIO17 GPIO2_IO17 FLEXPWM1_PWMB03 ENET2_RDATA00 FLEXIO3_FLEXIO17 ~ 156 PB18 = portB + 18 // [B1_02]: LCD_DATA14 XBAR1_INOUT16 LPSPI4_PCS2 SAI1_TX_BCLK FLEXIO2_FLEXIO18 GPIO2_IO18 FLEXPWM2_PWMA03 ENET2_RDATA01 FLEXIO3_FLEXIO18 ~ 157 PB19 = portB + 19 // [B1_03]: LCD_DATA15 XBAR1_INOUT17 LPSPI4_PCS1 SAI1_TX_SYNC FLEXIO2_FLEXIO19 GPIO2_IO19 FLEXPWM2_PWMB03 ENET2_RX_EN FLEXIO3_FLEXIO19 ~ 158 PB20 = portB + 20 // [B1_04]: LCD_DATA16 LPSPI4_PCS0 CSI_DATA15 ENET_RX_DATA00 FLEXIO2_FLEXIO20 GPIO2_IO20 GPT1_CLK FLEXIO3_FLEXIO20 ~ ~ 159 PB21 = portB + 21 // [B1_05]: LCD_DATA17 LPSPI4_SDI CSI_DATA14 ENET_RX_DATA01 FLEXIO2_FLEXIO21 GPIO2_IO21 GPT1_CAPTURE1 FLEXIO3_FLEXIO21 ~ ~ 160 PB22 = portB + 22 // [B1_06]: LCD_DATA18 LPSPI4_SDO CSI_DATA13 ENET_RX_EN FLEXIO2_FLEXIO22 GPIO2_IO22 GPT1_CAPTURE2 FLEXIO3_FLEXIO22 ~ ~ 161 PB23 = portB + 23 // [B1_07]: LCD_DATA19 LPSPI4_SCK CSI_DATA12 ENET_TX_DATA00 FLEXIO2_FLEXIO23 GPIO2_IO23 GPT1_COMPARE1 FLEXIO3_FLEXIO23 ~ ~ 162 PB24 = portB + 24 // [B1_08]: LCD_DATA20 QTIMER1_TIMER3 CSI_DATA11 ENET_TX_DATA01 FLEXIO2_FLEXIO24 GPIO2_IO24 FLEXCAN2_TX GPT1_COMPARE2 FLEXIO3_FLEXIO24 ~ 163 PB25 = portB + 25 // [B1_09]: LCD_DATA21 QTIMER2_TIMER3 CSI_DATA10 ENET_TX_EN FLEXIO2_FLEXIO25 GPIO2_IO25 FLEXCAN2_RX GPT1_COMPARE3 FLEXIO3_FLEXIO25 ~ 164 PB26 = portB + 26 // [B1_10]: LCD_DATA22 QTIMER3_TIMER3 CSI_DATA00 ENET_TX_CLK FLEXIO2_FLEXIO26 GPIO2_IO26 ENET_REF_CLK FLEXIO3_FLEXIO26 ~ ~ 165 PB27 = portB + 27 // [B1_11]: LCD_DATA23 QTIMER4_TIMER3 CSI_DATA01 ENET_RX_ER FLEXIO2_FLEXIO27 GPIO2_IO27 LPSPI4_PCS3 FLEXIO3_FLEXIO27 ~ ~ 166 PB28 = portB + 28 // [B1_12]: LPUART5_TX CSI_PIXCLK ENET_1588_EVENT0_IN FLEXIO2_FLEXIO28 GPIO2_IO28 USDHC1_CD_B FLEXIO3_FLEXIO28 ~ ~ ~ 167 PB29 = portB + 29 // [B1_13]: WDOG1_B LPUART5_RX CSI_VSYNC ENET_1588_EVENT0_OUT FLEXIO2_FLEXIO29 GPIO2_IO29 USDHC1_WP SEMC_DQS4 FLEXIO3_FLEXIO29 ~ 168 PB30 = portB + 30 // [B1_14]: ENET_MDC FLEXPWM4_PWMA02 CSI_HSYNC XBAR1_IN02 FLEXIO2_FLEXIO30 GPIO2_IO30 USDHC1_VSELECT ENET2_TDATA00 FLEXIO3_FLEXIO30 ~ 169 PB31 = portB + 31 // [B1_15]: ENET_MDIO FLEXPWM4_PWMA03 CSI_MCLK XBAR1_IN03 FLEXIO2_FLEXIO31 GPIO2_IO31 USDHC1_RESET_B ENET2_TDATA01 FLEXIO3_FLEXIO31 ~ 170 171 PC0 = portC + 0 // [SD_B1_00]: USDHC2_DATA3 FLEXSPIB_DATA03 FLEXPWM1_PWMA03 SAI1_TX_DATA03 LPUART4_TX GPIO3_IO00 SAI3_RX_DATA ~ ~ ~ 172 PC1 = portC + 1 // [SD_B1_01]: USDHC2_DATA2 FLEXSPIB_DATA02 FLEXPWM1_PWMB03 SAI1_TX_DATA02 LPUART4_RX GPIO3_IO01 SAI3_TX_DATA ~ ~ ~ 173 PC2 = portC + 2 // [SD_B1_02]: USDHC2_DATA1 FLEXSPIB_DATA01 FLEXPWM2_PWMA03 SAI1_TX_DATA01 FLEXCAN1_TX GPIO3_IO02 CCM_WAIT SAI3_TX_SYNC ~ ~ 174 PC3 = portC + 3 // [SD_B1_03]: USDHC2_DATA0 FLEXSPIB_DATA00 FLEXPWM2_PWMB03 SAI1_MCLK FLEXCAN1_RX GPIO3_IO03 CCM_PMIC_READY SAI3_TX_BCLK ~ ~ 175 PC4 = portC + 4 // [SD_B1_04]: USDHC2_CLK FLEXSPIB_SCLK LPI2C1_SCL SAI1_RX_SYNC FLEXSPIA_SS1_B GPIO3_IO04 CCM_STOP SAI3_MCLK ~ ~ 176 PC5 = portC + 5 // [SD_B1_05]: USDHC2_CMD FLEXSPIA_DQS LPI2C1_SDA SAI1_RX_BCLK FLEXSPIB_SS0_B GPIO3_IO05 SAI3_RX_SYNC ~ ~ ~ 177 PC6 = portC + 6 // [SD_B1_06]: USDHC2_RESET_B FLEXSPIA_SS0_B LPUART7_CTS_B SAI1_RX_DATA00 LPSPI2_PCS0 GPIO3_IO06 SAI3_RX_BCLK ~ ~ ~ 178 PC7 = portC + 7 // [SD_B1_07]: SEMC_CSX01 FLEXSPIA_SCLK LPUART7_RTS_B SAI1_TX_DATA00 LPSPI2_SCK GPIO3_IO07 ~ ~ ~ ~ 179 PC8 = portC + 8 // [SD_B1_08]: USDHC2_DATA4 FLEXSPIA_DATA00 LPUART7_TX SAI1_TX_BCLK LPSPI2_SD0 GPIO3_IO08 SEMC_CSX02 ~ ~ ~ 180 PC9 = portC + 9 // [SD_B1_09]: USDHC2_DATA5 FLEXSPIA_DATA01 LPUART7_RX SAI1_TX_SYNC LPSPI2_SDI GPIO3_IO09 ~ ~ ~ ~ 181 PC10 = portC + 10 // [SD_B1_10]: USDHC2_DATA6 FLEXSPIA_DATA02 LPUART2_RX LPI2C2_SDA LPSPI2_PCS2 GPIO3_IO10 ~ ~ ~ ~ 182 PC11 = portC + 11 // [SD_B1_11]: USDHC2_DATA7 FLEXSPIA_DATA03 LPUART2_TX LPI2C2_SCL LPSPI2_PCS3 GPIO3_IO11 ~ ~ ~ ~ 183 PC12 = portC + 12 // [SD_B0_00]: USDHC1_CMD FLEXPWM1_PWMA00 LPI2C3_SCL XBAR1_INOUT04 LPSPI1_SCK GPIO3_IO12 FLEXSPIA_SS1_B ENET2_TX_EN SEMC_DQS4 ~ 184 PC13 = portC + 13 // [SD_B0_01]: USDHC1_CLK FLEXPWM1_PWMB00 LPI2C3_SDA XBAR1_INOUT05 LPSPI1_PCS0 GPIO3_IO13 FLEXSPIB_SS1_B ENET2_TX_CLK ENET2_REF_CLK2 ~ 185 PC14 = portC + 14 // [SD_B0_02]: USDHC1_DATA0 FLEXPWM1_PWMA01 LPUART8_CTS_B XBAR1_INOUT06 LPSPI1_SDO GPIO3_IO14 ENET2_RX_ER SEMC_CLK5 ~ ~ 186 PC15 = portC + 15 // [SD_B0_03]: USDHC1_DATA1 FLEXPWM1_PWMB01 LPUART8_RTS_B XBAR1_INOUT07 LPSPI1_SDI GPIO3_IO15 ENET2_RDATA00 SEMC_CLK6 ~ ~ 187 PC16 = portC + 16 // [SD_B0_04]: USDHC1_DATA2 FLEXPWM1_PWMA02 LPUART8_TX XBAR1_INOUT08 FLEXSPIB_SS0_B GPIO3_IO16 CCM_CLKO1 ENET2_RDATA01 ~ ~ 188 PC17 = portC + 17 // [SD_B0_05]: USDHC1_DATA3 FLEXPWM1_PWMB02 LPUART8_RX XBAR1_INOUT09 FLEXSPIB_DQS GPIO3_IO17 CCM_CLKO2 ENET2_RX_EN ~ ~ 189 PC18 = portC + 18 // [EMC_32]: SEMC_DATA10 FLEXPWM3_PWMB01 LPUART7_RX CCM_PMIC_RDY CSI_DATA21 GPIO3_IO18 ENET2_TX_EN ~ ~ ~ 190 PC19 = portC + 19 // [EMC_33]: SEMC_DATA11 FLEXPWM3_PWMA02 USDHC1_RESET_B SAI3_RX_DATA CSI_DATA20 GPIO3_IO19 ENET2_TX_CLK ENET2_REF_CLK2 ~ ~ 191 PC20 = portC + 20 // [EMC_34]: SEMC_DATA12 FLEXPWM3_PWMB02 USDHC1_VSELECT SAI3_RX_SYNC CSI_DATA19 GPIO3_IO20 ENET2_RX_ER ~ ~ ~ 192 PC21 = portC + 21 // [EMC_35]: SEMC_DATA13 XBAR1_INOUT18 GPT1_COMPARE1 SAI3_RX_BCLK CSI_DATA18 GPIO3_IO21 USDHC1_CD_B ENET2_RDATA00 ~ ~ 193 PC22 = portC + 22 // [EMC_36]: SEMC_DATA14 XBAR1_IN22 GPT1_COMPARE2 SAI3_TX_DATA CSI_DATA17 GPIO3_IO22 USDHC1_WP ENET2_RDATA01 FLEXCAN3_TX ~ 194 PC23 = portC + 23 // [EMC_37]: SEMC_DATA15 XBAR1_IN23 GPT1_COMPARE3 SAI3_MCLK CSI_DATA16 GPIO3_IO23 USDHC2_WP ENET2_RX_EN FLEXCAN3_RX ~ 195 PC24 = portC + 24 // [EMC_38]: SEMC_DM01 FLEXPWM1_PWMA03 LPUART8_TX SAI3_TX_BCLK CSI_FIELD GPIO3_IO24 USDHC2_VSELECT ENET2_MDC ~ ~ 196 PC25 = portC + 25 // [EMC_39]: SEMC_DQS FLEXPWM1_PWMB03 LPUART8_RX SAI3_TX_SYNC WDOG1_WDOG_B GPIO3_IO25 USDHC2_CD_B ENET2_MDIO SEMC_DQS4 ~ 197 PC26 = portC + 26 // [EMC_40]: SEMC_RDY GPT2_CAPTURE2 LPSPI1_PCS2 USB_OTG2_OC ENET_MDC GPIO3_IO26 USDHC2_RESET_B SEMC_CLK5 ~ ~ 198 PC27 = portC + 27 // [EMC_41]: SEMC_CSX00 GPT2_CAPTURE1 LPSPI1_PCS3 USB_OTG2_PWR ENET_MDIO GPIO3_IO27 USDHC1_VSELECT ~ ~ ~ 199 _ = portC + 28 // 200 _ = portC + 29 // 201 _ = portC + 30 // 202 _ = portC + 31 // 203 204 PD0 = portD + 0 // [EMC_00]: SEMC_DATA00 FLEXPWM4_PWMA00 LPSPI2_SCK XBAR1_XBAR_IN02 FLEXIO1_FLEXIO00 GPIO4_IO00 ~ ~ ~ ~ 205 PD1 = portD + 1 // [EMC_01]: SEMC_DATA01 FLEXPWM4_PWMB00 LPSPI2_PCS0 XBAR1_IN03 FLEXIO1_FLEXIO01 GPIO4_IO01 ~ ~ ~ ~ 206 PD2 = portD + 2 // [EMC_02]: SEMC_DATA02 FLEXPWM4_PWMA01 LPSPI2_SDO XBAR1_INOUT04 FLEXIO1_FLEXIO02 GPIO4_IO02 ~ ~ ~ ~ 207 PD3 = portD + 3 // [EMC_03]: SEMC_DATA03 FLEXPWM4_PWMB01 LPSPI2_SDI XBAR1_INOUT05 FLEXIO1_FLEXIO03 GPIO4_IO03 ~ ~ ~ ~ 208 PD4 = portD + 4 // [EMC_04]: SEMC_DATA04 FLEXPWM4_PWMA02 SAI2_TX_DATA XBAR1_INOUT06 FLEXIO1_FLEXIO04 GPIO4_IO04 ~ ~ ~ ~ 209 PD5 = portD + 5 // [EMC_05]: SEMC_DATA05 FLEXPWM4_PWMB02 SAI2_TX_SYNC XBAR1_INOUT07 FLEXIO1_FLEXIO05 GPIO4_IO05 ~ ~ ~ ~ 210 PD6 = portD + 6 // [EMC_06]: SEMC_DATA06 FLEXPWM2_PWMA00 SAI2_TX_BCLK XBAR1_INOUT08 FLEXIO1_FLEXIO06 GPIO4_IO06 ~ ~ ~ ~ 211 PD7 = portD + 7 // [EMC_07]: SEMC_DATA07 FLEXPWM2_PWMB00 SAI2_MCLK XBAR1_INOUT09 FLEXIO1_FLEXIO07 GPIO4_IO07 ~ ~ ~ ~ 212 PD8 = portD + 8 // [EMC_08]: SEMC_DM00 FLEXPWM2_PWMA01 SAI2_RX_DATA XBAR1_INOUT17 FLEXIO1_FLEXIO08 GPIO4_IO08 ~ ~ ~ ~ 213 PD9 = portD + 9 // [EMC_09]: SEMC_ADDR00 FLEXPWM2_PWMB01 SAI2_RX_SYNC FLEXCAN2_TX FLEXIO1_FLEXIO09 GPIO4_IO09 FLEXSPI2_B_SS1_B ~ ~ ~ 214 PD10 = portD + 10 // [EMC_10]: SEMC_ADDR01 FLEXPWM2_PWMA02 SAI2_RX_BCLK FLEXCAN2_RX FLEXIO1_FLEXIO10 GPIO4_IO10 FLEXSPI2_B_SS0_B ~ ~ ~ 215 PD11 = portD + 11 // [EMC_11]: SEMC_ADDR02 FLEXPWM2_PWMB02 LPI2C4_SDA USDHC2_RESET_B FLEXIO1_FLEXIO11 GPIO4_IO11 FLEXSPI2_B_DQS ~ ~ ~ 216 PD12 = portD + 12 // [EMC_12]: SEMC_ADDR03 XBAR1_IN24 LPI2C4_SCL USDHC1_WP FLEXPWM1_PWMA03 GPIO4_IO12 FLEXSPI2_B_SCLK ~ ~ ~ 217 PD13 = portD + 13 // [EMC_13]: SEMC_ADDR04 XBAR1_IN25 LPUART3_TX MQS_RIGHT FLEXPWM1_PWMB03 GPIO4_IO13 FLEXSPI2_B_DATA00 ~ ~ ~ 218 PD14 = portD + 14 // [EMC_14]: SEMC_ADDR05 XBAR1_INOUT19 LPUART3_RX MQS_LEFT LPSPI2_PCS1 GPIO4_IO14 FLEXSPI2_B_DATA01 ~ ~ ~ 219 PD15 = portD + 15 // [EMC_15]: SEMC_ADDR06 XBAR1_IN20 LPUART3_CTS_B SPDIF_OUT QTIMER3_TIMER0 GPIO4_IO15 FLEXSPI2_B_DATA02 ~ ~ ~ 220 PD16 = portD + 16 // [EMC_16]: SEMC_ADDR07 XBAR1_IN21 LPUART3_RTS_B SPDIF_IN QTIMER3_TIMER1 GPIO4_IO16 FLEXSPI2_B_DATA03 ~ ~ ~ 221 PD17 = portD + 17 // [EMC_17]: SEMC_ADDR08 FLEXPWM4_PWMA03 LPUART4_CTS_B FLEXCAN1_TX QTIMER3_TIMER2 GPIO4_IO17 ~ ~ ~ ~ 222 PD18 = portD + 18 // [EMC_18]: SEMC_ADDR09 FLEXPWM4_PWMB03 LPUART4_RTS_B FLEXCAN1_RX QTIMER3_TIMER3 GPIO4_IO18 SNVS_VIO_5_CTL ~ ~ ~ 223 PD19 = portD + 19 // [EMC_19]: SEMC_ADDR11 FLEXPWM2_PWMA03 LPUART4_TX ENET_RDATA01 QTIMER2_TIMER0 GPIO4_IO19 SNVS_VIO_5 ~ ~ ~ 224 PD20 = portD + 20 // [EMC_20]: SEMC_ADDR12 FLEXPWM2_PWMB03 LPUART4_RX ENET_RDATA00 QTIMER2_TIMER1 GPIO4_IO20 ~ ~ ~ ~ 225 PD21 = portD + 21 // [EMC_21]: SEMC_BA0 FLEXPWM3_PWMA03 LPI2C3_SDA ENET_TDATA01 QTIMER2_TIMER2 GPIO4_IO21 ~ ~ ~ ~ 226 PD22 = portD + 22 // [EMC_22]: SEMC_BA1 FLEXPWM3_PWMB03 LPI2C3_SCL ENET_TDATA00 QTIMER2_TIMER3 GPIO4_IO22 FLEXSPI2_A_SS1_B ~ ~ ~ 227 PD23 = portD + 23 // [EMC_23]: SEMC_ADDR10 FLEXPWM1_PWMA00 LPUART5_TX ENET_RX_EN GPT1_CAPTURE2 GPIO4_IO23 FLEXSPI2_A_DQS ~ ~ ~ 228 PD24 = portD + 24 // [EMC_24]: SEMC_CAS FLEXPWM1_PWMB00 LPUART5_RX ENET_TX_EN GPT1_CAPTURE1 GPIO4_IO24 FLEXSPI2_A_SS0_B ~ ~ ~ 229 PD25 = portD + 25 // [EMC_25]: SEMC_RAS FLEXPWM1_PWMA01 LPUART6_TX ENET_TX_CLK ENET_REF_CLK GPIO4_IO25 FLEXSPI2_A_SCLK ~ ~ ~ 230 PD26 = portD + 26 // [EMC_26]: SEMC_CLK FLEXPWM1_PWMB01 LPUART6_RX ENET_RX_ER FLEXIO1_FLEXIO12 GPIO4_IO26 FLEXSPI2_A_DATA00 ~ ~ ~ 231 PD27 = portD + 27 // [EMC_27]: SEMC_CKE FLEXPWM1_PWMA02 LPUART5_RTS_B LPSPI1_SCK FLEXIO1_FLEXIO13 GPIO4_IO27 FLEXSPI2_A_DATA01 ~ ~ ~ 232 PD28 = portD + 28 // [EMC_28]: SEMC_WE FLEXPWM1_PWMB02 LPUART5_CTS_B LPSPI1_SDO FLEXIO1_FLEXIO14 GPIO4_IO28 FLEXSPI2_A_DATA02 ~ ~ ~ 233 PD29 = portD + 29 // [EMC_29]: SEMC_CS0 FLEXPWM3_PWMA00 LPUART6_RTS_B LPSPI1_SDI FLEXIO1_FLEXIO15 GPIO4_IO29 FLEXSPI2_A_DATA03 ~ ~ ~ 234 PD30 = portD + 30 // [EMC_30]: SEMC_DATA08 FLEXPWM3_PWMB00 LPUART6_CTS_B LPSPI1_PCS0 CSI_DATA23 GPIO4_IO30 ENET2_TDATA00 ~ ~ ~ 235 PD31 = portD + 31 // [EMC_31]: SEMC_DATA09 FLEXPWM3_PWMA01 LPUART7_TX LPSPI1_PCS1 CSI_DATA22 GPIO4_IO31 ENET2_TDATA01 ~ ~ ~ 236 ) 237 238 func (p Pin) getPos() uint8 { return uint8(p % 32) } 239 func (p Pin) getMask() uint32 { return uint32(1) << p.getPos() } 240 func (p Pin) getPort() Pin { return Pin(p/32) * 32 } 241 242 // Configure sets the GPIO pad and pin properties, and selects the appropriate 243 // alternate function, for a given Pin and PinConfig. 244 func (p Pin) Configure(config PinConfig) { 245 var ( 246 sre = uint32(0x01 << 0) 247 dse = func(n uint32) uint32 { return (n & 0x07) << 3 } 248 spd = func(n uint32) uint32 { return (n & 0x03) << 6 } 249 ode = uint32(0x01 << 11) 250 pke = uint32(0x01 << 12) 251 pue = uint32(0x01 << 13) 252 pup = func(n uint32) uint32 { return (n & 0x03) << 14 } 253 hys = uint32(0x01 << 16) 254 ) 255 256 _, gpio := p.getGPIO() // use fast GPIO for all pins 257 pad, mux := p.getPad() 258 259 // first configure the pad characteristics 260 switch config.Mode { 261 case PinInput: 262 gpio.GDIR.ClearBits(p.getMask()) 263 pad.Set(dse(7)) 264 265 case PinInputPullup: 266 gpio.GDIR.ClearBits(p.getMask()) 267 pad.Set(dse(7) | pke | pue | pup(3) | hys) 268 269 case PinInputPulldown: 270 gpio.GDIR.ClearBits(p.getMask()) 271 pad.Set(dse(7) | pke | pue | hys) 272 273 case PinOutput: 274 gpio.GDIR.SetBits(p.getMask()) 275 pad.Set(dse(7)) 276 277 case PinOutputOpenDrain: 278 gpio.GDIR.SetBits(p.getMask()) 279 pad.Set(dse(7) | ode) 280 281 case PinDisable: 282 gpio.GDIR.ClearBits(p.getMask()) 283 pad.Set(dse(7) | hys) 284 285 case PinInputAnalog: 286 gpio.GDIR.ClearBits(p.getMask()) 287 pad.Set(dse(7)) 288 289 case PinModeUARTTX: 290 pad.Set(sre | dse(3) | spd(3)) 291 292 case PinModeUARTRX: 293 pad.Set(dse(7) | pke | pue | pup(3) | hys) 294 295 case PinModeSPISDI: 296 pad.Set(dse(7) | spd(2)) 297 298 case PinModeSPISDO: 299 pad.Set(dse(7) | spd(2)) 300 301 case PinModeSPICLK: 302 pad.Set(dse(7) | spd(2)) 303 304 case PinModeSPICS: 305 pad.Set(dse(7)) 306 307 case PinModeI2CSDA, PinModeI2CSCL: 308 pad.Set(ode | sre | dse(4) | spd(1) | pke | pue | pup(3)) 309 } 310 311 // then configure the alternate function mux 312 mux.Set(p.getMuxMode(config)) 313 } 314 315 // Get returns the current value of a GPIO pin. 316 func (p Pin) Get() bool { 317 _, gpio := p.getGPIO() // use fast GPIO for all pins 318 return gpio.PSR.HasBits(p.getMask()) 319 } 320 321 // Set changes the value of the GPIO pin. The pin must be configured as output. 322 func (p Pin) Set(value bool) { 323 _, gpio := p.getGPIO() // use fast GPIO for all pins 324 if value { 325 gpio.DR_SET.Set(p.getMask()) 326 } else { 327 gpio.DR_CLEAR.Set(p.getMask()) 328 } 329 } 330 331 // Toggle switches an output pin from low to high or from high to low. 332 func (p Pin) Toggle() { 333 _, gpio := p.getGPIO() // use fast GPIO for all pins 334 gpio.DR_TOGGLE.Set(p.getMask()) 335 } 336 337 // dispatchInterrupt invokes the user-provided callback functions for external 338 // interrupts generated on the high-speed GPIO pins. 339 // 340 // Unfortunately, all four high-speed GPIO ports (A-D) are connected to just a 341 // single interrupt control line. Therefore, the interrupt status register (ISR) 342 // must be checked in all four GPIO ports on every interrupt. 343 func (jt *pinJumpTable) dispatchInterrupt(interrupt.Interrupt) { 344 handle := func(gpio *nxp.GPIO_Type, port Pin) { 345 if status := gpio.ISR.Get() & gpio.IMR.Get(); status != 0 { 346 gpio.ISR.Set(status) // clear interrupt 347 for status != 0 { 348 off := Pin(bits.TrailingZeros32(status)) // ctz 349 pin := Pin(port + off) 350 jt.lut[pin](pin) 351 status &^= 1 << off 352 } 353 } 354 } 355 if jt.numDefined > 0 { 356 handle(nxp.GPIO6, portA) 357 handle(nxp.GPIO7, portB) 358 handle(nxp.GPIO8, portC) 359 handle(nxp.GPIO9, portD) 360 } 361 } 362 363 // set associates a function with a given Pin in the receiver lookup table. If 364 // the function is nil, the given Pin's associated function is removed. 365 func (jt *pinJumpTable) set(pin Pin, fn func(Pin)) { 366 if int(pin) < len(jt.lut) { 367 if nil != fn { 368 if nil == jt.lut[pin] { 369 jt.numDefined++ 370 } 371 jt.lut[pin] = fn 372 } else { 373 if nil != jt.lut[pin] { 374 jt.numDefined-- 375 } 376 jt.lut[pin] = nil 377 } 378 } 379 } 380 381 // SetInterrupt sets an interrupt to be executed when a particular pin changes 382 // state. The pin should already be configured as an input, including a pull up 383 // or down if no external pull is provided. 384 // 385 // This call will replace a previously set callback on this pin. You can pass a 386 // nil func to unset the pin change interrupt. If you do so, the change 387 // parameter is ignored and can be set to any value (such as 0). 388 func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error { 389 _, gpio := p.getGPIO() // use fast GPIO for all pins 390 mask := p.getMask() 391 if nil != callback { 392 switch change { 393 case PinRising, PinFalling: 394 gpio.EDGE_SEL.ClearBits(mask) 395 var reg *volatile.Register32 396 var pos uint8 397 if pos = p.getPos(); pos < 16 { 398 reg = &gpio.ICR1 // ICR1 = pins 0-15 399 } else { 400 reg = &gpio.ICR2 // ICR2 = pins 16-31 401 pos -= 16 402 } 403 reg.ReplaceBits(uint32(change), 0x3, pos*2) 404 case PinToggle: 405 gpio.EDGE_SEL.SetBits(mask) 406 } 407 pinISR.set(p, callback) // associate the callback with the pin 408 gpio.ISR.Set(mask) // clear any pending interrupt (W1C) 409 gpio.IMR.SetBits(mask) // enable external interrupt 410 } else { 411 pinISR.set(p, nil) // remove any associated callback from the pin 412 gpio.ISR.Set(mask) // clear any pending interrupt (W1C) 413 gpio.IMR.ClearBits(mask) // disable external interrupt 414 } 415 // enable or disable the interrupt based on number of defined callbacks 416 if pinISR.numDefined > 0 { 417 if nil == pinInterrupt { 418 // create the Interrupt if it is not yet defined 419 irq := interrupt.New(nxp.IRQ_GPIO6_7_8_9, pinISR.dispatchInterrupt) 420 pinInterrupt = &irq 421 pinInterrupt.Enable() 422 } 423 } else { 424 if nil != pinInterrupt { 425 // disable the interrupt if it is defined 426 pinInterrupt.Disable() 427 } 428 } 429 return nil 430 } 431 432 // getGPIO returns both the normal (IPG_CLK_ROOT) and high-speed (AHB_CLK_ROOT) 433 // GPIO peripherals to which a given Pin is connected. 434 // 435 // Note that, currently, the device is configured to use high-speed GPIO for all 436 // pins (GPIO6-9), so the first return value should not be used (GPIO1-4). 437 // See the remarks and documentation reference in the comments preceding the 438 // const Pin definitions above. 439 func (p Pin) getGPIO() (norm *nxp.GPIO_Type, fast *nxp.GPIO_Type) { 440 switch p.getPort() { 441 case portA: 442 return nxp.GPIO1, nxp.GPIO6 443 case portB: 444 return nxp.GPIO2, nxp.GPIO7 445 case portC: 446 return nxp.GPIO3, nxp.GPIO8 447 case portD: 448 return nxp.GPIO4, nxp.GPIO9 449 default: 450 panic("machine: unknown port") 451 } 452 } 453 454 // getPad returns both the pad and mux configration registers for a given Pin. 455 func (p Pin) getPad() (pad *volatile.Register32, mux *volatile.Register32) { 456 switch p.getPort() { 457 case portA: 458 switch p.getPos() { 459 case 0: 460 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_00, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_00 461 case 1: 462 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_01, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_01 463 case 2: 464 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_02, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_02 465 case 3: 466 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_03, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_03 467 case 4: 468 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_04, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_04 469 case 5: 470 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_05, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_05 471 case 6: 472 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_06, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_06 473 case 7: 474 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_07, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_07 475 case 8: 476 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_08, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_08 477 case 9: 478 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_09, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_09 479 case 10: 480 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_10, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_10 481 case 11: 482 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_11, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_11 483 case 12: 484 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_12, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_12 485 case 13: 486 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_13, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_13 487 case 14: 488 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_14, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_14 489 case 15: 490 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B0_15, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B0_15 491 case 16: 492 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_00, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_00 493 case 17: 494 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_01, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_01 495 case 18: 496 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_02, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_02 497 case 19: 498 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_03, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_03 499 case 20: 500 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_04, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_04 501 case 21: 502 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_05, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_05 503 case 22: 504 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_06, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_06 505 case 23: 506 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_07, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_07 507 case 24: 508 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_08, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_08 509 case 25: 510 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_09, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_09 511 case 26: 512 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_10, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_10 513 case 27: 514 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_11, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_11 515 case 28: 516 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_12, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_12 517 case 29: 518 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_13, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_13 519 case 30: 520 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_14, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_14 521 case 31: 522 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_AD_B1_15, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_AD_B1_15 523 } 524 case portB: 525 switch p.getPos() { 526 case 0: 527 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_00, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_00 528 case 1: 529 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_01, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_01 530 case 2: 531 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_02, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_02 532 case 3: 533 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_03, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_03 534 case 4: 535 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_04, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_04 536 case 5: 537 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_05, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_05 538 case 6: 539 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_06, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_06 540 case 7: 541 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_07, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_07 542 case 8: 543 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_08, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_08 544 case 9: 545 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_09, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_09 546 case 10: 547 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_10, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_10 548 case 11: 549 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_11, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_11 550 case 12: 551 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_12, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_12 552 case 13: 553 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_13, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_13 554 case 14: 555 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_14, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_14 556 case 15: 557 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B0_15, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B0_15 558 case 16: 559 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_00, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_00 560 case 17: 561 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_01, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_01 562 case 18: 563 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_02, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_02 564 case 19: 565 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_03, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_03 566 case 20: 567 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_04, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_04 568 case 21: 569 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_05, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_05 570 case 22: 571 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_06, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_06 572 case 23: 573 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_07, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_07 574 case 24: 575 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_08, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_08 576 case 25: 577 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_09, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_09 578 case 26: 579 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_10, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_10 580 case 27: 581 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_11, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_11 582 case 28: 583 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_12, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_12 584 case 29: 585 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_13, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_13 586 case 30: 587 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_14, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_14 588 case 31: 589 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_B1_15, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_B1_15 590 } 591 case portC: 592 switch p.getPos() { 593 case 0: 594 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_00, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_00 595 case 1: 596 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_01, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_01 597 case 2: 598 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_02, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_02 599 case 3: 600 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_03, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_03 601 case 4: 602 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_04, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_04 603 case 5: 604 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_05, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_05 605 case 6: 606 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_06, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_06 607 case 7: 608 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_07, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_07 609 case 8: 610 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_08, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_08 611 case 9: 612 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_09, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_09 613 case 10: 614 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_10, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_10 615 case 11: 616 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B1_11, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B1_11 617 case 12: 618 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B0_00, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B0_00 619 case 13: 620 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B0_01, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B0_01 621 case 14: 622 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B0_02, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B0_02 623 case 15: 624 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B0_03, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B0_03 625 case 16: 626 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B0_04, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B0_04 627 case 17: 628 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_SD_B0_05, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_SD_B0_05 629 case 18: 630 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_32, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_32 631 case 19: 632 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_33, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_33 633 case 20: 634 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_34, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_34 635 case 21: 636 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_35, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_35 637 case 22: 638 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_36, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_36 639 case 23: 640 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_37, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_37 641 case 24: 642 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_38, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_38 643 case 25: 644 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_39, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_39 645 case 26: 646 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_40, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_40 647 case 27: 648 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_41, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_41 649 case 28, 29, 30, 31: 650 } 651 case portD: 652 switch p.getPos() { 653 case 0: 654 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_00, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_00 655 case 1: 656 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_01, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_01 657 case 2: 658 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_02, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_02 659 case 3: 660 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_03, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_03 661 case 4: 662 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_04, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_04 663 case 5: 664 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_05, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_05 665 case 6: 666 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_06, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_06 667 case 7: 668 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_07, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_07 669 case 8: 670 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_08, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_08 671 case 9: 672 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_09, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_09 673 case 10: 674 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_10, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_10 675 case 11: 676 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_11, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_11 677 case 12: 678 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_12, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_12 679 case 13: 680 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_13, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_13 681 case 14: 682 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_14, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_14 683 case 15: 684 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_15, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_15 685 case 16: 686 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_16, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_16 687 case 17: 688 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_17, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_17 689 case 18: 690 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_18, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_18 691 case 19: 692 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_19, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_19 693 case 20: 694 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_20, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_20 695 case 21: 696 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_21, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_21 697 case 22: 698 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_22, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_22 699 case 23: 700 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_23, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_23 701 case 24: 702 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_24, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_24 703 case 25: 704 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_25, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_25 705 case 26: 706 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_26, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_26 707 case 27: 708 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_27, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_27 709 case 28: 710 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_28, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_28 711 case 29: 712 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_29, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_29 713 case 30: 714 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_30, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_30 715 case 31: 716 return &nxp.IOMUXC.SW_PAD_CTL_PAD_GPIO_EMC_31, &nxp.IOMUXC.SW_MUX_CTL_PAD_GPIO_EMC_31 717 } 718 } 719 panic("machine: invalid pin") 720 } 721 722 // muxSelect is yet another level of indirection required to connect pins in an 723 // alternate function state to a desired peripheral (since more than one pin can 724 // provide a given alternate function). 725 // 726 // Once a pin is configured with a given alternate function mode, the IOMUXC 727 // device must then be configured to select which alternate function pin to 728 // route to the desired peripheral. 729 // 730 // The reference manual refers to this functionality as a "Daisy Chain". The 731 // associated docs are found in the i.MX RT1060 Processor Reference Manual: 732 // "Chapter 11.3.3 Daisy chain - multi pads driving same module input pin" 733 type muxSelect struct { 734 mux uint8 // AF mux selection (NOT a Pin type) 735 sel *volatile.Register32 // AF selection register 736 } 737 738 // connect configures the IOMUXC controller to route a given pin with alternate 739 // function to a desired peripheral (see godoc comments on type muxSelect). 740 func (s muxSelect) connect() { 741 s.sel.Set(uint32(s.mux)) 742 } 743 744 // getMuxMode acts as a callback from the `(Pin).Configure(PinMode)` routine to 745 // determine the alternate function setting for a given Pin and PinConfig. 746 // This value is used in the IOMUXC device's SW_MUX_CTL_PAD_GPIO_* registers. 747 func (p Pin) getMuxMode(config PinConfig) uint32 { 748 const forcePath = true // TODO: should be input parameter? 749 switch config.Mode { 750 751 // GPIO 752 case PinInput, PinInputPullup, PinInputPulldown, 753 PinOutput, PinOutputOpenDrain, PinDisable: 754 mode := uint32(0x5) // GPIO is always alternate function 5 755 if forcePath { 756 mode |= 0x10 // SION bit 757 } 758 return mode 759 760 // ADC 761 case PinInputAnalog: 762 mode := uint32(0x5) // use alternate function 5 (GPIO) 763 if forcePath { 764 mode |= 0x10 // SION bit 765 } 766 return mode 767 768 // UART RX/TX 769 case PinModeUARTRX, PinModeUARTTX: 770 mode := uint32(0x2) // UART is usually alternate function 2 on Teensy 4.x 771 // Teensy 4.1 has a UART (LPUART5) with alternate function 1 772 if p == PB28 || p == PB29 { 773 mode = 0x1 774 } 775 return mode 776 777 // SPI SDI 778 case PinModeSPISDI: 779 var mode uint32 780 switch p { 781 case PC15: // LPSPI1 SDI on PC15 alternate function 4 782 mode = uint32(0x4) 783 case PA2: // LPSPI3 SDI on PA2 alternate function 7 784 mode = uint32(0x7) 785 case PB1: // LPSPI4 SDI on PB1 alternate function 3 786 mode = uint32(0x3) 787 default: 788 panic("machine: invalid SPI SDI pin") 789 } 790 if forcePath { 791 mode |= 0x10 // SION bit 792 } 793 return mode 794 795 // SPI SDO 796 case PinModeSPISDO: 797 var mode uint32 798 switch p { 799 case PC14: // LPSPI1 SDO on PC14 alternate function 4 800 mode = uint32(0x4) 801 case PA30: // LPSPI3 SDO on PA30 alternate function 2 802 mode = uint32(0x2) 803 case PB2: // LPSPI4 SDO on PB2 alternate function 3 804 mode = uint32(0x3) 805 default: 806 panic("machine: invalid SPI SDO pin") 807 } 808 if forcePath { 809 mode |= 0x10 // SION bit 810 } 811 return mode 812 813 // SPI SCK 814 case PinModeSPICLK: 815 var mode uint32 816 switch p { 817 case PC12: // LPSPI1 SCK on PC12 alternate function 4 818 mode = uint32(0x4) 819 case PA31: // LPSPI3 SCK on PA31 alternate function 2 820 mode = uint32(0x2) 821 case PB3: // LPSPI4 SCK on PB3 alternate function 3 822 mode = uint32(0x3) 823 default: 824 panic("machine: invalid SPI CLK pin") 825 } 826 if forcePath { 827 mode |= 0x10 // SION bit 828 } 829 return mode 830 831 // SPI CS 832 case PinModeSPICS: 833 var mode uint32 834 switch p { 835 case PC13: // LPSPI1 CS on PC13 alternate function 4 836 mode = uint32(0x4) 837 case PA3: // LPSPI3 CS on PA3 alternate function 7 838 mode = uint32(0x7) 839 case PB0: // LPSPI4 CS on PB0 alternate function 3 840 mode = uint32(0x3) 841 default: // use alternate function 5 (GPIO) if non-CS pin selected 842 mode = uint32(0x5) 843 } 844 if forcePath { 845 mode |= 0x10 // SION bit 846 } 847 return mode 848 849 // I2C SDA 850 case PinModeI2CSDA: 851 var mode uint32 852 switch p { 853 case PA13: // LPI2C4 SDA on PA13 alternate function 0 854 mode = uint32(0) 855 case PA17: // LPI2C1 SDA on PA17 alternate function 3 856 mode = uint32(3) 857 case PA22: // LPI2C3 SDA on PA22 alternate function 1 858 mode = uint32(1) 859 default: 860 panic("machine: invalid I2C SDA pin") 861 } 862 if forcePath { 863 mode |= 0x10 // SION bit 864 } 865 return mode 866 867 // I2C SCL 868 case PinModeI2CSCL: 869 var mode uint32 870 switch p { 871 case PA12: // LPI2C4 SCL on PA12 alternate function 0 872 mode = uint32(0) 873 case PA16: // LPI2C1 SCL on PA16 alternate function 3 874 mode = uint32(3) 875 case PA23: // LPI2C3 SCL on PA23 alternate function 1 876 mode = uint32(1) 877 default: 878 panic("machine: invalid I2C SCL pin") 879 } 880 if forcePath { 881 mode |= 0x10 // SION bit 882 } 883 return mode 884 885 default: 886 panic("machine: invalid pin mode") 887 } 888 } 889 890 // maximum ADC value for the currently configured resolution (used for scaling) 891 var adcMaximum uint32 892 893 // InitADC is not used by this machine. Use `(ADC).Configure()`. 894 func InitADC() {} 895 896 // Configure initializes the receiver's ADC peripheral and pin for analog input. 897 func (a ADC) Configure(config ADCConfig) { 898 // if not specified, use defaults: 10-bit resolution, 4 samples/conversion 899 const ( 900 defaultResolution = uint32(10) 901 defaultSamples = uint32(4) 902 ) 903 904 a.Pin.Configure(PinConfig{Mode: PinInputAnalog}) 905 906 resolution, samples := config.Resolution, config.Samples 907 if 0 == resolution { 908 resolution = defaultResolution 909 } 910 if 0 == samples { 911 samples = defaultSamples 912 } 913 if resolution > 12 { 914 resolution = 12 // maximum resolution of 12 bits 915 } 916 adcMaximum = (uint32(1) << resolution) - 1 917 918 mode, average := a.mode(resolution, samples) 919 920 nxp.ADC1.CFG.Set(mode | nxp.ADC_CFG_ADHSC) // configure ADC1 921 nxp.ADC2.CFG.Set(mode | nxp.ADC_CFG_ADHSC) // configure ADC2 922 923 // begin calibration 924 nxp.ADC1.GC.Set(average | nxp.ADC_GC_CAL) 925 nxp.ADC2.GC.Set(average | nxp.ADC_GC_CAL) 926 927 for a.isCalibrating() { 928 } // wait for calibration 929 } 930 931 // Get performs a single ADC conversion, returning a 16-bit unsigned integer. 932 // The value returned will be scaled (uniformly distributed) if necessary so 933 // that it is always in the range [0..65535], regardless of the ADC's configured 934 // bit size (resolution). 935 func (a ADC) Get() uint16 { 936 if ch1, ch2, ok := a.Pin.getADCChannel(); ok { 937 for a.isCalibrating() { 938 } // wait for calibration 939 var val uint32 940 if noADCChannel != ch1 { 941 nxp.ADC1.HC0.Set(uint32(ch1)) 942 for !nxp.ADC1.HS.HasBits(nxp.ADC_HS_COCO0) { 943 } 944 val = nxp.ADC1.R0.Get() & 0xFFFF 945 } else { 946 nxp.ADC2.HC0.Set(uint32(ch2)) 947 for !nxp.ADC2.HS.HasBits(nxp.ADC_HS_COCO0) { 948 } 949 val = nxp.ADC2.R0.Get() & 0xFFFF 950 } 951 // should never be zero, but just in case, use UINT16_MAX so that the scalar 952 // gets factored out of the conversion result, leaving the original reading 953 // to be returned unaltered/unscaled. 954 if adcMaximum == 0 { 955 adcMaximum = 0xFFFF 956 } 957 // scale up to a 16-bit value 958 return uint16((val * 0xFFFF) / adcMaximum) 959 } 960 return 0 961 } 962 963 // mode constructs bit masks for mode and average - used in ADC configuration 964 // registers - from a given ADC bit size (resolution) and sample count. 965 func (a ADC) mode(resolution, samples uint32) (mode, average uint32) { 966 967 // use asynchronous clock (ADACK) (0 = IPG, 1 = IPG/2, or 3 = ADACK) 968 mode = (nxp.ADC_CFG_ADICLK_ADICLK_3 << nxp.ADC_CFG_ADICLK_Pos) & nxp.ADC_CFG_ADICLK_Msk 969 970 // input clock DIV2 (0 = DIV1, 1 = DIV2, 2 = DIV4, or 3 = DIV8) 971 mode |= (nxp.ADC_CFG_ADIV_ADIV_1 << nxp.ADC_CFG_ADIV_Pos) & nxp.ADC_CFG_ADIV_Msk 972 973 switch resolution { 974 case 8: // 8-bit conversion, sample period (ADC clocks) = 8 975 mode |= (nxp.ADC_CFG_MODE_MODE_0 << nxp.ADC_CFG_MODE_Pos) & nxp.ADC_CFG_MODE_Msk 976 mode |= (nxp.ADC_CFG_ADSTS_ADSTS_3 << nxp.ADC_CFG_ADSTS_Pos) & nxp.ADC_CFG_ADSTS_Msk 977 978 case 12: // 12-bit conversion, sample period (ADC clocks) = 24 979 mode |= (nxp.ADC_CFG_MODE_MODE_2 << nxp.ADC_CFG_MODE_Pos) & nxp.ADC_CFG_MODE_Msk 980 mode |= (nxp.ADC_CFG_ADSTS_ADSTS_3 << nxp.ADC_CFG_ADSTS_Pos) & nxp.ADC_CFG_ADSTS_Msk 981 mode |= nxp.ADC_CFG_ADLSMP 982 983 default: // 10-bit conversion, sample period (ADC clocks) = 20 984 mode |= (nxp.ADC_CFG_MODE_MODE_1 << nxp.ADC_CFG_MODE_Pos) & nxp.ADC_CFG_MODE_Msk 985 mode |= (nxp.ADC_CFG_ADSTS_ADSTS_2 << nxp.ADC_CFG_ADSTS_Pos) & nxp.ADC_CFG_ADSTS_Msk 986 mode |= nxp.ADC_CFG_ADLSMP 987 } 988 989 if samples >= 4 { 990 if samples >= 32 { 991 // 32 samples averaged 992 mode |= (nxp.ADC_CFG_AVGS_AVGS_3 << nxp.ADC_CFG_AVGS_Pos) & nxp.ADC_CFG_AVGS_Msk 993 } else if samples >= 16 { 994 // 16 samples averaged 995 mode |= (nxp.ADC_CFG_AVGS_AVGS_2 << nxp.ADC_CFG_AVGS_Pos) & nxp.ADC_CFG_AVGS_Msk 996 } else if samples >= 8 { 997 // 8 samples averaged 998 mode |= (nxp.ADC_CFG_AVGS_AVGS_1 << nxp.ADC_CFG_AVGS_Pos) & nxp.ADC_CFG_AVGS_Msk 999 } else { 1000 // 4 samples averaged 1001 mode |= (nxp.ADC_CFG_AVGS_AVGS_0 << nxp.ADC_CFG_AVGS_Pos) & nxp.ADC_CFG_AVGS_Msk 1002 } 1003 average = nxp.ADC_GC_AVGE 1004 } 1005 1006 return mode, average 1007 } 1008 1009 // isCalibrating returns true if and only if either one (or both) of ADC1 and 1010 // ADC2 have their calibrating flags set. ADC reads must wait until these flags 1011 // are clear before attempting a conversion. 1012 func (a ADC) isCalibrating() bool { 1013 return nxp.ADC1.GC.HasBits(nxp.ADC_GC_CAL) || nxp.ADC2.GC.HasBits(nxp.ADC_GC_CAL) 1014 } 1015 1016 const noADCChannel = uint8(0xFF) 1017 1018 // getADCChannel returns the input channel for ADC1/ADC2 of the receiver Pin p. 1019 func (p Pin) getADCChannel() (adc1, adc2 uint8, ok bool) { 1020 switch p { 1021 case PA12: // [AD_B0_12]: ADC1_IN1 ~ 1022 return 1, noADCChannel, true 1023 case PA13: // [AD_B0_13]: ADC1_IN2 ~ 1024 return 2, noADCChannel, true 1025 case PA14: // [AD_B0_14]: ADC1_IN3 ~ 1026 return 3, noADCChannel, true 1027 case PA15: // [AD_B0_15]: ADC1_IN4 ~ 1028 return 4, noADCChannel, true 1029 case PA16: // [AD_B1_00]: ADC1_IN5 ADC2_IN5 1030 return 5, 5, true 1031 case PA17: // [AD_B1_01]: ADC1_IN6 ADC2_IN6 1032 return 6, 6, true 1033 case PA18: // [AD_B1_02]: ADC1_IN7 ADC2_IN7 1034 return 7, 7, true 1035 case PA19: // [AD_B1_03]: ADC1_IN8 ADC2_IN8 1036 return 8, 8, true 1037 case PA20: // [AD_B1_04]: ADC1_IN9 ADC2_IN9 1038 return 9, 9, true 1039 case PA21: // [AD_B1_05]: ADC1_IN10 ADC2_IN10 1040 return 10, 10, true 1041 case PA22: // [AD_B1_06]: ADC1_IN11 ADC2_IN11 1042 return 11, 11, true 1043 case PA23: // [AD_B1_07]: ADC1_IN12 ADC2_IN12 1044 return 12, 12, true 1045 case PA24: // [AD_B1_08]: ADC1_IN13 ADC2_IN13 1046 return 13, 13, true 1047 case PA25: // [AD_B1_09]: ADC1_IN14 ADC2_IN14 1048 return 14, 14, true 1049 case PA26: // [AD_B1_10]: ADC1_IN15 ADC2_IN15 1050 return 15, 15, true 1051 case PA27: // [AD_B1_11]: ADC1_IN0 ADC2_IN0 1052 return 16, 16, true 1053 case PA28: // [AD_B1_12]: ~ ADC2_IN1 1054 return noADCChannel, 1, true 1055 case PA29: // [AD_B1_13]: ~ ADC2_IN2 1056 return noADCChannel, 2, true 1057 case PA30: // [AD_B1_14]: ~ ADC2_IN3 1058 return noADCChannel, 3, true 1059 case PA31: // [AD_B1_15]: ~ ADC2_IN4 1060 return noADCChannel, 4, true 1061 default: 1062 return noADCChannel, noADCChannel, false 1063 } 1064 }