diff --git a/boards/ti/lp_em_cc2340r5/Kconfig.lp_em_cc2340r5 b/boards/ti/lp_em_cc2340r5/Kconfig.lp_em_cc2340r5 new file mode 100644 index 0000000000000..fbc90c7ebc8ae --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/Kconfig.lp_em_cc2340r5 @@ -0,0 +1,7 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_LP_EM_CC2340R5 + select SOC_CC2340R5 diff --git a/boards/ti/lp_em_cc2340r5/board.yml b/boards/ti/lp_em_cc2340r5/board.yml new file mode 100644 index 0000000000000..8f51f66196184 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/board.yml @@ -0,0 +1,5 @@ +board: + name: lp_em_cc2340r5 + vendor: ti + socs: + - name: cc2340r5 diff --git a/boards/ti/lp_em_cc2340r5/boosterpack_connector.dtsi b/boards/ti/lp_em_cc2340r5/boosterpack_connector.dtsi new file mode 100644 index 0000000000000..f330b8c1e8233 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/boosterpack_connector.dtsi @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + boosterpack_header: connector { + compatible = "ti,boosterpack-header"; + #gpio-cells = <2>; + gpio-map = <3 0 &gpio0 22 0>, + <4 0 &gpio0 20 0>, + <7 0 &gpio0 18 0>, + <8 0 &gpio0 3 0>, + <9 0 &gpio0 24 0>, + <10 0 &gpio0 0 0>, + + <12 0 &gpio0 9 0>, + <13 0 &gpio0 10 0>, + <14 0 &gpio0 12 0>, + <15 0 &gpio0 13 0>, + <17 0 &gpio0 19 0>, + <18 0 &gpio0 11 0>, + + <23 0 &gpio0 23 0>, + <24 0 &gpio0 25 0>, + <25 0 &gpio0 1 0>, + <26 0 &gpio0 2 0>, + <27 0 &gpio0 5 0>, + <28 0 &gpio0 7 0>, + + <36 0 &gpio0 8 0>, + <37 0 &gpio0 21 0>, + <38 0 &gpio0 6 0>, + <39 0 &gpio0 14 0>, + <40 0 &gpio0 15 0>; + }; +}; diff --git a/boards/ti/lp_em_cc2340r5/doc/img/lp_em_cc2340r5.webp b/boards/ti/lp_em_cc2340r5/doc/img/lp_em_cc2340r5.webp new file mode 100644 index 0000000000000..df225cf6154ef Binary files /dev/null and b/boards/ti/lp_em_cc2340r5/doc/img/lp_em_cc2340r5.webp differ diff --git a/boards/ti/lp_em_cc2340r5/doc/index.rst b/boards/ti/lp_em_cc2340r5/doc/index.rst new file mode 100644 index 0000000000000..c392862ac53e2 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/doc/index.rst @@ -0,0 +1,128 @@ +.. _lp_em_cc2340r5: + +TI CC2340R5 Launchpad +##################### + +Overview +******** + +The Texas Instruments CC2340R5 LaunchPad |trade| (LP_EM_CC2340R5) is a +development kit for the SimpleLink |trade| multi-Standard CC2340R5 wireless MCU. + +See the `TI CC2340R5 LaunchPad Product Page`_ for details. + +.. figure:: img/lp_em_cc2340r5.webp + :align: center + :alt: TI CC2340R5 Launchpad + + Texas Instruments CC2340R5 LaunchPad |trade| + +Hardware +******** + +The CC2340R5 LaunchPad |trade| development kit features the CC2340R5 wireless MCU. +The board is equipped with two LEDs, two push buttons and BoosterPack connectors +for expansion. + +The CC2340R5 wireless MCU has a 48 MHz Arm |reg| Cortex |reg|-M0+ SoC and an +integrated 2.4 GHz transceiver supporting multiple protocols including Bluetooth +|reg| Low Energy and IEEE |reg| 802.15.4. + +See the `TI CC2340R5 Product Page`_ for additional details. + +Supported Features +================== + +The ``lp_em_cc2340r5`` board supports the following hardware features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+----------------------+ +| UART | on-chip | serial port | ++-----------+------------+----------------------+ +| SYSTIM | on-chip | system timer | ++-----------+------------+----------------------+ +| FLASH | on-chip | flash memory | ++-----------+------------+----------------------+ + +Other hardware features have not been enabled yet for this board. + +Connections and IOs +=================== + +All I/O signals are accessible from the BoosterPack connectors. Pin function +aligns with the LaunchPad standard. + ++-------+-----------+---------------------+ +| Pin | Function | Usage | ++=======+===========+=====================+ +| DIO0 | GPIO | | ++-------+-----------+---------------------+ +| DIO1 | ANALOG_IO | A4 | ++-------+-----------+---------------------+ +| DIO2 | ANALOG_IO | A3 | ++-------+-----------+---------------------+ +| DIO5 | ANALOG_IO | A5 | ++-------+-----------+---------------------+ +| DIO6 | SPI_CSN | SPI CS | ++-------+-----------+---------------------+ +| DIO7 | ANALOG_IO | A0 | ++-------+-----------+---------------------+ +| DIO8 | GPIO | | ++-------+-----------+---------------------+ +| DIO9 | GPIO | Button 2 | ++-------+-----------+---------------------+ +| DIO10 | GPIO | Button 1 | ++-------+-----------+---------------------+ +| DIO11 | SPI_CSN | SPI CS | ++-------+-----------+---------------------+ +| DIO12 | SPI_POCI | SPI POCI | ++-------+-----------+---------------------+ +| DIO13 | SPI_PICO | SPI_PICO | ++-------+-----------+---------------------+ +| DIO14 | GPIO | Red LED | ++-------+-----------+---------------------+ +| DIO15 | GPIO | Green LED | ++-------+-----------+---------------------+ +| DIO18 | SPI_CLK | SPI CLK | ++-------+-----------+---------------------+ +| DIO19 | GPIO | | ++-------+-----------+---------------------+ +| DIO20 | UART0_TX | UART TX | ++-------+-----------+---------------------+ +| DIO21 | GPIO | | ++-------+-----------+---------------------+ +| DIO22 | UART0_RX | UART RX | ++-------+-----------+---------------------+ +| DIO23 | ANALOG_IO | A8 | ++-------+-----------+---------------------+ +| DIO24 | ANALOG_IO | A7 | ++-------+-----------+---------------------+ + +Programming and Debugging +************************* + +The LP_EM_CC2340R5 requires an external debug probe such as the LP-XDS110 or +LP-XDS110ET. + +Currently there is no debug support in Zephyr for the LP_EM_CC2340R5, and the +built binaries for this target must be flashed/debugged using either Uniflash +or Code Composer Studio. + +References +********** + +CC2340R5 LaunchPad Quick Start Guide: + https://www.ti.com/lit/pdf/swru588 + +.. _TI CC2340R5 LaunchPad Product Page: + https://www.ti.com/tool/LP-EM-CC2340R5 + +.. _TI CC2340R5 Product Page: + https://www.ti.com/product/CC2340R5 diff --git a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5-pinctrl.dtsi b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5-pinctrl.dtsi new file mode 100644 index 0000000000000..1d929cfa6acaa --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5-pinctrl.dtsi @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* UART0 */ + uart0_tx_default: uart0_tx_default { + pinmux = <20 DIO20_UART0_TXD>; + bias-disable; + }; + uart0_rx_default: uart0_rx_default { + pinmux = <22 DIO22_UART0_RXD>; + bias-disable; + input-enable; + }; +}; diff --git a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts new file mode 100644 index 0000000000000..64d3e15020750 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.dts @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "boosterpack_connector.dtsi" +#include "lp_em_cc2340r5-pinctrl.dtsi" +#include +#include + +/ { + model = "LP_EM_CC2340R5"; + compatible = "ti,lp_em_cc2340r5"; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,code-partition = &slot0_partition; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + }; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &btn0; + sw1 = &btn1; + }; + + leds { + compatible = "gpio-leds"; + + led0: led_0 { + gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + + led1: led_1 { + gpios = <&gpio0 14 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + }; + + keys { + compatible = "gpio-keys"; + + btn0: btn_0 { + gpios = <&gpio0 10 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "Button 1"; + zephyr,code = ; + }; + + btn1: btn_1 { + gpios = <&gpio0 9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "Button 2"; + zephyr,code = ; + }; + }; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_rx_default &uart0_tx_default>; + pinctrl-names = "default"; +}; diff --git a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.yaml b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.yaml new file mode 100644 index 0000000000000..705f3cdef20a7 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5.yaml @@ -0,0 +1,14 @@ +identifier: lp_em_cc2340r5 +name: TI SimpleLink CC2340R5 LaunchPad +type: mcu +arch: arm +ram: 80 +flash: 512 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - uart +vendor: ti diff --git a/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5_defconfig b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5_defconfig new file mode 100644 index 0000000000000..7f9b629c25f38 --- /dev/null +++ b/boards/ti/lp_em_cc2340r5/lp_em_cc2340r5_defconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GPIO=y +CONFIG_SERIAL=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/drivers/flash/CMakeLists.txt b/drivers/flash/CMakeLists.txt index b8b345bb6d96e..50f6498c3a7b9 100644 --- a/drivers/flash/CMakeLists.txt +++ b/drivers/flash/CMakeLists.txt @@ -43,6 +43,7 @@ zephyr_library_sources_ifdef(CONFIG_FLASH_STM32_XSPI flash_stm32_xspi.c) zephyr_library_sources_ifdef(CONFIG_INFINEON_CAT1_QSPI_FLASH flash_ifx_cat1_qspi.c) zephyr_library_sources_ifdef(CONFIG_NORDIC_QSPI_NOR nrf_qspi_nor.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_CC13XX_CC26XX soc_flash_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_CC23X0 soc_flash_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_ESP32 flash_esp32.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_GECKO flash_gecko.c) zephyr_library_sources_ifdef(CONFIG_SOC_FLASH_ITE_IT8XXX2 flash_ite_it8xxx2.c) diff --git a/drivers/flash/Kconfig b/drivers/flash/Kconfig index bc9f6e69d7e35..edfa81224dc39 100644 --- a/drivers/flash/Kconfig +++ b/drivers/flash/Kconfig @@ -171,6 +171,7 @@ source "drivers/flash/Kconfig.b91" source "drivers/flash/Kconfig.cadence_nand" source "drivers/flash/Kconfig.cadence_qspi_nor" source "drivers/flash/Kconfig.cc13xx_cc26xx" +source "drivers/flash/Kconfig.cc23x0" source "drivers/flash/Kconfig.esp32" source "drivers/flash/Kconfig.gd32" source "drivers/flash/Kconfig.gecko" diff --git a/drivers/flash/Kconfig.cc23x0 b/drivers/flash/Kconfig.cc23x0 new file mode 100644 index 0000000000000..0a71900914422 --- /dev/null +++ b/drivers/flash/Kconfig.cc23x0 @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FLASH_CC23X0 + bool "TI SimpleLink CC23x0 flash controller driver" + default y + depends on DT_HAS_TI_CC23X0_FLASH_CONTROLLER_ENABLED + select FLASH_HAS_PAGE_LAYOUT + select FLASH_HAS_DRIVER_ENABLED + select MPU_ALLOW_FLASH_WRITE if ARM_MPU + help + Enables TI SimpleLink CC23x0 flash controller driver. diff --git a/drivers/flash/soc_flash_cc23x0.c b/drivers/flash/soc_flash_cc23x0.c new file mode 100644 index 0000000000000..a3e686fda6b15 --- /dev/null +++ b/drivers/flash/soc_flash_cc23x0.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include +#include + +#define DT_DRV_COMPAT ti_cc23x0_flash_controller +#define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) + +#define FLASH_ADDR DT_REG_ADDR(SOC_NV_FLASH_NODE) +#define FLASH_SIZE DT_REG_SIZE(SOC_NV_FLASH_NODE) +#define FLASH_ERASE_SIZE DT_PROP(SOC_NV_FLASH_NODE, erase_block_size) +#define FLASH_WRITE_SIZE DT_PROP(SOC_NV_FLASH_NODE, write_block_size) + +struct flash_cc23x0_data { + struct k_sem mutex; +}; + +static const struct flash_parameters flash_cc23x0_parameters = { + .write_block_size = FLASH_WRITE_SIZE, + .erase_value = 0xff, +}; + +static int flash_cc23x0_init(const struct device *dev) +{ + struct flash_cc23x0_data *data = dev->data; + + k_sem_init(&data->mutex, 1, 1); + + return 0; +} + +static void flash_cc23x0_cache_restore(uint32_t vims_mode) +{ + while (VIMSModeGet(VIMS_BASE) == VIMS_MODE_CHANGING) { + ; + } + + /* Restore VIMS mode and line buffers */ + if (vims_mode != VIMS_MODE_DISABLED) { + VIMSModeSafeSet(VIMS_BASE, vims_mode, true); + } + + VIMSLineBufEnable(VIMS_BASE); +} + +static uint32_t flash_cc23x0_cache_disable(void) +{ + uint32_t vims_mode; + + /* VIMS and both line buffers should be off during flash update */ + VIMSLineBufDisable(VIMS_BASE); + + while (VIMSModeGet(VIMS_BASE) == VIMS_MODE_CHANGING) { + ; + } + + /* Save current VIMS mode for restoring it later */ + vims_mode = VIMSModeGet(VIMS_BASE); + if (vims_mode != VIMS_MODE_DISABLED) { + VIMSModeSafeSet(VIMS_BASE, VIMS_MODE_DISABLED, true); + } + + return vims_mode; +} + +static int flash_cc23x0_erase(const struct device *dev, off_t offs, size_t size) +{ + struct flash_cc23x0_data *data = dev->data; + uint32_t vims_mode; + unsigned int key; + int i; + int rc = 0; + size_t cnt; + + if (!size) { + return 0; + } + + /* Offset and length should be multiple of erase size */ + if (((offs % FLASH_ERASE_SIZE) != 0) || ((size % FLASH_ERASE_SIZE) != 0)) { + return -EINVAL; + } + + if (k_sem_take(&data->mutex, K_FOREVER)) { + return -EACCES; + } + + vims_mode = flash_cc23x0_cache_disable(); + /* + * Disable all interrupts to prevent flash read, from TI's TRF: + * + * During a FLASH memory write or erase operation, the FLASH memory + * must not be read. + */ + key = irq_lock(); + + /* Erase sector/page one by one, break out in case of an error */ + cnt = size / FLASH_ERASE_SIZE; + for (i = 0; i < cnt; i++, offs += FLASH_ERASE_SIZE) { + while (FlashCheckFsmForReady() != FAPI_STATUS_FSM_READY) { + ; + } + + rc = FlashEraseSector(offs); + if (rc != FAPI_STATUS_SUCCESS) { + rc = -EIO; + break; + } + } + + irq_unlock(key); + + flash_cc23x0_cache_restore(vims_mode); + + k_sem_give(&data->mutex); + return rc; +} + +static int flash_cc23x0_write(const struct device *dev, off_t offs, const void *data, size_t size) +{ + struct flash_cc23x0_data *flash_data = dev->data; + uint32_t vims_mode; + unsigned int key; + int rc = 0; + + if (!size) { + return 0; + } + + if (offs < 0 || size < 1) { + return -EINVAL; + } + + if (offs + size > FLASH_SIZE) { + return -EINVAL; + } + + /* + * From TI's HAL 'driverlib/flash.h': + * + * The pui8DataBuffer pointer can not point to flash. + */ + if ((data >= (void *)FLASH_ADDR) && (data <= (void *)(FLASH_ADDR + FLASH_SIZE))) { + return -EINVAL; + } + + if (k_sem_take(&flash_data->mutex, K_FOREVER)) { + return -EACCES; + } + + vims_mode = flash_cc23x0_cache_disable(); + + key = irq_lock(); + + while (FlashCheckFsmForReady() != FAPI_STATUS_FSM_READY) { + ; + } + + rc = FlashProgram((uint8_t *)data, offs, size); + if (rc != FAPI_STATUS_SUCCESS) { + rc = -EIO; + } + + irq_unlock(key); + + flash_cc23x0_cache_restore(vims_mode); + + k_sem_give(&flash_data->mutex); + + return rc; +} + +static int flash_cc23x0_read(const struct device *dev, off_t offs, void *data, size_t size) +{ + ARG_UNUSED(dev); + + if (!size) { + return 0; + } + + if (offs < 0 || size < 1) { + return -EINVAL; + } + + if (offs + size > FLASH_SIZE) { + return -EINVAL; + } + + memcpy(data, (void *)offs, size); + + return 0; +} + +static const struct flash_parameters *flash_cc23x0_get_parameters(const struct device *dev) +{ + ARG_UNUSED(dev); + + return &flash_cc23x0_parameters; +} + +#if defined(CONFIG_FLASH_PAGE_LAYOUT) +static const struct flash_pages_layout dev_layout = { + .pages_count = FLASH_SIZE / FLASH_ERASE_SIZE, + .pages_size = FLASH_ERASE_SIZE, +}; + +static void flash_cc23x0_layout(const struct device *dev, const struct flash_pages_layout **layout, + size_t *layout_size) +{ + *layout = &dev_layout; + *layout_size = 1; +} +#endif /* CONFIG_FLASH_PAGE_LAYOUT */ + +static const struct flash_driver_api flash_cc23x0_api = { + .erase = flash_cc23x0_erase, + .write = flash_cc23x0_write, + .read = flash_cc23x0_read, + .get_parameters = flash_cc23x0_get_parameters, +#if defined(CONFIG_FLASH_PAGE_LAYOUT) + .page_layout = flash_cc23x0_layout, +#endif +}; + +static struct flash_cc23x0_data cc23x0_flash_data; + +DEVICE_DT_INST_DEFINE(0, flash_cc23x0_init, NULL, &cc23x0_flash_data, NULL, POST_KERNEL, + CONFIG_FLASH_INIT_PRIORITY, &flash_cc23x0_api); diff --git a/drivers/gpio/CMakeLists.txt b/drivers/gpio/CMakeLists.txt index 1cfc120ff28cd..9ab88460ba550 100644 --- a/drivers/gpio/CMakeLists.txt +++ b/drivers/gpio/CMakeLists.txt @@ -17,6 +17,7 @@ zephyr_library_sources_ifdef(CONFIG_GPIO_BCM2711 gpio_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_GPIO_BD8LB600FS gpio_bd8lb600fs.c) zephyr_library_sources_ifdef(CONFIG_GPIO_BRCMSTB gpio_brcmstb.c) zephyr_library_sources_ifdef(CONFIG_GPIO_CC13XX_CC26XX gpio_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_GPIO_CC23X0 gpio_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_GPIO_CC32XX gpio_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_GPIO_CMSDK_AHB gpio_cmsdk_ahb.c) zephyr_library_sources_ifdef(CONFIG_GPIO_CY8C95XX gpio_cy8c95xx.c) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 668691de9276d..66e7a0641512e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -107,6 +107,7 @@ source "drivers/gpio/Kconfig.bcm2711" source "drivers/gpio/Kconfig.bd8lb600fs" source "drivers/gpio/Kconfig.brcmstb" source "drivers/gpio/Kconfig.cc13xx_cc26xx" +source "drivers/gpio/Kconfig.cc23x0" source "drivers/gpio/Kconfig.cc32xx" source "drivers/gpio/Kconfig.cmsdk_ahb" source "drivers/gpio/Kconfig.creg_gpio" diff --git a/drivers/gpio/Kconfig.cc23x0 b/drivers/gpio/Kconfig.cc23x0 new file mode 100644 index 0000000000000..147fd029cf2cd --- /dev/null +++ b/drivers/gpio/Kconfig.cc23x0 @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config GPIO_CC23X0 + bool "TI SimpleLink CC23X0 GPIO driver" + default y + depends on DT_HAS_TI_CC23X0_GPIO_ENABLED + help + Enable the TI SimpleLink CC23x0 GPIO driver. diff --git a/drivers/gpio/gpio_cc23x0.c b/drivers/gpio/gpio_cc23x0.c new file mode 100644 index 0000000000000..643766e255d29 --- /dev/null +++ b/drivers/gpio/gpio_cc23x0.c @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_cc23x0_gpio + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define IOC_ADDR(index) (IOC_BASE + IOC_O_IOC0 + (sizeof(uint32_t) * (index))) + +struct gpio_cc23x0_config { + /* gpio_driver_config needs to be first */ + struct gpio_driver_config common; +}; + +struct gpio_cc23x0_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data common; + sys_slist_t callbacks; +}; + +static void set_pin_mask_non_atomic(uint8_t index, uint32_t registerBaseAddress) +{ + GPIOSetConfigDio(GPIO_BASE + registerBaseAddress, BIT(index)); +} + +static int gpio_cc23x0_config(const struct device *port, gpio_pin_t pin, gpio_flags_t flags) +{ + uint32_t config = 0; + uint32_t iocfg_reg = IOC_ADDR(pin); + gpio_flags_t direction = flags & GPIO_DIR_MASK; + + if (flags & GPIO_PULL_UP) { + config |= IOC_IOC0_PULLCTL_PULL_UP; + } else if (flags & GPIO_PULL_DOWN) { + config |= IOC_IOC0_PULLCTL_PULL_DOWN; + } else { + config |= IOC_IOC0_PULLCTL_PULL_DIS; + } + + if (!(flags & GPIO_SINGLE_ENDED)) { + config |= IOC_IOC0_IOMODE_NORMAL; + } else { + if (flags & GPIO_LINE_OPEN_DRAIN) { + config |= IOC_IOC0_IOMODE_OPEND; + } else { + config |= IOC_IOC0_IOMODE_OPENS; + } + } + if (direction & GPIO_INPUT) { + config |= IOC_IOC0_INPEN_EN | IOC_IOC0_HYSTEN_EN; + } + + GPIOSetConfigDio(iocfg_reg, config); + + if (flags & GPIO_OUTPUT) { + if (flags & GPIO_OUTPUT_INIT_HIGH) { + GPIOSetDio(pin); + } else if (flags & GPIO_OUTPUT_INIT_LOW) { + GPIOClearDio(pin); + } + GPIOSetOutputEnableDio(pin, GPIO_OUTPUT_ENABLE); + } else { + GPIOSetOutputEnableDio(pin, GPIO_OUTPUT_DISABLE); + } + return 0; +} + +#ifdef CONFIG_GPIO_GET_CONFIG +static int gpio_cc23x0_get_config(const struct device *port, gpio_pin_t pin, gpio_flags_t *flags) +{ + uint32_t out_flag = 0; + uint32_t iocfg_reg = IOC_ADDR(pin); + uint32_t config = GPIOGetConfigDio(iocfg_reg); + + /* GPIO input/output configuration flags */ + if (config & IOC_IOC0_INPEN_EN) { + out_flag |= GPIO_INPUT; + } + + if (GPIOGetOutputEnableDio(pin)) { + out_flag |= GPIO_OUTPUT; + + if (GPIOReadDio(pin)) { + out_flag |= GPIO_OUTPUT_INIT_HIGH; + } else { + /* This is the default value. If not explicitly set, + * the returned config will not be symmetric + */ + out_flag |= GPIO_OUTPUT_INIT_LOW; + } + } + + /* GPIO interrupt configuration flags */ + if ((config & IOC_IOC0_EDGEDET_M) != IOC_IOC0_EDGEDET_EDGE_DIS) { + if (config & IOC_IOC0_EDGEDET_EDGE_POS) { + out_flag |= GPIO_INT_EDGE_RISING; + } + + if (config & IOC_IOC0_EDGEDET_EDGE_NEG) { + out_flag |= GPIO_INT_EDGE_FALLING; + } + } else { + /* This is the default value. If not explicitly set, + * the returned config will not be symmetric + */ + out_flag |= GPIO_INT_DISABLE; + } + + /* GPIO pin drive flags */ + if (config & IOC_IOC0_IOMODE_OPENS) { + out_flag |= GPIO_OPEN_SOURCE; + } + + if (config & IOC_IOC0_IOMODE_OPEND) { + out_flag |= IOC_IOC0_IOMODE_OPEND; + } + + if (config & IOC_IOC0_PULLCTL_PULL_UP) { + out_flag |= GPIO_PULL_UP; + } + + if (config & IOC_IOC0_PULLCTL_PULL_DOWN) { + out_flag |= GPIO_PULL_DOWN; + } + + *flags = out_flag; + + return 0; +} +#endif + +static int gpio_cc23x0_port_get_raw(const struct device *port, uint32_t *value) +{ + *value = GPIOReadMultiDio(GPIO_DIO_ALL_MASK); + + return 0; +} + +static int gpio_cc23x0_port_set_masked_raw(const struct device *port, uint32_t mask, uint32_t value) +{ + GPIOWriteMultiDio(mask, value); + + return 0; +} + +static int gpio_cc23x0_port_set_bits_raw(const struct device *port, uint32_t mask) +{ + GPIOSetMultiDio(mask); + + return 0; +} + +static int gpio_cc23x0_port_clear_bits_raw(const struct device *port, uint32_t mask) +{ + GPIOClearMultiDio(mask); + + return 0; +} + +static int gpio_cc23x0_port_toggle_bits(const struct device *port, uint32_t mask) +{ + GPIOToggleMultiDio(mask); + + return 0; +} + +static int gpio_cc23x0xx_pin_interrupt_configure(const struct device *port, gpio_pin_t pin, + enum gpio_int_mode mode, enum gpio_int_trig trig) +{ + if (mode == GPIO_INT_MODE_LEVEL) { + return ENOTSUP; + } + + uint32_t config = GPIOGetConfigDio(IOC_ADDR(pin)) & ~IOC_IOC0_EDGEDET_M; + + if (mode == GPIO_INT_MODE_DISABLED) { + config |= IOC_IOC1_EDGEDET_EDGE_DIS; + + GPIOSetConfigDio(IOC_ADDR(pin), config); + + /* Disable interrupt mask */ + set_pin_mask_non_atomic(pin, GPIO_O_IMCLR); + + } else if (mode == GPIO_INT_MODE_EDGE) { + switch (trig) { + case GPIO_INT_TRIG_LOW: + config |= IOC_IOC1_EDGEDET_EDGE_NEG; + break; + case GPIO_INT_TRIG_HIGH: + config |= IOC_IOC1_EDGEDET_EDGE_POS; + break; + case GPIO_INT_TRIG_BOTH: + config |= IOC_IOC1_EDGEDET_EDGE_BOTH; + break; + default: + return ENOTSUP; + } + + GPIOSetConfigDio(IOC_ADDR(pin), config); + + /* Enable interrupt mask */ + set_pin_mask_non_atomic(pin, GPIO_O_ICLR); + set_pin_mask_non_atomic(pin, GPIO_O_IMSET); + } + + return 0; +} + +static int gpio_cc23x0_manage_callback(const struct device *port, struct gpio_callback *callback, + bool set) +{ + struct gpio_cc23x0_data *data = port->data; + + return gpio_manage_callback(&data->callbacks, callback, set); +} + +static uint32_t gpio_cc23x0_get_pending_int(const struct device *dev) +{ + return GPIOGetEventMultiDio(GPIO_DIO_ALL_MASK); +} + +static void gpio_cc23x0_isr(const struct device *dev) +{ + struct gpio_cc23x0_data *data = dev->data; + + uint32_t status = GPIOGetEventMultiDio(GPIO_DIO_ALL_MASK); + + GPIOClearEventMultiDio(status); + + gpio_fire_callbacks(&data->callbacks, dev, status); +} + +static int gpio_cc23x0_init(const struct device *dev) +{ + /* Enable GPIO domain clock */ + CLKCTLEnable(CLKCTL_BASE, CLKCTL_GPIO); + + /* Enable IRQ */ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), gpio_cc23x0_isr, + DEVICE_DT_INST_GET(0), 0); + + irq_enable(DT_INST_IRQN(0)); + + return 0; +} + +static const struct gpio_driver_api gpio_cc23x0_driver_api = { + .pin_configure = gpio_cc23x0_config, +#ifdef CONFIG_GPIO_GET_CONFIG + .pin_get_config = gpio_cc23x0_get_config, +#endif + .port_get_raw = gpio_cc23x0_port_get_raw, + .port_set_masked_raw = gpio_cc23x0_port_set_masked_raw, + .port_set_bits_raw = gpio_cc23x0_port_set_bits_raw, + .port_clear_bits_raw = gpio_cc23x0_port_clear_bits_raw, + .port_toggle_bits = gpio_cc23x0_port_toggle_bits, + .pin_interrupt_configure = gpio_cc23x0xx_pin_interrupt_configure, + .manage_callback = gpio_cc23x0_manage_callback, + .get_pending_int = gpio_cc23x0_get_pending_int, +}; + +static const struct gpio_cc23x0_config gpio_cc23x0_config_0 = { + .common = {/* Read ngpios from DT */ + .port_pin_mask = GPIO_PORT_PIN_MASK_FROM_DT_INST(0)}}; + +static struct gpio_cc23x0_data gpio_cc23x0_data_0; + +DEVICE_DT_INST_DEFINE(0, gpio_cc23x0_init, NULL, &gpio_cc23x0_data_0, &gpio_cc23x0_config_0, + PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, &gpio_cc23x0_driver_api); diff --git a/drivers/pinctrl/CMakeLists.txt b/drivers/pinctrl/CMakeLists.txt index e56922d083ebe..ee17efc789fb1 100644 --- a/drivers/pinctrl/CMakeLists.txt +++ b/drivers/pinctrl/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_PINCTRL_IMX pinctrl_imx.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_SIFIVE pinctrl_sifive.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_NXP_IOCON pinctrl_lpc_iocon.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_CC13XX_CC26XX pinctrl_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_PINCTRL_CC23X0 pinctrl_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_ESP32 pinctrl_esp32.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_RV32M1 pinctrl_rv32m1.c) zephyr_library_sources_ifdef(CONFIG_PINCTRL_INFINEON_CAT1 pinctrl_ifx_cat1.c) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 299372eea7f6b..44bd890564355 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -50,6 +50,7 @@ source "drivers/pinctrl/Kconfig.imx" source "drivers/pinctrl/Kconfig.sifive" source "drivers/pinctrl/Kconfig.lpc_iocon" source "drivers/pinctrl/Kconfig.cc13xx_cc26xx" +source "drivers/pinctrl/Kconfig.cc23x0" source "drivers/pinctrl/Kconfig.esp32" source "drivers/pinctrl/Kconfig.rv32m1" source "drivers/pinctrl/Kconfig.ifx_cat1" diff --git a/drivers/pinctrl/Kconfig.cc23x0 b/drivers/pinctrl/Kconfig.cc23x0 new file mode 100644 index 0000000000000..f10e2215aa05e --- /dev/null +++ b/drivers/pinctrl/Kconfig.cc23x0 @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config PINCTRL_CC23X0 + bool "TI SimpleLink CC23X0 pinctrl driver" + default y + depends on DT_HAS_TI_CC23X0_PINCTRL_ENABLED + help + Enable the TI SimpleLink CC23X0 pinctrl driver diff --git a/drivers/pinctrl/pinctrl_cc23x0.c b/drivers/pinctrl/pinctrl_cc23x0.c new file mode 100644 index 0000000000000..41ce0be662e97 --- /dev/null +++ b/drivers/pinctrl/pinctrl_cc23x0.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_cc23x0_pinctrl + +#include + +#include + +#define IOC_BASE_REG DT_REG_ADDR(DT_NODELABEL(pinctrl)) +#define IOC_BASE_PIN_REG 0x00000100 +#define IOC_ADDR(index) (IOC_BASE_REG + IOC_BASE_PIN_REG + (sizeof(uint32_t) * (index))) + +static int pinctrl_cc23x0_set(uint32_t pin, uint32_t func, uint32_t mode) +{ + uint32_t iocfg_reg = IOC_ADDR(pin); + + HWREG(iocfg_reg) = mode | func; + + return 0; +} + +int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt, uintptr_t reg) +{ + ARG_UNUSED(reg); + + for (uint8_t i = 0U; i < pin_cnt; i++) { + pinctrl_cc23x0_set(pins[i].pin, pins[i].iofunc, pins[i].iomode); + } + + return 0; +} diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 8aeea35684b25..6c55d9d11247d 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_APBUART uart_apbuart.c) zephyr_library_sources_ifdef(CONFIG_UART_BCM2711_MU uart_bcm2711.c) zephyr_library_sources_ifdef(CONFIG_UART_BT uart_bt.c) zephyr_library_sources_ifdef(CONFIG_UART_CC13XX_CC26XX uart_cc13xx_cc26xx.c) +zephyr_library_sources_ifdef(CONFIG_UART_CC23X0 uart_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_UART_CC32XX uart_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_UART_CDNS uart_cdns.c) zephyr_library_sources_ifdef(CONFIG_UART_CMSDK_APB uart_cmsdk_apb.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 2b1ff32c56622..92e68f90741f2 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -164,6 +164,7 @@ rsource "Kconfig.b91" rsource "Kconfig.bcm2711" rsource "Kconfig.bt" rsource "Kconfig.cc13xx_cc26xx" +rsource "Kconfig.cc23x0" rsource "Kconfig.cc32xx" rsource "Kconfig.cdns" rsource "Kconfig.cmsdk_apb" diff --git a/drivers/serial/Kconfig.cc23x0 b/drivers/serial/Kconfig.cc23x0 new file mode 100644 index 0000000000000..e285ee14671a8 --- /dev/null +++ b/drivers/serial/Kconfig.cc23x0 @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config UART_CC23X0 + bool "TI SimpleLink CC23x0 UART driver" + default y + depends on DT_HAS_TI_CC23X0_UART_ENABLED + select SERIAL_HAS_DRIVER + select SERIAL_SUPPORT_INTERRUPT + select PINCTRL + help + Enable the TI SimpleLink CC23x0 UART driver. diff --git a/drivers/serial/uart_cc23x0.c b/drivers/serial/uart_cc23x0.c new file mode 100644 index 0000000000000..5576871aacac7 --- /dev/null +++ b/drivers/serial/uart_cc23x0.c @@ -0,0 +1,405 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_cc23x0_uart + +#include +#include +#include +#include + +#include + +#include +#include + +struct uart_cc23x0_config { + uint32_t reg; + uint32_t sys_clk_freq; + const struct pinctrl_dev_config *pcfg; +}; + +struct uart_cc23x0_data { + struct uart_config uart_config; +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + uart_irq_callback_user_data_t callback; + void *user_data; +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +static int uart_cc23x0_poll_in(const struct device *dev, unsigned char *c) +{ + const struct uart_cc23x0_config *config = dev->config; + + if (!UARTCharAvailable(config->reg)) { + return -1; + } + + *c = UARTGetCharNonBlocking(config->reg); + + return 0; +} + +static void uart_cc23x0_poll_out(const struct device *dev, unsigned char c) +{ + const struct uart_cc23x0_config *config = dev->config; + + UARTPutChar(config->reg, c); +} + +static int uart_cc23x0_err_check(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + uint32_t flags = UARTGetRxError(config->reg); + int error = 0; + + error |= (flags & UART_RXERROR_FRAMING) ? UART_ERROR_FRAMING : 0; + error |= (flags & UART_RXERROR_PARITY) ? UART_ERROR_PARITY : 0; + error |= (flags & UART_RXERROR_BREAK) ? UART_BREAK : 0; + error |= (flags & UART_RXERROR_OVERRUN) ? UART_ERROR_OVERRUN : 0; + + UARTClearRxError(config->reg); + + return error; +} + +static int uart_cc23x0_configure(const struct device *dev, const struct uart_config *cfg) +{ + const struct uart_cc23x0_config *config = dev->config; + struct uart_cc23x0_data *data = dev->data; + uint32_t line_ctrl = 0; + bool flow_ctrl; + + switch (cfg->parity) { + case UART_CFG_PARITY_NONE: + line_ctrl |= UART_CONFIG_PAR_NONE; + break; + case UART_CFG_PARITY_ODD: + line_ctrl |= UART_CONFIG_PAR_ODD; + break; + case UART_CFG_PARITY_EVEN: + line_ctrl |= UART_CONFIG_PAR_EVEN; + break; + case UART_CFG_PARITY_MARK: + line_ctrl |= UART_CONFIG_PAR_ONE; + break; + case UART_CFG_PARITY_SPACE: + line_ctrl |= UART_CONFIG_PAR_ZERO; + break; + default: + return -EINVAL; + } + + switch (cfg->stop_bits) { + case UART_CFG_STOP_BITS_1: + line_ctrl |= UART_CONFIG_STOP_ONE; + break; + case UART_CFG_STOP_BITS_2: + line_ctrl |= UART_CONFIG_STOP_TWO; + break; + case UART_CFG_STOP_BITS_0_5: + case UART_CFG_STOP_BITS_1_5: + return -ENOTSUP; + default: + return -EINVAL; + } + + switch (cfg->data_bits) { + case UART_CFG_DATA_BITS_5: + line_ctrl |= UART_CONFIG_WLEN_5; + break; + case UART_CFG_DATA_BITS_6: + line_ctrl |= UART_CONFIG_WLEN_6; + break; + case UART_CFG_DATA_BITS_7: + line_ctrl |= UART_CONFIG_WLEN_7; + break; + case UART_CFG_DATA_BITS_8: + line_ctrl |= UART_CONFIG_WLEN_8; + break; + default: + return -EINVAL; + } + + switch (cfg->flow_ctrl) { + case UART_CFG_FLOW_CTRL_NONE: + flow_ctrl = false; + break; + case UART_CFG_FLOW_CTRL_RTS_CTS: + flow_ctrl = true; + break; + case UART_CFG_FLOW_CTRL_DTR_DSR: + return -ENOTSUP; + default: + return -EINVAL; + } + + /* Disables UART before setting control registers */ + UARTConfigSetExpClk(config->reg, config->sys_clk_freq, cfg->baudrate, line_ctrl); + + if (flow_ctrl) { + UARTEnableCTS(config->reg); + UARTEnableRTS(config->reg); + } else { + UARTDisableCTS(config->reg); + UARTDisableRTS(config->reg); + } + + /* Re-enable UART */ + UARTEnable(config->reg); + + /* Make use of the FIFO to reduce chances of data being lost */ + UARTEnableFifo(config->reg); + + data->uart_config = *cfg; + + return 0; +} + +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE +static int uart_cc23x0_config_get(const struct device *dev, struct uart_config *cfg) +{ + const struct uart_cc23x0_data *data = dev->data; + + *cfg = data->uart_config; + return 0; +} +#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + +static int uart_cc23x0_fifo_fill(const struct device *dev, const uint8_t *buf, int len) +{ + const struct uart_cc23x0_config *config = dev->config; + int n = 0; + + while (n < len) { + if (!UARTSpaceAvailable(config->reg)) { + break; + } + UARTPutCharNonBlocking(config->reg, buf[n]); + n++; + } + + return n; +} + +static int uart_cc23x0_fifo_read(const struct device *dev, uint8_t *buf, const int len) +{ + const struct uart_cc23x0_config *config = dev->config; + int c, n; + + n = 0; + while (n < len) { + if (!UARTCharAvailable(config->reg)) { + break; + } + c = UARTGetCharNonBlocking(config->reg); + buf[n++] = c; + } + + return n; +} + +static void uart_cc23x0_irq_tx_enable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + UARTEnableInt(config->reg, UART_INT_TX); +} + +static void uart_cc23x0_irq_tx_disable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + UARTDisableInt(config->reg, UART_INT_TX); +} + +static int uart_cc23x0_irq_tx_ready(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTSpaceAvailable(config->reg) ? 1 : 0; +} + +static void uart_cc23x0_irq_rx_enable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + /* Trigger the ISR on both RX and Receive Timeout. This is to allow + * the use of the hardware FIFOs for more efficient operation + */ + UARTEnableInt(config->reg, UART_INT_RX | UART_INT_RT); +} + +static void uart_cc23x0_irq_rx_disable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + UARTDisableInt(config->reg, UART_INT_RX | UART_INT_RT); +} + +static int uart_cc23x0_irq_tx_complete(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTBusy(config->reg) ? 0 : 1; +} + +static int uart_cc23x0_irq_rx_ready(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTCharAvailable(config->reg) ? 1 : 0; +} + +static void uart_cc23x0_irq_err_enable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTEnableInt(config->reg, UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE); +} + +static void uart_cc23x0_irq_err_disable(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + return UARTDisableInt(config->reg, UART_INT_OE | UART_INT_BE | UART_INT_PE | UART_INT_FE); +} + +static int uart_cc23x0_irq_is_pending(const struct device *dev) +{ + const struct uart_cc23x0_config *config = dev->config; + + /* Read masked interrupt status */ + uint32_t status = UARTIntStatus(config->reg, true); + + return status ? 1 : 0; +} + +static int uart_cc23x0_irq_update(const struct device *dev) +{ + ARG_UNUSED(dev); + return 1; +} + +static void uart_cc23x0_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb, + void *user_data) +{ + struct uart_cc23x0_data *data = dev->data; + + data->callback = cb; + data->user_data = user_data; +} + +static void uart_cc23x0_isr(const struct device *dev) +{ + struct uart_cc23x0_data *data = dev->data; + + if (data->callback) { + data->callback(dev, data->user_data); + } +} + +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +static const struct uart_driver_api uart_cc23x0_driver_api = { + .poll_in = uart_cc23x0_poll_in, + .poll_out = uart_cc23x0_poll_out, + .err_check = uart_cc23x0_err_check, +#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE + .configure = uart_cc23x0_configure, + .config_get = uart_cc23x0_config_get, +#endif +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + .fifo_fill = uart_cc23x0_fifo_fill, + .fifo_read = uart_cc23x0_fifo_read, + .irq_tx_enable = uart_cc23x0_irq_tx_enable, + .irq_tx_disable = uart_cc23x0_irq_tx_disable, + .irq_tx_ready = uart_cc23x0_irq_tx_ready, + .irq_rx_enable = uart_cc23x0_irq_rx_enable, + .irq_rx_disable = uart_cc23x0_irq_rx_disable, + .irq_tx_complete = uart_cc23x0_irq_tx_complete, + .irq_rx_ready = uart_cc23x0_irq_rx_ready, + .irq_err_enable = uart_cc23x0_irq_err_enable, + .irq_err_disable = uart_cc23x0_irq_err_disable, + .irq_is_pending = uart_cc23x0_irq_is_pending, + .irq_update = uart_cc23x0_irq_update, + .irq_callback_set = uart_cc23x0_irq_callback_set, +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +}; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN +#define UART_CC23X0_IRQ_CFG(n) \ + do { \ + UARTClearInt(config->reg, UART_INT_RX); \ + UARTClearInt(config->reg, UART_INT_RT); \ + \ + IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), uart_cc23x0_isr, \ + DEVICE_DT_INST_GET(n), 0); \ + irq_enable(DT_INST_IRQN(n)); \ + } while (false) + +#define UART_CC23X0_INT_FIELDS .callback = NULL, .user_data = NULL, +#else +#define UART_CC23X0_IRQ_CFG(n) +#define UART_CC23X0_INT_FIELDS +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ + +#define UART_CC23X0_DEVICE_DEFINE(n) \ + \ + DEVICE_DT_INST_DEFINE(n, uart_cc23x0_init_##n, NULL, &uart_cc23x0_data_##n, \ + &uart_cc23x0_config_##n, PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ + &uart_cc23x0_driver_api) + +#define UART_CC23X0_INIT_FUNC(n) \ + static int uart_cc23x0_init_##n(const struct device *dev) \ + { \ + const struct uart_cc23x0_config *config = dev->config; \ + struct uart_cc23x0_data *data = dev->data; \ + int ret; \ + \ + CLKCTLEnable(CLKCTL_BASE, CLKCTL_UART0); \ + \ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); \ + if (ret < 0) { \ + return ret; \ + } \ + \ + /* Configure and enable UART */ \ + ret = uart_cc23x0_configure(dev, &data->uart_config); \ + \ + /* Enable interrupts */ \ + UART_CC23X0_IRQ_CFG(n); \ + \ + return ret; \ + } + +#define UART_CC23X0_INIT(n) \ + PINCTRL_DT_INST_DEFINE(n); \ + UART_CC23X0_INIT_FUNC(n); \ + \ + static struct uart_cc23x0_config uart_cc23x0_config_##n = { \ + .reg = DT_INST_REG_ADDR(n), \ + .sys_clk_freq = DT_INST_PROP_BY_PHANDLE(n, clocks, clock_frequency), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ + }; \ + \ + static struct uart_cc23x0_data uart_cc23x0_data_##n = { \ + .uart_config = \ + { \ + .baudrate = DT_INST_PROP(n, current_speed), \ + .parity = DT_INST_ENUM_IDX(n, parity), \ + .stop_bits = DT_INST_ENUM_IDX(n, stop_bits), \ + .data_bits = DT_INST_ENUM_IDX(n, data_bits), \ + .flow_ctrl = DT_INST_PROP(n, hw_flow_control), \ + }, \ + UART_CC23X0_INT_FIELDS \ + }; \ + UART_CC23X0_DEVICE_DEFINE(n); + +DT_INST_FOREACH_STATUS_OKAY(UART_CC23X0_INIT) diff --git a/drivers/timer/CMakeLists.txt b/drivers/timer/CMakeLists.txt index 51b0e552f4a41..9a6b2697e988c 100644 --- a/drivers/timer/CMakeLists.txt +++ b/drivers/timer/CMakeLists.txt @@ -12,6 +12,7 @@ zephyr_library_sources_ifdef(CONFIG_ARCV2_TIMER arcv2_timer0.c) zephyr_library_sources_ifdef(CONFIG_ARM_ARCH_TIMER arm_arch_timer.c) zephyr_library_sources_ifdef(CONFIG_INTEL_ADSP_TIMER intel_adsp_timer.c) zephyr_library_sources_ifdef(CONFIG_CC13XX_CC26XX_RTC_TIMER cc13xx_cc26xx_rtc_timer.c) +zephyr_library_sources_ifdef(CONFIG_CC23X0_SYSTIM_TIMER cc23x0_systim_timer.c) zephyr_library_sources_ifdef(CONFIG_CH32V00X_SYSTICK wch_systick_ch32v00x.c) zephyr_library_sources_ifdef(CONFIG_CORTEX_M_SYSTICK cortex_m_systick.c) zephyr_library_sources_ifdef(CONFIG_ESP32_SYS_TIMER esp32_sys_timer.c) diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index f017589a60e18..839dec71fa26b 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -70,6 +70,7 @@ source "drivers/timer/Kconfig.arcv2" source "drivers/timer/Kconfig.arm_arch" source "drivers/timer/Kconfig.cavs" source "drivers/timer/Kconfig.cc13xx_cc26xx_rtc" +source "drivers/timer/Kconfig.cc23x0_systim" source "drivers/timer/Kconfig.wch_ch32v00x" source "drivers/timer/Kconfig.cortex_m_systick" source "drivers/timer/Kconfig.esp32" diff --git a/drivers/timer/Kconfig.cc23x0_systim b/drivers/timer/Kconfig.cc23x0_systim new file mode 100644 index 0000000000000..41db73e6d52c6 --- /dev/null +++ b/drivers/timer/Kconfig.cc23x0_systim @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config CC23X0_SYSTIM_TIMER + bool "TI SimpleLink CC23X0 system clock timer" + default y + depends on HAS_CC23X0_SDK + select TICKLESS_CAPABLE + help + This module provides the "system clock driver" interfaces + for the TI Simplelink CC23X0 devices. diff --git a/drivers/timer/cc23x0_systim_timer.c b/drivers/timer/cc23x0_systim_timer.c new file mode 100644 index 0000000000000..1bc264ba179b2 --- /dev/null +++ b/drivers/timer/cc23x0_systim_timer.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_cc23x0_systim_timer + +/* + * TI SimpleLink CC23X0 timer driver based on SYSTIM + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* Kernel tick period in microseconds (same timebase as systim) */ +#define TICK_PERIOD_MICRO_SEC (1000000 / CONFIG_SYS_CLOCK_TICKS_PER_SEC) + +/* + * Max number of systim ticks into the future + * + * Under the hood, the kernel timer uses the SysTimer whose events trigger + * immediately if the compare value is less than 2^22 systimer ticks in the past + * (4.194sec at 1us resolution). Therefore, the max number of SysTimer ticks you + * can schedule into the future is 2^32 - 2^22 - 1 ticks (~= 4290 sec at 1us + * resolution). + */ +#define SYSTIM_TIMEOUT_MAX 0xFFBFFFFFU + +/* Set systim interrupt to lowest priority */ +#define SYSTIM_ISR_PRIORITY 3U + +/* Keep track of systim counter at previous announcement to the kernel */ +static uint32_t last_systim_count; + +static void systim_isr(const void *arg); +static int sys_clock_driver_init(void); + +/* + * Set system clock timeout. + */ +void sys_clock_set_timeout(int32_t ticks, bool idle) +{ + ARG_UNUSED(idle); + + /* If timeout is necessary */ + if (ticks != K_TICKS_FOREVER) { + /* Get current value as early as possible */ + uint32_t now_tick = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); + uint32_t timeout = ticks * TICK_PERIOD_MICRO_SEC; + + if (timeout > SYSTIM_TIMEOUT_MAX) { + timeout = SYSTIM_TIMEOUT_MAX; + } + /* This should wrap around */ + HWREG(SYSTIM_BASE + SYSTIM_O_CH0CC) = now_tick + timeout; + } +} + +uint32_t sys_clock_elapsed(void) +{ + /* Get current value as early as possible */ + uint32_t current_systim_count = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); + uint32_t elapsed_systim; + + if (current_systim_count >= last_systim_count) { + elapsed_systim = current_systim_count - last_systim_count; + } else { + elapsed_systim = (UINT32_MAX - last_systim_count) + current_systim_count; + } + + int32_t elapsed_ticks = elapsed_systim / TICK_PERIOD_MICRO_SEC; + + return elapsed_ticks; +} + +uint32_t sys_clock_cycle_get_32(void) +{ + return HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); +} + +void systim_isr(const void *arg) +{ + /* Get current value as early as possible */ + uint32_t current_systim_count = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); + uint32_t elapsed_systim; + + if (current_systim_count >= last_systim_count) { + elapsed_systim = current_systim_count - last_systim_count; + } else { + elapsed_systim = (UINT32_MAX - last_systim_count) + current_systim_count; + } + + int32_t elapsed_ticks = elapsed_systim / TICK_PERIOD_MICRO_SEC; + + sys_clock_announce(elapsed_ticks); + + last_systim_count = current_systim_count; + + /* Do not re-arm systim. Zephyr will do so through sys_clock_set_timeout */ +} + +static int sys_clock_driver_init(void) +{ + uint32_t now_tick; + + /* Get current value as early as possible */ + now_tick = HWREG(SYSTIM_BASE + SYSTIM_O_TIME1U); + last_systim_count = now_tick; + + /* Clear any pending interrupts on SysTimer channel 0 */ + HWREG(SYSTIM_BASE + SYSTIM_O_ICLR) = SYSTIM_ICLR_EV0_CLR; + + /* + * Configure SysTimer channel 0 to compare mode with timer + * resolution of 1 us. + */ + HWREG(SYSTIM_BASE + SYSTIM_O_CH0CFG) = 0; + + /* Make SysTimer halt on CPU debug halt */ + HWREG(SYSTIM_BASE + SYSTIM_O_EMU) = SYSTIM_EMU_HALT_STOP; + + HWREG(EVTSVT_BASE + EVTSVT_O_CPUIRQ16SEL) = EVTSVT_CPUIRQ16SEL_PUBID_SYSTIM0; + + /* + * Set IMASK for channel 0. IMASK is used by the power driver to know + * which systimer channels are active. + */ + HWREG(SYSTIM_BASE + SYSTIM_O_IMSET) = SYSTIM_IMSET_EV0_SET; + + /* This should wrap around and set a maximum timeout */ + HWREG(SYSTIM_BASE + SYSTIM_O_CH0CC) = now_tick + SYSTIM_TIMEOUT_MAX; + + /* Take configurable interrupt IRQ16 for systimer */ + IRQ_CONNECT(CPUIRQ16_IRQn, SYSTIM_ISR_PRIORITY, systim_isr, 0, 0); + irq_enable(CPUIRQ16_IRQn); + + return 0; +} + +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/dts/arm/ti/cc2340r5.dtsi b/dts/arm/ti/cc2340r5.dtsi new file mode 100644 index 0000000000000..c275b2e1de8a9 --- /dev/null +++ b/dts/arm/ti/cc2340r5.dtsi @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + sram0: memory@20000000 { + reg = <0x20000000 DT_SIZE_K(36)>; + }; +}; + +/* Main flash */ +&flash0 { + reg = <0x0 DT_SIZE_K(512)>; + #address-cells = <1>; + #size-cells = <1>; + + slot0_partition: partition@0 { + label = "image-0"; + reg = <0x0 DT_SIZE_K(512)>; + }; +}; + +/* CCFG */ +&flash1 { + reg = <0x4e020000 DT_SIZE_K(2)>; + ti,bldr-vtor-flash = <0>; + ti,serial-io-cfg-index = <0>; + ti,debug-port; + ti,energy-trace; + ti,flash-verify; + ti,flash-program; + ti,chip-erase; + ti,ret-to-factory; + ti,wr-er-prot-sect0-31 = <0xffffffff>; + ti,wr-er-prot-sect32-255 = <0xffffffff>; + ti,wr-er-prot-ccfg-sect = <0>; + ti,wr-er-prot-fcfg-sect = <0>; + ti,wr-er-prot-engr-sect = <0>; + ti,chip-er-retain-sect0-31 = <0>; + ti,chip-er-retain-sect32-255 = <0>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + ti_ccfg_partition: partition@4e020000 { + compatible = "zephyr,memory-region"; + reg = <0x4e020000 0x800>; + zephyr,memory-region = "FLASH_CCFG"; + }; + }; +}; diff --git a/dts/arm/ti/cc23x0.dtsi b/dts/arm/ti/cc23x0.dtsi new file mode 100644 index 0000000000000..6b307980ce3e7 --- /dev/null +++ b/dts/arm/ti/cc23x0.dtsi @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/ { + chosen { + zephyr,flash-controller = &flash_controller; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-m0+"; + clock-frequency = ; + reg = <0>; + }; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + }; + + sysclk: system-clock { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + soc { + flash_controller: flash-controller@40021000 { + compatible = "ti,cc23x0-flash-controller"; + reg = <0x40021000 0x408>; + #address-cells = <1>; + #size-cells = <1>; + + /* Main flash sector */ + flash0: flash@0 { + compatible = "soc-nv-flash"; + erase-block-size = ; + write-block-size = <0x10>; + }; + + /* CCFG flash sector */ + flash1: flash@4e020000 { + compatible = "ti,cc23x0-ccfg-flash", "soc-nv-flash"; + erase-block-size = ; + write-block-size = <0x10>; + }; + }; + + pinctrl: pinctrl@40003000 { + compatible = "ti,cc23x0-pinctrl"; + reg = <0x40003000 0xc14>; + }; + + gpio0: gpio@40023000 { + compatible = "ti,cc23x0-gpio"; + reg = <0x40023000 0x804>; + interrupts = <5 0>; /* GPIO combined on CPUIRQ5 */ + status = "disabled"; + gpio-controller; + #gpio-cells = <2>; /* Pin (ID), and flags */ + ngpios = <26>; /* Only [DIO0, DIO25] are available */ + }; + + uart0: uart@40034000 { + compatible = "ti,cc23x0-uart"; + reg = <0x40034000 0x52>; + interrupts = <11 0>; + clocks = <&sysclk>; + status = "disabled"; + }; + }; +}; + +&nvic { + arm,num-irq-priority-bits = <2>; /* Interrupt levels are 0-192 in steps of 64 */ +}; + +&systick { + status = "disabled"; +}; diff --git a/dts/bindings/flash_controller/ti,cc23x0-flash-controller.yaml b/dts/bindings/flash_controller/ti,cc23x0-flash-controller.yaml new file mode 100644 index 0000000000000..538e75aa16d89 --- /dev/null +++ b/dts/bindings/flash_controller/ti,cc23x0-flash-controller.yaml @@ -0,0 +1,5 @@ +description: Texas Instruments CC23X0 flash controller + +compatible: "ti,cc23x0-flash-controller" + +include: flash-controller.yaml diff --git a/dts/bindings/gpio/ti,cc23x0-gpio.yaml b/dts/bindings/gpio/ti,cc23x0-gpio.yaml new file mode 100644 index 0000000000000..ced5e1352d97a --- /dev/null +++ b/dts/bindings/gpio/ti,cc23x0-gpio.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +description: TI SimpleLink CC23X0 GPIO node + +compatible: "ti,cc23x0-gpio" + +include: [gpio-controller.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + "#gpio-cells": + const: 2 + +gpio-cells: + - pin + - flags diff --git a/dts/bindings/mtd/ti,cc23x0-ccfg-flash.yaml b/dts/bindings/mtd/ti,cc23x0-ccfg-flash.yaml new file mode 100644 index 0000000000000..0786ec7c478cd --- /dev/null +++ b/dts/bindings/mtd/ti,cc23x0-ccfg-flash.yaml @@ -0,0 +1,161 @@ +# Copyright (c) 2024 BayLibre, SAS +# SPDX-License-Identifier: Apache-2.0 + +description: | + This binding describes the TI CC23X0 flash CCFG (custom configuration) + area content. + + Notes: + The flash CCFG sector node (e.g. flash1) should have both + "ti,cc23x0-ccfg-flash" and the "soc-nv-flash" compatibles. + The latter is used from mcuboot and other modules to identify + the flash area. + +compatible: "ti,cc23x0-ccfg-flash" + +include: soc-nv-flash.yaml + +properties: + ti,bldr-vtor-flash: + type: int + description: | + Bootloader entry point when a boot from flash is selected. + Valid range: 0 - 0x0effffff + Default is 0, which is the standard initial configuration. + default: 0 + + ti,serial-io-cfg-index: + type: int + description: | + Index of which I/O mapping to use for UART/SPI. + Valid range: 0 - 2 + Default is 0, which is the standard initial configuration. Other values can be + used depending on I/O availability. + default: 0 + + ti,pin-trigger: + type: boolean + description: | + If not present, then bootloader unconditionally triggers. + Else normal pin trigger check is performed. + + ti,pin-trigger-dio: + type: int + description: | + Index of DIO pin to use for pin trigger check. + Valid range: 0 - 25 + Default is 0, which is the standard initial configuration. Other values can be + used depending on DIO availability. + default: 0 + + ti,pin-trigger-level-hi: + type: boolean + description: | + If not present, then the level on trigger pin that triggers bootloader is low. + Else level that triggers bootloader is high. + + ti,debug-port: + type: boolean + description: | + If not present, then the SWD port is disabled altogether at a certain point in boot + before invoking either bootloader or application. + + ti,energy-trace: + type: boolean + description: | + Allows using EnergyTrace power analyzer tool. + EnergyTrace software is an energy-based code analysis tool that measures + and displays the energy profile of an application and helps optimize it for + ultra-low-power consumption. + + ti,flash-verify: + type: boolean + description: | + Determines whether flash verifying SACI commands are allowed. These commands only check + integrity against a provided CRC32 value, never return any flash contents. Flash verify + commands are always allowed after a chip erase and until the first reset after the CCFG + sector has been programmed. + + ti,flash-program: + type: boolean + description: | + Determines whether flash programming SACI commands are allowed. + Reset to allowed after a chip erase. + + ti,chip-erase: + type: boolean + description: | + Determines whether chip erasing SACI commands are allowed. + + ti,ret-to-factory: + type: boolean + description: | + Allows return-to-factory procedure by SACI. + To do full failure analysis including flash, a return to factory procedure is supported. + + ti,wr-er-prot-sect0-31: + type: int + description: | + Bitmask for write/erase protection of individual sectors in sector range [0, 31]. + Controls whether flash programming is allowed through SACI. The same mechanism + controls whether the application is allowed to program these sectors. + 0 = protected. + Valid range: 0 - 0xffffffff + Default is 0xffffffff to allow programming these sectors. + default: 0xffffffff + + ti,wr-er-prot-sect32-255: + type: int + description: | + Bitmask for write/erase protection of groups of 8 sectors, in sector range [32, 255]. + Bit i protects sectors [32 + 8i, 39 + 8i]. + 0 = protected. + Valid range: 0 - 0xffffffff + Default is 0xffffffff to allow programming these sectors. + default: 0xffffffff + + ti,wr-er-prot-ccfg-sect: + type: int + description: | + Bitmask for write/erase protection of CCFG sectors. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 + + ti,wr-er-prot-fcfg-sect: + type: int + description: | + Bitmask for write/erase protection of FCFG sectors. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 + + ti,wr-er-prot-engr-sect: + type: int + description: | + Bitmask for write/erase protection of ENGR sectors. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 + + ti,chip-er-retain-sect0-31: + type: int + description: | + Bitmask for chip erase protection of individual sectors in sector range [0, 31]. + Controls whether a chip erase affects a sector or not. The mechanism is intended + to allow flash sectors devoted to logging or runtime state/configuration to survive + the chip erase during a FW update. + 0 = protected. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 + + ti,chip-er-retain-sect32-255: + type: int + description: | + Bitmask for chip erase protection of groups of 8 sectors, in sector range [32, 255]. + Bit i protects sectors [32 + 8i, 39 + 8i]. + 0 = protected. + Valid range: 0 - 0xffffffff + Default is 0 to prevent from mistakenly programming these sectors. + default: 0 diff --git a/dts/bindings/pinctrl/ti,cc23x0-pinctrl.yaml b/dts/bindings/pinctrl/ti,cc23x0-pinctrl.yaml new file mode 100644 index 0000000000000..9f3b17221b7ca --- /dev/null +++ b/dts/bindings/pinctrl/ti,cc23x0-pinctrl.yaml @@ -0,0 +1,62 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# SPDX-License-Identifier: Apache-2.0 + +description: | + TI SimpleLink CC23X0 pinctrl node. + + Device pin configuration should be placed in the child nodes of this node. + Populate the 'pinmux' field with a pair consisting of a pin number and its IO + functions. + + The node has the 'pinctrl' node label set in your SoC's devicetree, + so you can modify it like this: + + &pinctrl { + /* your modifications go here */ + }; + + All device pin configurations should be placed in child nodes of the + 'pinctrl' node, as in the i2c0 example shown at the end. + + Here is a list of + supported standard pin properties: + + - bias-disable: Disable pull-up/down. + - bias-pull-down: Enable pull-down resistor. + - bias-pull-up: Enable pull-up resistor. + - drive-open-drain: Output driver is open-drain. + - drive-open-source: Output driver is open-source. + - input-enable: enable input. + - input-schmitt-enable: enable input schmitt circuit. + +compatible: "ti,cc23x0-pinctrl" + +include: base.yaml + +properties: + reg: + required: true + +child-binding: + description: | + This binding gives a base representation of the CC23X0 + pins configuration. + + include: + - name: pincfg-node.yaml + property-allowlist: + - bias-disable + - bias-pull-down + - bias-pull-up + - drive-open-drain + - drive-open-source + - input-enable + - input-schmitt-enable + + properties: + pinmux: + required: true + type: array + description: | + CC23X0 pin's configuration (IO pin, IO function). diff --git a/dts/bindings/serial/ti,cc23x0-uart.yaml b/dts/bindings/serial/ti,cc23x0-uart.yaml new file mode 100644 index 0000000000000..f2587a0a26761 --- /dev/null +++ b/dts/bindings/serial/ti,cc23x0-uart.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +description: TI SimpleLink CC23X0 UART node + +compatible: "ti,cc23x0-uart" + +include: [uart-controller.yaml, pinctrl-device.yaml, base.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + pinctrl-0: + required: true + + pinctrl-names: + required: true + + stop-bits: + description: | + Sets the number of stop bits. Defaults to standard of 1 if not specified. + default: "1" + + data-bits: + description: | + Sets the number of data bits. Defaults to standard of 8 if not specified. + default: 8 diff --git a/dts/bindings/timer/ti,cc23x0-timer.yaml b/dts/bindings/timer/ti,cc23x0-timer.yaml new file mode 100644 index 0000000000000..94b70e1a145ec --- /dev/null +++ b/dts/bindings/timer/ti,cc23x0-timer.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Baylibre SAS +# SPDX-License-Identifier: Apache-2.0 + +description: TI SimpleLink CC23x0 Timer Node + +compatible: "ti,cc23x0-systim-timer" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true diff --git a/include/zephyr/dt-bindings/pinctrl/cc23x0-pinctrl.h b/include/zephyr/dt-bindings/pinctrl/cc23x0-pinctrl.h new file mode 100644 index 0000000000000..1c365965c9df5 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/cc23x0-pinctrl.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef CC23X0_PINCTRL_COMMON_H_ +#define CC23X0_PINCTRL_COMMON_H_ + +/* + * The whole TI CC23X0 pin configuration information is encoded in a 32-bit + * bitfield organized as follow: + * + * - 31: Reserved + * - 30: Input hysteresis + * - 29: Input capability of IO + * - 28..27: Reserved + * - 26..24: IO mode + * - 23..22: Reserved + * - 21..20: Wakeup configuration from shutdown + * - 19: Reserved + * - 18: Wakeup capability from standby + * - 17..16: Edge detection configuration + * - 15: Reserved + * - 14..13: Pull control + * - 12..3: Reserved + * - 2..0: Function configuration + */ + +/* TI CC23X0 function configuration */ + +#define IOC_PORTCFG_BASE 0U +#define IOC_PORTCFG_PFUNC1 1U +#define IOC_PORTCFG_PFUNC2 2U +#define IOC_PORTCFG_PFUNC3 3U +#define IOC_PORTCFG_PFUNC4 4U +#define IOC_PORTCFG_PFUNC5 5U +#define IOC_PORTCFG_ANA 6U +#define IOC_PORTCFG_DTB 7U + +/* TI CC23X0 peripheral pin mapping */ + +#define DIO0_GPIO0 IOC_PORTCFG_BASE +#define DIO0_SPI0_CSN IOC_PORTCFG_PFUNC1 +#define DIO0_I2C0_SDA IOC_PORTCFG_PFUNC2 +#define DIO0_T3_C2 IOC_PORTCFG_PFUNC3 +#define DIO0_ADC5 IOC_PORTCFG_ANA + +#define DIO1_GPIO1 IOC_PORTCFG_BASE +#define DIO1_T3_C1 IOC_PORTCFG_PFUNC1 +#define DIO1_LRFD7 IOC_PORTCFG_PFUNC2 +#define DIO1_T1_F IOC_PORTCFG_PFUNC3 +#define DIO1_UART0_RTS IOC_PORTCFG_PFUNC4 +#define DIO1_ADC4 IOC_PORTCFG_ANA +#define DIO1_DTB2 IOC_PORTCFG_DTB + +#define DIO2_GPIO2 IOC_PORTCFG_BASE +#define DIO2_T0_PE IOC_PORTCFG_PFUNC1 +#define DIO2_T2_C1N IOC_PORTCFG_PFUNC2 +#define DIO2_UART0_CTS IOC_PORTCFG_PFUNC3 +#define DIO2_ADC3 IOC_PORTCFG_ANA + +#define DIO3_GPIO3 IOC_PORTCFG_BASE +#define DIO3_LFCI IOC_PORTCFG_PFUNC1 +#define DIO3_T0_C1N IOC_PORTCFG_PFUNC2 +#define DIO3_LRFD0 IOC_PORTCFG_PFUNC3 +#define DIO3_T3_C1 IOC_PORTCFG_PFUNC4 +#define DIO3_T1_C2 IOC_PORTCFG_PFUNC5 +#define DIO3_LFXT_P IOC_PORTCFG_ANA +#define DIO3_DTB7 IOC_PORTCFG_DTB + +#define DIO4_GPIO4 IOC_PORTCFG_BASE +#define DIO4_T0_C2N IOC_PORTCFG_PFUNC1 +#define DIO4_UART0_TXD IOC_PORTCFG_PFUNC2 +#define DIO4_LRFD1 IOC_PORTCFG_PFUNC3 +#define DIO4_SPI0_MOSI IOC_PORTCFG_PFUNC4 +#define DIO4_T0_C2 IOC_PORTCFG_PFUNC5 +#define DIO4_LFXT_N IOC_PORTCFG_ANA +#define DIO4_DTB8 IOC_PORTCFG_DTB + +#define DIO5_GPIO5 IOC_PORTCFG_BASE +#define DIO5_T2_C2 IOC_PORTCFG_PFUNC1 +#define DIO5_LRFD6 IOC_PORTCFG_PFUNC3 +#define DIO5_ADC2 IOC_PORTCFG_ANA + +#define DIO6_GPIO6 IOC_PORTCFG_BASE +#define DIO6_SPI0_CSN IOC_PORTCFG_PFUNC1 +#define DIO6_I2C0_SCL IOC_PORTCFG_PFUNC2 +#define DIO6_T1_C2 IOC_PORTCFG_PFUNC3 +#define DIO6_LRFD2 IOC_PORTCFG_PFUNC4 +#define DIO6_UART0_TXD IOC_PORTCFG_PFUNC5 +#define DIO6_ADC1_AREFP IOC_PORTCFG_ANA +#define DIO6_DTB6 IOC_PORTCFG_DTB + +#define DIO7_GPIO7 IOC_PORTCFG_BASE +#define DIO7_T3_C1 IOC_PORTCFG_PFUNC1 +#define DIO7_LRFD4 IOC_PORTCFG_PFUNC3 +#define DIO7_ADC0_AREFM IOC_PORTCFG_ANA + +#define DIO8_GPIO8 IOC_PORTCFG_BASE +#define DIO8_SPI0_SCLK IOC_PORTCFG_PFUNC1 +#define DIO8_UART0_RTS IOC_PORTCFG_PFUNC2 +#define DIO8_T1_C0N IOC_PORTCFG_PFUNC3 +#define DIO8_I2C0_SDA IOC_PORTCFG_PFUNC4 +#define DIO8_T0_C0N IOC_PORTCFG_PFUNC5 +#define DIO8_DTB3 IOC_PORTCFG_DTB + +#define DIO9_GPIO9 IOC_PORTCFG_BASE +#define DIO9_T3_C0 IOC_PORTCFG_PFUNC1 +#define DIO9_LRFD3 IOC_PORTCFG_PFUNC3 + +#define DIO10_GPIO10 IOC_PORTCFG_BASE +#define DIO10_LPC0 IOC_PORTCFG_PFUNC1 +#define DIO10_T2_PE IOC_PORTCFG_PFUNC2 +#define DIO10_T3_C0N IOC_PORTCFG_PFUNC3 + +#define DIO11_GPIO11 IOC_PORTCFG_BASE +#define DIO11_SPI0_CSN IOC_PORTCFG_PFUNC1 +#define DIO11_T1_C2N IOC_PORTCFG_PFUNC2 +#define DIO11_T0_C0 IOC_PORTCFG_PFUNC3 +#define DIO11_LRFD0 IOC_PORTCFG_PFUNC4 +#define DIO11_SPI0_MISO IOC_PORTCFG_PFUNC5 +#define DIO11_DTB9 IOC_PORTCFG_DTB + +#define DIO12_GPIO12 IOC_PORTCFG_BASE +#define DIO12_SPI0_MISO IOC_PORTCFG_PFUNC1 +#define DIO12_SPI0_MOSI IOC_PORTCFG_PFUNC2 +#define DIO12_UART0_RXD IOC_PORTCFG_PFUNC3 +#define DIO12_T1_C1 IOC_PORTCFG_PFUNC4 +#define DIO12_I2C0_SDA IOC_PORTCFG_PFUNC5 +#define DIO12_DTB13 IOC_PORTCFG_DTB + +#define DIO13_GPIO13 IOC_PORTCFG_BASE +#define DIO13_SPI0_MISO IOC_PORTCFG_PFUNC1 +#define DIO13_SPI0_MOSI IOC_PORTCFG_PFUNC2 +#define DIO13_UART0_TXD IOC_PORTCFG_PFUNC3 +#define DIO13_T0_C0N IOC_PORTCFG_PFUNC4 +#define DIO13_T1_F IOC_PORTCFG_PFUNC5 +#define DIO13_DTB4 IOC_PORTCFG_DTB + +#define DIO14_GPIO14 IOC_PORTCFG_BASE +#define DIO14_T3_C2 IOC_PORTCFG_PFUNC1 +#define DIO14_T1_C2N IOC_PORTCFG_PFUNC2 +#define DIO14_LRFD5 IOC_PORTCFG_PFUNC3 +#define DIO14_T1_F IOC_PORTCFG_PFUNC4 + +#define DIO15_GPIO15 IOC_PORTCFG_BASE +#define DIO15_UART0_RXD IOC_PORTCFG_PFUNC1 +#define DIO15_T2_C0N IOC_PORTCFG_PFUNC2 +#define DIO15_CKMIN IOC_PORTCFG_PFUNC3 + +#define DIO16_GPIO16 IOC_PORTCFG_BASE +#define DIO16_SPI0_MOSI IOC_PORTCFG_PFUNC1 +#define DIO16_UART0_RXD IOC_PORTCFG_PFUNC2 +#define DIO16_I2C0_SDA IOC_PORTCFG_PFUNC3 +#define DIO16_T1_C2 IOC_PORTCFG_PFUNC4 +#define DIO16_T1_C0N IOC_PORTCFG_PFUNC5 +#define DIO16_DTB10 IOC_PORTCFG_DTB + +#define DIO17_GPIO17 IOC_PORTCFG_BASE +#define DIO17_SPI0_SCLK IOC_PORTCFG_PFUNC1 +#define DIO17_UART0_TXD IOC_PORTCFG_PFUNC2 +#define DIO17_I2C0_SCL IOC_PORTCFG_PFUNC3 +#define DIO17_T1_C1N IOC_PORTCFG_PFUNC4 +#define DIO17_T0_C2 IOC_PORTCFG_PFUNC5 +#define DIO17_DTB11 IOC_PORTCFG_DTB + +#define DIO18_GPIO18 IOC_PORTCFG_BASE +#define DIO18_T3_C0 IOC_PORTCFG_PFUNC1 +#define DIO18_LPC0 IOC_PORTCFG_PFUNC2 +#define DIO18_UART0_TXD IOC_PORTCFG_PFUNC3 +#define DIO18_SPI0_SCLK IOC_PORTCFG_PFUNC4 +#define DIO18_DTB12 IOC_PORTCFG_DTB + +#define DIO19_GPIO19 IOC_PORTCFG_BASE +#define DIO19_T3_C1 IOC_PORTCFG_PFUNC1 +#define DIO19_T2_PE IOC_PORTCFG_PFUNC2 +#define DIO19_SPI0_MOSI IOC_PORTCFG_PFUNC4 +#define DIO19_DTB0 IOC_PORTCFG_DTB + +#define DIO20_GPIO20 IOC_PORTCFG_BASE +#define DIO20_LPC0 IOC_PORTCFG_PFUNC1 +#define DIO20_UART0_TXD IOC_PORTCFG_PFUNC2 +#define DIO20_UART0_RXD IOC_PORTCFG_PFUNC3 +#define DIO20_T1_C0 IOC_PORTCFG_PFUNC4 +#define DIO20_SPI0_MISO IOC_PORTCFG_PFUNC5 +#define DIO20_ADC11 IOC_PORTCFG_ANA +#define DIO20_DTB14 IOC_PORTCFG_DTB + +#define DIO21_GPIO21 IOC_PORTCFG_BASE +#define DIO21_UART0_CTS IOC_PORTCFG_PFUNC1 +#define DIO21_T1_C1N IOC_PORTCFG_PFUNC2 +#define DIO21_T0_C1 IOC_PORTCFG_PFUNC3 +#define DIO21_SPI0_MISO IOC_PORTCFG_PFUNC4 +#define DIO21_LRFD1 IOC_PORTCFG_PFUNC5 +#define DIO21_ADC10_LPCP IOC_PORTCFG_ANA +#define DIO21_DTB15 IOC_PORTCFG_DTB + +#define DIO22_GPIO22 IOC_PORTCFG_BASE +#define DIO22_T2_C0 IOC_PORTCFG_PFUNC1 +#define DIO22_UART0_RXD IOC_PORTCFG_PFUNC2 +#define DIO22_T3_C1N IOC_PORTCFG_PFUNC3 +#define DIO22_ADC9 IOC_PORTCFG_ANA +#define DIO22_DTB1 IOC_PORTCFG_DTB + +#define DIO23_GPIO23 IOC_PORTCFG_BASE +#define DIO23_T2_C1 IOC_PORTCFG_PFUNC1 +#define DIO23_T3_C2N IOC_PORTCFG_PFUNC3 +#define DIO23_ADC8_LPCP_LPCM IOC_PORTCFG_ANA + +#define DIO24_GPIO24 IOC_PORTCFG_BASE +#define DIO24_SPI0_SCLK IOC_PORTCFG_PFUNC1 +#define DIO24_T1_C0 IOC_PORTCFG_PFUNC2 +#define DIO24_T3_C0 IOC_PORTCFG_PFUNC3 +#define DIO24_T0_PE IOC_PORTCFG_PFUNC4 +#define DIO24_I2C0_SCL IOC_PORTCFG_PFUNC5 +#define DIO24_ADC7_LPCP_LPCM IOC_PORTCFG_ANA +#define DIO24_DTB5 IOC_PORTCFG_DTB + +#define DIO25_GPIO25 IOC_PORTCFG_BASE +#define DIO25_SPI0_MISO IOC_PORTCFG_PFUNC1 +#define DIO25_I2C0_SCL IOC_PORTCFG_PFUNC2 +#define DIO25_T2_C2N IOC_PORTCFG_PFUNC3 +#define DIO25_ADC6 IOC_PORTCFG_ANA + +#endif /* CC23X0_PINCTRL_COMMON_H_ */ diff --git a/modules/Kconfig.simplelink b/modules/Kconfig.simplelink index 13b26b1ca1a48..3a1cea8ebb3e3 100644 --- a/modules/Kconfig.simplelink +++ b/modules/Kconfig.simplelink @@ -32,3 +32,8 @@ config HAS_CC13X2_CC26X2_SDK config HAS_CC13X2X7_CC26X2X7_SDK bool + +# CC23X0 SDK HAL configuration + +config HAS_CC23X0_SDK + bool diff --git a/soc/ti/simplelink/Kconfig b/soc/ti/simplelink/Kconfig index af4cd5f74333e..e4e57d9a9dd7d 100644 --- a/soc/ti/simplelink/Kconfig +++ b/soc/ti/simplelink/Kconfig @@ -12,4 +12,10 @@ config HAS_TI_CCFG Selected when CCFG (Customer Configuration) registers appear at the end of flash +config TI_SIMPLELINK_DYNAMIC_DPL_OBJECTS + bool + help + Turn on dynamic memory allocation for DPL objects. Reserves + extra memory for this. + endif # SOC_FAMILY_TI_SIMPLELINK diff --git a/soc/ti/simplelink/cc23x0/CMakeLists.txt b/soc/ti/simplelink/cc23x0/CMakeLists.txt new file mode 100644 index 0000000000000..b8e02adbd58e8 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/CMakeLists.txt @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(soc.c) +zephyr_sources(ccfg.c) +zephyr_include_directories(.) + +zephyr_linker_sources_ifdef(CONFIG_HAS_TI_CCFG SECTIONS ccfg.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/ti/simplelink/cc23x0/Kconfig b/soc/ti/simplelink/cc23x0/Kconfig new file mode 100644 index 0000000000000..fa1c2c45af3e3 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/Kconfig @@ -0,0 +1,49 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_CC23X0 + select ARM + select CPU_CORTEX_M0PLUS + select CPU_CORTEX_M_HAS_VTOR + select SOC_RESET_HOOK + select TICKLESS_KERNEL + select DYNAMIC_INTERRUPTS + select HAS_CC23X0_SDK + select HAS_TI_CCFG + select TI_SIMPLELINK_DYNAMIC_DPL_OBJECTS + select EVENTS + select DYNAMIC_THREAD + select DYNAMIC_THREAD_ALLOC + select THREAD_STACK_INFO + select BUILD_OUTPUT_HEX + select BUILD_NO_GAP_FILL + +menu "Bootloader Configuration" +depends on SOC_SERIES_CC23X0 + +choice CC23X0_BLDR_VTOR_TYPE + prompt "Pointer to user bootloader vector table" + default CC23X0_BLDR_VTOR_TYPE_UNDEF + +config CC23X0_BLDR_VTOR_TYPE_UNDEF + bool "ROM serial bootloader" + +config CC23X0_BLDR_VTOR_TYPE_FORBID + bool "No bootloader invoked" + +config CC23X0_BLDR_VTOR_TYPE_USE_FCFG + bool "Use factory configuration" + +config CC23X0_BLDR_VTOR_TYPE_FLASH + bool "Use valid main flash address" + +endchoice # CC23X0_BLDR_VTOR_TYPE + +config CC23X0_BLDR_ENABLED + bool "Bootloader commands" + help + If n, bootloader ignores all commands. + +endmenu # "Bootloader Configuration" diff --git a/soc/ti/simplelink/cc23x0/Kconfig.defconfig b/soc/ti/simplelink/cc23x0/Kconfig.defconfig new file mode 100644 index 0000000000000..442c9b09c9e07 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/Kconfig.defconfig @@ -0,0 +1,19 @@ +# Texas Instruments SimpleLink CC23X0 + +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_CC23X0 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/cpus/cpu@0,clock-frequency) + +config SYS_CLOCK_TICKS_PER_SEC + default 1000 + +config NUM_IRQS + default 19 + +endif diff --git a/soc/ti/simplelink/cc23x0/Kconfig.soc b/soc/ti/simplelink/cc23x0/Kconfig.soc new file mode 100644 index 0000000000000..6817c069f9399 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/Kconfig.soc @@ -0,0 +1,22 @@ +# Copyright (c) 2024 Texas Instruments Incorporated +# Copyright (c) 2024 BayLibre, SAS +# +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_CC23X0 + bool + select SOC_FAMILY_TI_SIMPLELINK + help + Enable support for TI SimpleLink CC23X0 series SOCs. + +config SOC_CC2340R5 + bool + select SOC_SERIES_CC23X0 + help + CC2340R5 + +config SOC_SERIES + default "cc23x0" if SOC_SERIES_CC23X0 + +config SOC + default "cc2340r5" if SOC_CC2340R5 diff --git a/soc/ti/simplelink/cc23x0/ccfg.c b/soc/ti/simplelink/cc23x0/ccfg.c new file mode 100644 index 0000000000000..08031e40adc0a --- /dev/null +++ b/soc/ti/simplelink/cc23x0/ccfg.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include + +#define CC23_CCFG_FLASH DT_INST(0, ti_cc23x0_ccfg_flash) +#define CC23_CCFG_FLASH_PROP(prop) DT_PROP(CC23_CCFG_FLASH, prop) + +#define CC23_TO_PERM_VAL(en) ((en) ? CCFG_PERMISSION_ALLOW : CCFG_PERMISSION_FORBID) + +#if CONFIG_CC23X0_BLDR_VTOR_TYPE_UNDEF +#define CC23X0_BLDR_VTOR 0xffffffff +#elif CONFIG_CC23X0_BLDR_VTOR_TYPE_FORBID +#define CC23X0_BLDR_VTOR 0xfffffffc +#elif CONFIG_CC23X0_BLDR_VTOR_TYPE_USE_FCFG +#define CC23X0_BLDR_VTOR 0xfffffff0 +#else +#define CC23X0_BLDR_VTOR CC23_CCFG_FLASH_PROP(ti_bldr_vtor_flash) +#endif + +#define CC23X0_P_APP_VTOR DT_REG_ADDR(DT_CHOSEN(zephyr_code_partition)) + +#if CC23_CCFG_FLASH_PROP(ti_chip_erase) == 0 +#warning ti,chip-erase property is NOT PRESENT in your device tree, \ + flashing this firmware will LOCK YOUR DEVICE. +#endif + +/* Default CCFG */ +const ccfg_t ccfg __attribute__((section(".ti_ccfg"))) __attribute__((used)) = { + .bootCfg.pBldrVtor = (void *)CC23X0_BLDR_VTOR, + .bootCfg.bldrParam.serialRomBldrParamStruct.bldrEnabled = + IS_ENABLED(CONFIG_CC23X0_BLDR_ENABLED), + .bootCfg.bldrParam.serialRomBldrParamStruct.serialIoCfgIndex = + CC23_CCFG_FLASH_PROP(ti_serial_io_cfg_index), + .bootCfg.bldrParam.serialRomBldrParamStruct.pinTriggerEnabled = + CC23_CCFG_FLASH_PROP(ti_pin_trigger), + .bootCfg.bldrParam.serialRomBldrParamStruct.pinTriggerDio = + CC23_CCFG_FLASH_PROP(ti_pin_trigger_dio), + .bootCfg.bldrParam.serialRomBldrParamStruct.pinTriggerLevel = + CC23_CCFG_FLASH_PROP(ti_pin_trigger_level_hi), + .bootCfg.pAppVtor = (void *)CC23X0_P_APP_VTOR, + + .hwOpts = {0xffffffff, 0xffffffff}, + + .permissions.allowDebugPort = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_debug_port)), + .permissions.allowEnergyTrace = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_energy_trace)), + .permissions.allowFlashVerify = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_flash_verify)), + .permissions.allowFlashProgram = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_flash_program)), + .permissions.allowChipErase = CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_chip_erase)), + .permissions.allowToolsClientMode = CCFG_PERMISSION_ALLOW, + .permissions.allowReturnToFactory = + CC23_TO_PERM_VAL(CC23_CCFG_FLASH_PROP(ti_ret_to_factory)), + .permissions.allowFakeStby = CCFG_PERMISSION_ALLOW, + + .misc.saciTimeoutOverride = 0, + .misc.saciTimeoutExp = XCFG_MISC_SACITOEXP_8SEC, + + .flashProt.writeEraseProt.mainSectors0_31 = CC23_CCFG_FLASH_PROP(ti_wr_er_prot_sect0_31), + .flashProt.writeEraseProt.mainSectors32_255 = + CC23_CCFG_FLASH_PROP(ti_wr_er_prot_sect32_255), + .flashProt.writeEraseProt.ccfgSector = CC23_CCFG_FLASH_PROP(ti_wr_er_prot_ccfg_sect), + .flashProt.writeEraseProt.fcfgSector = CC23_CCFG_FLASH_PROP(ti_wr_er_prot_fcfg_sect), + .flashProt.writeEraseProt.engrSector = CC23_CCFG_FLASH_PROP(ti_wr_er_prot_engr_sect), + + .flashProt.res = 0xffffffff, + + .flashProt.chipEraseRetain.mainSectors0_31 = + CC23_CCFG_FLASH_PROP(ti_chip_er_retain_sect0_31), + .flashProt.chipEraseRetain.mainSectors32_255 = + CC23_CCFG_FLASH_PROP(ti_chip_er_retain_sect32_255), + + .debugCfg.authorization = CCFG_DBGAUTH_DBGOPEN, + .debugCfg.allowBldr = CCFG_DBGBLDR_ALLOW, +}; diff --git a/soc/ti/simplelink/cc23x0/ccfg.ld b/soc/ti/simplelink/cc23x0/ccfg.ld new file mode 100644 index 0000000000000..a9baf05dcf46d --- /dev/null +++ b/soc/ti/simplelink/cc23x0/ccfg.ld @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +GROUP_START(FLASH_CCFG) + +CRC_CCFG_BOOT_CFG_begin = 0x4e020000; +CRC_CCFG_BOOT_CFG_end = 0x4e02000B; +CRC_CCFG_begin = 0x4E020010; +CRC_CCFG_end = 0x4E02074B; +CRC_CCFG_DEBUG_begin = 0x4E0207D0; +CRC_CCFG_DEBUG_end = 0x4E0207FB; +CRC_CCFG_USER_RECORD_begin = 0x4E020750; +CRC_CCFG_USER_RECORD_end = 0x4E0207CB; +SECTION_PROLOGUE(.ti_ccfg,,) +{ + KEEP(*(_TI_CCFG_SECTION_NAME)) +} GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_NODELABEL(ti_ccfg_partition))) + +GROUP_END(FLASH_CCFG) diff --git a/soc/ti/simplelink/cc23x0/linker.ld b/soc/ti/simplelink/cc23x0/linker.ld new file mode 100644 index 0000000000000..448cc70c043d1 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/linker.ld @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include diff --git a/soc/ti/simplelink/cc23x0/pinctrl_soc.h b/soc/ti/simplelink/cc23x0/pinctrl_soc.h new file mode 100644 index 0000000000000..4c2c6fefd1605 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/pinctrl_soc.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TI_SIMPLELINK_CC23X0_SOC_PINCTRL_H_ +#define TI_SIMPLELINK_CC23X0_SOC_PINCTRL_H_ + +#include + +/* IO enabling/disabling */ +#define IOC_INPUT_ENABLE BIT(29) +#define IOC_INPUT_DISABLE 0U +#define IOC_HYST_ENABLE BIT(30) +#define IOC_HYST_DISABLE 0U + +/* IO modes */ +#define IOC_IOMODE_NORMAL 0U +#define IOC_IOMODE_INV BIT(24) +#define IOC_IOMODE_OPEN_DRAIN_NORMAL BIT(25) +#define IOC_IOMODE_OPEN_DRAIN_INV GENMASK(25, 24) +#define IOC_IOMODE_OPEN_SRC_NORMAL BIT(26) +#define IOC_IOMODE_OPEN_SRC_INV (BIT(26) | BIT(24)) + +/* IO pull */ +#define IOC_NO_IOPULL 0U +#define IOC_IOPULL_UP BIT(14) +#define IOC_IOPULL_DOWN BIT(13) + +typedef struct pinctrl_soc_pin { + uint32_t pin; + uint32_t iofunc; + uint32_t iomode; +} pinctrl_soc_pin_t; + +/* Convert DT flags to SoC flags */ +#define CC23X0_PIN_FLAGS(node_id) \ + (DT_PROP(node_id, bias_pull_up) * IOC_IOPULL_UP | \ + DT_PROP(node_id, bias_pull_down) * IOC_IOPULL_DOWN | \ + DT_PROP(node_id, bias_disable) * IOC_NO_IOPULL | \ + DT_PROP(node_id, drive_open_drain) * IOC_IOMODE_OPEN_DRAIN_NORMAL | \ + DT_PROP(node_id, drive_open_source) * IOC_IOMODE_OPEN_SRC_NORMAL | \ + DT_PROP(node_id, input_enable) * IOC_INPUT_ENABLE | \ + DT_PROP(node_id, input_schmitt_enable) * IOC_HYST_ENABLE) + +#define CC23X0_DT_PIN(node_id) \ + {.pin = DT_PROP_BY_IDX(node_id, pinmux, 0), \ + .iofunc = DT_PROP_BY_IDX(node_id, pinmux, 1), \ + .iomode = CC23X0_PIN_FLAGS(node_id)}, + +#define Z_PINCTRL_STATE_PIN_INIT(node_id, prop, idx) \ + CC23X0_DT_PIN(DT_PROP_BY_IDX(node_id, prop, idx)) + +#define Z_PINCTRL_STATE_PINS_INIT(node_id, prop) \ + {DT_FOREACH_PROP_ELEM(node_id, prop, Z_PINCTRL_STATE_PIN_INIT)} + +#endif /* TI_SIMPLELINK_CC23X0_SOC_PINCTRL_H_ */ diff --git a/soc/ti/simplelink/cc23x0/soc.c b/soc/ti/simplelink/cc23x0/soc.c new file mode 100644 index 0000000000000..cddae58b4e05d --- /dev/null +++ b/soc/ti/simplelink/cc23x0/soc.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +void soc_reset_hook(void) +{ + /* Perform necessary trim of the device. */ + SetupTrimDevice(); +} diff --git a/soc/ti/simplelink/cc23x0/soc.h b/soc/ti/simplelink/cc23x0/soc.h new file mode 100644 index 0000000000000..968cbc99d9c54 --- /dev/null +++ b/soc/ti/simplelink/cc23x0/soc.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Texas Instruments Incorporated + * Copyright (c) 2024 BayLibre, SAS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef TI_SIMPLELINK_CC23X0_SOC_H_ +#define TI_SIMPLELINK_CC23X0_SOC_H_ + +#include "cmsis/cc23x0r5.h" + +#endif /* TI_SIMPLELINK_CC23X0_SOC_H_ */ diff --git a/soc/ti/simplelink/soc.yml b/soc/ti/simplelink/soc.yml index 2dbf91f315e6f..bbf1ef19de4b5 100644 --- a/soc/ti/simplelink/soc.yml +++ b/soc/ti/simplelink/soc.yml @@ -13,6 +13,9 @@ family: - name: cc1352r7 - name: cc2652p7 - name: cc2652r7 + - name: cc23x0 + socs: + - name: cc2340r5 - name: cc32xx socs: - name: cc3220sf diff --git a/west.yml b/west.yml index 0c17ee71197d0..8f20001e358f4 100644 --- a/west.yml +++ b/west.yml @@ -253,7 +253,7 @@ manifest: groups: - hal - name: hal_ti - revision: 2e7b95ad079e9f636884eedc6853e6ad98b85f65 + revision: 258652a3ac5d7df68ba8df20e4705c3bd98ede38 path: modules/hal/ti groups: - hal