diff --git a/boards/arm/lpcxpresso55s69/doc/index.rst b/boards/arm/lpcxpresso55s69/doc/index.rst index 3a4936e19c1..3888bfb96f8 100644 --- a/boards/arm/lpcxpresso55s69/doc/index.rst +++ b/boards/arm/lpcxpresso55s69/doc/index.rst @@ -84,6 +84,8 @@ features: +-----------+------------+-------------------------------------+ | COUNTER | on-chip | counter | +-----------+------------+-------------------------------------+ +| I2S | on-chip | i2s | ++-----------+------------+-------------------------------------+ Targets available ================== @@ -143,6 +145,14 @@ functionality of a pin. +---------+-----------------+----------------------------+ | PIO1_24 | USART | USART RX | +---------+-----------------+----------------------------+ +| PIO0_20 | I2S | I2S DATAOUT | ++---------+-----------------+----------------------------+ +| PIO0_19 | I2S | I2S TX WS | ++---------+-----------------+----------------------------+ +| PIO0_21 | I2S | I2S TX SCK | ++---------+-----------------+----------------------------+ +| PIO1_13 | I2S | I2S DATAIN | ++---------+-----------------+----------------------------+ Memory mappings =============== diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts index cda49688a39..c69df0b62ed 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.dts @@ -129,3 +129,25 @@ zephyr_udc0: &usbhs { &ctimer4 { status = "okay"; }; + +/* I2S receive channel */ +i2s0: &flexcomm6 { + status = "okay"; + compatible = "nxp,lpc-i2s"; + label = "I2S_0"; + #address-cells = <1>; + #size-cells = <0>; + dmas = <&dma0 16>; + dma-names = "rx"; +}; + +/* I2S transmit channel */ +i2s1: &flexcomm7 { + status = "okay"; + compatible = "nxp,lpc-i2s"; + label = "I2S_1"; + #address-cells = <1>; + #size-cells = <0>; + dmas = <&dma0 19>; + dma-names = "tx"; +}; diff --git a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml index 4fa2ba8cf6e..520ed04295c 100644 --- a/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml +++ b/boards/arm/lpcxpresso55s69/lpcxpresso55s69_cpu0.yaml @@ -22,6 +22,7 @@ supported: - counter - gpio - i2c + - i2s - spi - usb_device - watchdog diff --git a/boards/arm/lpcxpresso55s69/pinmux.c b/boards/arm/lpcxpresso55s69/pinmux.c index fd471a889de..10edfb7fc37 100644 --- a/boards/arm/lpcxpresso55s69/pinmux.c +++ b/boards/arm/lpcxpresso55s69/pinmux.c @@ -183,6 +183,70 @@ static int lpcxpresso_55s69_pinmux_init(const struct device *dev) IOCON_PIO_OPENDRAIN_DI); #endif +#if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm6), nxp_lpc_i2s, okay)) && \ + (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm7), nxp_lpc_i2s, okay)) && \ + CONFIG_I2S + CLOCK_EnableClock(kCLOCK_Sysctl); + /* Set shared signal set 0 SCK, WS from Transmit I2S - Flexcomm 7 */ + SYSCTL->SHAREDCTRLSET[0] = SYSCTL_SHAREDCTRLSET_SHAREDSCKSEL(7) | + SYSCTL_SHAREDCTRLSET_SHAREDWSSEL(7); + +#ifdef CONFIG_I2S_TEST_SEPARATE_DEVICES + /* Select Data in from Transmit I2S - Flexcomm 7 */ + SYSCTL->SHAREDCTRLSET[0] |= SYSCTL_SHAREDCTRLSET_SHAREDDATASEL(7); + /* Enable Transmit I2S - Flexcomm 7 for Shared Data Out */ + SYSCTL->SHAREDCTRLSET[0] |= SYSCTL_SHAREDCTRLSET_FC7DATAOUTEN(1); +#endif + + /* Set Receive I2S - Flexcomm 6 SCK, WS from shared signal set 0 */ + SYSCTL->FCCTRLSEL[6] = SYSCTL_FCCTRLSEL_SCKINSEL(1) | + SYSCTL_FCCTRLSEL_WSINSEL(1); + + /* Set Transmit I2S - Flexcomm 7 SCK, WS from shared signal set 0 */ + SYSCTL->FCCTRLSEL[7] = SYSCTL_FCCTRLSEL_SCKINSEL(1) | + SYSCTL_FCCTRLSEL_WSINSEL(1); + +#ifdef CONFIG_I2S_TEST_SEPARATE_DEVICES + /* Select Receive I2S - Flexcomm 6 Data in from shared signal set 0 */ + SYSCTL->FCCTRLSEL[6] |= SYSCTL_FCCTRLSEL_DATAINSEL(1); + /* Select Transmit I2S - Flexcomm 7 Data out to shared signal set 0 */ + SYSCTL->FCCTRLSEL[7] |= SYSCTL_FCCTRLSEL_DATAOUTSEL(1); +#endif + + /* Pin is configured as FC7_TXD_SCL_MISO_WS */ + pinmux_pin_set(port0, 19, IOCON_PIO_FUNC7 | + IOCON_PIO_MODE_PULLUP | + IOCON_PIO_SLEW_FAST | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_OPENDRAIN_DI); + + /* Pin is configured as FC7_RXD_SDA_MOSI_DATA */ + pinmux_pin_set(port0, 20, IOCON_PIO_FUNC7 | + IOCON_PIO_MODE_PULLUP | + IOCON_PIO_SLEW_FAST | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_OPENDRAIN_DI); + + /* Pin is configured as FC7_SCK */ + pinmux_pin_set(port0, 21, IOCON_PIO_FUNC7 | + IOCON_PIO_MODE_PULLUP | + IOCON_PIO_SLEW_FAST | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_OPENDRAIN_DI); + + /* Pin is configured as FC6_RXD_SDA_MOSI_DATA */ + pinmux_pin_set(port1, 13, IOCON_PIO_FUNC2 | + IOCON_PIO_MODE_PULLUP | + IOCON_PIO_SLEW_FAST | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_OPENDRAIN_DI); + +#endif + return 0; } diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S69_cpu0 b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S69_cpu0 index 52a922326a6..5d2e7783cec 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S69_cpu0 +++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.defconfig.lpc55S69_cpu0 @@ -49,4 +49,9 @@ config COUNTER_MCUX_CTIMER default y depends on COUNTER +config I2S_MCUX_FLEXCOMM + default y if HAS_MCUX_FLEXCOMM + depends on I2S + select INIT_PLL0 + endif # SOC_LPC55S69_CPU0 diff --git a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc index 61d1ca1d019..c8e4359ddb5 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc +++ b/soc/arm/nxp_lpc/lpc55xxx/Kconfig.soc @@ -77,6 +77,9 @@ config SOC_PART_NUMBER_LPC55XXX option that you should not set directly. The part number selection choice defines the default value for this string. +config INIT_PLL0 + bool "Initialize PLL0" + config SECOND_CORE_MCUX bool "Enable LPC55xxx's second core" depends on HAS_MCUX diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.c b/soc/arm/nxp_lpc/lpc55xxx/soc.c index 4c215461462..b82bc8b429e 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.c +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.c @@ -36,6 +36,18 @@ #define TO_CLOCK_ATTACH_ID(inst, val) MUX_A(CM_CTIMERCLKSEL##inst, val) #define CTIMER_CLOCK_SETUP(node_id) CLOCK_AttachClk(CTIMER_CLOCK_SOURCE(node_id)); +#ifdef CONFIG_INIT_PLL0 +const pll_setup_t pll0Setup = { + .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(2U) | + SYSCON_PLL0CTRL_SELP(31U), + .pllndec = SYSCON_PLL0NDEC_NDIV(125U), + .pllpdec = SYSCON_PLL0PDEC_PDIV(8U), + .pllsscg = {0x0U, (SYSCON_PLL0SSCG1_MDIV_EXT(3072U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, + .pllRate = 24576000U, + .flags = PLL_SETUPFLAG_WAITLOCK} +; +#endif + /** * * @brief Initialize the system clock @@ -60,6 +72,25 @@ static ALWAYS_INLINE void clock_init(void) /* Enable FRO HF(96MHz) output */ CLOCK_SetupFROClocking(96000000U); +#ifdef CONFIG_INIT_PLL0 + /*!< Ensure XTAL16M is on */ + PMC->PDRUNCFGCLR0 |= PMC_PDRUNCFG0_PDEN_XTAL32M_MASK; + PMC->PDRUNCFGCLR0 |= PMC_PDRUNCFG0_PDEN_LDOXO32M_MASK; + + /*!< Ensure CLK_IN is on */ + SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; + ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; + + /*!< Switch PLL0 clock source selector to XTAL16M */ + CLOCK_AttachClk(kEXT_CLK_to_PLL0); + + /*!< Configure PLL to the desired values */ + CLOCK_SetPLL0Freq(&pll0Setup); + + CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 0U, true); + CLOCK_SetClkDiv(kCLOCK_DivPll0Clk, 1U, false); +#endif + #if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE) /*!< Set FLASH wait states for core */ CLOCK_SetFLASHAccessCyclesForFreq(96000000U); @@ -132,6 +163,16 @@ static ALWAYS_INLINE void clock_init(void) DT_FOREACH_STATUS_OKAY(nxp_lpc_ctimer, CTIMER_CLOCK_SETUP) +#if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm6), nxp_lpc_i2s, okay)) + /* attach PLL0 clock to FLEXCOMM6 */ + CLOCK_AttachClk(kPLL0_DIV_to_FLEXCOMM6); +#endif + +#if (DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(flexcomm7), nxp_lpc_i2s, okay)) + /* attach PLL0 clock to FLEXCOMM6 */ + CLOCK_AttachClk(kPLL0_DIV_to_FLEXCOMM7); +#endif + #endif /* CONFIG_SOC_LPC55S69_CPU0 */ } diff --git a/soc/arm/nxp_lpc/lpc55xxx/soc.h b/soc/arm/nxp_lpc/lpc55xxx/soc.h index e2b6c95efeb..c17e8a10637 100644 --- a/soc/arm/nxp_lpc/lpc55xxx/soc.h +++ b/soc/arm/nxp_lpc/lpc55xxx/soc.h @@ -27,7 +27,9 @@ #define IOCON_PIO_DIGITAL_EN 0x0100u /*!<@brief Enables digital function */ #define IOCON_PIO_FUNC0 0x00u /*!<@brief Selects pin function 0 */ #define IOCON_PIO_FUNC1 0x01u /*!<@brief Selects pin function 1 */ +#define IOCON_PIO_FUNC2 0x02u /*!<@brief Selects pin function 1 */ #define IOCON_PIO_FUNC5 0x05u /*!<@brief Selects pin function 5 */ +#define IOCON_PIO_FUNC7 0x07u /*!<@brief Selects pin function 5 */ #define IOCON_PIO_FUNC6 0x06u /*!<@brief Selects pin function 6 */ #define IOCON_PIO_FUNC9 0x09u /*!<@brief Selects pin function 9 */ #define IOCON_PIO_FUNC10 0x0Au /*!<@brief Selects pin function 10 */ @@ -35,6 +37,7 @@ #define IOCON_PIO_MODE_INACT 0x00u /*!<@brief No addition pin function */ #define IOCON_PIO_OPENDRAIN_DI 0x00u /*!<@brief Open drain is disabled */ #define IOCON_PIO_SLEW_STANDARD 0x00u /*!<@brief Standard slew rate mode */ +#define IOCON_PIO_SLEW_FAST 0x40u /*!<@brief Fast slew rate mode */ #define IOCON_PIO_MODE_PULLDOWN 0x10u /*!<@brief Selects pull-down function */ #define IOCON_PIO_MODE_PULLUP 0x20u /*!<@brief Selects pull-up function */ #define IOCON_PIO_INPFILT_OFF 0x1000u /*!<@brief Input filter disabled */