diff --git a/.style_ignored_dirs b/.style_ignored_dirs index db04681179..ca3a119eb1 100644 --- a/.style_ignored_dirs +++ b/.style_ignored_dirs @@ -57,6 +57,8 @@ hw/mcu/stm/stm32_common/src/stm32_driver_mod_i2c_v2.c hw/mcu/stm/stm32_common/src/stm32_driver_mod_timer.c hw/mcu/stm/stm32_common/src/stm32_driver_mod_spi.c +hw/mcu/nxp/lpc55xx/src/clock_config.c + # Nordic preserved code style hw/mcu/nordic/nrf52xxx/src/system_nrf52.c hw/mcu/nordic/nrf51xxx/src/system_nrf51.c diff --git a/hw/mcu/nxp/lpc55xx/include/clock_config.h b/hw/mcu/nxp/lpc55xx/include/clock_config.h new file mode 100644 index 0000000000..1e37f41b56 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/include/clock_config.h @@ -0,0 +1,167 @@ +/* + * Copyright 2017-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 16000000U /*!< Board xtal frequency in Hz */ +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFRO12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ + +/******************************************************************************* + * API for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFRO12M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF96M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockFROHF96M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ + +/******************************************************************************* + * API for BOARD_BootClockFROHF96M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockFROHF96M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ + +/******************************************************************************* + * API for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL100M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ + +/******************************************************************************* + * API for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL150M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************* Configuration BOARD_BootClockPLL1_150M ******************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL1_150M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL1_150M_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL1_150M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL1_150M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/mcu/nxp/lpc55xx/include/mcu/cmsis_nvic.h b/hw/mcu/nxp/lpc55xx/include/mcu/cmsis_nvic.h new file mode 100644 index 0000000000..4b6b981246 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/include/mcu/cmsis_nvic.h @@ -0,0 +1,29 @@ +/* mbed Microcontroller Library - cmsis_nvic + * Copyright (c) 2009-2011 ARM Limited. All rights reserved. + * + * CMSIS-style functionality to support dynamic vectors + */ + +#ifndef MBED_CMSIS_NVIC_H +#define MBED_CMSIS_NVIC_H + +#include + +#define NVIC_NUM_VECTORS (16 + 59) // CORE + MCU Peripherals +#define NVIC_USER_IRQ_OFFSET 16 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void NVIC_Relocate(void); +void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector); +uint32_t NVIC_GetVector(IRQn_Type IRQn); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/mcu/nxp/lpc55xx/include/mcu/cortex_m33.h b/hw/mcu/nxp/lpc55xx/include/mcu/cortex_m33.h new file mode 100644 index 0000000000..2760461ba3 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/include/mcu/cortex_m33.h @@ -0,0 +1,40 @@ +/* + * 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 __MCU_CORTEX_M33_H__ +#define __MCU_CORTEX_M33_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static inline void +hal_debug_break(void) +{ + __BKPT(1); +} + +#ifdef __cplusplus +} +#endif + +#endif /* __MCU_CORTEX_M33_H__ */ diff --git a/hw/mcu/nxp/lpc55xx/include/mcu/mcu.h b/hw/mcu/nxp/lpc55xx/include/mcu/mcu.h new file mode 100644 index 0000000000..23632150c3 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/include/mcu/mcu.h @@ -0,0 +1,41 @@ +/* + * 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 __MCU_MCU_H_ +#define __MCU_MCU_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SVC_IRQ_NUMBER SVC_IRQn + +/* + * Defines for naming GPIOs. + */ +#define MCU_GPIO_PORT0(pin) ((0 * 32) + (pin)) +#define MCU_GPIO_PORT1(pin) ((1 * 32) + (pin)) + +#ifdef __cplusplus +} +#endif + +#endif /* __MCU_MCU_H_ */ diff --git a/hw/mcu/nxp/lpc55xx/include/mcu/mcu_vectors.h b/hw/mcu/nxp/lpc55xx/include/mcu/mcu_vectors.h new file mode 100644 index 0000000000..9a9f2e5638 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/include/mcu/mcu_vectors.h @@ -0,0 +1,24 @@ +/* + * 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. + */ + +#if (defined(CPU_LPC55S28JBD100) || defined(CPU_LPC55S28JBD64) || defined(CPU_LPC55S28JEV98)) +#include "vectors/lpc55s28_vectors.h" +#else +#error "Please select first the target LPC55 device used in your application" +#endif diff --git a/hw/mcu/nxp/lpc55xx/include/mcu/mcux_hal.h b/hw/mcu/nxp/lpc55xx/include/mcu/mcux_hal.h new file mode 100644 index 0000000000..0a377aa2de --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/include/mcu/mcux_hal.h @@ -0,0 +1,64 @@ +/* + * 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 __MCUX_HAL_H_ +#define __MCUX_HAL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Helper functions to enable/disable interrupts. */ +#define __HAL_DISABLE_INTERRUPTS(x) \ + do { \ + x = __get_PRIMASK(); \ + __disable_irq(); \ + } while(0); + +#define __HAL_ENABLE_INTERRUPTS(x) \ + do { \ + if (!x) { \ + __enable_irq(); \ + } \ + } while(0); + +struct nxp_hal_i2c_cfg { + int8_t pin_scl; + int8_t pin_sda; + uint32_t frequency; +}; + +struct nxp_hal_spi_cfg { + uint32_t clk_pin; + uint32_t pcs_pin; + uint32_t sout_pin; + uint32_t sin_pin; +}; + +struct hal_flash; +extern const struct hal_flash mcux_flash_dev; +extern const struct hal_flash mcux_qspi_dev; + +#ifdef __cplusplus +} +#endif + +#endif /* __MCUX_HAL_H_ */ diff --git a/hw/mcu/nxp/lpc55xx/include/mcu/vectors/lpc55s28_vectors.h b/hw/mcu/nxp/lpc55xx/include/mcu/vectors/lpc55s28_vectors.h new file mode 100644 index 0000000000..29ef52bfb1 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/include/mcu/vectors/lpc55s28_vectors.h @@ -0,0 +1,95 @@ +/* + * 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. + */ + +INT_VECTOR_STACK_TOP(__StackTop) +INT_VECTOR_RESET_HANDLER(Reset_Handler) +INT_VECTOR_NMI_HANDLER(NMI_Handler) +INT_VECTOR_HARDFAULT_HANDLER(HardFault_Handler) +INT_VECTOR_MEMMANAGE_HANDLER(MemManage_Handler) +INT_VECTOR_BUSFAULT_HANDLER(BusFault_Handler) +INT_VECTOR_USAGEFAULT_HANDLER(UsageFault_Handler) +INT_VECTOR_UNUSED(0) +INT_VECTOR_UNUSED(0) +INT_VECTOR_UNUSED(0) +INT_VECTOR_UNUSED(0) +INT_VECTOR_SVC_HANDLER(SVC_Handler) +INT_VECTOR_DEBUGMON_HANDLER(DebugMon_Handler) +INT_VECTOR_UNUSED(0) +INT_VECTOR_PENDSV_HANDLER(PendSV_Handler) +INT_VECTOR_SYSTICK_HANDLER(SysTick_Handler) +INT_VECTOR(WDT_BOD_IRQHandler) +INT_VECTOR(DMA0_IRQHandler) +INT_VECTOR(GINT0_IRQHandler) +INT_VECTOR(GINT1_IRQHandler) +INT_VECTOR(PIN_INT0_IRQHandler) +INT_VECTOR(PIN_INT1_IRQHandler) +INT_VECTOR(PIN_INT2_IRQHandler) +INT_VECTOR(PIN_INT3_IRQHandler) +INT_VECTOR(UTICK0_IRQHandler) +INT_VECTOR(MRT0_IRQHandler) +INT_VECTOR(CTIMER0_IRQHandler) +INT_VECTOR(CTIMER1_IRQHandler) +INT_VECTOR(SCT0_IRQHandler) +INT_VECTOR(CTIMER3_IRQHandler) +INT_VECTOR(FLEXCOMM0_IRQHandler) +INT_VECTOR(FLEXCOMM1_IRQHandler) +INT_VECTOR(FLEXCOMM2_IRQHandler) +INT_VECTOR(FLEXCOMM3_IRQHandler) +INT_VECTOR(FLEXCOMM4_IRQHandler) +INT_VECTOR(FLEXCOMM5_IRQHandler) +INT_VECTOR(FLEXCOMM6_IRQHandler) +INT_VECTOR(FLEXCOMM7_IRQHandler) +INT_VECTOR(ADC0_IRQHandler) +INT_VECTOR(Reserved39_IRQHandler) +INT_VECTOR(ACMP_IRQHandler) +INT_VECTOR(Reserved41_IRQHandler) +INT_VECTOR(Reserved42_IRQHandler) +INT_VECTOR(USB0_NEEDCLK_IRQHandler) +INT_VECTOR(USB0_IRQHandler) +INT_VECTOR(RTC_IRQHandler) +INT_VECTOR(Reserved46_IRQHandler) +INT_VECTOR(Reserved47_IRQHandler) +INT_VECTOR(PIN_INT4_IRQHandler) +INT_VECTOR(PIN_INT5_IRQHandler) +INT_VECTOR(PIN_INT6_IRQHandler) +INT_VECTOR(PIN_INT7_IRQHandler) +INT_VECTOR(CTIMER2_IRQHandler) +INT_VECTOR(CTIMER4_IRQHandler) +INT_VECTOR(OS_EVENT_IRQHandler) +INT_VECTOR(Reserved55_IRQHandler) +INT_VECTOR(Reserved56_IRQHandler) +INT_VECTOR(Reserved57_IRQHandler) +INT_VECTOR(SDIO_IRQHandler) +INT_VECTOR(Reserved59_IRQHandler) +INT_VECTOR(Reserved60_IRQHandler) +INT_VECTOR(Reserved61_IRQHandler) +INT_VECTOR(USB1_PHY_IRQHandler) +INT_VECTOR(USB1_IRQHandler) +INT_VECTOR(USB1_NEEDCLK_IRQHandler) +INT_VECTOR(SEC_HYPERVISOR_CALL_IRQHandler) +INT_VECTOR(SEC_GPIO_INT0_IRQ0_IRQHandler) +INT_VECTOR(SEC_GPIO_INT0_IRQ1_IRQHandler) +INT_VECTOR(PLU_IRQHandler) +INT_VECTOR(SEC_VIO_IRQHandler) +INT_VECTOR(HASHCRYPT_IRQHandler) +INT_VECTOR(CASER_IRQHandler) +INT_VECTOR(PUF_IRQHandler) +INT_VECTOR(PQ_IRQHandler) +INT_VECTOR(DMA1_IRQHandler) +INT_VECTOR(FLEXCOMM8_IRQHandler) diff --git a/hw/mcu/nxp/lpc55xx/pkg.yml b/hw/mcu/nxp/lpc55xx/pkg.yml new file mode 100644 index 0000000000..aaca3e4d5b --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/pkg.yml @@ -0,0 +1,62 @@ +# +# 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. +# + +pkg.name: hw/mcu/nxp/lpc55xx +pkg.description: LPC55xx common MCU definitions and files +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + +pkg.type: sdk + +pkg.include_dirs: + - "@nxp-mcux-sdk/CMSIS/Include" + - "@nxp-mcux-sdk/drivers/common" + +pkg.include_dirs.MCU_LPC55S69: + - "@nxp-mcux-sdk/utilities/debug_console_lite" +pkg.source_files.MCU_LPC55S69: + - "@nxp-mcux-sdk/devices/LPC55S69/system_LPC55S69_cm33_core0.c" + +pkg.src_dirs: + - "src" + +pkg.deps: + - "@apache-mynewt-core/hw/hal" + - "@apache-mynewt-core/hw/cmsis-core" + - "@apache-mynewt-core/hw/mcu/nxp/mcux-sdk" + +pkg.deps.UART_0: + - "@apache-mynewt-core/hw/drivers/uart/uart_hal" + +pkg.deps.UART_1: + - "@apache-mynewt-core/hw/drivers/uart/uart_hal" + +pkg.deps.UART_2: + - "@apache-mynewt-core/hw/drivers/uart/uart_hal" + +pkg.deps.UART_3: + - "@apache-mynewt-core/hw/drivers/uart/uart_hal" + +pkg.deps.UART_4: + - "@apache-mynewt-core/hw/drivers/uart/uart_hal" + +pkg.deps.UART_5: + - "@apache-mynewt-core/hw/drivers/uart/uart_hal" + diff --git a/hw/mcu/nxp/lpc55xx/src/clock_config.c b/hw/mcu/nxp/lpc55xx/src/clock_config.c new file mode 100644 index 0000000000..1d45e5319b --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/clock_config.c @@ -0,0 +1,374 @@ +/* + * Copyright 2017-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/*********************************************************************************************************************** + * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file + * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. + **********************************************************************************************************************/ +/* + * How to set up clock using clock driver functions: + * + * 1. Setup clock sources. + * + * 2. Set up wait states of the flash. + * + * 3. Set up all dividers. + * + * 4. Set up all selectors to provide selected clocks. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v7.0 +processor: LPC55S69 +mcu_data: ksdk2_0 +processor_version: 0.7.2 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_power.h" +#include "fsl_clock.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockPLL150M(); +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockFRO12M ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFRO12M +outputs: +- {id: System_clock.outFreq, value: 12 MHz} +settings: +- {id: ANALOG_CONTROL_FRO192M_CTRL_ENDI_FRO_96M_CFG, value: Enable} +sources: +- {id: ANACTRL.fro_hf.outFreq, value: 96 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFRO12M configuration + ******************************************************************************/ +void BOARD_BootClockFRO12M(void) +{ +#ifndef SDK_SECONDARY_CORE + /*!< Set up the clock sources */ + /*!< Configure FRO192M */ + POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ + + CLOCK_SetupFROClocking(96000000U); /* Enable FRO HF(96MHz) output */ + + POWER_SetVoltageForFreq( + 12000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(12000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO12M */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKFRO12M_CORE_CLOCK; +#endif +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockFROHF96M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockFROHF96M +outputs: +- {id: System_clock.outFreq, value: 96 MHz} +settings: +- {id: ANALOG_CONTROL_FRO192M_CTRL_ENDI_FRO_96M_CFG, value: Enable} +- {id: SYSCON.MAINCLKSELA.sel, value: ANACTRL.fro_hf_clk} +sources: +- {id: ANACTRL.fro_hf.outFreq, value: 96 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockFROHF96M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockFROHF96M configuration + ******************************************************************************/ +void BOARD_BootClockFROHF96M(void) +{ +#ifndef SDK_SECONDARY_CORE + /*!< Set up the clock sources */ + /*!< Configure FRO192M */ + POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ + + CLOCK_SetupFROClocking(96000000U); /* Enable FRO HF(96MHz) output */ + + POWER_SetVoltageForFreq( + 96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /*!< Switch MAIN_CLK to FRO_HF */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKFROHF96M_CORE_CLOCK; +#endif +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL100M +outputs: +- {id: System_clock.outFreq, value: 100 MHz} +settings: +- {id: PLL0_Mode, value: Normal} +- {id: ANALOG_CONTROL_FRO192M_CTRL_ENDI_FRO_96M_CFG, value: Enable} +- {id: ENABLE_CLKIN_ENA, value: Enabled} +- {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} +- {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL0_BYPASS} +- {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} +- {id: SYSCON.PLL0M_MULT.scale, value: '100', locked: true} +- {id: SYSCON.PLL0N_DIV.scale, value: '4', locked: true} +- {id: SYSCON.PLL0_PDEC.scale, value: '4', locked: true} +sources: +- {id: ANACTRL.fro_hf.outFreq, value: 96 MHz} +- {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +void BOARD_BootClockPLL100M(void) +{ +#ifndef SDK_SECONDARY_CORE + /*!< Set up the clock sources */ + /*!< Configure FRO192M */ + POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ + + CLOCK_SetupFROClocking(96000000U); /* Enable FRO HF(96MHz) output */ + + /*!< Configure XTAL32M */ + POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ + POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ + CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ + SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ + ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ + + POWER_SetVoltageForFreq( + 100000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(100000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up PLL */ + CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ + POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ + POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); + const pll_setup_t pll0Setup = { + .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(26U), + .pllndec = SYSCON_PLL0NDEC_NDIV(4U), + .pllpdec = SYSCON_PLL0PDEC_PDIV(2U), + .pllsscg = {0x0U, (SYSCON_PLL0SSCG1_MDIV_EXT(100U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, + .pllRate = 100000000U, + .flags = PLL_SETUPFLAG_WAITLOCK}; + CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; +#endif +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL150M ********************* + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL150M +called_from_default_init: true +outputs: +- {id: System_clock.outFreq, value: 150 MHz} +settings: +- {id: PLL0_Mode, value: Normal} +- {id: ENABLE_CLKIN_ENA, value: Enabled} +- {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} +- {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL0_BYPASS} +- {id: SYSCON.PLL0CLKSEL.sel, value: SYSCON.CLK_IN_EN} +- {id: SYSCON.PLL0M_MULT.scale, value: '150', locked: true} +- {id: SYSCON.PLL0N_DIV.scale, value: '8', locked: true} +- {id: SYSCON.PLL0_PDEC.scale, value: '2', locked: true} +sources: +- {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL150M configuration + ******************************************************************************/ +void BOARD_BootClockPLL150M(void) +{ +#ifndef SDK_SECONDARY_CORE + /*!< Set up the clock sources */ + /*!< Configure FRO192M */ + POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ + + /*!< Configure XTAL32M */ + POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ + POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ + CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ + SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ + ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ + + POWER_SetVoltageForFreq( + 150000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(150000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up PLL */ + CLOCK_AttachClk(kEXT_CLK_to_PLL0); /*!< Switch PLL0CLKSEL to EXT_CLK */ + POWER_DisablePD(kPDRUNCFG_PD_PLL0); /* Ensure PLL is on */ + POWER_DisablePD(kPDRUNCFG_PD_PLL0_SSCG); + const pll_setup_t pll0Setup = { + .pllctrl = SYSCON_PLL0CTRL_CLKEN_MASK | SYSCON_PLL0CTRL_SELI(53U) | SYSCON_PLL0CTRL_SELP(31U), + .pllndec = SYSCON_PLL0NDEC_NDIV(8U), + .pllpdec = SYSCON_PLL0PDEC_PDIV(1U), + .pllsscg = {0x0U, (SYSCON_PLL0SSCG1_MDIV_EXT(150U) | SYSCON_PLL0SSCG1_SEL_EXT_MASK)}, + .pllRate = 150000000U, + .flags = PLL_SETUPFLAG_WAITLOCK}; + CLOCK_SetPLL0Freq(&pll0Setup); /*!< Configure PLL0 to the desired values */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL0_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL0 */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKPLL150M_CORE_CLOCK; +#endif +} + +/******************************************************************************* + ******************* Configuration BOARD_BootClockPLL1_150M ******************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL1_150M +outputs: +- {id: System_clock.outFreq, value: 150 MHz} +settings: +- {id: PLL1_Mode, value: Normal} +- {id: ENABLE_CLKIN_ENA, value: Enabled} +- {id: ENABLE_SYSTEM_CLK_OUT, value: Enabled} +- {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL1_BYPASS} +- {id: SYSCON.PLL1CLKSEL.sel, value: SYSCON.CLK_IN_EN} +- {id: SYSCON.PLL1M_MULT.scale, value: '150', locked: true} +- {id: SYSCON.PLL1N_DIV.scale, value: '8', locked: true} +- {id: SYSCON.PLL1_PDEC.scale, value: '2', locked: true} +sources: +- {id: SYSCON.XTAL32M.outFreq, value: 16 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL1_150M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL1_150M configuration + ******************************************************************************/ +void BOARD_BootClockPLL1_150M(void) +{ +#ifndef SDK_SECONDARY_CORE + /*!< Set up the clock sources */ + /*!< Configure FRO192M */ + POWER_DisablePD(kPDRUNCFG_PD_FRO192M); /*!< Ensure FRO is on */ + CLOCK_SetupFROClocking(12000000U); /*!< Set up FRO to the 12 MHz, just for sure */ + CLOCK_AttachClk(kFRO12M_to_MAIN_CLK); /*!< Switch to FRO 12MHz first to ensure we can change the clock setting */ + + /*!< Configure XTAL32M */ + POWER_DisablePD(kPDRUNCFG_PD_XTAL32M); /* Ensure XTAL32M is powered */ + POWER_DisablePD(kPDRUNCFG_PD_LDOXO32M); /* Ensure XTAL32M is powered */ + CLOCK_SetupExtClocking(16000000U); /* Enable clk_in clock */ + SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_CLKIN_ENA_MASK; /* Enable clk_in from XTAL32M clock */ + ANACTRL->XO32M_CTRL |= ANACTRL_XO32M_CTRL_ENABLE_SYSTEM_CLK_OUT_MASK; /* Enable clk_in to system */ + + POWER_SetVoltageForFreq(150000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(150000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up PLL1 */ + CLOCK_AttachClk(kEXT_CLK_to_PLL1); /*!< Switch PLL1CLKSEL to EXT_CLK */ + POWER_DisablePD(kPDRUNCFG_PD_PLL1); /* Ensure PLL is on */ + const pll_setup_t pll1Setup = { + .pllctrl = SYSCON_PLL1CTRL_CLKEN_MASK | SYSCON_PLL1CTRL_SELI(53U) | SYSCON_PLL1CTRL_SELP(31U), + .pllndec = SYSCON_PLL1NDEC_NDIV(8U), + .pllpdec = SYSCON_PLL1PDEC_PDIV(1U), + .pllmdec = SYSCON_PLL1MDEC_MDIV(150U), + .pllRate = 150000000U, + .flags = PLL_SETUPFLAG_WAITLOCK + }; + CLOCK_SetPLL1Freq(&pll1Setup); /*!< Configure PLL1 to the desired values */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kPLL1_to_MAIN_CLK); /*!< Switch MAIN_CLK to PLL1 */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKPLL1_150M_CORE_CLOCK; +#endif +} + diff --git a/hw/mcu/nxp/lpc55xx/src/hal_flash.c b/hw/mcu/nxp/lpc55xx/src/hal_flash.c new file mode 100644 index 0000000000..a330d56eb2 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_flash.c @@ -0,0 +1,178 @@ +/* + * 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. + */ + +/* + * Internal flash for the Kinetis family. + * Size of the flash depends on the MCU model, flash is memory mapped + * and is divided to 4k sectors throughout. + */ + +#include +#include +#include +#include + +#include + +/* + * Alignment restriction on writes. + */ +#define MCUX_FLASH_ALIGN MYNEWT_VAL(MCU_FLASH_MIN_WRITE_SIZE) + +static int mcux_flash_read(const struct hal_flash *dev, uint32_t address, + void *dst, uint32_t num_bytes); +static int mcux_flash_write(const struct hal_flash *dev, uint32_t address, + const void *src, uint32_t num_bytes); +static int mcux_flash_erase_sector(const struct hal_flash *dev, + uint32_t sector_address); +static int mcux_flash_sector_info(const struct hal_flash *dev, int idx, + uint32_t *addr, uint32_t *sz); +static int mcux_flash_init(const struct hal_flash *dev); + +static const struct hal_flash_funcs mcux_flash_funcs = { + .hff_read = mcux_flash_read, + .hff_write = mcux_flash_write, + .hff_erase_sector = mcux_flash_erase_sector, + .hff_sector_info = mcux_flash_sector_info, + .hff_init = mcux_flash_init +}; + +static flash_config_t mcux_config = {0}; + +struct hal_flash mcux_flash_dev = { + /* Most items are set after FLASH_Init() */ + .hf_itf = &mcux_flash_funcs, + .hf_align = MCUX_FLASH_ALIGN, + .hf_erased_val = 0xff, +}; + +static int +mcux_flash_read(const struct hal_flash *dev, + uint32_t address, + void *dst, + uint32_t num_bytes) +{ + status_t status = FLASH_VerifyErase(&mcux_config, address, num_bytes); + /* If flash is erased memcpy will result in hard fault, just fill 0xFF */ + if (status == kStatus_FLASH_Success) { + memset(dst, 0xFF, num_bytes); + } else { + memcpy(dst, (void *)address, num_bytes); + } + return 0; +} + +static int +mcux_flash_write(const struct hal_flash *dev, + uint32_t address, + const void *src, + uint32_t len) +{ + uint8_t padded[MCUX_FLASH_ALIGN]; + uint8_t pad_len; + + if (address % MCUX_FLASH_ALIGN) { + /* + * Unaligned write. + */ + return -1; + } + + pad_len = len & (MCUX_FLASH_ALIGN - 1); + if (pad_len) { + /* + * FLASH_Program also needs length to be aligned to 8 bytes. + * Pad these writes. + */ + len -= pad_len; + memcpy(padded, (uint8_t *)src + len, pad_len); + memset(padded + pad_len, 0xff, sizeof(padded) - pad_len); + } + if (len) { + if (FLASH_Program(&mcux_config, address, (void *)src, len) != + kStatus_Success) { + return -1; + } + } + if (pad_len) { + if (FLASH_Program(&mcux_config, address + len, (void *)padded, + MCUX_FLASH_ALIGN) != kStatus_Success) { + return -1; + } + } + return 0; +} + +static int +mcux_flash_erase_sector(const struct hal_flash *dev, uint32_t sector_address) +{ + int sr; + int rc; + uint32_t sector_size; + FLASH_GetProperty(&mcux_config, + kFLASH_PropertyPflashSectorSize, + §or_size); + + OS_ENTER_CRITICAL(sr); + rc = FLASH_Erase(&mcux_config, sector_address, + sector_size, + kFLASH_ApiEraseKey); + OS_EXIT_CRITICAL(sr); + if (rc == kStatus_Success) { + return 0; + } + return -1; +} + +static int +mcux_flash_sector_info(const struct hal_flash *dev, + int idx, + uint32_t *addr, + uint32_t *sz) +{ + uint32_t sector_size; + FLASH_GetProperty(&mcux_config, + kFLASH_PropertyPflashSectorSize, + §or_size); + *addr = mcux_flash_dev.hf_base_addr + (idx * sector_size); + FLASH_GetProperty(&mcux_config, + kFLASH_PropertyPflashSectorSize, + sz); + return 0; +} + +static int +mcux_flash_init(const struct hal_flash *dev) +{ + uint32_t sector_size; + if (FLASH_Init(&mcux_config) != kStatus_FLASH_Success) { + return -1; + } + FLASH_GetProperty(&mcux_config, + kFLASH_PropertyPflashBlockBaseAddr, + &mcux_flash_dev.hf_base_addr); + FLASH_GetProperty(&mcux_config, + kFLASH_PropertyPflashTotalSize, + &mcux_flash_dev.hf_size); + FLASH_GetProperty(&mcux_config, + kFLASH_PropertyPflashSectorSize, + §or_size); + mcux_flash_dev.hf_sector_cnt = (mcux_flash_dev.hf_size / sector_size); + return 0; +} diff --git a/hw/mcu/nxp/lpc55xx/src/hal_gpio.c b/hw/mcu/nxp/lpc55xx/src/hal_gpio.c new file mode 100644 index 0000000000..f1301c9dca --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_gpio.c @@ -0,0 +1,255 @@ +/* + * 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. + */ +#include "hal/hal_gpio.h" +#include "mcu/cmsis_nvic.h" +#include +#include + +#include "fsl_common.h" +#include "fsl_clock.h" +#include "fsl_gpio.h" +#include "fsl_iocon.h" +#include "fsl_pint.h" + +void PIN_INT0_IRQHandler(void); +void PIN_INT1_IRQHandler(void); +void PIN_INT2_IRQHandler(void); +void PIN_INT3_IRQHandler(void); +void PIN_INT4_IRQHandler(void); +void PIN_INT5_IRQHandler(void); +void PIN_INT6_IRQHandler(void); +void PIN_INT7_IRQHandler(void); + +static void (*pin_int_handlers[])(void) = { + PIN_INT0_IRQHandler, + PIN_INT1_IRQHandler, + PIN_INT2_IRQHandler, + PIN_INT3_IRQHandler, + PIN_INT4_IRQHandler, + PIN_INT5_IRQHandler, + PIN_INT6_IRQHandler, + PIN_INT7_IRQHandler, +}; + +struct hal_gpio_irq { + hal_gpio_irq_handler_t func; + void *arg; + int pin; + pint_pin_enable_t trigger; +}; + +/* Each GPIO port has pins from 0 to 31 */ +#define GPIO_INDEX(pin) ((pin) & 0x1F) +#define GPIO_PORT(pin) (((pin) >> 5) & 0x07) +#define GPIO_MASK(pin) (1 << GPIO_INDEX(pin)) +#define GPIO_PIN(port, pin) ((((port) & 0x07) << 5) | ((pin) & 0x1F)) +#define HAL_GPIO_MAX_IRQ FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS + +static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS; +static clock_ip_name_t const gpio_clocks[] = { kCLOCK_Gpio0, kCLOCK_Gpio1 }; +static IRQn_Type const pint_irqs[] = PINT_IRQS; +static struct hal_gpio_irq hal_gpio_irqs[HAL_GPIO_MAX_IRQ] = {0}; + +int +hal_gpio_init_in(int pin, hal_gpio_pull_t pull) +{ + gpio_pin_config_t gconfig = { + .pinDirection = kGPIO_DigitalInput, + }; + uint32_t modefunc = IOCON_FUNC0; + + if (pull == HAL_GPIO_PULL_DOWN) { + modefunc = IOCON_FUNC0 | IOCON_MODE_PULLDOWN; + } else if (pull == HAL_GPIO_PULL_UP) { + modefunc = IOCON_FUNC0 | IOCON_MODE_PULLUP; + } else { + modefunc = IOCON_FUNC0; + } + + CLOCK_EnableClock(gpio_clocks[GPIO_PORT(pin)]); + GPIO_PinInit(GPIO, GPIO_PORT(pin), GPIO_INDEX(pin), &gconfig); + IOCON_PinMuxSet(IOCON, GPIO_PORT(pin), GPIO_INDEX(pin), modefunc); + + return 0; +} + +int +hal_gpio_init_out(int pin, int val) +{ + gpio_pin_config_t gconfig = { + .pinDirection = kGPIO_DigitalOutput, + .outputLogic = (uint8_t)val, + }; + + CLOCK_EnableClock(gpio_clocks[GPIO_PORT(pin)]); + GPIO_PinInit(GPIO, GPIO_PORT(pin), GPIO_INDEX(pin), &gconfig); + IOCON_PinMuxSet(IOCON, GPIO_PORT(pin), GPIO_INDEX(pin), IOCON_FUNC0); + + return 0; +} + +void +hal_gpio_write(int pin, int val) +{ + GPIO_PinWrite(s_gpioBases[0], GPIO_PORT(pin), GPIO_INDEX(pin), val); +} + +int +hal_gpio_read(int pin) +{ + return (int)GPIO_PinRead(s_gpioBases[0], GPIO_PORT(pin), GPIO_INDEX(pin)); +} + +int +hal_gpio_toggle(int pin) +{ + GPIO_PortToggle(s_gpioBases[0], GPIO_PORT(pin), 1 << GPIO_INDEX(pin)); + + return 0; +} + +/* + * Find out whether we have a GPIO event slot available. + */ +static int +hal_gpio_find_empty_slot(void) +{ + int i; + for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { + if (hal_gpio_irqs[i].func == NULL) { + return i; + } + } + return -1; +} + +/* + * Find a GPIO pin on the irq list. + */ +static int +find_irq_by_pin(int pin) +{ + int i; + for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { + if (hal_gpio_irqs[i].func != NULL && hal_gpio_irqs[i].pin == pin) { + return i; + } + } + return -1; +} + +static void +pint_callback(pint_pin_int_t pintr, uint32_t pmatch_status) +{ + hal_gpio_irqs[pintr].func(hal_gpio_irqs[pintr].arg); +} + +/** + * Initialize a given pin to trigger a GPIO IRQ callback. + * + * @param pin The pin to trigger GPIO interrupt on + * @param handler The handler function to call + * @param arg The argument to provide to the IRQ handler + * @param trig The trigger mode (e.g. rising, falling) + * @param pull The mode of the pin (e.g. pullup, pulldown) + * + * @return 0 on success, non-zero error code on failure. + */ +int +hal_gpio_irq_init(int pin, + hal_gpio_irq_handler_t handler, + void *arg, + hal_gpio_irq_trig_t trig, + hal_gpio_pull_t pull) +{ + int i = hal_gpio_find_empty_slot(); + if (i < 0) { + return -1; + } + hal_gpio_irqs[i].pin = pin; + hal_gpio_irqs[i].func = handler; + hal_gpio_irqs[i].arg = arg; + + switch (trig) { + case HAL_GPIO_TRIG_RISING: + hal_gpio_irqs[i].trigger = kPINT_PinIntEnableRiseEdge; + break; + case HAL_GPIO_TRIG_FALLING: + hal_gpio_irqs[i].trigger = kPINT_PinIntEnableFallEdge; + break; + case HAL_GPIO_TRIG_BOTH: + hal_gpio_irqs[i].trigger = kPINT_PinIntEnableBothEdges; + break; + case HAL_GPIO_TRIG_LOW: + hal_gpio_irqs[i].trigger = kPINT_PinIntEnableLowLevel; + break; + case HAL_GPIO_TRIG_HIGH: + hal_gpio_irqs[i].trigger = kPINT_PinIntEnableHighLevel; + break; + default: + return -1; + } + NVIC_SetVector(pint_irqs[i], (uint32_t)pin_int_handlers[i]); + PINT_PinInterruptConfig(PINT, (pint_pin_int_t)i, kPINT_PinIntEnableNone, pint_callback); + return hal_gpio_init_in(pin, pull); +} + + +/** + * Release a pin from being configured to trigger IRQ on state change. + * + * @param pin The pin to release + */ +void +hal_gpio_irq_release(int pin) +{ + int i = find_irq_by_pin(pin); + if (i >= 0) { + PINT_DisableCallbackByIndex(PINT, (pint_pin_int_t)i); + hal_gpio_irqs[i].func = NULL; + } +} + +/** + * Enable IRQs on the passed pin + * + * @param pin The pin to enable IRQs on + */ +void +hal_gpio_irq_enable(int pin) +{ + int i = find_irq_by_pin(pin); + if (i >= 0) { + PINT_EnableCallbackByIndex(PINT, (pint_pin_int_t)i); + } +} + +/** + * Disable IRQs on the passed pin + * + * @param pin The pin to disable IRQs on + */ +void +hal_gpio_irq_disable(int pin) +{ + int i = find_irq_by_pin(pin); + if (i >= 0) { + PINT_DisableCallbackByIndex(PINT, (pint_pin_int_t)i); + } +} diff --git a/hw/mcu/nxp/lpc55xx/src/hal_os_tick.c b/hw/mcu/nxp/lpc55xx/src/hal_os_tick.c new file mode 100644 index 0000000000..1f48d5609a --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_os_tick.c @@ -0,0 +1,64 @@ +/* + * 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. + */ + +#include +#include +#include "os/mynewt.h" +#include + +#include "mcu/cmsis_nvic.h" +#include "fsl_clock.h" + +void +os_tick_idle(os_time_t ticks) +{ + OS_ASSERT_CRITICAL(); + + __DSB(); + __WFI(); +} + +void +os_tick_init(uint32_t os_ticks_per_sec, int prio) +{ + uint32_t sr; + + /* Disable interrupts */ + OS_ENTER_CRITICAL(sr); + + /* Disable SysTick timer */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + /* Initialize Reload value */ + SysTick->LOAD = SystemCoreClock / os_ticks_per_sec; + SysTick->VAL = 0UL; + /* Set clock source to processor clock */ + SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk; + /* Enable SysTick IRQ */ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; + + /* Set isr in vector table and enable interrupt */ + NVIC_SetPriority(SysTick_IRQn, prio); + /* Enable at the NVIC */ + EnableIRQ(SysTick_IRQn); + + /* Enable SysTick timer */ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; + + OS_EXIT_CRITICAL(sr); +} diff --git a/hw/mcu/nxp/lpc55xx/src/hal_reset_cause.c b/hw/mcu/nxp/lpc55xx/src/hal_reset_cause.c new file mode 100644 index 0000000000..54533b53d2 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_reset_cause.c @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#include "hal/hal_system.h" +#include "fsl_power.h" + +enum hal_reset_reason +hal_reset_cause(void) +{ + static enum hal_reset_reason reason; + power_device_reset_cause_t reset_cause; + power_device_boot_mode_t boot_mode; + uint32_t wakeupio_cause; + + if (reason) { + return reason; + } + POWER_GetWakeUpCause(&reset_cause, &boot_mode, &wakeupio_cause); + + switch (reset_cause) { + case kRESET_CAUSE_POR: + reason = HAL_RESET_POR; + break; + case kRESET_CAUSE_PADRESET: + reason = HAL_RESET_PIN; + break; + case kRESET_CAUSE_BODRESET: + reason = HAL_RESET_BROWNOUT; + break; + case kRESET_CAUSE_ARMSYSTEMRESET: + case kRESET_CAUSE_SWRRESET: + reason = HAL_RESET_SOFT; + break; + case kRESET_CAUSE_WDTRESET: + case kRESET_CAUSE_CDOGRESET: + reason = HAL_RESET_WATCHDOG; + break; + /* Reset causes in DEEP-POWER-DOWN low power mode */ + case kRESET_CAUSE_DPDRESET_WAKEUPIO: + case kRESET_CAUSE_DPDRESET_RTC: + case kRESET_CAUSE_DPDRESET_OSTIMER: + case kRESET_CAUSE_DPDRESET_WAKEUPIO_RTC: + case kRESET_CAUSE_DPDRESET_WAKEUPIO_OSTIMER: + case kRESET_CAUSE_DPDRESET_RTC_OSTIMER: + case kRESET_CAUSE_DPDRESET_WAKEUPIO_RTC_OSTIMER: + reason = HAL_RESET_SYS_OFF_INT; + break; + case kRESET_CAUSE_NOT_RELEVANT: + case kRESET_CAUSE_NOT_DETERMINISTIC: + reason = HAL_RESET_OTHER; + } + + return reason; +} diff --git a/hw/mcu/nxp/lpc55xx/src/hal_system.c b/hw/mcu/nxp/lpc55xx/src/hal_system.c new file mode 100644 index 0000000000..3a96c28ea2 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_system.c @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +int hal_debugger_connected(void) +{ + return CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk; +} + +void hal_system_reset(void) +{ + +#if MYNEWT_VAL(HAL_SYSTEM_RESET_CB) + hal_system_reset_cb(); +#endif + + while (1) { + HAL_DEBUG_BREAK(); + NVIC_SystemReset(); + } +} + +void +SystemInitHook(void) +{ + NVIC_Relocate(); + if (MYNEWT_VAL_CHOICE(LPC55XX_BOOT_CLOCK, FRO12M)) { + BOARD_BootClockFRO12M(); + } else if (MYNEWT_VAL_CHOICE(LPC55XX_BOOT_CLOCK, FROHF96M)) { + BOARD_BootClockFROHF96M(); + } else if (MYNEWT_VAL_CHOICE(LPC55XX_BOOT_CLOCK, PLL100M)) { + BOARD_BootClockPLL100M(); + } else if (MYNEWT_VAL_CHOICE(LPC55XX_BOOT_CLOCK, PLL150M)) { + BOARD_BootClockPLL150M(); + } else if (MYNEWT_VAL_CHOICE(LPC55XX_BOOT_CLOCK, PLL1_150M)) { + BOARD_BootClockPLL1_150M(); + } +} diff --git a/hw/mcu/nxp/lpc55xx/src/hal_system_init.c b/hw/mcu/nxp/lpc55xx/src/hal_system_init.c new file mode 100644 index 0000000000..78a3c5b4c2 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_system_init.c @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#include "os/mynewt.h" +#include + +void +hal_system_init(void) +{ + SystemCoreClockUpdate(); + + /* Relocate the vector table */ + NVIC_Relocate(); +} + diff --git a/hw/mcu/nxp/lpc55xx/src/hal_system_start.c b/hw/mcu/nxp/lpc55xx/src/hal_system_start.c new file mode 100644 index 0000000000..d7156d4d0c --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_system_start.c @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#include +#include +#include + +/** + * Boots the image described by the supplied image header. + * + * @param hdr The header for the image to boot. + */ +void +hal_system_start(void *img_start) +{ + /* Set the VTOR to default. */ + SCB->VTOR = 0; + + // Memory barriers for good measure. + __ISB(); + __DSB(); + + /* First word contains initial MSP value. */ + __set_MSP(*(uint32_t *)img_start); + __set_PSP(*(uint32_t *)img_start); + + /* Second word contains address of entry point (Reset_Handler). */ + void (*entry)(void) = (void (*)(void))*(uint32_t *)(img_start + 4); + + /* Jump to image. */ + entry(); + + /* Should never reach this point */ + while (1) + ; +} diff --git a/hw/mcu/nxp/lpc55xx/src/hal_timer.c b/hw/mcu/nxp/lpc55xx/src/hal_timer.c new file mode 100644 index 0000000000..e370e0910a --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_timer.c @@ -0,0 +1,401 @@ +/* + * 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. + */ + +#include +#include + +#include +#include +#include + +#include + +struct ctimer_hal_tmr; +struct ctimer_hal_tmr_cfg { + CTIMER_Type *base; + clock_ip_name_t clock_gate; + clock_attach_id_t clock_id; + IRQn_Type irqn; + void (*isr)(void); +}; + +struct ctimer_hal_tmr { + const struct ctimer_hal_tmr_cfg *cfg; + uint32_t freq; +#if MYNEWT_VAL(CTIMER_AUTO_OFF_COUNT) + uint8_t overflow_count; +#endif + + TAILQ_HEAD(hal_timer_qhead, hal_timer) hal_timer_q; +}; + +#if MYNEWT_VAL(CTIMER_AUTO_OFF_COUNT) +#define INC_OVERFLOW(tmr) (++(tmr->overflow_count)) +#define OVERFLOW_COUNT(tmr) tmr->overflow_count +#define OVERFLOW_COUNT_RESET(tmr) tmr->overflow_count = 0 +#else +#define INC_OVERFLOW(tmr) +#define OVERFLOW_COUNT(tmr) 0 +#define OVERFLOW_COUNT_RESET(tmr) +#endif + +static void timer_irq_handler(struct ctimer_hal_tmr *tmr); + +#define TIMER_CFG_DEF(n) \ +static void CTIMER ## n ## _IRQHandler(void); \ +struct ctimer_hal_tmr_cfg TIMER_ ## n ## _cfg = { \ + .base = CTIMER ## n, \ + .clock_gate = kCLOCK_Timer ## n, \ + .clock_id = kMAIN_CLK_to_CTIMER ## n, \ + .irqn = CTIMER ## n ## _IRQn, \ + .isr = CTIMER ## n ## _IRQHandler, \ +};\ +struct ctimer_hal_tmr ctimer_hal_tmr_ ## n = {\ + .cfg = &TIMER_ ## n ## _cfg,\ +};\ +static void CTIMER ## n ## _IRQHandler(void) \ +{ \ + timer_irq_handler(&ctimer_hal_tmr_ ## n); \ +} + +TIMER_CFG_DEF(0); +TIMER_CFG_DEF(1); +TIMER_CFG_DEF(2); +TIMER_CFG_DEF(3); +TIMER_CFG_DEF(4); + +#define TIMER_REF(n) (MYNEWT_VAL_TIMER_ ## n) ? &ctimer_hal_tmr_ ## n : NULL, + +//static const IRQn_Type ctimer_timer_irqs[] = CTIMER_IRQS; + +static struct ctimer_hal_tmr *const timers[FSL_FEATURE_SOC_CTIMER_COUNT] = { + TIMER_REF(0) + TIMER_REF(1) + TIMER_REF(2) + TIMER_REF(3) + TIMER_REF(4) +}; + +static uint32_t +ctimer_tmr_read(struct ctimer_hal_tmr *tmr) +{ + CTIMER_Type *base = tmr->cfg->base; + if (MYNEWT_VAL(CTIMER_AUTO_OFF_COUNT) && 0 == (base->TCR & CTIMER_TCR_CEN_MASK)) { + CTIMER_StartTimer(base); + OVERFLOW_COUNT_RESET(tmr); + } + return CTIMER_GetTimerCountValue(tmr->cfg->base); +} + +static uint32_t +ctimer_tmr_get_freq(const struct ctimer_hal_tmr *tmr) +{ + return tmr->freq; +} + +static void +ctimer_tmr_config_freq(ctimer_config_t *config, uint32_t freq_hz) +{ + config->prescale = (SystemCoreClock / freq_hz) - 1; +} + +static void +timer_irq_handler(struct ctimer_hal_tmr *tmr) +{ + struct hal_timer *timer; + CTIMER_Type *base = tmr->cfg->base; + bool empty_run = true; + struct _ctimer_match_config match_action = { + .enableInterrupt = true + }; + + while ((timer = TAILQ_FIRST(&tmr->hal_timer_q)) != NULL) { + if ((int32_t)(CTIMER_GetTimerCountValue(base) - timer->expiry) >= 0) { + TAILQ_REMOVE(&tmr->hal_timer_q, timer, link); + timer->link.tqe_prev = NULL; + timer->cb_func(timer->cb_arg); + empty_run = false; + } else { + break; + } + } + + timer = TAILQ_FIRST(&tmr->hal_timer_q); + if (timer) { + match_action.matchValue = timer->expiry; + CTIMER_SetupMatch(base, kCTIMER_Match_0, &match_action); + } else { + if (MYNEWT_VAL(CTIMER_AUTO_OFF_COUNT)) { + if (empty_run && OVERFLOW_COUNT(tmr) == MYNEWT_VAL(CTIMER_AUTO_OFF_COUNT)) { + CTIMER_StopTimer(base); + } else { + INC_OVERFLOW(tmr); + match_action.matchValue = CTIMER_GetTimerCountValue(base); + CTIMER_SetupMatch(base, kCTIMER_Match_0, &match_action); + } + } else { + CTIMER_DisableInterrupts(base, kCTIMER_Match0InterruptEnable); + } + } + CTIMER_ClearStatusFlags(base, kCTIMER_Match0Flag); +} + +int +hal_timer_init(int num, void *cfg) +{ + const struct ctimer_hal_tmr *tmr; + ctimer_config_t default_config; + IRQn_Type irqn; + CTIMER_Type *base; + + (void)cfg; + + if (num >= FSL_FEATURE_SOC_CTIMER_COUNT || !(tmr = timers[num])) { + return -1; + } + + base = tmr->cfg->base; + + CLOCK_AttachClk(tmr->cfg->clock_id); + CLOCK_EnableClock(tmr->cfg->clock_gate); + CTIMER_GetDefaultConfig(&default_config); + CTIMER_Init(base, &default_config); + + irqn = tmr->cfg->irqn; + NVIC_SetPriority(irqn, (1 << __NVIC_PRIO_BITS) - 1); + NVIC_SetVector(irqn, (uint32_t)tmr->cfg->isr); + NVIC_EnableIRQ(irqn); + if (MYNEWT_VAL_CTIMER_AUTO_OFF_COUNT) { + ctimer_match_config_t match = { + .matchValue = base->TC, + .enableInterrupt = true, + }; + CTIMER_SetupMatch(base, kCTIMER_Match_0, &match); + + } + CTIMER_StartTimer(base); + + return 0; +} + +int +hal_timer_deinit(int num) +{ + const struct ctimer_hal_tmr *tmr; + + if (num >= FSL_FEATURE_SOC_CTIMER_COUNT || !(tmr = timers[num])) { + return -1; + } + + CTIMER_Deinit(tmr->cfg->base); + + return 0; +} + +int +hal_timer_config(int num, uint32_t freq_hz) +{ + struct ctimer_hal_tmr *tmr; + ctimer_config_t timer_config; + CTIMER_Type *base; + os_sr_t sr; + + if (num >= FSL_FEATURE_SOC_CTIMER_COUNT || !(tmr = timers[num])) { + return -1; + } + base = tmr->cfg->base; + + OS_ENTER_CRITICAL(sr); + + CTIMER_GetDefaultConfig(&timer_config); + ctimer_tmr_config_freq(&timer_config, freq_hz); + CTIMER_StopTimer(base); + CTIMER_Init(base, &timer_config); + tmr->freq = SystemCoreClock / (timer_config.prescale + 1); + CTIMER_EnableInterrupts(base, kCTIMER_Match0InterruptEnable); + CTIMER_StartTimer(base); + + OS_EXIT_CRITICAL(sr); + + return 0; +} + +uint32_t +hal_timer_get_resolution(int num) +{ + const struct ctimer_hal_tmr *tmr; + + if (num >= FSL_FEATURE_SOC_CTIMER_COUNT || !(tmr = timers[num])) { + return 0; + } + + return (1000000000 / ctimer_tmr_get_freq(tmr)); +} + +uint32_t +hal_timer_read(int num) +{ + struct ctimer_hal_tmr *tmr; + + if (num >= FSL_FEATURE_SOC_CTIMER_COUNT || !(tmr = timers[num])) { + return 0; + } + + return ctimer_tmr_read(tmr); +} + +int +hal_timer_delay(int num, uint32_t ticks) +{ + struct ctimer_hal_tmr *tmr; + uint32_t until; + + if (num >= FSL_FEATURE_SOC_CTIMER_COUNT || !(tmr = timers[num])) { + return -1; + } + + until = ctimer_tmr_read(tmr) + ticks; + while ((int32_t)(ctimer_tmr_read(tmr) - until) <= 0) { + } + + return 0; +} + +int +hal_timer_set_cb(int num, struct hal_timer *timer, hal_timer_cb cb_func, + void *arg) +{ + const struct ctimer_hal_tmr *tmr; + + if (num >= FSL_FEATURE_SOC_CTIMER_COUNT || !(tmr = timers[num])) { + return -1; + } + + timer->cb_func = cb_func; + timer->cb_arg = arg; + timer->bsp_timer = (struct ctimer_hal_tmr *)tmr; + timer->link.tqe_prev = NULL; + + return 0; +} + +int +hal_timer_start(struct hal_timer *timer, uint32_t ticks) +{ + struct ctimer_hal_tmr *tmr; + uint32_t tick; + + tmr = (struct ctimer_hal_tmr *)timer->bsp_timer; + + tick = ticks + CTIMER_GetTimerCountValue(tmr->cfg->base); + + return hal_timer_start_at(timer, tick); +} + +int +hal_timer_start_at(struct hal_timer *timer, uint32_t tick) +{ + struct ctimer_hal_tmr *tmr; + struct hal_timer *entry; + CTIMER_Type *base; + os_sr_t sr; + + if (!timer || timer->link.tqe_prev || !timer->cb_func) { + return -1; + } + + tmr = (struct ctimer_hal_tmr *)timer->bsp_timer; + base = tmr->cfg->base; + timer->expiry = tick; + + OS_ENTER_CRITICAL(sr); + + if (TAILQ_EMPTY(&tmr->hal_timer_q)) { + TAILQ_INSERT_HEAD(&tmr->hal_timer_q, timer, link); + } else { + TAILQ_FOREACH(entry, &tmr->hal_timer_q, link) { + if ((int32_t)(timer->expiry - entry->expiry) < 0) { + TAILQ_INSERT_BEFORE(entry, timer, link); + break; + } + } + if (!entry) { + TAILQ_INSERT_TAIL(&tmr->hal_timer_q, timer, link); + } + } + + if (timer == TAILQ_FIRST(&tmr->hal_timer_q)) { + ctimer_match_config_t match = { + .matchValue = timer->expiry, + .enableInterrupt = true, + }; + CTIMER_SetupMatch(base, kCTIMER_Match_0, &match); + CTIMER_EnableResetMatchChannel(base, kCTIMER_Match_0, true); + OVERFLOW_COUNT_RESET(tmr); + } + + if (0 == (base->TCR & CTIMER_TCR_CEN_MASK)) { + CTIMER_StartTimer(base); + } + + OS_EXIT_CRITICAL(sr); + + return 0; +} + +int +hal_timer_stop(struct hal_timer *timer) +{ + struct ctimer_hal_tmr *tmr; + struct hal_timer *entry = NULL; + bool reset_period; + CTIMER_Type *base; + os_sr_t sr; + + tmr = (struct ctimer_hal_tmr *)timer->bsp_timer; + base = tmr->cfg->base; + + OS_ENTER_CRITICAL(sr); + + if (timer->link.tqe_prev != NULL) { + reset_period = false; + /* Is timer first in the queue? */ + if (timer == TAILQ_FIRST(&tmr->hal_timer_q)) { + entry = TAILQ_NEXT(timer, link); + reset_period = true; + } + TAILQ_REMOVE(&tmr->hal_timer_q, timer, link); + timer->link.tqe_prev = NULL; + if (reset_period) { + if (entry) { + ctimer_match_config_t match = { + .matchValue = entry->expiry, + .enableInterrupt = true, + }; + CTIMER_SetupMatch(base, kCTIMER_Match_0, &match); + } else { + CTIMER_StopTimer(tmr->cfg->base); + } + } + } + + OS_EXIT_CRITICAL(sr); + + return 0; +} diff --git a/hw/mcu/nxp/lpc55xx/src/hal_uart.c b/hw/mcu/nxp/lpc55xx/src/hal_uart.c new file mode 100644 index 0000000000..6900ac3d78 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_uart.c @@ -0,0 +1,645 @@ +/* + * 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. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define IOCON_PIN(uart_num, pin, func) (((func) << 8) | ((uart_num) << 5) | pin) +#define P0_0_FC3_SCK IOCON_PIN(0, 0, 2) +#define P0_1_FC3_CTS_SDAX_SSEL0 IOCON_PIN(0, 1, 2) +#define P0_2_FC3_TXD_SCL_MISO IOCON_PIN(0, 2, 1) +#define P0_3_FC3_RXD_SDA_MOSI IOCON_PIN(0, 3, 1) +#define P0_4_FC4_SCK IOCON_PIN(0, 4, 2) +#define P0_4_FC3_CTS_SDAX_SSEL0 IOCON_PIN(0, 4, 8) +#define P0_5_FC4_RXD_SDA_MOSI IOCON_PIN(0, 5, 2) +#define P0_5_FC3_RTS_SCLX_SSEL1 IOCON_PIN(0, 5, 8) +#define P0_6_FC3_SCK IOCON_PIN(0, 6, 1) +#define P0_7_FC3_RTS_SCLX_SSEL1 IOCON_PIN(0, 7, 1) +#define P0_7_FC5_SCK IOCON_PIN(0, 7, 3) +#define P0_7_FC1_SCK IOCON_PIN(0, 7, 4) +#define P0_8_FC3_SSEL3 IOCON_PIN(0, 8, 1) +#define P0_8_FC5_RXD_SDA_MOSI IOCON_PIN(0, 8, 3) +#define P0_9_FC3_SSEL2 IOCON_PIN(0, 9, 1) +#define P0_9_FC5_TXD_SCL_MISO IOCON_PIN(0, 9, 3) +#define P0_10_FC6_SCK IOCON_PIN(0, 10, 1) +#define P0_10_FC1_TXD_SCL_MISO IOCON_PIN(0, 10, 4) +#define P0_11_FC6_RXD_SDA_MOSI IOCON_PIN(0, 11, 1) +#define P0_12_FC3_TXD_SCL_MISO IOCON_PIN(0, 12, 1) +#define P0_12_FC6_TXD_SCL_MISO IOCON_PIN(0, 12, 7) +#define P0_13_FC1_CTS_SDAX_SSEL0 IOCON_PIN(0, 13, 1) +#define P0_13_FC1_RXD_SDA_MOSI IOCON_PIN(0, 13, 5) +#define P0_14_FC1_RTS_SCLX_SSEL1 IOCON_PIN(0, 14, 1) +#define P0_14_FC1_TXD_SCL_MISO IOCON_PIN(0, 14, 6) +#define P0_15_FC6_CTS_SDAX_SSEL0 IOCON_PIN(0, 15, 1) +#define P0_16_FC4_TXD_SCL_MISO IOCON_PIN(0, 16, 1) +#define P0_17_FC4_SSEL2 IOCON_PIN(0, 17, 1) +#define P0_18_FC4_CTS_SDAX_SSEL0 IOCON_PIN(0, 18, 1) +#define P0_19_FC1_RTS_SCLX_SSEL1 IOCON_PIN(0, 19, 1) +#define P0_19_FC7_TXD_SCL_MISO IOCON_PIN(0, 19, 7) +#define P0_20_FC3_CTS_SDAX_SSEL0 IOCON_PIN(0, 20, 1) +#define P0_20_FC7_RXD_SDA_MOSI IOCON_PIN(0, 20, 7) +#define P0_20_FC4_TXD_SCL_MISO IOCON_PIN(0, 20, 11) +#define P0_21_FC3_RTS_SCLX_SSEL1 IOCON_PIN(0, 21, 1) +#define P0_21_FC7_SCK IOCON_PIN(0, 21, 7) +#define P0_22_FC6_TXD_SCL_MISO IOCON_PIN(0, 22, 1) +#define P0_23_FC0_CTS_SDAX_SSEL0 IOCON_PIN(0, 23, 5) +#define P0_24_FC0_RXD_SDA_MOSI IOCON_PIN(0, 24, 1) +#define P0_25_FC0_TXD_SCL_MISO IOCON_PIN(0, 25, 1) +#define P0_26_FC2_RXD_SDA_MOSI IOCON_PIN(0, 26, 1) +#define P0_26_FC0_SCK IOCON_PIN(0, 26, 8) +#define P0_27_FC2_TXD_SCL_MISO IOCON_PIN(0, 27, 1) +#define P0_27_FC7_RXD_SDA_MOSI IOCON_PIN(0, 27, 7) +#define P0_28_FC0_SCK IOCON_PIN(0, 28, 1) +#define P0_29_FC0_RXD_SDA_MOSI IOCON_PIN(0, 29, 1) +#define P0_30_FC0_TXD_SCL_MISO IOCON_PIN(0, 30, 1) +#define P0_31_FC0_CTS_SDAX_SSEL0 IOCON_PIN(0, 31, 1) +#define P1_0_FC0_RTS_SCLX_SSEL1 IOCON_PIN(1, 0, 1) +#define P1_1_FC3_RXD_SDA_MOSI IOCON_PIN(1, 1, 1) +#define P1_4_FC0_SCK IOCON_PIN(1, 4, 1) +#define P1_5_FC0_RXD_SDA_MOSI IOCON_PIN(1, 5, 1) +#define P1_6_FC0_TXD_SCL_MISO IOCON_PIN(1, 6, 1) +#define P1_7_FC0_RXD_SDA_MOSI IOCON_PIN(1, 7, 1) +#define P1_8_FC0_CTS_SDAX_SSEL0 IOCON_PIN(1, 8, 1) +#define P1_8_FC4_SSEL2 IOCON_PIN(1, 8, 5) +#define P1_9_FC1_SCK IOCON_PIN(1, 9, 2) +#define P1_9_FC4_CTS_SDAX_SSEL0 IOCON_PIN(1, 9, 5) +#define P1_10_FC1_RXD_SDA_MOSI IOCON_PIN(1, 10, 2) +#define P1_11_FC1_TXD_SCL_MISO IOCON_PIN(1, 11, 2) +#define P1_12_FC6_SCK IOCON_PIN(1, 12, 2) +#define P1_13_FC6_RXD_SDA_MOSI IOCON_PIN(1, 13, 2) +#define P1_14_FC5_CTS_SDAX_SSEL0 IOCON_PIN(1, 14, 4) +#define P1_15_FC5_RTS_SCLX_SSEL1 IOCON_PIN(1, 15, 4) +#define P1_15_FC4_RTS_SCLX_SSEL1 IOCON_PIN(1, 15, 5) +#define P1_16_FC6_TXD_SCL_MISO IOCON_PIN(1, 16, 2) +#define P1_17_FC6_RTS_SCLX_SSEL1 IOCON_PIN(1, 17, 3) +#define P1_19_FC4_SCK IOCON_PIN(1, 19, 5) +#define P1_20_FC7_RTS_SCLX_SSEL1 IOCON_PIN(1, 20, 1) +#define P1_20_FC4_TXD_SCL_MISO IOCON_PIN(1, 20, 5) +#define P1_21_FC7_CTS_SDAX_SSEL0 IOCON_PIN(1, 21, 1) +#define P1_21_FC4_RXD_SDA_MOSI IOCON_PIN(1, 21, 5) +#define P1_22_FC4_SSEL3 IOCON_PIN(1, 22, 5) +#define P1_23_FC2_SCK IOCON_PIN(1, 23, 1) +#define P1_23_FC3_SSEL2 IOCON_PIN(1, 23, 5) +#define P1_24_FC2_RXD_SDA_MOSI IOCON_PIN(1, 24, 1) +#define P1_24_FC3_SSEL3 IOCON_PIN(1, 24, 5) +#define P1_25_FC2_TXD_SCL_MISO IOCON_PIN(1, 25, 1) +#define P1_26_FC2_CTS_SDAX_SSEL0 IOCON_PIN(1, 26, 1) +#define P1_27_FC2_RTS_SCLX_SSEL1 IOCON_PIN(1, 27, 1) +#define P1_28_FC7_SCK IOCON_PIN(1, 28, 1) +#define P1_29_FC7_RXD_SDA_MOSI IOCON_PIN(1, 29, 1) +#define P1_28_FC7_TXD_SCL_MISO IOCON_PIN(1, 30, 1) +#define SPI3_SCK_P0_0 P0_0_FC3_SCK +#define SPI3_SSEL0_P0_1 IOCON_PIN(0, 1, 2) +#define SPI3_SSEL0_P0_1 IOCON_PIN(0, 1, 2) + +/*! @brief Ring buffer size (Unit: Byte). */ +#define TX_BUF_SZ 32 + +struct uart_ring { + uint16_t ur_head; + uint16_t ur_tail; + uint16_t ur_size; + uint8_t _pad; + uint8_t *ur_buf; +}; + +struct hal_uart { + USART_Type *base; + clock_attach_id_t clk_src; + uint32_t irqn; + clock_ip_name_t p_clock; + int pin_rx; + int pin_tx; + + hal_uart_rx_char u_rx_func; + hal_uart_tx_char u_tx_func; + hal_uart_tx_done u_tx_done; + void *u_func_arg; + + uint8_t u_configured : 1; + uint8_t u_open : 1; + uint8_t u_tx_started : 1; + uint8_t u_rx_stall : 1; + + uint8_t u_rx_buf; + + struct uart_ring ur_tx; + uint8_t tx_buffer[TX_BUF_SZ]; + + usart_handle_t fsl_handle; + void (*isr)(void); +}; + +#define UART_INSTANCE(n) \ + static void uart_irq ## n(void); \ + static struct hal_uart uart ## n = { \ + .base = USART ## n, \ + .clk_src = MYNEWT_VAL_UART_ ## n ## _CLK_SOURCE, \ + .irqn = FLEXCOMM ## n ## _IRQn, \ + .p_clock = kCLOCK_MinUart ## n, \ + .pin_rx = MYNEWT_VAL_UART_ ## n ## _PIN_RX, \ + .pin_tx = MYNEWT_VAL_UART_ ## n ## _PIN_TX, \ + .ur_tx.ur_buf = uart ## n.tx_buffer, \ + .ur_tx.ur_size = TX_BUF_SZ, \ + .isr = uart_irq ## n, \ + }; \ + static void uart_irq ## n(void) \ + { \ + USART_TransferHandleIRQ(uart ## n.base, &uart ## n.fsl_handle); \ + } + +UART_INSTANCE(0) +UART_INSTANCE(1) +UART_INSTANCE(2) +UART_INSTANCE(3) +UART_INSTANCE(4) +UART_INSTANCE(5) +UART_INSTANCE(6) +UART_INSTANCE(7) + +#define UART_REF(n) (MYNEWT_VAL_UART_ ## n) ? &uart ## n : NULL + +static struct hal_uart *uarts[FSL_FEATURE_SOC_FLEXCOMM_COUNT] = { + UART_REF(0), + UART_REF(1), + UART_REF(2), + UART_REF(3), + UART_REF(4), + UART_REF(5), + UART_REF(6), + UART_REF(7), +}; + +typedef enum { + IOCON_PIN_FUNC_NONE, + IOCON_PIN_FUNC_CLKOUT, + IOCON_PIN_FUNC_CMP0_OUT, + IOCON_PIN_FUNC_CT0MAT0, + IOCON_PIN_FUNC_CT0MAT1, + IOCON_PIN_FUNC_CT0MAT2, + IOCON_PIN_FUNC_CT0MAT3, + IOCON_PIN_FUNC_CT1MAT0, + IOCON_PIN_FUNC_CT1MAT1, + IOCON_PIN_FUNC_CT1MAT2, + IOCON_PIN_FUNC_CT1MAT3, + IOCON_PIN_FUNC_CT2MAT0, + IOCON_PIN_FUNC_CT2MAT1, + IOCON_PIN_FUNC_CT2MAT2, + IOCON_PIN_FUNC_CT2MAT3, + IOCON_PIN_FUNC_CT3MAT0, + IOCON_PIN_FUNC_CT3MAT1, + IOCON_PIN_FUNC_CT3MAT2, + IOCON_PIN_FUNC_CT3MAT3, + IOCON_PIN_FUNC_CT4MAT0, + IOCON_PIN_FUNC_CT_INP0, + IOCON_PIN_FUNC_CT_INP1, + IOCON_PIN_FUNC_CT_INP2, + IOCON_PIN_FUNC_CT_INP3, + IOCON_PIN_FUNC_CT_INP4, + IOCON_PIN_FUNC_CT_INP5, + IOCON_PIN_FUNC_CT_INP6, + IOCON_PIN_FUNC_CT_INP7, + IOCON_PIN_FUNC_CT_INP8, + IOCON_PIN_FUNC_CT_INP9, + IOCON_PIN_FUNC_CT_INP10, + IOCON_PIN_FUNC_CT_INP12, + IOCON_PIN_FUNC_CT_INP13, + IOCON_PIN_FUNC_CT_INP14, + IOCON_PIN_FUNC_CT_INP15, + IOCON_PIN_FUNC_CT_INP16, + IOCON_PIN_FUNC_FC0_CTS_SDAX_SSEL0, + IOCON_PIN_FUNC_FC0_RTS_SCLX_SSEL1, + IOCON_PIN_FUNC_FC0_RXD_SDA_MOSI, + IOCON_PIN_FUNC_FC0_SCK, + IOCON_PIN_FUNC_FC0_TXD_SCL_MISO, + IOCON_PIN_FUNC_FC1_CTS_SDAX_SSEL0, + IOCON_PIN_FUNC_FC1_RTS_SCLX_SSEL1, + IOCON_PIN_FUNC_FC1_RXD_SDA_MOSI, + IOCON_PIN_FUNC_FC1_SCK, + IOCON_PIN_FUNC_FC1_TXD_SCL_MISO, + IOCON_PIN_FUNC_FC2_CTS_SDAX_SSEL0, + IOCON_PIN_FUNC_FC2_RTS_SCLX_SSEL1, + IOCON_PIN_FUNC_FC2_RXD_SDA_MOSI, + IOCON_PIN_FUNC_FC2_SCK, + IOCON_PIN_FUNC_FC2_TXD_SCL_MISO, + IOCON_PIN_FUNC_FC3_CTS_SDAX_SSEL0, + IOCON_PIN_FUNC_FC3_RTS_SCLX_SSEL1, + IOCON_PIN_FUNC_FC3_RXD_SDA_MOSI, + IOCON_PIN_FUNC_FC3_SCK, + IOCON_PIN_FUNC_FC3_SSEL2, + IOCON_PIN_FUNC_FC3_SSEL3, + IOCON_PIN_FUNC_FC3_TXD_SCL_MISO, + IOCON_PIN_FUNC_FC4_CTS_SDAX_SSEL0, + IOCON_PIN_FUNC_FC4_RTS_SCLX_SSEL1, + IOCON_PIN_FUNC_FC4_RXD_SDA_MOSI, + IOCON_PIN_FUNC_FC4_SCK, + IOCON_PIN_FUNC_FC4_SSEL2, + IOCON_PIN_FUNC_FC4_SSEL3, + IOCON_PIN_FUNC_FC4_TXD_SCL_MISO, + IOCON_PIN_FUNC_FC5_CTS_SDAX_SSEL0, + IOCON_PIN_FUNC_FC5_RTS_SCLX_SSEL1, + IOCON_PIN_FUNC_FC5_RXD_SDA_MOSI, + IOCON_PIN_FUNC_FC5_SCK, + IOCON_PIN_FUNC_FC5_TXD_SCL_MISO, + IOCON_PIN_FUNC_FC6_CTS_SDAX_SSEL0, + IOCON_PIN_FUNC_FC6_RTS_SCLX_SSEL1, + IOCON_PIN_FUNC_FC6_RXD_SDA_MOSI, + IOCON_PIN_FUNC_FC6_SCK, + IOCON_PIN_FUNC_FC6_TXD_SCL_MISO, + IOCON_PIN_FUNC_FC7_CTS_SDAX_SSEL0, + IOCON_PIN_FUNC_FC7_RTS_SCLX_SSEL1, + IOCON_PIN_FUNC_FC7_RXD_SDA_MOSI, + IOCON_PIN_FUNC_FC7_SCK, + IOCON_PIN_FUNC_FC7_TXD_SCL_MISO, + IOCON_PIN_FUNC_FREQME_GPIO_CLK_A, + IOCON_PIN_FUNC_FREQME_GPIO_CLK_B, + IOCON_PIN_FUNC_HS_SPI_SCK, + IOCON_PIN_FUNC_HS_SPI_SSEL0, + IOCON_PIN_FUNC_HS_SPI_SSEL1, + IOCON_PIN_FUNC_HS_SPI_SSEL2, + IOCON_PIN_FUNC_HS_SPI_SSEL3, + IOCON_PIN_FUNC_HS_SPI_MISO, + IOCON_PIN_FUNC_MCLK, + IOCON_PIN_FUNC_P0_SEC0, + IOCON_PIN_FUNC_P0_SEC1, + IOCON_PIN_FUNC_P0_SEC2, + IOCON_PIN_FUNC_P0_SEC3, + IOCON_PIN_FUNC_P0_SEC4, + IOCON_PIN_FUNC_P0_SEC5, + IOCON_PIN_FUNC_P0_SEC6, + IOCON_PIN_FUNC_P0_SEC7, + IOCON_PIN_FUNC_P0_SEC8, + IOCON_PIN_FUNC_P0_SEC9, + IOCON_PIN_FUNC_P0_SEC10, + IOCON_PIN_FUNC_P0_SEC11, + IOCON_PIN_FUNC_P0_SEC12, + IOCON_PIN_FUNC_P0_SEC13, + IOCON_PIN_FUNC_P0_SEC14, + IOCON_PIN_FUNC_P0_SEC15, + IOCON_PIN_FUNC_P0_SEC16, + IOCON_PIN_FUNC_P0_SEC17, + IOCON_PIN_FUNC_P0_SEC18, + IOCON_PIN_FUNC_P0_SEC19, + IOCON_PIN_FUNC_P0_SEC20, + IOCON_PIN_FUNC_P0_SEC21, + IOCON_PIN_FUNC_P0_SEC22, + IOCON_PIN_FUNC_P0_SEC23, + IOCON_PIN_FUNC_P0_SEC24, + IOCON_PIN_FUNC_P0_SEC25, + IOCON_PIN_FUNC_P0_SEC26, + IOCON_PIN_FUNC_P0_SEC27, + IOCON_PIN_FUNC_P0_SEC28, + IOCON_PIN_FUNC_P0_SEC29, + IOCON_PIN_FUNC_P0_SEC30, + IOCON_PIN_FUNC_P0_SEC31, + IOCON_PIN_FUNC_PLU_IN0, + IOCON_PIN_FUNC_PLU_IN1, + IOCON_PIN_FUNC_PLU_IN2, + IOCON_PIN_FUNC_PLU_IN3, + IOCON_PIN_FUNC_PLU_IN4, + IOCON_PIN_FUNC_PLU_IN5, + IOCON_PIN_FUNC_PLU_OUT0, + IOCON_PIN_FUNC_PLU_OUT1, + IOCON_PIN_FUNC_PLU_OUT2, + IOCON_PIN_FUNC_PLU_OUT3, + IOCON_PIN_FUNC_PLU_OUT4, + IOCON_PIN_FUNC_PLU_OUT5, + IOCON_PIN_FUNC_PLU_OUT6, + IOCON_PIN_FUNC_PLU_OUT7, + IOCON_PIN_FUNC_CLKIN, + IOCON_PIN_FUNC_SCT0_OUT0, + IOCON_PIN_FUNC_SCT0_OUT1, + IOCON_PIN_FUNC_SCT0_OUT2, + IOCON_PIN_FUNC_SCT0_OUT3, + IOCON_PIN_FUNC_SCT0_OUT4, + IOCON_PIN_FUNC_SCT0_OUT5, + IOCON_PIN_FUNC_SCT0_OUT6, + IOCON_PIN_FUNC_SCT0_OUT7, + IOCON_PIN_FUNC_SCT0_OUT8, + IOCON_PIN_FUNC_SCT0_OUT9, + IOCON_PIN_FUNC_SCT_GPI0, + IOCON_PIN_FUNC_SCT_GPI1, + IOCON_PIN_FUNC_SCT_GPI2, + IOCON_PIN_FUNC_SCT_GPI3, + IOCON_PIN_FUNC_SCT_GPI4, + IOCON_PIN_FUNC_SCT_GPI5, + IOCON_PIN_FUNC_SCT_GPI6, + IOCON_PIN_FUNC_SCT_GPI7, + IOCON_PIN_FUNC_SD0_CARD_DET_N, + IOCON_PIN_FUNC_SD0_CLK, + IOCON_PIN_FUNC_SD0_CMD, + IOCON_PIN_FUNC_SD0_D0, + IOCON_PIN_FUNC_SD0_D1, + IOCON_PIN_FUNC_SD0_D2, + IOCON_PIN_FUNC_SD0_D3, + IOCON_PIN_FUNC_SD0_D4, + IOCON_PIN_FUNC_SD0_D5, + IOCON_PIN_FUNC_SD0_D6, + IOCON_PIN_FUNC_SD0_D7, + IOCON_PIN_FUNC_SD0_POW_EN, + IOCON_PIN_FUNC_SD0_WR_PRT, + IOCON_PIN_FUNC_SD1_BACKEND_PWR, + IOCON_PIN_FUNC_SD1_CARD_INT_N, + IOCON_PIN_FUNC_SD1_CLK, + IOCON_PIN_FUNC_SD1_CMD, + IOCON_PIN_FUNC_SD1_D0, + IOCON_PIN_FUNC_SD1_D1, + IOCON_PIN_FUNC_SD1_D2, + IOCON_PIN_FUNC_SD1_D3, + IOCON_PIN_FUNC_SD1_POW_EN, + IOCON_PIN_FUNC_SWO, + IOCON_PIN_FUNC_SWCLK, + IOCON_PIN_FUNC_SWDIO, + IOCON_PIN_FUNC_USB0_FRAME, + IOCON_PIN_FUNC_USB0_IDVALUE, + IOCON_PIN_FUNC_USB0_OVERCURRENTN, + IOCON_PIN_FUNC_USB0_uart_numPWRN, + IOCON_PIN_FUNC_USB0_VBUS, + IOCON_PIN_FUNC_USB1_FRAME, + IOCON_PIN_FUNC_USB1_LEDN, + IOCON_PIN_FUNC_USB1_OVERCURRENTN, + IOCON_PIN_FUNC_USB1_uart_numPWRN, + IOCON_PIN_FUNC_UTICK_CAP0, + IOCON_PIN_FUNC_UTICK_CAP1, + IOCON_PIN_FUNC_UTICK_CAP2, + IOCON_PIN_FUNC_UTICK_CAP3, +} iocon_pinmux_t; + +typedef enum { + FCX_TXD_SCL_MISO, + FCX_RXD_SDA_MOSI, + FCX_CTS_SDAX_SSEL0, + FCX_RTS_SCLX_SSEL1, + FCX_SCK, + FCX_SSEL2, + FCX_SSEL3, +} flexcomm_pin_t; + +static struct hal_uart * +fsl_uart(int uart_num) +{ + if (uart_num >= FSL_FEATURE_SOC_USART_COUNT) { + return NULL; + } else { + return uarts[uart_num]; + } + +} + +int +hal_uart_init_cbs(int uart_num, hal_uart_tx_char tx_func, + hal_uart_tx_done tx_done, hal_uart_rx_char rx_func, void *arg) +{ + struct hal_uart *uart = fsl_uart(uart_num); + + if (uart == NULL) { + return -1; + } + + uart->u_rx_func = rx_func; + uart->u_tx_func = tx_func; + uart->u_tx_done = tx_done; + uart->u_func_arg = arg; + + return 0; +} + +void +hal_uart_blocking_tx(int uart_num, uint8_t byte) +{ + struct hal_uart *uart = fsl_uart(uart_num); + + if (uart == NULL || !uart->u_configured || !uart->u_open) { + return; + } + + USART_WriteBlocking(uart->base, &byte, 1); +} + +static int +hal_uart_tx_fill_buf(struct hal_uart *uart) +{ + int data; + int i; + + for (i = 0; i < sizeof(uart->tx_buffer); i++) { + data = uart->u_tx_func(uart->u_func_arg); + if (data < 0) { + break; + } + uart->tx_buffer[i] = data; + } + + return i; +} + +void +hal_uart_start_tx(int uart_num) +{ + struct hal_uart *uart = fsl_uart(uart_num); + usart_transfer_t transfer; + int rc; + + if (uart == NULL || !uart->u_configured || !uart->u_open) { + return; + } + + /* add data to TX ring buffer */ + if (uart->u_tx_started == 0) { + rc = hal_uart_tx_fill_buf(uart); + uart->u_tx_started = rc > 0; + if (uart->u_tx_started) { + transfer.txData = uart->tx_buffer; + transfer.dataSize = rc; + USART_TransferSendNonBlocking(uart->base, &uart->fsl_handle, &transfer); + } + } +} + +void +hal_uart_start_rx(int uart_num) +{ + struct hal_uart *uart = fsl_uart(uart_num); + usart_transfer_t transfer; + size_t received; + int sr; + int rc = 0; + + + if (uart == NULL || !uart->u_configured || !uart->u_open) { + return; + } + + if (uart->u_rx_stall) { + __HAL_DISABLE_INTERRUPTS(sr); + rc = uart->u_rx_func(uart->u_func_arg, uart->u_rx_buf); + if (rc == 0) { + uart->u_rx_stall = 0; + transfer.rxData = &uart->u_rx_buf; + transfer.dataSize = 1; + USART_TransferReceiveNonBlocking(uart->base, &uart->fsl_handle, &transfer, &received); + } + __HAL_ENABLE_INTERRUPTS(sr); + } +} + +static void +usart_transfer_callback(USART_Type *base, usart_handle_t *handle, status_t status, void *user_data) +{ + struct hal_uart *uart = user_data; + usart_transfer_t xfer; + int rc; + + switch (status) { + case kStatus_USART_TxIdle: + rc = hal_uart_tx_fill_buf(uart); + uart->u_tx_started = rc > 0; + if (uart->u_tx_started) { + xfer.txData = uart->tx_buffer; + xfer.dataSize = rc; + USART_TransferSendNonBlocking(uart->base, &uart->fsl_handle, &xfer); + } else { + if (uart->u_tx_done) { + uart->u_tx_done(uart->u_func_arg); + } + } + break; + case kStatus_USART_RxIdle: + rc = uart->u_rx_func(uart->u_func_arg, uart->u_rx_buf); + if (rc < 0) { + uart->u_rx_stall = 1; + } else { + xfer.rxData = &uart->u_rx_buf; + xfer.dataSize = 1; + USART_TransferReceiveNonBlocking(uart->base, &uart->fsl_handle, &xfer, NULL); + } + break; + default: + break; + } +} + +int +hal_uart_config(int uart_num, int32_t speed, uint8_t databits, uint8_t stopbits, + enum hal_uart_parity parity, enum hal_uart_flow_ctl flow_ctl) +{ + struct hal_uart *uart = fsl_uart(uart_num); + usart_config_t uconfig; + + if (uart == NULL) { + return -OS_EINVAL; + } + + if (!uart->u_configured || uart->u_open) { + return -OS_EBUSY; + } + + CLOCK_AttachClk(uart->clk_src); + /* PIN config (all UARTs use kuart_num_MuxAlt3) */ + CLOCK_EnableClock(uart->p_clock); + IOCON_PinMuxSet(IOCON, (uart->pin_rx >> 5) & 1, uart->pin_rx & 31, (uart->pin_rx >> 8) | IOCON_DIGITAL_EN); + IOCON_PinMuxSet(IOCON, (uart->pin_tx >> 5) & 1, uart->pin_tx & 31, (uart->pin_tx >> 8) | IOCON_DIGITAL_EN); + + /* UART CONFIG */ + USART_GetDefaultConfig(&uconfig); + uconfig.baudRate_Bps = speed; + uconfig.enableRx = true; + uconfig.enableTx = true; + + /* TODO: only handles 8 databits currently */ + + switch (stopbits) { + case 1: + uconfig.stopBitCount = kUSART_OneStopBit; + break; + case 2: + uconfig.stopBitCount = kUSART_TwoStopBit; + break; + default: + return -1; + } + + switch (parity) { + case HAL_UART_PARITY_NONE: + uconfig.parityMode = kUSART_ParityDisabled; + break; + case HAL_UART_PARITY_ODD: + uconfig.parityMode = kUSART_ParityOdd; + break; + case HAL_UART_PARITY_EVEN: + uconfig.parityMode = kUSART_ParityEven; + break; + } + + /* TODO: HW flow control not supuart_numed */ + assert(flow_ctl == HAL_UART_FLOW_CTL_NONE); + + uart->u_open = 1; + uart->u_tx_started = 0; + uart->u_rx_stall = 1; + + NVIC_SetVector(uart->irqn, (uint32_t)uart->isr); + + /* Initialize UART device */ + USART_Init(uart->base, &uconfig, CLOCK_GetFlexCommClkFreq(uart->clk_src)); + USART_TransferCreateHandle(uart->base, &uart->fsl_handle, usart_transfer_callback, uart); + + hal_uart_start_rx(uart_num); + + return 0; +} + +int +hal_uart_close(int uart_num) +{ + struct hal_uart *uart = fsl_uart(uart_num); + + if (uart == NULL || !uart->u_open) { + return -1; + } + + uart->u_open = 0; + USART_DisableInterrupts(uart->base, kUSART_AllInterruptEnables); + + return 0; +} + +int +hal_uart_init(int uart_num, void *cfg) +{ + struct hal_uart *uart = fsl_uart(uart_num); + + if (uart == NULL) { + return -1; + } + uart->u_configured = 1; + + return 0; +} diff --git a/hw/mcu/nxp/lpc55xx/src/hal_watchdog.c b/hw/mcu/nxp/lpc55xx/src/hal_watchdog.c new file mode 100644 index 0000000000..3e4b775098 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/src/hal_watchdog.c @@ -0,0 +1,56 @@ +/* + * 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. + */ + +#include + +#include + +#ifndef WATCHDOG_STUB +#endif + +int hal_watchdog_init(uint32_t expire_msecs) +{ +#ifndef WATCHDOG_STUB + wwdt_config_t config; + + SYSCON->CLOCK_CTRL |= SYSCON_CLOCK_CTRL_FRO1MHZ_CLK_ENA_MASK; + SYSCON->WDTCLKDIV &= ~SYSCON_WDTCLKDIV_HALT_MASK; + + WWDT_GetDefaultConfig(&config); + config.clockFreq_Hz = 1000000; + config.timeoutValue = expire_msecs * 1000; + WWDT_Init(WWDT, &config); +#endif + + return 0; +} + +void hal_watchdog_enable(void) +{ +#ifndef WATCHDOG_STUB + WWDT_Enable(WWDT); +#endif +} + +void hal_watchdog_tickle(void) +{ +#ifndef WATCHDOG_STUB + WWDT_Refresh(WWDT); +#endif +} diff --git a/hw/mcu/nxp/lpc55xx/syscfg.yml b/hw/mcu/nxp/lpc55xx/syscfg.yml new file mode 100644 index 0000000000..f5011ba016 --- /dev/null +++ b/hw/mcu/nxp/lpc55xx/syscfg.yml @@ -0,0 +1,385 @@ +# 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. +# + +syscfg.defs: + MCU_FLASH_MIN_WRITE_SIZE: + description: > + Specifies the required alignment for internal flash writes. + Used internally by the newt tool. + value: 512 + restrictions: $notnull + + LPC55XX_BOOT_CLOCK: + description: > + Bootclock selection + choices: + - FRO12M + - FROHF96M + - PLL100M + - PLL150M + - PLL1_150M + value: FRO12M + + UART_0: + description: 'Whether to enable UART0 (Flexcomm0)' + value: 0 + UART_0_CLK_SOURCE: + description: 'UART0 (Flexcomm0) clock source' + value: kMAIN_CLK_to_FLEXCOMM0 + UART_0_PIN_TX: + description: 'TX pin for UART0' + value: P0_30_FC0_TXD_SCL_MISO + UART_0_PIN_RX: + description: 'RX pin for UART0' + value: P0_29_FC0_RXD_SDA_MOSI + + UART_1: + description: 'Whether to enable UART1' + value: 0 + UART_1_CLK_SOURCE: + description: 'UART1 (Flexcomm1) clock source' + value: kMAIN_CLK_to_FLEXCOMM1 + UART_1_PIN_TX: + description: 'TX pin for UART1' + value: -1 + UART_1_PIN_RX: + description: 'RX pin for UART1x' + value: -1 + + UART_2: + description: 'Whether to enable UART2' + value: 0 + UART_2_CLK_SOURCE: + description: 'UART2 (Flexcomm2) clock source' + value: kMAIN_CLK_to_FLEXCOMM2 + UART_2_PIN_TX: + description: 'TX pin for UART2' + value: -1 + UART_2_PIN_RX: + description: 'RX pin for UART2' + value: -1 + + UART_3: + description: 'Whether to enable UART3' + value: 0 + UART_3_CLK_SOURCE: + description: 'UART3 (Flexcomm3) clock source' + value: kMAIN_CLK_to_FLEXCOMM3 + UART_3_PIN_TX: + description: 'TX pin for UART3' + value: -1 + UART_3_PIN_RX: + description: 'RX pin for UART3' + value: -1 + + UART_4: + description: 'Whether to enable UART4' + value: 0 + UART_4_CLK_SOURCE: + description: 'UART4 (Flexcomm4) clock source' + value: kMAIN_CLK_to_FLEXCOMM4 + UART_4_PIN_TX: + description: 'TX pin for UART4' + value: -1 + UART_4_PIN_RX: + description: 'RX pin for UART4' + value: -1 + + UART_5: + description: 'Whether to enable UART5' + value: 0 + UART_5_CLK_SOURCE: + description: 'UART5 (Flexcomm5) clock source' + value: kMAIN_CLK_to_FLEXCOMM5 + UART_5_PIN_TX: + description: 'TX pin for UART5' + value: -1 + UART_5_PIN_RX: + description: 'RX pin for UART5' + value: -1 + + UART_6: + description: 'Whether to enable UART6' + value: 0 + UART_6_CLK_SOURCE: + description: 'UART6 (Flexcomm6) clock source' + value: kMAIN_CLK_to_FLEXCOMM6 + UART_6_PIN_TX: + description: 'TX pin for UART6' + value: -1 + UART_6_PIN_RX: + description: 'RX pin for UART6' + value: -1 + + UART_7: + description: 'Whether to enable UART7' + value: 0 + UART_7_CLK_SOURCE: + description: 'UART7 (Flexcomm7) clock source' + value: kMAIN_CLK_to_FLEXCOMM7 + UART_7_PIN_TX: + description: 'TX pin for UART7' + value: -1 + UART_7_PIN_RX: + description: 'RX pin for UART7' + value: -1 + + I2C_0: + description: 'Enable I2C0' + value: 0 + I2C_0_PORT: + description: 'GPIO port for I2C0' + value: PORTB + I2C_0_MUX: + description: 'Pin mux selection for I2C0' + value: kPORT_MuxAlt2 + I2C_0_PIN_SCL: + description: 'SCL pin for I2C_0' + value: 0 + I2C_0_PIN_SDA: + description: 'SDA pin for I2C_0' + value: 1 + I2C_0_FREQ_KHZ: + description: 'Frequency [kHz] for I2C_0' + value: 100 + + I2C_1: + description: 'Enable I2C1.' + value: 0 + I2C_1_PORT: + description: 'GPIO port for I2C1' + value: PORTC + I2C_1_MUX: + description: 'Pin mux selection for I2C1' + value: kPORT_MuxAlt2 + I2C_1_PIN_SCL: + description: 'SCL pin for I2C_1' + value: 10 + I2C_1_PIN_SDA: + description: 'SDA pin for I2C_1' + value: 11 + I2C_1_FREQ_KHZ: + description: 'Frequency [kHz] for I2C_1' + value: 100 + + I2C_2: + description: 'Enable I2C2.' + value: 0 + I2C_2_PORT: + description: 'GPIO port for I2C2' + value: PORTA + I2C_2_MUX: + description: 'Pin mux selection for I2C2' + value: kPORT_MuxAlt4 + I2C_2_PIN_SCL: + description: 'SCL pin for I2C_2' + value: 2 + I2C_2_PIN_SDA: + description: 'SDA pin for I2C_2' + value: 1 + I2C_2_FREQ_KHZ: + description: 'Frequency [kHz] for I2C_2' + value: 100 + + I2C_3: + description: 'Enable I2C3.' + value: 0 + I2C_3_PORT: + description: 'GPIO port for I2C3' + value: PORTA + I2C_3_MUX: + description: 'Pin mux selection for I2C3' + value: kPORT_MuxAlt4 + I2C_3_PIN_SCL: + description: 'SCL pin for I2C_3' + value: 2 + I2C_3_PIN_SDA: + description: 'SDA pin for I2C_3' + value: 1 + I2C_3_FREQ_KHZ: + description: 'Frequency [kHz] for I2C_3' + value: 100 + + SPI_0_MASTER: + description: 'Enable NXP SPI Master 0' + value: 0 + restrictions: + - "!SPI_0_SLAVE" + SPI_0_MASTER_PORT: + description: 'GPIO port for SPI_0_MASTER' + value: PORTA + SPI_0_MASTER_MUX: + description: 'Pin mux selection for SPI_0_MASTER' + value: kPORT_MuxAlt2 + SPI_0_MASTER_PIN_SCK: + description: 'SCK pin for SPI_0_MASTER' + value: 15 + SPI_0_MASTER_PIN_MOSI: + description: 'MOSI pin for SPI_0_MASTER' + value: 16 + SPI_0_MASTER_PIN_MISO: + description: 'MISO pin for SPI_0_MASTER' + value: 17 + + SPI_0_SLAVE: + description: 'Enable NXP SPI Slave 0' + value: 0 + restrictions: + - "!SPI_0_MASTER" + SPI_0_SLAVE_PORT: + description: 'GPIO port for SPI_0_SLAVE' + value: PORTA + SPI_0_SLAVE_MUX: + description: 'Pin mux selection for SPI_0_SLAVE' + value: kPORT_MuxAlt2 + SPI_0_SLAVE_PIN_SCK: + description: 'SCK pin for SPI_0_SLAVE' + value: 15 + SPI_0_SLAVE_PIN_MOSI: + description: 'MOSI pin for SPI_0_SLAVE' + value: 17 + SPI_0_SLAVE_PIN_MISO: + description: 'MISO pin for SPI_0_SLAVE' + value: 16 + SPI_0_SLAVE_PIN_SS: + description: 'SS pin for SPI_0_SLAVE' + value: 14 + + SPI_1_MASTER: + description: 'Enable NXP SPI Master 1' + value: 0 + restrictions: + - "!SPI_1_SLAVE" + SPI_1_MASTER_PORT: + description: 'GPIO port for SPI_1_MASTER' + value: PORTD + SPI_1_MASTER_MUX: + description: 'Pin mux selection for SPI_1_MASTER' + value: kPORT_MuxAlt7 + SPI_1_MASTER_PIN_SCK: + description: 'SCK pin for SPI_1_MASTER' + value: 5 + SPI_1_MASTER_PIN_MOSI: + description: 'MOSI pin for SPI_1_MASTER' + value: 6 + SPI_1_MASTER_PIN_MISO: + description: 'MISO pin for SPI_1_MASTER' + value: 7 + + SPI_1_SLAVE: + description: 'Enable NXP SPI Slave 1' + value: 0 + restrictions: + - "!SPI_1_MASTER" + SPI_1_SLAVE_PORT: + description: 'GPIO port for SPI_0_SLAVE' + value: PORTD + SPI_1_SLAVE_MUX: + description: 'Pin mux selection for SPI_0_SLAVE' + value: kPORT_MuxAlt7 + SPI_1_SLAVE_PIN_SCK: + description: 'SCK pin for SPI_1_SLAVE' + value: 5 + SPI_1_SLAVE_PIN_MOSI: + description: 'MOSI pin for SPI_1_SLAVE' + value: 7 + SPI_1_SLAVE_PIN_MISO: + description: 'MISO pin for SPI_1_SLAVE' + value: 6 + SPI_1_SLAVE_PIN_SS: + description: 'SS pin for SPI_1_SLAVE' + value: 4 + + SPI_2_MASTER: + description: 'Enable NXP SPI Master 2' + value: 0 + restrictions: + - "!SPI_2_SLAVE" + SPI_2_MASTER_PORT: + description: 'GPIO port for SPI_1_MASTER' + value: PORTB + SPI_2_MASTER_MUX: + description: 'Pin mux selection for SPI_1_MASTER' + value: kPORT_MuxAlt2 + SPI_2_MASTER_PIN_SCK: + description: 'SCK pin for SPI_2_MASTER' + value: 21 + SPI_2_MASTER_PIN_MOSI: + description: 'MOSI pin for SPI_2_MASTER' + value: 22 + SPI_2_MASTER_PIN_MISO: + description: 'MISO pin for SPI_2_MASTER' + value: 23 + + SPI_2_SLAVE: + description: 'Enable NXP SPI Slave 2' + value: 0 + restrictions: + - "!SPI_2_MASTER" + SPI_2_SLAVE_PORT: + description: 'GPIO port for SPI_0_SLAVE' + value: PORTB + SPI_2_SLAVE_MUX: + description: 'Pin mux selection for SPI_0_SLAVE' + value: kPORT_MuxAlt2 + SPI_2_SLAVE_PIN_SCK: + description: 'SCK pin for SPI_2_SLAVE' + value: 21 + SPI_2_SLAVE_PIN_MOSI: + description: 'MOSI pin for SPI_2_SLAVE' + value: 23 + SPI_2_SLAVE_PIN_MISO: + description: 'MISO pin for SPI_2_SLAVE' + value: 22 + SPI_2_SLAVE_PIN_SS: + description: 'SS pin for SPI_2_SLAVE' + value: 20 + + CTIMER_AUTO_OFF_COUNT: + description: > + Automatically turn off timer when not in use for number of + overflow events. + value: 1 + TIMER_0: + description: "Whether to enable Timer 0" + value: 1 + TIMER_1: + description: "Whether to enable Timer 1" + value: 0 + TIMER_2: + description: "Whether to enable Timer 2" + value: 0 + TIMER_3: + description: "Whether to enable Timer 3" + value: 0 + TIMER_4: + description: "Whether to enable Timer 4" + value: 0 + +syscfg.vals: + OS_TICKS_PER_SEC: 1000 + MCU_LPCXXXX: 1 + MCUX_DRIVERS_WWDT: 1 + MCUX_DRIVERS_FLEXCOMM: 1 + MCUX_DRIVERS_PINT: 1 + MCUX_DRIVERS_LPC_GPIO: 1 + MCUX_DRIVERS_LPC_IOCON: 1 + MCUX_DRIVERS_LPC_DMA: 1 + MCUX_DRIVERS_IAP1: 1 + MCUX_DRIVERS_COMMON: 1 + MCUX_DRIVERS_CTIMER: 1