From 817e41f9658fb247c557488bb8ddb6c2c5ea1083 Mon Sep 17 00:00:00 2001 From: Stancu Florin Date: Mon, 13 Sep 2021 13:31:59 +0300 Subject: [PATCH] boards: cc1352p1_launchxl: new board, support antenna switching Added new CC1352P1 LaunchXL board supporting 20dBm TX for its sub-GHz radio. Note that the board has a multiplexer circuit to switch between 2.4GHz, High-Power TX and Sub1GHz states, for which a custom board module was implemented, together with board-specific device-tree bindings and pinctrl definitions for each of the RF states. Signed-off-by: Stancu Florin --- boards/arm/cc1352p1_launchxl/CMakeLists.txt | 6 + boards/arm/cc1352p1_launchxl/Kconfig.board | 20 ++ .../arm/cc1352p1_launchxl/Kconfig.defconfig | 11 + boards/arm/cc1352p1_launchxl/board.cmake | 5 + boards/arm/cc1352p1_launchxl/board_antenna.c | 135 ++++++++++ .../cc1352p1_launchxl-pinctrl.dtsi | 81 ++++++ .../cc1352p1_launchxl/cc1352p1_launchxl.dts | 147 +++++++++++ .../cc1352p1_launchxl/cc1352p1_launchxl.yaml | 14 + .../cc1352p1_launchxl_defconfig | 27 ++ .../doc/img/cc1352p1_launchxl.jpg | Bin 0 -> 41693 bytes boards/arm/cc1352p1_launchxl/doc/index.rst | 244 ++++++++++++++++++ .../dts/bindings/skyworks,sky13317.yaml | 14 + .../arm/cc1352p1_launchxl/support/openocd.cfg | 1 + drivers/ieee802154/Kconfig.cc13xx_cc26xx | 15 ++ .../ieee802154_cc13xx_cc26xx_subg.c | 84 +++--- 15 files changed, 768 insertions(+), 36 deletions(-) create mode 100644 boards/arm/cc1352p1_launchxl/CMakeLists.txt create mode 100644 boards/arm/cc1352p1_launchxl/Kconfig.board create mode 100644 boards/arm/cc1352p1_launchxl/Kconfig.defconfig create mode 100644 boards/arm/cc1352p1_launchxl/board.cmake create mode 100644 boards/arm/cc1352p1_launchxl/board_antenna.c create mode 100644 boards/arm/cc1352p1_launchxl/cc1352p1_launchxl-pinctrl.dtsi create mode 100644 boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts create mode 100644 boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml create mode 100644 boards/arm/cc1352p1_launchxl/cc1352p1_launchxl_defconfig create mode 100644 boards/arm/cc1352p1_launchxl/doc/img/cc1352p1_launchxl.jpg create mode 100644 boards/arm/cc1352p1_launchxl/doc/index.rst create mode 100644 boards/arm/cc1352p1_launchxl/dts/bindings/skyworks,sky13317.yaml create mode 100644 boards/arm/cc1352p1_launchxl/support/openocd.cfg diff --git a/boards/arm/cc1352p1_launchxl/CMakeLists.txt b/boards/arm/cc1352p1_launchxl/CMakeLists.txt new file mode 100644 index 00000000000..4c3dbf723e6 --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/CMakeLists.txt @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() +zephyr_library_sources( + board_antenna.c + ) diff --git a/boards/arm/cc1352p1_launchxl/Kconfig.board b/boards/arm/cc1352p1_launchxl/Kconfig.board new file mode 100644 index 00000000000..d6a880aa47a --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/Kconfig.board @@ -0,0 +1,20 @@ +# TI CC1352R LaunchXL board + +# Copyright (c) 2021 Florin Stancu +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_CC1352P1_LAUNCHXL + bool "TI CC1352P1 LaunchXL" + depends on SOC_CC1352P + +if BOARD_CC1352P1_LAUNCHXL + +config BOARD_ANTENNA_INIT_PRIO + int "Board antenna switch initialization priority" + default 70 + help + Set the priority for board init, must be greater than + KERNEL_INIT_PRIORITY_DEVICE but smaller than + IEEE802154_CC13XX_CC26XX_SUB_GHZ_INIT_PRIO. + +endif # BOARD_CC1352P1_LAUNCHXL diff --git a/boards/arm/cc1352p1_launchxl/Kconfig.defconfig b/boards/arm/cc1352p1_launchxl/Kconfig.defconfig new file mode 100644 index 00000000000..907daaf0010 --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/Kconfig.defconfig @@ -0,0 +1,11 @@ +# TI CC1352P1 LaunchXL board + +# Copyright (c) 2021 Florin Stancu +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_CC1352P1_LAUNCHXL + +config BOARD + default "cc1352p1_launchxl" + +endif # BOARD_CC1352P1_LAUNCHXL diff --git a/boards/arm/cc1352p1_launchxl/board.cmake b/boards/arm/cc1352p1_launchxl/board.cmake new file mode 100644 index 00000000000..1c437041486 --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/board.cmake @@ -0,0 +1,5 @@ +# Copyright (c) 2021 Florin Stancu +# +# SPDX-License-Identifier: Apache-2.0 + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) diff --git a/boards/arm/cc1352p1_launchxl/board_antenna.c b/boards/arm/cc1352p1_launchxl/board_antenna.c new file mode 100644 index 00000000000..8bdefedd190 --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/board_antenna.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2021 Florin Stancu + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Implements the RF driver callback to configure the on-board antenna + * switch. + */ + +#define DT_DRV_COMPAT skyworks_sky13317 + +#include +#include +#include +#include + +#include +#include +#include + +/* custom pinctrl states for the antenna mux */ +#define PINCTRL_STATE_ANT_24G 1 +#define PINCTRL_STATE_ANT_24G_PA 2 +#define PINCTRL_STATE_ANT_SUBG 3 +#define PINCTRL_STATE_ANT_SUBG_PA 4 + +#define BOARD_ANT_GPIO_24G 0 +#define BOARD_ANT_GPIO_PA 1 +#define BOARD_ANT_GPIO_SUBG 2 + +#define ANTENNA_MUX DT_NODELABEL(antenna_mux0) + +static int board_antenna_init(const struct device *dev); +static void board_cc13xx_rf_callback(RF_Handle client, RF_GlobalEvent events, + void *arg); + +const RFCC26XX_HWAttrsV2 RFCC26XX_hwAttrs = { + .hwiPriority = INT_PRI_LEVEL7, + .swiPriority = 0, + .xoscHfAlwaysNeeded = true, + /* RF driver callback for custom antenna switching */ + .globalCallback = board_cc13xx_rf_callback, + /* Subscribe to events */ + .globalEventMask = (RF_GlobalEventRadioSetup | + RF_GlobalEventRadioPowerDown), +}; + +PINCTRL_DT_INST_DEFINE(0); +DEVICE_DT_INST_DEFINE(0, board_antenna_init, NULL, NULL, NULL, + POST_KERNEL, CONFIG_BOARD_ANTENNA_INIT_PRIO, NULL); + +static const struct pinctrl_dev_config *ant_pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0); +static const struct gpio_dt_spec ant_gpios[] = { + GPIO_DT_SPEC_GET_BY_IDX_OR(ANTENNA_MUX, gpios, BOARD_ANT_GPIO_24G, {0}), + GPIO_DT_SPEC_GET_BY_IDX_OR(ANTENNA_MUX, gpios, BOARD_ANT_GPIO_PA, {0}), + GPIO_DT_SPEC_GET_BY_IDX_OR(ANTENNA_MUX, gpios, BOARD_ANT_GPIO_SUBG, {0}), +}; + + +/** + * Antenna switch GPIO init routine. + */ +int board_antenna_init(const struct device *dev) +{ + ARG_UNUSED(dev); + int i; + + /* default pinctrl configuration: set all antenna mux control pins as GPIOs */ + pinctrl_apply_state(ant_pcfg, PINCTRL_STATE_DEFAULT); + /* set all GPIOs to 0 (all RF paths disabled) */ + for (i = 0; i < ARRAY_SIZE(ant_gpios); i++) { + gpio_pin_configure_dt(&ant_gpios[i], 0); + } + return 0; +} + +/** + * Custom TI RFCC26XX callback for switching the on-board antenna mux on radio setup. + */ +void board_cc13xx_rf_callback(RF_Handle client, RF_GlobalEvent events, void *arg) +{ + bool sub1GHz = false; + uint8_t loDivider = 0; + int i; + + /* Clear all antenna switch GPIOs (for all cases). */ + for (i = 0; i < ARRAY_SIZE(ant_gpios); i++) { + gpio_pin_configure_dt(&ant_gpios[i], 0); + } + + if (events & RF_GlobalEventRadioSetup) { + /* Decode the current PA configuration. */ + RF_TxPowerTable_PAType paType = (RF_TxPowerTable_PAType) + RF_getTxPower(client).paType; + /* Decode the generic argument as a setup command. */ + RF_RadioSetup *setupCommand = (RF_RadioSetup *)arg; + + switch (setupCommand->common.commandNo) { + case CMD_RADIO_SETUP: + case CMD_BLE5_RADIO_SETUP: + loDivider = RF_LODIVIDER_MASK & setupCommand->common.loDivider; + break; + case CMD_PROP_RADIO_DIV_SETUP: + loDivider = RF_LODIVIDER_MASK & setupCommand->prop_div.loDivider; + break; + default: + break; + } + sub1GHz = (loDivider != 0); + + if (sub1GHz) { + if (paType == RF_TxPowerTable_HighPA) { + /* Note: RFC_GPO3 is a work-around because the RFC_GPO1 */ + /* is sometimes not de-asserted on CC1352 Rev A. */ + pinctrl_apply_state(ant_pcfg, PINCTRL_STATE_ANT_SUBG_PA); + } else { + pinctrl_apply_state(ant_pcfg, PINCTRL_STATE_ANT_SUBG); + /* Manually set the sub-GHZ antenna switch DIO */ + gpio_pin_configure_dt(&ant_gpios[BOARD_ANT_GPIO_SUBG], 1); + } + } else /* 2.4 GHz */ { + if (paType == RF_TxPowerTable_HighPA) { + pinctrl_apply_state(ant_pcfg, PINCTRL_STATE_ANT_24G_PA); + } else { + pinctrl_apply_state(ant_pcfg, PINCTRL_STATE_ANT_24G); + /* Manually set the 2.4GHZ antenna switch DIO */ + gpio_pin_configure_dt(&ant_gpios[BOARD_ANT_GPIO_24G], 1); + } + } + } else { + pinctrl_apply_state(ant_pcfg, PINCTRL_STATE_DEFAULT); + } +} diff --git a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl-pinctrl.dtsi b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl-pinctrl.dtsi new file mode 100644 index 00000000000..0fa9c59e60a --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl-pinctrl.dtsi @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022 Vaishnav Achath + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +&pinctrl { + /* UART0 */ + uart0_tx_default: uart0_tx_default { + pinmux = <13 IOC_PORT_MCU_UART0_TX>; + bias-disable; + }; + uart0_rx_default: uart0_rx_default { + pinmux = <12 IOC_PORT_MCU_UART0_RX>; + bias-disable; + input-enable; + }; + + /* I2C0 */ + i2c0_scl_default: i2c0_scl_default { + pinmux = <4 IOC_PORT_MCU_I2C_MSSCL>; + bias-pull-up; + drive-open-drain; + input-enable; + }; + i2c0_sda_default: i2c0_sda_default { + pinmux = <5 IOC_PORT_MCU_I2C_MSSDA>; + bias-pull-up; + drive-open-drain; + input-enable; + }; + i2c0_scl_sleep: i2c0_scl_sleep { + pinmux = <4 IOC_PORT_GPIO>; + bias-disable; + }; + i2c0_sda_sleep: i2c0_sda_sleep { + pinmux = <5 IOC_PORT_GPIO>; + bias-disable; + }; + + /* SPI0 */ + spi0_sck_default: spi0_sck_default { + pinmux = <10 IOC_PORT_MCU_SSI0_CLK>; + bias-disable; + }; + spi0_mosi_default: spi0_mosi_default { + pinmux = <9 IOC_PORT_MCU_SSI0_TX>; + bias-disable; + }; + spi0_miso_default: spi0_miso_default { + pinmux = <8 IOC_PORT_MCU_SSI0_RX>; + bias-disable; + input-enable; + }; + spi0_cs_default: spi0_cs_default { + pinmux = <11 IOC_PORT_MCU_SSI0_FSS>; + bias-disable; + }; + + /* On-board antenna pinmux states */ + board_ant_24g_off: board_ant_24g_off { + pinmux = <28 IOC_PORT_GPIO>; + }; + board_ant_24g_on: board_ant_24g_on { + pinmux = <28 IOC_PORT_RFC_GPO0>; + }; + board_ant_tx_pa_off: board_ant_tx_pa_off { + pinmux = <29 IOC_PORT_GPIO>; + }; + board_ant_tx_pa_on: board_ant_tx_pa_on { + pinmux = <29 IOC_PORT_RFC_GPO3>; + }; + board_ant_subg_off: board_ant_subg_off { + pinmux = <30 IOC_PORT_GPIO>; + }; + board_ant_subg_on: board_ant_subg_on { + pinmux = <30 IOC_PORT_RFC_GPO0>; + }; +}; diff --git a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts new file mode 100644 index 00000000000..af7f3de82dd --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.dts @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2021 Florin Stancu + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include "../cc1352r1_launchxl/boosterpack_connector.dtsi" +#include "cc1352p1_launchxl-pinctrl.dtsi" + +/ { + model = "TI CC1352P1 LaunchXL"; + compatible = "ti,launchxl-cc1352p1"; + + aliases { + led0 = &led0; + led1 = &led1; + sw0 = &btn0; + sw1 = &btn1; + }; + + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,ieee802154 = &ieee802154; + }; + + /** + * The CC1352P LAUNCHXL has an on-board antenna switch (SKY13317-373LF) used to select the + * appropriate RF signal port based on the currently-used PHY. + * + * Truth table: + * + * Path DIO28 DIO29 DIO30 + * =========== ===== ===== ===== + * Off 0 0 0 + * Sub-1 GHz 0 0 1 // DIO30 mux to IOC_PORT_RFC_GPO0 for auto + * 2.4 GHz 1 0 0 // DIO28 mux to IOC_PORT_RFC_GPO0 for auto + * 20 dBm TX 0 1 0 // DIO29 mux to IOC_PORT_RFC_GPO3 for auto + */ + antenna_mux0: antenna_mux0 { + compatible = "skyworks,sky13317"; + status = "okay"; + gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>, <&gpio0 29 GPIO_ACTIVE_HIGH>, \ + <&gpio0 30 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&board_ant_24g_off &board_ant_tx_pa_off &board_ant_subg_off>; + pinctrl-1 = <&board_ant_24g_on &board_ant_tx_pa_off &board_ant_subg_off>; + pinctrl-2 = <&board_ant_24g_on &board_ant_tx_pa_on &board_ant_subg_off>; + pinctrl-3 = <&board_ant_24g_off &board_ant_tx_pa_off &board_ant_subg_on>; + pinctrl-4 = <&board_ant_24g_off &board_ant_tx_pa_on &board_ant_subg_on>; + pinctrl-names = "default", "ant_24g", "ant_24g_pa", "ant_subg", "ant_subg_pa"; + }; + + leds { + compatible = "gpio-leds"; + led0: led_0 { + gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; + label = "Green LED"; + }; + led1: led_1 { + gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; + label = "Red LED"; + }; + }; + + keys { + compatible = "gpio-keys"; + btn0: btn_0 { + gpios = <&gpio0 15 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "Push button 1"; + }; + btn1: btn_1 { + gpios = <&gpio0 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "Push button 2"; + }; + }; + + power-states { + idle: idle { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <1000>; + }; + + standby: standby { + compatible = "zephyr,power-state"; + power-state-name = "standby"; + min-residency-us = <5000>; + exit-latency-us = <240>; + }; + }; +}; + +&cpu0 { + clock-frequency = <48000000>; + cpu-power-states = <&idle &standby>; +}; + +&trng { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&uart0 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart0_rx_default &uart0_tx_default>; + pinctrl-names = "default"; +}; + +&i2c0 { + status = "okay"; + pinctrl-0 = <&i2c0_scl_default &i2c0_sda_default>; + pinctrl-1 = <&i2c0_scl_sleep &i2c0_sda_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&spi0 { + status = "okay"; + pinctrl-0 = <&spi0_sck_default &spi0_mosi_default + &spi0_miso_default &spi0_cs_default>; + pinctrl-names = "default"; + cs-gpios = <&gpio0 11 GPIO_ACTIVE_LOW>; +}; + +&rtc { + status = "okay"; +}; + +&radio { + status = "okay"; +}; + +&ieee802154 { + status = "okay"; +}; + +&ieee802154g { + status = "disabled"; +}; diff --git a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml new file mode 100644 index 00000000000..38d1d7505fb --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl.yaml @@ -0,0 +1,14 @@ +identifier: cc1352p1_launchxl +name: TI SimpleLink CC1352P LaunchPad +type: mcu +arch: arm +ram: 80 +flash: 352 +toolchain: + - zephyr + - gnuarmemb + - xtools +supported: + - gpio + - i2c + - spi diff --git a/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl_defconfig b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl_defconfig new file mode 100644 index 00000000000..45a87b265cc --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/cc1352p1_launchxl_defconfig @@ -0,0 +1,27 @@ +# +# Copyright (c) 2021 Florin Stancu +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SOC_SERIES_CC13X2_CC26X2=y +CONFIG_SOC_CC1352P=y +CONFIG_BOARD_CC1352P1_LAUNCHXL=y +CONFIG_BUILD_OUTPUT_HEX=y +# custom callback for the antenna switch +CONFIG_CC13X2_CC26X2_HAS_CUSTOM_RF_HWATTRS=y + +CONFIG_CC13X2_CC26X2_BOOTLOADER_ENABLE=y +CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_ENABLE=y +CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_PIN=15 + +# Enable MPU and hardware stack protection +CONFIG_ARM_MPU=y +CONFIG_HW_STACK_PROTECTION=y + +CONFIG_PINCTRL=y +CONFIG_GPIO=y +CONFIG_SERIAL=y + +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/arm/cc1352p1_launchxl/doc/img/cc1352p1_launchxl.jpg b/boards/arm/cc1352p1_launchxl/doc/img/cc1352p1_launchxl.jpg new file mode 100644 index 0000000000000000000000000000000000000000..53a8647e7182f5cddbabf4e8c06e3ff315d7c90f GIT binary patch literal 41693 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 literal 0 HcmV?d00001 diff --git a/boards/arm/cc1352p1_launchxl/doc/index.rst b/boards/arm/cc1352p1_launchxl/doc/index.rst new file mode 100644 index 00000000000..8087a38d71e --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/doc/index.rst @@ -0,0 +1,244 @@ +.. _cc1352p1_launchxl: + +CC1352P1 LaunchXL +################# + +Overview +******** + +The Texas Instruments CC1352P LaunchPad |trade| (LAUNCHXL-CC1352P1) is a +development kit for the SimpleLink |trade| multi-Standard CC1352P wireless MCU. + +See the `TI CC1352P LaunchPad Product Page`_ for details. + +.. figure:: img/cc1352p1_launchxl.jpg + :width: 400px + :align: center + :alt: TI CC1352P1 LaunchPad + + Texas Instruments CC1352P1 LaunchPad |trade| + +Hardware +******** + +The CC1352P LaunchPad |trade| development kit features the CC1352P wireless MCU. +The board is equipped with two LEDs, two push buttons, antenna switch and +BoosterPack connectors for expansion. It also includes an integrated (XDS110) +debugger. + +The CC1352P wireless MCU has a 48 MHz Arm |reg| Cortex |reg|-M4F SoC and an +integrated sub-1GHz and 2.4 GHz transceiver with integrated 20dBm power amplifier +(PA) supporting multiple protocols including Bluetooth |reg| Low Energy and IEEE +|reg| 802.15.4. + +See the `TI CC1352P Product Page`_ for additional details. + +Supported Features +================== + +The CC1352P LaunchPad board configuration supports the following hardware +features: + ++-----------+------------+----------------------+ +| Interface | Controller | Driver/Component | ++===========+============+======================+ +| GPIO | on-chip | gpio | ++-----------+------------+----------------------+ +| MPU | on-chip | arch/arm | ++-----------+------------+----------------------+ +| NVIC | on-chip | arch/arm | ++-----------+------------+----------------------+ +| PINMUX | on-chip | pinmux | ++-----------+------------+----------------------+ +| UART | on-chip | serial | ++-----------+------------+----------------------+ +| I2C | on-chip | i2c | ++-----------+------------+----------------------+ +| SPI | on-chip | spi | ++-----------+------------+----------------------+ + +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 | ++=======+===========+=====================+ +| DIO3 | GPIO | | ++-------+-----------+---------------------+ +| DIO4 | I2C_MSSCL | I2C SCL | ++-------+-----------+---------------------+ +| DIO5 | I2C_MSSDA | I2C SDA | ++-------+-----------+---------------------+ +| DIO6 | GPIO | Red LED | ++-------+-----------+---------------------+ +| DIO7 | GPIO | Green LED | ++-------+-----------+---------------------+ +| DIO8 | SSI0_RX | SPI MISO | ++-------+-----------+---------------------+ +| DIO9 | SSI0_TX | SPI MOSI | ++-------+-----------+---------------------+ +| DIO10 | SSI0_CLK | SPI CLK | ++-------+-----------+---------------------+ +| DIO11 | SSIO_CS | SPI CS | ++-------+-----------+---------------------+ +| DIO12 | UART0_RX | UART RXD | ++-------+-----------+---------------------+ +| DIO13 | UART0_TX | UART TXD | ++-------+-----------+---------------------+ +| DIO14 | GPIO | Button 2 | ++-------+-----------+---------------------+ +| DIO15 | GPIO | Button 1 | ++-------+-----------+---------------------+ +| DIO16 | | JTAG TDO | ++-------+-----------+---------------------+ +| DIO17 | | JTAG TDI | ++-------+-----------+---------------------+ +| DIO18 | UART0_RTS | UART RTS / JTAG SWO | ++-------+-----------+---------------------+ +| DIO19 | UART0_CTS | UART CTS | ++-------+-----------+---------------------+ +| DIO20 | GPIO | Flash CS | ++-------+-----------+---------------------+ +| DIO21 | GPIO | | ++-------+-----------+---------------------+ +| DIO22 | GPIO | | ++-------+-----------+---------------------+ +| DIO23 | AUX_IO | A0 | ++-------+-----------+---------------------+ +| DIO24 | AUX_IO | A1 | ++-------+-----------+---------------------+ +| DIO25 | AUX_IO | A2 | ++-------+-----------+---------------------+ +| DIO26 | AUX_IO | A3 | ++-------+-----------+---------------------+ +| DIO27 | AUX_IO | A4 | ++-------+-----------+---------------------+ +| DIO28 | AUX_IO | A5 | ++-------+-----------+---------------------+ +| DIO29 | AUX_IO | A6 | ++-------+-----------+---------------------+ +| DIO30 | AUX_IO | A7 | ++-------+-----------+---------------------+ + +Programming and Debugging +************************* + +Before flashing or debugging ensure the RESET, TMS, TCK, TDO, and TDI jumpers +are in place. Also place jumpers on the the TXD and RXD signals for a serial +console using the XDS110 application serial port. + +Prerequisites: +============== + +#. Ensure the XDS-110 emulation firmware on the board is updated. + + Download and install the latest `XDS-110 emulation package`_. + + Follow these `xds110 firmware update directions + `_ + + Note that the emulation package install may place the xdsdfu utility + in ``/ccs_base/common/uscif/xds110/``. + +#. Install OpenOCD + + You can obtain OpenOCD by following these + :ref:`installing the latest Zephyr SDK instructions `. + + After the installation, add the directory containing the OpenOCD executable + to your environment's PATH variable. For example, use this command in Linux: + + .. code-block:: console + + export PATH=$ZEPHYR_SDK_INSTALL_DIR/sysroots/x86_64-pokysdk-linux/usr/bin/openocd:$PATH + +Flashing +======== + +Applications for the ``CC1352P LaunchPad`` board configuration can be built and +flashed in the usual way (see :ref:`build_an_application` and +:ref:`application_run` for more details). + +Here is an example for the :ref:`hello_world` application. + +First, run your favorite terminal program to listen for output. + +.. code-block:: console + + $ screen 115200 + +Replace :code:`` with the port where the XDS110 application +serial device can be found. For example, :code:`/dev/ttyACM0`. + +Then build and flash the application in the usual way. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cc1352p1_launchxl + :goals: build flash + +Debugging +========= + +You can debug an application in the usual way. Here is an example for the +:ref:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: cc1352p1_launchxl + :maybe-skip-config: + :goals: debug + +Bootloader +========== + +The ROM bootloader on CC13x2 and CC26x2 devices is enabled by default. The +bootloader will start if there is no valid application image in flash or the +so-called backdoor is enabled (via option +:kconfig:option:`CONFIG_CC13X2_CC26X2_BOOTLOADER_BACKDOOR_ENABLE`) and BTN-1 is held +down during reset. See the bootloader documentation in chapter 10 of the `TI +CC13x2 / CC26x2 Technical Reference Manual`_ for additional information. + +Power Management and UART +========================= + +System and device power management are supported on this platform, and +can be enabled via the standard Kconfig options in Zephyr, such as +:kconfig:option:`CONFIG_PM`, :kconfig:option:`CONFIG_PM_DEVICE`. + +When system power management is turned on (CONFIG_PM=y), +sleep state 2 (standby mode) is allowed, and polling is used to retrieve input +by calling uart_poll_in(), it is possible for characters to be missed if the +system enters standby mode between calls to uart_poll_in(). This is because +the UART is inactive while the system is in standby mode. The workaround is to +disable sleep state 2 while polling: + +.. code-block:: c + + pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + + pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); + + +References +********** + +CC1352P1 LaunchPad Quick Start Guide: + http://www.ti.com/lit/pdf/swru525 + +.. _TI CC1352P LaunchPad Product Page: + https://www.ti.com/tool/LAUNCHXL-CC1352P + +.. _TI CC1352P Product Page: + https://www.ti.com/product/CC1352P + +.. _TI CC13x2 / CC26x2 Technical Reference Manual: + http://www.ti.com/lit/pdf/swcu185 + +.. _XDS-110 emulation package: + http://processors.wiki.ti.com/index.php/XDS_Emulation_Software_Package#XDS_Emulation_Software_.28emupack.29_Download diff --git a/boards/arm/cc1352p1_launchxl/dts/bindings/skyworks,sky13317.yaml b/boards/arm/cc1352p1_launchxl/dts/bindings/skyworks,sky13317.yaml new file mode 100644 index 00000000000..b9f92fade40 --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/dts/bindings/skyworks,sky13317.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2022 Stancu Florin +# SPDX-License-Identifier: Apache-2.0 + +description: Skyworks SKY13317 pHEMT GaAs SP3T Antenna Switch + +compatible: "skyworks,sky13317" + +include: [pinctrl-device.yaml, base.yaml] + +properties: + gpios: + type: phandle-array + required: true + description: Antenna mux control pins diff --git a/boards/arm/cc1352p1_launchxl/support/openocd.cfg b/boards/arm/cc1352p1_launchxl/support/openocd.cfg new file mode 100644 index 00000000000..017bb64263b --- /dev/null +++ b/boards/arm/cc1352p1_launchxl/support/openocd.cfg @@ -0,0 +1 @@ +source [find board/ti_cc13x2_launchpad.cfg] diff --git a/drivers/ieee802154/Kconfig.cc13xx_cc26xx b/drivers/ieee802154/Kconfig.cc13xx_cc26xx index a9015283810..50039418e0b 100644 --- a/drivers/ieee802154/Kconfig.cc13xx_cc26xx +++ b/drivers/ieee802154/Kconfig.cc13xx_cc26xx @@ -92,4 +92,19 @@ config IEEE802154_CC13XX_CC26XX_SUB_GHZ_RADIO_TX_RETRIES Number of transmission attempts radio driver should do, before replying it could not send the packet. +config IEEE802154_CC13XX_CC26XX_SUB_GHZ_CUSTOM_RADIO_SETUP + bool "Use custom radio setup structures (advanced)" + default n + help + Imports the radio setup structure from an external module instead of using + the default one. + Allows overriding the RF modulation / protocol settings. + +config IEEE802154_CC13XX_CC26XX_SUB_GHZ_CUSTOM_POWER_TABLE + bool "Use custom power table structure (advanced)" + default n + help + Imports the radio power table from an external module. + Allows overriding the RF modulation settings. + endif # IEEE802154_CC13XX_CC26XX_SUB_GHZ diff --git a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c index e2b7c66d0ef..1e550cfe02c 100644 --- a/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c +++ b/drivers/ieee802154/ieee802154_cc13xx_cc26xx_subg.c @@ -50,9 +50,17 @@ static void ieee802154_cc13xx_cc26xx_subg_setup_rx_buffers( #define CMD_PROP_RADIO_DIV_SETUP_PA CMD_PROP_RADIO_DIV_SETUP #endif -/* Radio values for CC13x2R (note: CC26x2 does not support sub-GHz radio) */ +#if defined(CONFIG_IEEE802154_CC13XX_CC26XX_SUB_GHZ_CUSTOM_RADIO_SETUP) +/* User-defined CMD_PROP_RADIO_DIV_SETUP structures */ #if defined(CONFIG_SOC_CC1352R) -/* R overrides from SmartRF Studio (200kbps, 50kHz deviation, 2-GFSK, 311.8kHz Rx BW) */ +extern volatile rfc_CMD_PROP_RADIO_DIV_SETUP_t ieee802154_cc13xx_subg_radio_div_setup; +#elif defined(CONFIG_SOC_CC1352P) +extern volatile rfc_CMD_PROP_RADIO_DIV_SETUP_PA_t ieee802154_cc13xx_subg_radio_div_setup; +#endif /* CONFIG_SOC_CC1352x, extern RADIO_DIV_SETUP */ + +#elif defined(CONFIG_SOC_CC1352R) +/* Radio values for CC13x2R (note: CC26x2 does not support sub-GHz radio) */ +/* From SmartRF Studio (200kbps, 50kHz deviation, 2-GFSK, 311.8kHz Rx BW) */ static uint32_t ieee802154_cc13xx_overrides_sub_ghz[] = { /* DC/DC regulator: In Tx, use DCDCCTL5[3:0]=0x7 (DITHER_EN=0 and IPEAK=7). */ (uint32_t)0x00F788D3, @@ -78,7 +86,7 @@ static uint32_t ieee802154_cc13xx_overrides_sub_ghz[] = { }; /* Radio setup command for CC1312R / CC1352R */ -static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_t ieee802154_cc13xx_radio_div_setup = { +static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_t ieee802154_cc13xx_subg_radio_div_setup = { .commandNo = CMD_PROP_RADIO_DIV_SETUP, .condition.rule = COND_NEVER, .modulation.modType = 1, /* FSK */ @@ -99,32 +107,6 @@ static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_t ieee802154_cc13xx_radio_div_setup .pRegOverride = ieee802154_cc13xx_overrides_sub_ghz, }; -/* Sub GHz power table */ -static const RF_TxPowerTable_Entry txPowerTable_sub_ghz[] = { - { -20, RF_TxPowerTable_DEFAULT_PA_ENTRY(0, 3, 0, 2) }, - { -15, RF_TxPowerTable_DEFAULT_PA_ENTRY(1, 3, 0, 3) }, - { -10, RF_TxPowerTable_DEFAULT_PA_ENTRY(2, 3, 0, 5) }, - { -5, RF_TxPowerTable_DEFAULT_PA_ENTRY(4, 3, 0, 5) }, - { 0, RF_TxPowerTable_DEFAULT_PA_ENTRY(8, 3, 0, 8) }, - { 1, RF_TxPowerTable_DEFAULT_PA_ENTRY(9, 3, 0, 9) }, - { 2, RF_TxPowerTable_DEFAULT_PA_ENTRY(10, 3, 0, 9) }, - { 3, RF_TxPowerTable_DEFAULT_PA_ENTRY(11, 3, 0, 10) }, - { 4, RF_TxPowerTable_DEFAULT_PA_ENTRY(13, 3, 0, 11) }, - { 5, RF_TxPowerTable_DEFAULT_PA_ENTRY(14, 3, 0, 14) }, - { 6, RF_TxPowerTable_DEFAULT_PA_ENTRY(17, 3, 0, 16) }, - { 7, RF_TxPowerTable_DEFAULT_PA_ENTRY(20, 3, 0, 19) }, - { 8, RF_TxPowerTable_DEFAULT_PA_ENTRY(24, 3, 0, 22) }, - { 9, RF_TxPowerTable_DEFAULT_PA_ENTRY(28, 3, 0, 31) }, - { 10, RF_TxPowerTable_DEFAULT_PA_ENTRY(18, 2, 0, 31) }, - { 11, RF_TxPowerTable_DEFAULT_PA_ENTRY(26, 2, 0, 51) }, - { 12, RF_TxPowerTable_DEFAULT_PA_ENTRY(16, 0, 0, 82) }, - { 13, RF_TxPowerTable_DEFAULT_PA_ENTRY(36, 0, 0, 89) }, -#ifdef CC13X2_CC26X2_BOOST_MODE - { 14, RF_TxPowerTable_DEFAULT_PA_ENTRY(63, 0, 1, 0) }, -#endif - RF_TxPowerTable_TERMINATION_ENTRY -}; - /* Radio values for CC13X2P */ #elif defined(CONFIG_SOC_CC1352P) /* CC1352P overrides from SmartRF Studio (200kbps, 50kHz deviation, 2-GFSK, 311.8kHz Rx BW) */ @@ -175,8 +157,8 @@ static uint32_t rf_prop_overrides_tx_20[] = { (uint32_t)0xFFFFFFFF }; -/* Radio setup command for CC1312R / CC1352R */ -static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_PA_t ieee802154_cc13xx_radio_div_setup = { +/* Radio setup command for CC1312P / CC1352P */ +static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_PA_t ieee802154_cc13xx_subg_radio_div_setup = { .commandNo = CMD_PROP_RADIO_DIV_SETUP_PA, .condition.rule = COND_NEVER, .modulation.modType = 1, /* FSK */ @@ -198,9 +180,40 @@ static volatile rfc_CMD_PROP_RADIO_DIV_SETUP_PA_t ieee802154_cc13xx_radio_div_se .pRegOverrideTxStd = rf_prop_overrides_tx_std, .pRegOverrideTx20 = rf_prop_overrides_tx_20, }; +#endif /* CONFIG_SOC_CC1352x, default CMD_PROP_RADIO_DIV_SETUP structures */ +/* Sub GHz power tables */ +#if defined(CONFIG_IEEE802154_CC13XX_CC26XX_SUB_GHZ_CUSTOM_POWER_TABLE) +extern RF_TxPowerTable_Entry ieee802154_cc13xx_subg_power_table[]; + +#elif defined(CONFIG_SOC_CC1352R) +static const RF_TxPowerTable_Entry ieee802154_cc13xx_subg_power_table[] = { + { -20, RF_TxPowerTable_DEFAULT_PA_ENTRY(0, 3, 0, 2) }, + { -15, RF_TxPowerTable_DEFAULT_PA_ENTRY(1, 3, 0, 3) }, + { -10, RF_TxPowerTable_DEFAULT_PA_ENTRY(2, 3, 0, 5) }, + { -5, RF_TxPowerTable_DEFAULT_PA_ENTRY(4, 3, 0, 5) }, + { 0, RF_TxPowerTable_DEFAULT_PA_ENTRY(8, 3, 0, 8) }, + { 1, RF_TxPowerTable_DEFAULT_PA_ENTRY(9, 3, 0, 9) }, + { 2, RF_TxPowerTable_DEFAULT_PA_ENTRY(10, 3, 0, 9) }, + { 3, RF_TxPowerTable_DEFAULT_PA_ENTRY(11, 3, 0, 10) }, + { 4, RF_TxPowerTable_DEFAULT_PA_ENTRY(13, 3, 0, 11) }, + { 5, RF_TxPowerTable_DEFAULT_PA_ENTRY(14, 3, 0, 14) }, + { 6, RF_TxPowerTable_DEFAULT_PA_ENTRY(17, 3, 0, 16) }, + { 7, RF_TxPowerTable_DEFAULT_PA_ENTRY(20, 3, 0, 19) }, + { 8, RF_TxPowerTable_DEFAULT_PA_ENTRY(24, 3, 0, 22) }, + { 9, RF_TxPowerTable_DEFAULT_PA_ENTRY(28, 3, 0, 31) }, + { 10, RF_TxPowerTable_DEFAULT_PA_ENTRY(18, 2, 0, 31) }, + { 11, RF_TxPowerTable_DEFAULT_PA_ENTRY(26, 2, 0, 51) }, + { 12, RF_TxPowerTable_DEFAULT_PA_ENTRY(16, 0, 0, 82) }, + { 13, RF_TxPowerTable_DEFAULT_PA_ENTRY(36, 0, 0, 89) }, +#ifdef CC13X2_CC26X2_BOOST_MODE + { 14, RF_TxPowerTable_DEFAULT_PA_ENTRY(63, 0, 1, 0) }, +#endif + RF_TxPowerTable_TERMINATION_ENTRY +}; +#elif defined(CONFIG_SOC_CC1352P) /* Sub GHz power table */ -static const RF_TxPowerTable_Entry txPowerTable_sub_ghz[] = { +static const RF_TxPowerTable_Entry ieee802154_cc13xx_subg_power_table[] = { { -20, RF_TxPowerTable_DEFAULT_PA_ENTRY(0, 3, 0, 2) }, { -15, RF_TxPowerTable_DEFAULT_PA_ENTRY(1, 3, 0, 3) }, { -10, RF_TxPowerTable_DEFAULT_PA_ENTRY(2, 3, 0, 5) }, @@ -230,8 +243,7 @@ static const RF_TxPowerTable_Entry txPowerTable_sub_ghz[] = { { 20, RF_TxPowerTable_HIGH_PA_ENTRY(18, 3, 0, 71, 27) }, RF_TxPowerTable_TERMINATION_ENTRY }; - -#endif /* CONFIG_SOC_CC1352* */ +#endif /* CONFIG_SOC_CC1352x power table */ /** RF patches to use (note: RF core keeps a pointer to this, so no stack). */ static RF_Mode rf_mode = { @@ -442,7 +454,7 @@ static int ieee802154_cc13xx_cc26xx_subg_set_txpower( RF_Stat status; RF_TxPowerTable_Value power_table_value = RF_TxPowerTable_findValue( - (RF_TxPowerTable_Entry *)txPowerTable_sub_ghz, dbm); + (RF_TxPowerTable_Entry *)ieee802154_cc13xx_subg_power_table, dbm); if (power_table_value.rawValue == RF_TxPowerTable_INVALID_VALUE) { LOG_DBG("RF_TxPowerTable_findValue() failed"); @@ -780,7 +792,7 @@ static int ieee802154_cc13xx_cc26xx_subg_init(const struct device *dev) rf_params.pClientEventCb = client_event_callback; drv_data->rf_handle = RF_open(&drv_data->rf_object, - &rf_mode, (RF_RadioSetup *)&ieee802154_cc13xx_radio_div_setup, + &rf_mode, (RF_RadioSetup *)&ieee802154_cc13xx_subg_radio_div_setup, &rf_params); if (drv_data->rf_handle == NULL) { LOG_ERR("RF_open() failed");