From 2fc0fbcf7e756b1f1e8e3358cca232d3f11d9101 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 24 Jul 2017 16:46:30 -0600 Subject: [PATCH] Squashed commit of the following: commit 89e9d426e91c056e659fccf5e5c4392618f8f777 Author: Gregory Nutt Date: Mon Jul 24 16:44:19 2017 -0600 Update some comments commit 9c5d8a5833350006ed389e898b11c8c8a20e5f4f Author: Gregory Nutt Date: Mon Jul 24 16:15:54 2017 -0600 Spirit: Rename drivers/wireless/spirit/src to lib. Move Spirit network driver out of IEEE802.15.4 into drivers/wireless/spirit/drivers commit cabc0ec9e6eb558dcb715ab17264383aa0105e7a Merge: 87b616414a 6bd744c4b3 Author: Gregory Nutt Date: Mon Jul 24 15:38:40 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 87b616414a79c01a71acea78f8258e05325c1996 Author: Gregory Nutt Date: Mon Jul 24 15:37:27 2017 -0600 Spirit radio driver is mutating into a standalone network driver. commit 507798233868a661ae8adad3e3aa117075a7a146 Author: Gregory Nutt Date: Mon Jul 24 13:32:08 2017 -0600 Spirit: More radio initialization logic commit 33af25704ce9ca83d576300d153cfe31cc6d2576 Author: Gregory Nutt Date: Mon Jul 24 12:19:14 2017 -0600 Spirit: Beginning of radio initialization logic commit 97b20014c016e55952a8f9d8f4ae29e2cc555b23 Author: Gregory Nutt Date: Mon Jul 24 09:42:06 2017 -0600 Spirit: More initialization logic. commit 295d8e27824c0417fccea2344b30bb5c93ffbabe Author: Gregory Nutt Date: Sun Jul 23 15:39:53 2017 -0600 Spirit: Add header file containing enumeration of commands. commit 8a2d9dd8eb9cc70cbcdd1b913fc9022b9c9ec8da Author: Gregory Nutt Date: Sun Jul 23 11:33:50 2017 -0600 Spirit: Add GPIO initialization logic commit 8b6d80c44f92024c45a6ba63ba1af3fdafe94dc3 Author: Gregory Nutt Date: Sun Jul 23 10:07:25 2017 -0600 Spirit: Add interrupt control logic. commit 423f846fe5c914f92a4bfea4d9d1fa33de1c77a5 Author: Gregory Nutt Date: Sat Jul 22 19:06:52 2017 -0600 Spirit: Yet a little more radio initialization logic. commit 5895b979823e51ddde5ad52e6de66a8ad662e883 Author: Gregory Nutt Date: Sat Jul 22 15:36:05 2017 -0600 Spirit: A little more radio initialization logic. commit 86311ab30aad386203c181c792847dd1d37f9a02 Author: Gregory Nutt Date: Sat Jul 22 13:02:32 2017 -0600 Spirit: A miniscule amount of radio initialization logic. commit ad55e89d5ee12ea1eeea95fcd38ff3da0db4416a Merge: 90a7666655 f4e46b0da7 Author: Gregory Nutt Date: Sat Jul 22 10:56:30 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 90a766665534b05da0157dbc383cb06a98c86a79 Author: Gregory Nutt Date: Sat Jul 22 10:52:52 2017 -0600 Spirit1: A few fixes for a clean build of initial configuration (not much there yet) commit bbbf04c223230a52a7705a2161128265cfbaa480 Merge: 623d54a7f7 2319ea53a9 Author: Gregory Nutt Date: Sat Jul 22 09:53:57 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 623d54a7f719e9032099f88f38203efee4b80722 Author: Gregory Nutt Date: Sat Jul 22 09:43:52 2017 -0600 b-l475e-iot01a: Add a configuration for testing sprit radio. commit d309d73d9f4665f9d870eb03531f450043d9389d Merge: 52c3ddfae6 d88dc9b2e5 Author: Gregory Nutt Date: Sat Jul 22 09:02:06 2017 -0600 Merge remote-tracking branch 'origin/master' into spirit commit 52c3ddfae6802e111c2b5cf1207baf21a61dd00b Author: Gregory Nutt Date: Sat Jul 22 08:33:04 2017 -0600 Spirit: Add register definition header file. commit 8d842ab5e8f9ca653b42f9ee88dc279f06b4fa98 Author: Gregory Nutt Date: Fri Jul 21 17:27:03 2017 -0600 b-l475e-iot01a: Add initial, unverified support for the SPSRGF/Spirit1 module. commit 73d902a1048616fb9c2dd2147cabcd8ee78e19ac Author: Gregory Nutt Date: Fri Jul 21 15:49:43 2017 -0600 Spirit: Fixes to get skeleton IEEE 802.15.4 driver build. commit ebc5a8387bb94f0cc3827533795f3e4a33207e67 Author: Gregory Nutt Date: Fri Jul 21 15:16:29 2017 -0600 Spirit1: Add framework for IEEE 802.15.4 driver. Does not yet build. commit 52e195a7ae14ddb18bdd56258f4877381d2501ca Author: Gregory Nutt Date: Fri Jul 21 14:02:42 2017 -0600 Spirit: A little more SPI logic. commit 90048d0c5b8a5af4d81a15d99535c84ed38d8ae9 Author: Gregory Nutt Date: Fri Jul 21 11:19:06 2017 -0600 Spirit: Build directories setup. Some initial files added, mostly just to verify build. commit 8273a381ac1f6bb081b292b5e73226185e9e634c Author: Gregory Nutt Date: Fri Jul 21 08:34:04 2017 -0600 USB composite: Remove references to CDC/ACM and USB MSC from composite logic. They are no longer coupled. --- arch/arm/src/stm32l4/stm32l4_spi.c | 4 +- .../include/b-l475e-iot01a_clock.h | 14 +- configs/b-l475e-iot01a/include/board.h | 72 +- configs/b-l475e-iot01a/spirit-mac/defconfig | 61 + configs/b-l475e-iot01a/src/Makefile | 6 +- configs/b-l475e-iot01a/src/b-l475e-iot01a.h | 102 +- configs/b-l475e-iot01a/src/stm32_boot.c | 11 + configs/b-l475e-iot01a/src/stm32_bringup.c | 10 + configs/b-l475e-iot01a/src/stm32_spi.c | 252 ++ configs/b-l475e-iot01a/src/stm32_spirit.c | 285 ++ .../include/stm32l476vg-disco-clocking.h | 10 +- drivers/usbdev/composite.h | 9 - drivers/wireless/Kconfig | 1 + drivers/wireless/Make.defs | 12 +- drivers/wireless/spirit/Kconfig | 26 + drivers/wireless/spirit/Make.defs | 43 + drivers/wireless/spirit/drivers/Kconfig | 17 + drivers/wireless/spirit/drivers/Make.defs | 49 + .../wireless/spirit/drivers/spirit_netdev.c | 1290 +++++++++ drivers/wireless/spirit/include/Make.defs | 39 + .../wireless/spirit/include/spirit_commands.h | 147 + .../wireless/spirit/include/spirit_config.h | 46 + .../wireless/spirit/include/spirit_general.h | 135 + drivers/wireless/spirit/include/spirit_gpio.h | 238 ++ drivers/wireless/spirit/include/spirit_irq.h | 455 ++++ .../spirit/include/spirit_management.h | 79 + .../wireless/spirit/include/spirit_pktbasic.h | 209 ++ .../spirit/include/spirit_pktcommon.h | 205 ++ drivers/wireless/spirit/include/spirit_qi.h | 194 ++ .../wireless/spirit/include/spirit_radio.h | 720 +++++ drivers/wireless/spirit/include/spirit_regs.h | 2379 +++++++++++++++++ drivers/wireless/spirit/include/spirit_spi.h | 204 ++ .../wireless/spirit/include/spirit_timer.h | 146 + .../wireless/spirit/include/spirit_types.h | 162 ++ drivers/wireless/spirit/lib/Make.defs | 44 + drivers/wireless/spirit/lib/spirit_gpio.c | 101 + drivers/wireless/spirit/lib/spirit_irq.c | 324 +++ .../wireless/spirit/lib/spirit_management.c | 89 + drivers/wireless/spirit/lib/spirit_pktbasic.c | 92 + drivers/wireless/spirit/lib/spirit_qi.c | 224 ++ drivers/wireless/spirit/lib/spirit_radio.c | 1449 ++++++++++ drivers/wireless/spirit/lib/spirit_spi.c | 421 +++ drivers/wireless/spirit/lib/spirit_timer.c | 141 + include/nuttx/usb/composite.h | 18 - include/nuttx/wireless/spirit.h | 104 + 45 files changed, 10587 insertions(+), 52 deletions(-) create mode 100644 configs/b-l475e-iot01a/spirit-mac/defconfig create mode 100644 configs/b-l475e-iot01a/src/stm32_spi.c create mode 100644 configs/b-l475e-iot01a/src/stm32_spirit.c create mode 100644 drivers/wireless/spirit/Kconfig create mode 100644 drivers/wireless/spirit/Make.defs create mode 100644 drivers/wireless/spirit/drivers/Kconfig create mode 100644 drivers/wireless/spirit/drivers/Make.defs create mode 100644 drivers/wireless/spirit/drivers/spirit_netdev.c create mode 100644 drivers/wireless/spirit/include/Make.defs create mode 100644 drivers/wireless/spirit/include/spirit_commands.h create mode 100644 drivers/wireless/spirit/include/spirit_config.h create mode 100644 drivers/wireless/spirit/include/spirit_general.h create mode 100644 drivers/wireless/spirit/include/spirit_gpio.h create mode 100644 drivers/wireless/spirit/include/spirit_irq.h create mode 100644 drivers/wireless/spirit/include/spirit_management.h create mode 100644 drivers/wireless/spirit/include/spirit_pktbasic.h create mode 100644 drivers/wireless/spirit/include/spirit_pktcommon.h create mode 100644 drivers/wireless/spirit/include/spirit_qi.h create mode 100644 drivers/wireless/spirit/include/spirit_radio.h create mode 100644 drivers/wireless/spirit/include/spirit_regs.h create mode 100644 drivers/wireless/spirit/include/spirit_spi.h create mode 100644 drivers/wireless/spirit/include/spirit_timer.h create mode 100644 drivers/wireless/spirit/include/spirit_types.h create mode 100644 drivers/wireless/spirit/lib/Make.defs create mode 100644 drivers/wireless/spirit/lib/spirit_gpio.c create mode 100644 drivers/wireless/spirit/lib/spirit_irq.c create mode 100644 drivers/wireless/spirit/lib/spirit_management.c create mode 100644 drivers/wireless/spirit/lib/spirit_pktbasic.c create mode 100644 drivers/wireless/spirit/lib/spirit_qi.c create mode 100644 drivers/wireless/spirit/lib/spirit_radio.c create mode 100644 drivers/wireless/spirit/lib/spirit_spi.c create mode 100644 drivers/wireless/spirit/lib/spirit_timer.c create mode 100644 include/nuttx/wireless/spirit.h diff --git a/arch/arm/src/stm32l4/stm32l4_spi.c b/arch/arm/src/stm32l4/stm32l4_spi.c index 67efad4aa8..856de17230 100644 --- a/arch/arm/src/stm32l4/stm32l4_spi.c +++ b/arch/arm/src/stm32l4/stm32l4_spi.c @@ -79,8 +79,6 @@ #include #include -#include - #include "up_internal.h" #include "up_arch.h" @@ -90,6 +88,8 @@ #include "stm32l4_dma.h" #include "stm32l4_spi.h" +#include + #if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || \ defined(CONFIG_STM32L4_SPI3) diff --git a/configs/b-l475e-iot01a/include/b-l475e-iot01a_clock.h b/configs/b-l475e-iot01a/include/b-l475e-iot01a_clock.h index 98d789327e..16e8300d43 100644 --- a/configs/b-l475e-iot01a/include/b-l475e-iot01a_clock.h +++ b/configs/b-l475e-iot01a/include/b-l475e-iot01a_clock.h @@ -48,18 +48,18 @@ * Pre-processor Definitions ************************************************************************************/ +/* Clocking *************************************************************************/ + #if 1 -# define HSI_CLOCK_CONFIG /* HSI-16 clock configuration */ +# define HSI_CLOCK_CONFIG 1 /* HSI-16 clock configuration */ #elif 0 /* Make sure you installed one! */ -# define HSE_CLOCK_CONFIG /* HSE with 8 MHz xtal */ +# define HSE_CLOCK_CONFIG 1 /* HSE with 8 MHz xtal */ #else -# define MSI_CLOCK_CONFIG /* MSI @ 4 MHz autotrimmed via LSE */ +# define MSI_CLOCK_CONFIG 1 /* MSI @ 4 MHz autotrimmed via LSE */ #endif -/* Clocking *************************************************************************/ - #if defined(HSI_CLOCK_CONFIG) /* The STMicro IoT board supports both HSE and LSE crystals. As shipped, the HSE * crystal (X1) is not populated. Therefore the STMicro IoT board will need to run off the @@ -265,7 +265,7 @@ #define STM32L4_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */ #define STM32L4_HCLK_FREQUENCY STM32L4_SYSCLK_FREQUENCY -#define STM32L4_BOARD_HCLK STM32L4_HCLK_FREQUENCY /* Same as above, to satisfy compiler */ +#define STM32L4_BOARD_HCLK STM32L4_HCLK_FREQUENCY /* Same as above, to satisfy compiler */ /* APB1 clock (PCLK1) is HCLK/1 (80MHz) */ @@ -401,7 +401,7 @@ #define STM32L4_PLLCFG_PLLP 0 #undef STM32L4_PLLCFG_PLLP_ENABLED #define STM32L4_PLLCFG_PLLQ 0 -#undef STM32L4_PLLCFG_PLLQ_ENABLED +#undef STM32L4_PLLCFG_PLLQ_ENABLED #define STM32L4_PLLCFG_PLLR RCC_PLLCFG_PLLR_2 #define STM32L4_PLLCFG_PLLR_ENABLED diff --git a/configs/b-l475e-iot01a/include/board.h b/configs/b-l475e-iot01a/include/board.h index 6c10a3aab9..0a08e2eafa 100644 --- a/configs/b-l475e-iot01a/include/board.h +++ b/configs/b-l475e-iot01a/include/board.h @@ -46,8 +46,6 @@ # include #endif -#include - /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ @@ -97,6 +95,55 @@ * 2Hz, then a fatal error has been detected and the system has halted. */ +/* SPSGRF-915 Spirit1 library definitions ***********************************(*******/ + +/* The TX_WAIT_PCKT_PERIOD should equal the max packet tx time. */ + +#define SPIRIT_TX_WAIT_PCKT_PERIOD 50 + +/* The RX_WAIT_ACK_PERIOD is the period within which the ACK packet must be received. + * ca PACKET_LENGTH / DATA_RATE + ELABORATION_TIME + SPI_OPERATIONS_USED. + */ + +#define SPIRIT_RX_WAIT_ACK_PERIOD 50 + +#define SPIRIT_CCA_THRESHOLD -90.0 /* dBm */ +#define SPIRIT_XTAL_FREQUENCY 50000000 /* Hz */ +#define SPIRIT_XTAL_OFFSET_PPM 0 +#define SPIRIT_BASE_FREQUENCY 868.0e6 +#define SPIRIT_CHANNEL_SPACE 20e3 +#define SPIRIT_CHANNEL_NUMBER 0 +#define SPIRIT_MODULATION_SELECT FSK +#define SPIRIT_DATARATE 38400 +#define SPIRIT_FREQ_DEVIATION 20e3 +#define SPIRIT_BANDWIDTH 100.5E3 +#define SPIRIT_POWER_DBM 10.0 +#define SPIRIT_PREAMBLE_LENGTH PKT_PREAMBLE_LENGTH_04BYTES +#define SPIRIT_SYNC_LENGTH PKT_SYNC_LENGTH_4BYTES +#define SPIRIT_SYNC_WORD 0x88888888 +#define SPIRIT_LENGTH_TYPE PKT_LENGTH_VAR +#define SPIRIT_LENGTH_WIDTH 8 +#define SPIRIT_CRC_MODE PKT_CRC_MODE_16BITS_2 +#define SPIRIT_CONTROL_LENGTH PKT_CONTROL_LENGTH_0BYTES +#define SPIRIT_EN_ADDRESS S_DISABLE +#define SPIRIT_EN_FEC S_DISABLE +#define SPIRIT_EN_WHITENING S_DISABLE +#define SPIRIT_MAX_FIFO_LEN 96 +#define SPIRIT_RANGE_TYPE RANGE_EXT_NONE /* RANGE_EXT_SKYWORKS */ + +/* The MAX_PACKET_LEN is an arbitrary value used to define the two array + * spirit_txbuf and spirit_rxbuf. + * + * The SPIRIT1 supports with its packet handler a length of 65,535 bytes, + * and in direct mode (without packet handler) there is no limit of data. + */ + +#define SPIRIT_MAX_PACKET_LEN SPIRIT_MAX_FIFO_LEN + +/* Spirit1 IC version */ + +#define SPIRIT_VERSION SPIRIT_VERSION_3_0 + /* Alternate function pin selections ************************************************/ /* USART1: Connected to STLink Debug via PB6, PB7 */ @@ -109,6 +156,27 @@ #define GPIO_UART4_RX GPIO_UART4_RX_1 #define GPIO_UART4_TX GPIO_UART4_TX_1 +/* SPSGRF + * + * -------- ----------------------- ---------------- + * SPSGRF Board Signal STM32L4 pin + * -------- ----------------------- ---------------- + * SPI_CLK INTERNAL-SPI3_SCK PC10 SPI3_SCK + * SPI_MISO INTERNAL-SPI3_MISO PC11 SPI3_MISO + * SPI_MOSI INTERNAL-SPI3_MOSI PC12 SPI3_MOSI + * SPI_CS SPSGRF-915-SPI3_CSN PB5 GPIO_Output + * GPIO(3) SPSGRF-915-GPIO3_EXTI5 PE5 GPIO_EXTI5 + * GPIO(2) N/C N/A + * GPIO(1) N/C N/A + * GPIO(0) N/C N/A + * SDN SPSGRF-915-SDN PB15 GPIO_Output + * -------- ----------------------- ---------------- + */ + +#define GPIO_SPI3_SCK GPIO_SPI3_SCK_2 +#define GPIO_SPI3_MISO GPIO_SPI3_MISO_2 +#define GPIO_SPI3_MOSI GPIO_SPI3_MOSI_2 + /************************************************************************************ * Public Data ************************************************************************************/ diff --git a/configs/b-l475e-iot01a/spirit-mac/defconfig b/configs/b-l475e-iot01a/spirit-mac/defconfig new file mode 100644 index 0000000000..949577a205 --- /dev/null +++ b/configs/b-l475e-iot01a/spirit-mac/defconfig @@ -0,0 +1,61 @@ +# CONFIG_NET_ETHERNET is not set +# CONFIG_NET_IPv4 is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_DF_H is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +CONFIG_ARCH_BOARD_B_L475E_IOT01A=y +CONFIG_ARCH_BOARD="b-l475e-iot01a" +CONFIG_ARCH_CHIP_STM32L4=y +CONFIG_ARCH_CHIP_STM32L475VG=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_ARCH="arm" +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_DISABLE_POLL=y +CONFIG_DRIVERS_IEEE802154=y +CONFIG_DRIVERS_WIRELESS=y +CONFIG_EXAMPLES_NSH=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_IEEE802154_I8SAK=y +CONFIG_IEEE802154_MACDEV=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBM=y +CONFIG_MAX_TASKS=16 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_MM_REGIONS=2 +CONFIG_NET_6LOWPAN=y +CONFIG_NET_IPv6=y +CONFIG_NET=y +CONFIG_NETDEV_LATEINIT=y +CONFIG_NETDEVICES=y +CONFIG_NFILE_DESCRIPTORS=8 +CONFIG_NFILE_STREAMS=8 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_MQ_MSGS=4 +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PREALLOC_WDOGS=16 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_SPIRIT_NETDEV=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32L4_SPI3=y +CONFIG_STM32L4_UART4=y +CONFIG_UART4_SERIAL_CONSOLE=y +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_WATCHDOG=y +CONFIG_WIRELESS_IEEE802154=y +CONFIG_WIRELESS=y diff --git a/configs/b-l475e-iot01a/src/Makefile b/configs/b-l475e-iot01a/src/Makefile index 1eb8cab4da..501a72c1d5 100644 --- a/configs/b-l475e-iot01a/src/Makefile +++ b/configs/b-l475e-iot01a/src/Makefile @@ -35,7 +35,7 @@ -include $(TOPDIR)/Make.defs ASRCS = -CSRCS = stm32_boot.c stm32_bringup.c +CSRCS = stm32_boot.c stm32_bringup.c stm32_spi.c ifeq ($(CONFIG_LIB_BOARDCTL),y) CSRCS += stm32_appinit.c @@ -47,4 +47,8 @@ else CSRCS += stm32_userleds.c endif +ifeq ($(CONFIG_SPIRIT_NETDEV),y) +CSRCS += stm32_spirit.c +endif + include $(TOPDIR)/configs/Board.mk diff --git a/configs/b-l475e-iot01a/src/b-l475e-iot01a.h b/configs/b-l475e-iot01a/src/b-l475e-iot01a.h index 390becb9df..cc2ef3a9a7 100644 --- a/configs/b-l475e-iot01a/src/b-l475e-iot01a.h +++ b/configs/b-l475e-iot01a/src/b-l475e-iot01a.h @@ -48,12 +48,77 @@ * Pre-processor Definitions ****************************************************************************/ +/* Configuration ************************************************************/ + +#define HAVE_SPSGRF 1 + +/* SPSGRF support depends on: + * + * CONFIG_STM32L4_SPI3 - SPI3 support + * CONFIG_WL_SPIRIT - Spirit wireless library + * CONFIG_SPIRIT_NETDEV - Spirit network driver + * CONFIG_SCHED_HPWORK - HP work queue support + * CONFIG_SCHED_LPWORK - LP work queue support + * CONFIG_NET - Networking enabled + * CONFIG_NET_6LOWPAN - 6LoWPAN stack enabled + * + * And probably a few other things. + */ + +#if !defined(CONFIG_STM32L4_SPI3) +# undef HAVE_SPSGRF +#endif + +#if !defined(CONFIG_WL_SPIRIT) || !defined(CONFIG_SPIRIT_NETDEV) +# undef HAVE_SPSGRF +#endif + +#if !defined(CONFIG_SCHED_HPWORK) || !defined(CONFIG_SCHED_LPWORK) +# undef HAVE_SPSGRF +#endif + +#if !defined(CONFIG_NET) || !defined(CONFIG_NET_6LOWPAN) +# undef HAVE_SPSGRF +#endif + +/* GPIO Definitions *********************************************************/ /* LEDs */ -#define GPIO_LED1 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ - GPIO_OUTPUT_CLEAR|GPIO_PORTA|GPIO_PIN5) -#define GPIO_LED2 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\ - GPIO_OUTPUT_CLEAR|GPIO_PORTB|GPIO_PIN14) +#define GPIO_LED1 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz |\ + GPIO_OUTPUT_CLEAR | GPIO_PORTA | GPIO_PIN5) +#define GPIO_LED2 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz |\ + GPIO_OUTPUT_CLEAR | GPIO_PORTB | GPIO_PIN14) + +/* SPSGRF + * + * -------- ----------------------- ---------------- + * SPSGRF Board Signal STM32L4 pin + * -------- ----------------------- ---------------- + * SPI_CLK INTERNAL-SPI3_SCK PC10 SPI3_SCK + * SPI_MISO INTERNAL-SPI3_MISO PC11 SPI3_MISO + * SPI_MOSI INTERNAL-SPI3_MOSI PC12 SPI3_MOSI + * SPI_CS SPSGRF-915-SPI3_CSN PB5 GPIO_Output + * GPIO(3) SPSGRF-915-GPIO3_EXTI5 PE5 GPIO_EXTI5 + * GPIO(2) N/C N/A + * GPIO(1) N/C N/A + * GPIO(0) N/C N/A + * SDN SPSGRF-915-SDN PB15 GPIO_Output + * -------- ----------------------- ---------------- + * + * NOTES: + * - The Interrupt request is active low. + * - When SDN =1 the Spirit is completely shut down and the contents of the + * registers are lost. + */ + +#define GPIO_SPSGRF_CS (GPIO_OUTPUT | GPIO_FLOAT | GPIO_PUSHPULL | \ + GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | \ + GPIO_PORTB | GPIO_PIN5) +#define GPIO_SPSGRF_INT (GPIO_INPUT | GPIO_FLOAT | GPIO_SPEED_100MHz | \ + GPIO_EXTI | GPIO_PORTE | GPIO_PIN5) +#define GPIO_SPSGRF_SDN (GPIO_OUTPUT | GPIO_FLOAT | GPIO_PUSHPULL | \ + GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | \ + GPIO_PORTB | GPIO_PIN15) /**************************************************************************** * Public Types @@ -84,5 +149,34 @@ int stm32l4_bringup(void); #endif +/************************************************************************************ + * Name: stm32l4_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the Nucleo-F401RE and + * Nucleo-F411RE boards. + * + ************************************************************************************/ + +#if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || defined(CONFIG_STM32L4_SPI3) +void weak_function stm32l4_spidev_initialize(void); +#endif + +/**************************************************************************** + * Name: stm32l4_spirit_initialize + * + * Description: + * Initialize the Spirit device. + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +#ifdef HAVE_SPSGRF +int stm32l4_spirit_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_B_L475E_IOT01A_SRC_B_L475E_IOT01A_H */ diff --git a/configs/b-l475e-iot01a/src/stm32_boot.c b/configs/b-l475e-iot01a/src/stm32_boot.c index 118a83fc33..085398fff3 100644 --- a/configs/b-l475e-iot01a/src/stm32_boot.c +++ b/configs/b-l475e-iot01a/src/stm32_boot.c @@ -62,6 +62,17 @@ void stm32l4_board_initialize(void) { +#if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || defined(CONFIG_STM32L4_SPI3) + /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak function + * stm32l4_spidev_initialize() has been brought into the link. + */ + + if (stm32l4_spidev_initialize) + { + stm32l4_spidev_initialize(); + } +#endif + #ifdef CONFIG_ARCH_LEDS /* Configure on-board LEDs if LED support has been selected. */ diff --git a/configs/b-l475e-iot01a/src/stm32_bringup.c b/configs/b-l475e-iot01a/src/stm32_bringup.c index 55bb4d41b3..f293042ba2 100644 --- a/configs/b-l475e-iot01a/src/stm32_bringup.c +++ b/configs/b-l475e-iot01a/src/stm32_bringup.c @@ -97,5 +97,15 @@ int stm32l4_bringup(void) #endif /* CONFIG_USERLED_LOWER */ #endif /* CONFIG_USERLED && !CONFIG_ARCH_LEDS */ +#ifdef HAVE_SPSGRF + /* Configure Spirit/SPSGRF wireless */ + + ret = stm32l4_spirit_initialize(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32l4_spirit_initialize() failed: %d\n", ret); + } +#endif + return ret; } diff --git a/configs/b-l475e-iot01a/src/stm32_spi.c b/configs/b-l475e-iot01a/src/stm32_spi.c new file mode 100644 index 0000000000..cfb80a42ff --- /dev/null +++ b/configs/b-l475e-iot01a/src/stm32_spi.c @@ -0,0 +1,252 @@ +/**************************************************************************** + * configs/b-f475e-iot01a/src/stm32_spi.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "stm32l4_gpio.h" +#include "stm32l4_spi.h" + +#include "b-l475e-iot01a.h" + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Currently no devices are defined on SPI1 or SPI2 */ + +#undef CONFIG_STM32L4_SPI1 +#undef CONFIG_STM32L4_SPI2 + +/* Only the SPSGRF is currently supported on SPI3 */ + +#ifndef HAVE_SPSGRF +# undef CONFIG_STM32L4_SPI3 +#endif + +#if defined(CONFIG_STM32L4_SPI1) || defined(CONFIG_STM32L4_SPI2) || defined(CONFIG_STM32L4_SPI3) + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/* Global driver instances */ + +#ifdef CONFIG_STM32L4_SPI1 +struct spi_dev_s *g_spi1; +#endif + +#ifdef CONFIG_STM32L4_SPI2 +struct spi_dev_s *g_spi2; +#endif + +#ifdef CONFIG_STM32L4_SPI3 +struct spi_dev_s *g_spi3; +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32l4_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the Nucleo-F401RE and + * Nucleo-F411RE boards. + * + ************************************************************************************/ + +void weak_function stm32l4_spidev_initialize(void) +{ +#ifdef CONFIG_STM32L4_SPI1 + /* Configure SPI-based devices */ + + g_spi1 = stm32l4_spibus_initialize(1); + if (!g_spi1) + { + spierr("ERROR: [boot] FAILED to initialize SPI port 1\n"); + } + + /* Configure chip select GPIOs */ +#endif + +#ifdef CONFIG_STM32L4_SPI2 + /* Configure SPI-based devices */ + + g_spi2 = stm32l4_spibus_initialize(2); + + /* Configure chip select GPIOs */ +#endif + +#ifdef CONFIG_STM32L4_SPI2 + /* Configure SPI-based devices */ + + g_spi3 = stm32l4_spibus_initialize(3); + + /* Configure chip select GPIOs */ + +#ifdef HAVE_SPSGRF + stm32l4_configgpio(GPIO_SPSGRF_CS); +#endif +#endif +} + +/**************************************************************************** + * Name: stm32l4_spi1/2/3select and stm32l4_spi1/2/3status + * + * Description: + * The external functions, stm32l4_spi1/2/3select and stm32l4_spi1/2/3status must be + * provided by board-specific logic. They are implementations of the select + * and status methods of the SPI interface defined by struct spi_ops_s (see + * include/nuttx/spi/spi.h). All other methods (including up_spiinitialize()) + * are provided by common STM32 logic. To use this common SPI logic on your + * board: + * + * 1. Provide logic in stm32l4_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32l4_spi1/2/3select() and stm32l4_spi1/2/3status() functions in your + * board-specific logic. These functions will perform chip selection and + * status operations using GPIOs in the way your board is configured. + * 3. Add a calls to up_spiinitialize() in your low level application + * initialization logic + * 4. The handle returned by up_spiinitialize() may then be used to bind the + * SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +#ifdef CONFIG_STM32L4_SPI1 +void stm32l4_spi1select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) +{ + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); +} + +uint8_t stm32l4_spi1status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif + +#ifdef CONFIG_STM32L4_SPI2 +void stm32l4_spi2select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) +{ + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); +} + +uint8_t stm32l4_spi2status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif + +#ifdef CONFIG_STM32L4_SPI3 +void stm32l4_spi3select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected) +{ + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); + +#ifdef HAVE_SPSGRF + if (devid == SPIDEV_WIRELESS(0)) + { + stm32l4_gpiowrite(GPIO_SPSGRF_CS, !selected); + } +#endif +} + +uint8_t stm32l4_spi3status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32l4_spi1cmddata + * + * Description: + * Set or clear the SH1101A A0 or SD1306 D/C n bit to select data (true) + * or command (false). This function must be provided by platform-specific + * logic. This is an implementation of the cmddata method of the SPI + * interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h). + * + * Input Parameters: + * + * spi - SPI device that controls the bus the device that requires the CMD/ + * DATA selection. + * devid - If there are multiple devices on the bus, this selects which one + * to select cmd or data. NOTE: This design restricts, for example, + * one one SPI display per SPI bus. + * cmd - true: select command; false: select data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +#ifdef CONFIG_STM32L4_SPI1 +int stm32l4_spi1cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + return OK; +} +#endif + +#ifdef CONFIG_STM32L4_SPI2 +int stm32l4_spi2cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + return OK; +} +#endif + +#ifdef CONFIG_STM32L4_SPI3 +int stm32l4_spi3cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd) +{ + return OK; +} +#endif +#endif /* CONFIG_SPI_CMDDATA */ + +#endif /* CONFIG_STM32L4_SPI1 || CONFIG_STM32L4_SPI2 || CONFIG_STM32L4_SPI3 */ diff --git a/configs/b-l475e-iot01a/src/stm32_spirit.c b/configs/b-l475e-iot01a/src/stm32_spirit.c new file mode 100644 index 0000000000..4aadd015a9 --- /dev/null +++ b/configs/b-l475e-iot01a/src/stm32_spirit.c @@ -0,0 +1,285 @@ +/**************************************************************************** + * configs/b-l475e-iot01a/src/stm32_spirit.c + * + * Copyright (C) 2017 Gregory Nutt, All rights reserver + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "stm32l4_gpio.h" +#include "stm32l4_exti.h" +#include "stm32l4_spi.h" + +#include "b-l475e-iot01a.h" + +#ifdef HAVE_SPSGRF + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_DRIVERS_WIRELESS +# error Wireless support requires CONFIG_DRIVERS_WIRELESS +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct stm32l4_priv_s +{ + struct spirit_lower_s dev; + xcpt_t handler; + FAR void *arg; + uint32_t intcfg; + uint32_t sdncfg; + uint8_t spidev; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* IRQ/GPIO access callbacks. These operations all hidden behind callbacks + * to isolate the Spirit driver from differences in GPIO interrupt handling + * varying boards and MCUs. + * + * stm32l4_reset - Reset the Spirit part. + * stm32l4_attach_irq - Attach the Spirit interrupt handler to the GPIO + interrupt + * stm32l4_enable_irq - Enable or disable the GPIO interrupt + */ + +static int stm32l4_reset(FAR const struct spirit_lower_s *lower); +static int stm32l4_attach_irq(FAR const struct spirit_lower_s *lower, + xcpt_t handler, FAR void *arg); +static void stm32l4_enable_irq(FAR const struct spirit_lower_s *lower, + bool state); +static int stm32l4_spirit_devsetup(FAR struct stm32l4_priv_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* A reference to a structure of this type must be passed to the Spirit + * driver. This structure provides information about the configuration + * of the Spirit and provides some board-specific hooks. + * + * Memory for this structure is provided by the caller. It is not copied + * by the driver and is presumed to persist while the driver is active. The + * memory must be writable because, under certain circumstances, the driver + * may modify frequency or X plate resistance values. + */ + +static struct stm32l4_priv_s g_spirit = +{ + .dev.reset = stm32l4_reset, + .dev.attach = stm32l4_attach_irq, + .dev.enable = stm32l4_enable_irq, + .handler = NULL, + .arg = NULL, + .intcfg = GPIO_SPSGRF_INT, + .sdncfg = GPIO_SPSGRF_SDN, + .spidev = 3, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Reset the Spirit 1 part */ + +static int stm32l4_reset(FAR const struct spirit_lower_s *lower) +{ + FAR struct stm32l4_priv_s *priv = (FAR struct stm32l4_priv_s *)lower; + + DEBUGASSERT(priv != NULL); + + /* Reset pulse */ + + stm32l4_gpiowrite(priv->sdncfg, true); + stm32l4_gpiowrite(priv->sdncfg, false); + + /* Wait minimum 1.5 ms to allow Spirit a proper boot-up sequence */ + + usleep(1500); + return OK; +} + +/* IRQ/GPIO access callbacks. These operations all hidden behind + * callbacks to isolate the Spirit driver from differences in GPIO + * interrupt handling by varying boards and MCUs. If possible, + * interrupts should be configured on both rising and falling edges + * so that contact and loss-of-contact events can be detected. + * + * stm32l4_attach_irq - Attach the Spirit interrupt handler to the GPIO + * interrupt + * stm32l4_enable_irq - Enable or disable the GPIO interrupt + */ + +static int stm32l4_attach_irq(FAR const struct spirit_lower_s *lower, + xcpt_t handler, FAR void *arg) +{ + FAR struct stm32l4_priv_s *priv = (FAR struct stm32l4_priv_s *)lower; + + DEBUGASSERT(priv != NULL); + + /* Just save the handler for use when the interrupt is enabled */ + + priv->handler = handler; + priv->arg = arg; + return OK; +} + +static void stm32l4_enable_irq(FAR const struct spirit_lower_s *lower, + bool state) +{ + FAR struct stm32l4_priv_s *priv = (FAR struct stm32l4_priv_s *)lower; + + /* The caller should not attempt to enable interrupts if the handler + * has not yet been 'attached' + */ + + DEBUGASSERT(priv != NULL && (priv->handler != NULL || !state)); + + wlinfo("state:%d\n", (int)state); + + /* Attach and enable, or detach and disable */ + + if (state) + { + /* Enable interrupts on falling edge (active low) */ + + (void)stm32l4_gpiosetevent(priv->intcfg, false, true, false, + priv->handler, priv->arg); + } + else + { + /* Disable interrupts */ + + (void)stm32l4_gpiosetevent(priv->intcfg, false, false, false, + NULL, NULL); + } +} + +/**************************************************************************** + * Name: stm32l4_spirit_devsetup + * + * Description: + * Initialize one the Spirit device + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +static int stm32l4_spirit_devsetup(FAR struct stm32l4_priv_s *priv) +{ + FAR struct spi_dev_s *spi; + int ret; + + /* Configure the interrupt pin and SDN pins. Innitializing the SDN to '1' + * powers down the Spirit. + */ + + stm32l4_configgpio(priv->intcfg); + stm32l4_configgpio(priv->sdncfg); + + /* Initialize the SPI bus and get an instance of the SPI interface */ + + spi = stm32l4_spibus_initialize(priv->spidev); + if (spi == NULL) + { + wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->spidev); + return -ENODEV; + } + + /* Initialize and register the SPI Spirit device */ + + ret = spirit_netdev_initialize(spi, &priv->dev); + if (ret < 0) + { + wlerr("ERROR: spirit_netdev_initialize failed %d\n", priv->spidev); + return -ENODEV; + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32l4_spirit_initialize + * + * Description: + * Initialize the Spirit device. + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +int stm32l4_spirit_initialize(void) +{ + int ret; + + wlinfo("Configuring Spirit\n"); + + ret = stm32l4_spirit_devsetup(&g_spirit); + if (ret < 0) + { + wlerr("ERROR: Failed to initialize Spirit: %d\n", ret); + } + + return OK; +} +#endif /* HAVE_SPSGRF */ diff --git a/configs/stm32l476vg-disco/include/stm32l476vg-disco-clocking.h b/configs/stm32l476vg-disco/include/stm32l476vg-disco-clocking.h index 9ceef6c2b2..f0b3f4afb2 100644 --- a/configs/stm32l476vg-disco/include/stm32l476vg-disco-clocking.h +++ b/configs/stm32l476vg-disco/include/stm32l476vg-disco-clocking.h @@ -76,13 +76,13 @@ */ #if 0 -# define HSI_CLOCK_CONFIG /* HSI-16 clock configuration */ +# define HSI_CLOCK_CONFIG 1 /* HSI-16 clock configuration */ #elif 0 /* Make sure you actually installed one! */ -# define HSE_CLOCK_CONFIG /* HSE with 8 MHz xtal */ +# define HSE_CLOCK_CONFIG 1 /* HSE with 8 MHz xtal */ #else -# define MSI_CLOCK_CONFIG /* MSI @ 4 MHz autotrimmed via LSE */ +# define MSI_CLOCK_CONFIG 1 /* MSI @ 4 MHz autotrimmed via LSE */ #endif #if defined(HSI_CLOCK_CONFIG) @@ -287,7 +287,7 @@ #define STM32L4_PLLCFG_PLLP 0 #undef STM32L4_PLLCFG_PLLP_ENABLED #define STM32L4_PLLCFG_PLLQ 0 -#undef STM32L4_PLLCFG_PLLQ_ENABLED +#undef STM32L4_PLLCFG_PLLQ_ENABLED #define STM32L4_PLLCFG_PLLR RCC_PLLCFG_PLLR_2 #define STM32L4_PLLCFG_PLLR_ENABLED @@ -324,7 +324,7 @@ #define STM32L4_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */ #define STM32L4_HCLK_FREQUENCY STM32L4_SYSCLK_FREQUENCY -#define STM32L4_BOARD_HCLK STM32L4_HCLK_FREQUENCY /* Same as above, to satisfy compiler */ +#define STM32L4_BOARD_HCLK STM32L4_HCLK_FREQUENCY /* Same as above, to satisfy compiler */ /* Configure the APB1 prescaler */ diff --git a/drivers/usbdev/composite.h b/drivers/usbdev/composite.h index 7bf30bc141..1092b52731 100644 --- a/drivers/usbdev/composite.h +++ b/drivers/usbdev/composite.h @@ -51,15 +51,6 @@ #ifdef CONFIG_USBDEV_COMPOSITE -#ifdef CONFIG_CDCACM_COMPOSITE -# include -# include "cdcacm.h" -#endif - -#ifdef CONFIG_USBMSC_COMPOSITE -# include "usbmsc.h" -#endif - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ diff --git a/drivers/wireless/Kconfig b/drivers/wireless/Kconfig index 39622d66fd..f4a0dc7191 100644 --- a/drivers/wireless/Kconfig +++ b/drivers/wireless/Kconfig @@ -16,6 +16,7 @@ menuconfig WL_CC3000 select SPI source drivers/wireless/cc3000/Kconfig +source drivers/wireless/spirit/Kconfig menuconfig DRIVERS_IEEE802154 bool "IEEE 802.15.4 Device Support" diff --git a/drivers/wireless/Make.defs b/drivers/wireless/Make.defs index d6f1df5372..8e41eafbf0 100644 --- a/drivers/wireless/Make.defs +++ b/drivers/wireless/Make.defs @@ -53,14 +53,18 @@ ifeq ($(CONFIG_WL_CC1101),y) CSRCS += cc1101.c ISM1_868MHzGFSK100kbps.c ISM2_905MHzGFSK250kbps.c endif -ifeq ($(CONFIG_WL_NRF24L01),y) -CSRCS += nrf24l01.c -endif - ifeq ($(CONFIG_WL_CC3000),y) include wireless$(DELIM)cc3000$(DELIM)Make.defs endif +ifeq ($(CONFIG_WL_SPIRIT),y) +include wireless$(DELIM)spirit$(DELIM)Make.defs +endif + +ifeq ($(CONFIG_WL_NRF24L01),y) +CSRCS += nrf24l01.c +endif + # Include wireless devices build support DEPPATH += --dep-path wireless diff --git a/drivers/wireless/spirit/Kconfig b/drivers/wireless/spirit/Kconfig new file mode 100644 index 0000000000..2a3f6d6de5 --- /dev/null +++ b/drivers/wireless/spirit/Kconfig @@ -0,0 +1,26 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config WL_SPIRIT + bool "STMicro Spririt Radio Library" + default n + select SPI + ---help--- + Enable support for the STMicro Spririt Radio Library + +if WL_SPIRIT + +config WL_SPIRIT_SPIFREQUENCY + int "Spirit SPI frequency" + default 10000000 + ---help--- + Frequency at which to operate the SPI interface to the Spirit part. + The default is the absolution maximum and you may likely have to + reduce this for your board. + +endif + +source drivers/wireless/spirit/drivers/Kconfig + diff --git a/drivers/wireless/spirit/Make.defs b/drivers/wireless/spirit/Make.defs new file mode 100644 index 0000000000..d8debdb0d7 --- /dev/null +++ b/drivers/wireless/spirit/Make.defs @@ -0,0 +1,43 @@ +############################################################################ +# drivers/wireless/spirit/Make.defs +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifeq ($(CONFIG_WL_SPIRIT),y) + +# Include Spirit library support + +include wireless$(DELIM)spirit$(DELIM)lib$(DELIM)Make.defs +include wireless$(DELIM)spirit$(DELIM)include$(DELIM)Make.defs + +endif diff --git a/drivers/wireless/spirit/drivers/Kconfig b/drivers/wireless/spirit/drivers/Kconfig new file mode 100644 index 0000000000..7860a4a35c --- /dev/null +++ b/drivers/wireless/spirit/drivers/Kconfig @@ -0,0 +1,17 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config SPIRIT_NETDEV + bool "STMicro Spirit1-based Network Driver" + default n + select WL_SPIRIT + ---help--- + This selection enables support for the TMicro Spirit1-based device. + This configuration generates an IEEE802.15.4 work-alike radio device that + works with the 6LoWPAN stack. + +if SPIRIT_NETDEV + +endif # SPIRIT_NETDEV diff --git a/drivers/wireless/spirit/drivers/Make.defs b/drivers/wireless/spirit/drivers/Make.defs new file mode 100644 index 0000000000..270c38aea1 --- /dev/null +++ b/drivers/wireless/spirit/drivers/Make.defs @@ -0,0 +1,49 @@ +############################################################################ +# drivers/spirit/drivers/Make.defs +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Include Spirit1 drivers into the build + +ifeq ($(CONFIG_SPIRIT_NETDEV),y) + +CSRCS += spirit_netdev.c + +# Include Spirit1 build support + +DEPPATH += --dep-path wireless$(DELIM)spirit$(DELIM)drivers +VPATH += :wireless$(DELIM)spirit$(DELIM)drivers +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" \ + $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)spirit$(DELIM)drivers} + +endif # CONFIG_SPIRIT_NETDEV \ No newline at end of file diff --git a/drivers/wireless/spirit/drivers/spirit_netdev.c b/drivers/wireless/spirit/drivers/spirit_netdev.c new file mode 100644 index 0000000000..8c9e19521e --- /dev/null +++ b/drivers/wireless/spirit/drivers/spirit_netdev.c @@ -0,0 +1,1290 @@ +/**************************************************************************** + * drivers/wireless/spirit/drivers/spirit_netdev.c + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "spirit_types.h" +#include "spirit_general.h" +#include "spirit_irq.h" +#include "spirit_spi.h" +#include "spirit_gpio.h" +#include "spirit_commands.h" +#include "spirit_radio.h" +#include "spirit_pktbasic.h" +#include "spirit_qi.h" +#include "spirit_timer.h" + +#include + +#include "spirit1.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if !defined(CONFIG_SCHED_HPWORK) || !defined(CONFIG_SCHED_HPWORK) +# error Both high and low priority work queues required in this driver +#endif + +#ifndef CONFIG_SPI_EXCHANGE +# error CONFIG_SPI_EXCHANGE required for this driver +#endif + +#if !defined(CONFIG_NET) || !defined(CONFIG_NET_6LOWPAN) +# error 6LoWPAN network support is required. +#endif + +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define SPIRIT_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define SPIRIT_TXTIMEOUT (60*CLK_TCK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* SPIRIT1 device instance + * + * Make sure that struct ieee802154_radio_s remains first. If not it will break the + * code + */ + +struct spirit_driver_s +{ + struct ieee802154_driver_s ieee; /* Interface understood by the network */ + struct spirit_library_s spirit; /* Spirit library state */ + FAR const struct spirit1_lower_s *lower; /* Low-level MCU-specific support */ + struct work_s hpwork; /* Interrupt continuation work queue support */ + struct work_s lpwork; /* Net poll work queue support */ + WDOG_ID txpoll; /* TX poll timer */ + WDOG_ID txtimeout; /* TX timeout timer */ + bool ifup; /* Spirit is on and interface is up */ + uint8_t panid[2]; /* PAN identifier, ffff = not set */ + uint16_t saddr; /* Short address, ffff = not set */ + uint8_t eaddr[8]; /* Extended address, ffffffffffffffff = not set */ + uint8_t channel; /* 11 to 26 for the 2.4 GHz band */ + uint8_t devmode; /* Device mode: device, coord, pancoord */ + uint8_t paenabled; /* Enable usage of PA */ + uint8_t rxmode; /* Reception mode: Main, no CRC, promiscuous */ + int32_t txpower; /* TX power in mBm = dBm/100 */ + struct ieee802154_cca_s cca; /* Clear channel assessement method */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Common TX logic */ + +static int spirit_transmit(FAR struct spirit_driver_s *priv); +static int spirit_txpoll(FAR struct net_driver_s *dev); + +/* Interrupt handling */ + +static void spirit_interrupt_work(FAR void *arg); +static int spirit_interrupt(int irq, FAR void *context, FAR void *arg); + +/* Watchdog timer expirations */ + +static void spirit_txtimeout_work(FAR void *arg); +static void spirit_txtimeout_expiry(int argc, wdparm_t arg, ...); + +static void spirit_poll_work(FAR void *arg); +static void spirit_poll_expiry(int argc, wdparm_t arg, ...); + +/* NuttX callback functions */ + +static int spirit_ifup(FAR struct net_driver_s *dev); +static int spirit_ifdown(FAR struct net_driver_s *dev); + +static void spirit_txavail_work(FAR void *arg); +static int spirit_txavail(FAR struct net_driver_s *dev); + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int spirit_addmac(FAR struct net_driver_s *dev, + FAR const uint8_t *mac); +#ifdef CONFIG_NET_IGMP +static int spirit_rmmac(FAR struct net_driver_s *dev, + FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NET_ICMPv6 +static void spirit_ipv6multicast(FAR struct spirit_driver_s *priv); +#endif +#endif +#ifdef CONFIG_NETDEV_IOCTL +static int spirit_ioctl(FAR struct net_driver_s *dev, int cmd, + unsigned long arg); +#endif +static int spirit_get_mhrlen(FAR struct ieee802154_driver_s *netdev, + FAR const struct ieee802154_frame_meta_s *meta); +static int spirit_req_data(FAR struct ieee802154_driver_s *netdev, + FAR const struct ieee802154_frame_meta_s *meta, + FAR struct iob_s *framelist); + +/* Initialization */ + +int spirit_hw_initialize(FAR struct spirit_driver_s *dev, + FAR struct spi_dev_s *spi); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Spirit radio initialization */ + +static const struct radio_init_s g_radio_init = +{ + SPIRIT_BASE_FREQUENCY, /* base_frequency */ + SPIRIT_CHANNEL_SPACE, /* chspace */ + SPIRIT_XTAL_OFFSET_PPM, /* xtal_offset_ppm */ + SPIRIT_CHANNEL_NUMBER, /* chnum */ + SPIRIT_MODULATION_SELECT, /* modselect */ + SPIRIT_DATARATE, /* datarate */ + SPIRIT_FREQ_DEVIATION, /* freqdev */ + SPIRIT_BANDWIDTH /* bandwidth */ +}; + +/* Spirit PktBasic initialization */ + +static const struct pktbasic_init_s g_pktbasic_init = +{ + SPIRIT_SYNC_WORD, /* syncwords */ + SPIRIT_PREAMBLE_LENGTH, /* premblen */ + SPIRIT_SYNC_LENGTH, /* synclen */ + SPIRIT_LENGTH_TYPE, /* fixedvarlen */ + SPIRIT_LENGTH_WIDTH, /* pktlenwidth */ + SPIRIT_CRC_MODE, /* crcmode */ + SPIRIT_CONTROL_LENGTH, /* ctrllen */ + SPIRIT_EN_ADDRESS, /* txdestaddr */ + SPIRIT_EN_FEC, /* fec */ + SPIRIT_EN_WHITENING /* datawhite */ + }; + +static const struct spirit_gpio_init_s g_gpioinit = +{ + SPIRIT_GPIO_3, /* gpiopin */ + SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP, /* gpiomode */ + SPIRIT_GPIO_DIG_OUT_IRQ /* gpioio */ +}; + +#if 0 +static const struct spririt_csma_init_s g_csma_init = +{ + S_ENABLE, /* enable persistent mode */ + TBIT_TIME_64, /* Tcca time */ + TCCA_TIME_3, /* Lcca length */ + 3, /* max nr of backoffs (<8) */ + 1, /* BU counter seed */ + 8 /* BU prescaler */ +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spirit_transmit + * + * Description: + * Start hardware transmission. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * the network is locked. + * + ****************************************************************************/ + +static int spirit_transmit(FAR struct spirit_driver_s *priv) +{ + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ + + /* Increment statistics */ + + NETDEV_TXPACKETS(&priv->ieee.i_dev); + + /* Send the packet: address=dev->d_buf, length=dev->d_len */ + + /* Enable Tx interrupts */ + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->txtimeout, SPIRIT_TXTIMEOUT, + spirit_txtimeout_expiry, 1, (wdparm_t)priv); + return OK; +} + +/**************************************************************************** + * Name: spirit_txpoll + * + * Description: + * The transmitter is available, check if the network has any outgoing + * packets ready to send. This is a callback from devif_poll(). + * devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * the network is locked. + * + ****************************************************************************/ + +static int spirit_txpoll(FAR struct net_driver_s *dev) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)dev->d_private; + return 0; +} + +/**************************************************************************** + * Name: spirit_interrupt_work + * + * Description: + * Actual thread to handle the irq outside of privaleged mode. + * + ****************************************************************************/ + +static void spirit_interrupt_work(FAR void *arg) +{ + FAR struct spirit_driver_s *dev = (FAR struct spirit_driver_s *)arg; + uint8_t status = 0; + + DEBUGASSERT(dev != NULL); + + /* Process the Spirit1 interrupt */ + + wlinfo("Status: 0x%02X\n", status); + UNUSED(status); + + /* Re-enable the interrupt. */ + + DEBUGASSERT(dev->lower != NULL && dev->lower->enable != NULL); + dev->lower->enable(dev->lower, true); +} + +/**************************************************************************** + * Name: spirit_interrupt + * + * Description: + * Actual interrupt handler ran inside privileged space. + * + ****************************************************************************/ + +static int spirit_interrupt(int irq, FAR void *context, FAR void *arg) +{ + FAR struct spirit_driver_s *dev = (FAR struct spirit_driver_s *)arg; + + DEBUGASSERT(dev != NULL); + + /* TODO: Determine if a TX transfer just completed . + * If a TX transfer just completed, then cancel the TX timeout so + * there will be no race condition between any subsequent timeout + * expiration and the deferred interrupt processing. + */ + + //wd_cancel(priv->txtimeout); + + /* In complex environments, we cannot do SPI transfers from the interrupt + * handler because semaphores are probably used to lock the SPI bus. In + * this case, we will defer processing to the worker thread. This is also + * much kinder in the use of system resources and is, therefore, probably + * a good thing to do in any event. + * + * Notice that further GPIO interrupts are disabled until the work is + * actually performed. This is to prevent overrun of the worker thread. + * Interrupts are re-enabled in enc_irqworker() when the work is completed. + */ + + dev->lower->enable(dev->lower, false); + + return work_queue(HPWORK, &dev->hpwork, spirit_interrupt_work, + (FAR void *)dev, 0); +} + +/**************************************************************************** + * Name: spirit_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static void spirit_txtimeout_work(FAR void *arg) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)arg; + + /* Lock the network and serialize driver operations if necessary. + * NOTE: Serialization is only required in the case where the driver work + * is performed on an LP worker thread and where more than one LP worker + * thread has been configured. + */ + + net_lock(); + + /* Increment statistics and dump debug info */ + + NETDEV_TXTIMEOUTS(&priv->ieee.i_dev); + + /* Then reset the hardware */ + + /* Then poll the network for new XMIT data */ + + (void)devif_poll(&priv->ieee.i_dev, spirit_txpoll); + net_unlock(); +} + +/**************************************************************************** + * Name: spirit_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void spirit_txtimeout_expiry(int argc, wdparm_t arg, ...) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)arg; + + DEBUGASSERT(priv != NULL && priv->lower != NULL); + + /* Disable further Spirit interrupts. This will prevent some race + * conditions with interrupt work. There is still a potential race + * condition with interrupt work that is already queued and in progress. + */ + + DEBUGASSERT(priv->lower->enable != NULL); + priv->lower->enable(priv->lower, false); + + /* Schedule to perform the TX timeout processing on the worker thread. */ + + work_queue(LPWORK, &priv->hpwork, spirit_txtimeout_work, priv, 0); +} + +/**************************************************************************** + * Name: spirit_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void spirit_poll_process(FAR struct spirit_driver_s *priv) +{ +} + +/**************************************************************************** + * Name: spirit_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static void spirit_poll_work(FAR void *arg) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)arg; + + /* Lock the network and serialize driver operations if necessary. + * NOTE: Serialization is only required in the case where the driver work + * is performed on an LP worker thread and where more than one LP worker + * thread has been configured. + */ + + net_lock(); + + /* Perform the poll */ + + /* Check if there is room in the send another TX packet. We cannot perform + * the TX poll if he are unable to accept another packet for transmission. + */ + + /* If so, update TCP timing states and poll the network for new XMIT data. + * Hmmm.. might be bug here. Does this mean if there is a transmit in + * progress, we will missing TCP time state updates? + */ + + (void)devif_timer(&priv->ieee.i_dev, spirit_txpoll); + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->txpoll, SPIRIT_WDDELAY, spirit_poll_expiry, 1, + (wdparm_t)priv); + net_unlock(); +} + +/**************************************************************************** + * Name: spirit_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void spirit_poll_expiry(int argc, wdparm_t arg, ...) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)arg; + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(LPWORK, &priv->lpwork, spirit_poll_work, priv, 0); +} + +/**************************************************************************** + * Name: spirit_ifup + * + * Description: + * NuttX Callback: Bring up the Spirit interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int spirit_ifup(FAR struct net_driver_s *dev) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)dev->d_private; + +#ifdef CONFIG_NET_IPv4 + ninfo("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); +#endif +#ifdef CONFIG_NET_IPv6 + ninfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); +#endif + + /* Initialize PHYs, the Spirit interface, and setup up Spirit interrupts */ + + /* Instantiate the MAC address from dev->d_mac.ether.ether_addr_octet */ + +#ifdef CONFIG_NET_ICMPv6 + /* Set up IPv6 multicast address filtering */ + + spirit_ipv6multicast(priv); +#endif + + /* Set and activate a timer process */ + + (void)wd_start(priv->txpoll, SPIRIT_WDDELAY, spirit_poll_expiry, 1, + (wdparm_t)priv); + + /* Enable the Spirit interrupt */ + + priv->ifup = true; + + DEBUGASSERT(priv->lower->enable != NULL); + priv->lower->enable(priv->lower, true); + + return OK; +} + +/**************************************************************************** + * Name: spirit_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int spirit_ifdown(FAR struct net_driver_s *dev) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)dev->d_private; + irqstate_t flags; + + /* Disable the Spirit interrupt */ + + flags = enter_critical_section(); + + DEBUGASSERT(priv->lower->enable != NULL); + priv->lower->enable(priv->lower, false); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->txpoll); + wd_cancel(priv->txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the spirit_ifup() always + * successfully brings the interface back up. + */ + + /* Mark the device "down" */ + + priv->ifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: spirit_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +static void spirit_txavail_work(FAR void *arg) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)arg; + + /* Lock the network and serialize driver operations if necessary. + * NOTE: Serialization is only required in the case where the driver work + * is performed on an LP worker thread and where more than one LP worker + * thread has been configured. + */ + + net_lock(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->ifup) + { + /* Check if there is room in the hardware to hold another outgoing packet. */ + + /* If so, then poll the network for new XMIT data */ + + (void)devif_poll(&priv->ieee.i_dev, spirit_txpoll); + } + + net_unlock(); +} + +/**************************************************************************** + * Name: spirit_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int spirit_txavail(FAR struct net_driver_s *dev) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)dev->d_private; + + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->lpwork)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(LPWORK, &priv->lpwork, spirit_txavail_work, priv, 0); + } + + return OK; +} + +/**************************************************************************** + * Name: spirit_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * None + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int spirit_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) +{ + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: spirit_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int spirit_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) +{ + return -ENOSYS; +} +#endif + +/**************************************************************************** + * Name: spirit_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void spirit_ipv6multicast(FAR struct spirit_driver_s *priv) +{ + return -ENOSYS; +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Name: spirit_ioctl + * + * Description: + * Handle network IOCTL commands directed to this device. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * cmd - The IOCTL command + * arg - The argument for the IOCTL command + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_IOCTL +static int spirit_ioctl(FAR struct net_driver_s *dev, int cmd, + unsigned long arg) +{ + FAR struct spirit_driver_s *priv = (FAR struct spirit_driver_s *)dev->d_private; + int ret; + + /* Decode and dispatch the driver-specific IOCTL command */ + + switch (cmd) + { + /* Add cases here to support the IOCTL commands */ + + default: + nerr("ERROR: Unrecognized IOCTL command: %d\n", command); + ret = -ENOTTY; /* Special return value for this case */ + } + + return ret; +} +#endif + +/**************************************************************************** + * Name: spirit_get_mhrlen + * + * Description: + * Calculate the MAC header length given the frame meta-data. + * + * Input parameters: + * netdev - The networkd device that will mediate the MAC interface + * meta - Meta data needed to recreate the MAC header + * + * Returned Value: + * A non-negative MAC headeer length is returned on success; a negated + * errno value is returned on any failure. + * + ****************************************************************************/ + +static int spirit_get_mhrlen(FAR struct ieee802154_driver_s *netdev, + FAR const struct ieee802154_frame_meta_s *meta) +{ + FAR struct spirit_driver_s *priv; + + DEBUGASSERT(netdev != NULL && netdev->i_dev.d_private != NULL && meta != NULL); + priv = (FAR struct spirit_driver_s *)netdev->i_dev.d_private; + + return -ENOSYS; +} + +/**************************************************************************** + * Name: spirit_req_data + * + * Description: + * Requests the transfer of a list of frames to the MAC. + * + * Input parameters: + * netdev - The networkd device that will mediate the MAC interface + * meta - Meta data needed to recreate the MAC header + * framelist - Head of a list of frames to be transferred. + * + * Returned Value: + * Zero (OK) returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +static int spirit_req_data(FAR struct ieee802154_driver_s *netdev, + FAR const struct ieee802154_frame_meta_s *meta, + FAR struct iob_s *framelist) +{ + FAR struct spirit_driver_s *priv; + FAR struct iob_s *iob; + int ret; + + wlinfo("Received framelist\n"); + + DEBUGASSERT(netdev != NULL && netdev->i_dev.d_private != NULL); + priv = (FAR struct spirit_driver_s *)netdev->i_dev.d_private; + + DEBUGASSERT(meta != NULL && framelist != NULL); + + /* Add the incoming list of frames to the MAC's outgoing queue */ + + for (iob = framelist; iob != NULL; iob = framelist) + { + /* Increment statistics */ + + NETDEV_TXPACKETS(&priv->md_dev.i_dev); + + /* Remove the IOB from the queue */ + + framelist = iob->io_flink; + iob->io_flink = NULL; + + /* Apply the Spirit header to the frame */ +# warning Missing logic + + /* Add the IOB to the queue of outgoing IOBs. */ +# warning Missing logic + + /* If there are no transmissions in progress, then start tranmssion + * of the frame in the IOB at the head of the IOB queue. + */ +# warning Missing logic + + //NETDEV_TXERRORS(&priv->md_dev.i_dev); + + NETDEV_TXDONE(&priv->md_dev.i_dev); + } + + return OK; +} + +/**************************************************************************** + * Name: spirit_hw_initialize + * + * Description: + * Initialize the Spirit1 radio. + * + ****************************************************************************/ + +int spirit_hw_initialize(FAR struct spirit_driver_s *priv, + FAR struct spi_dev_s *spi) +{ + FAR struct spirit_library_s *spirit = &priv->spirit; + int ret; + + /* Configures the Spirit1 radio library */ + + spirit->spi = spi; + spirit->xtal_frequency = SPIRIT_XTAL_FREQUENCY; + + /* Reset the Spirit1 radio part */ + + DEBUGASSERT(priv->lower != NULL && priv->lower->reset != NULL); + ret = priv->lower->reset(priv->lower) ; + if (ret < 0) + { + return ret; + } + + /* Soft reset of Spirit1 core */ + + ret = spirit_command(spirit, COMMAND_SRES); + if (ret < 0) + { + return ret; + } + + priv->ifup = false; + + /* Configure the Spirit1 radio part */ + + ret = spirit_radio_initialize(spirit, &g_radio_init); + if (ret < 0) + { + return ret; + } + + ret = spirit_radio_set_palevel(spirit, 0, SPIRIT_POWER_DBM); + if (ret < 0) + { + return ret; + } + + ret =spirit_radio_set_palevel_maxindex(spirit, 0); + if (ret < 0) + { + return ret; + } + + /* Configures the SPIRIT1 packet handling logic */ + + ret = spirit_pktbasic_initialize(spirit, &g_pktbasic_init); + if (ret < 0) + { + return ret; + } + + /* Enable the following interrupt sources, routed to GPIO */ + + ret = spirit_irq_disable_all(spirit); + if (ret < 0) + { + return ret; + } + + ret = spirit_irq_clr_pending(spirit); + if (ret < 0) + { + return ret; + } + + ret = spirit_irq_enable(spirit, TX_DATA_SENT, S_ENABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_irq_enable(spirit, RX_DATA_READY, S_ENABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_irq_enable(spirit, VALID_SYNC, S_ENABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_irq_enable(spirit, RX_DATA_DISC, S_ENABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_irq_enable(spirit, TX_FIFO_ERROR, S_ENABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_irq_enable(spirit, RX_FIFO_ERROR, S_ENABLE); + if (ret < 0) + { + return ret; + } + +#ifdef CONFIG_SPIRIT_FIFOS + ret = spirit_irq_enable(spirit, TX_FIFO_ALMOST_EMPTY, S_ENABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_irq_enable(spirit, RX_FIFO_ALMOST_FULL, S_ENABLE); + if (ret < 0) + { + return ret; + } +#endif + + /* Configure Spirit1 */ + + ret = spirit_radio_persistentrx(spirit, S_ENABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_qi_set_sqithreshold(spirit, SQI_TH_0); + if (ret < 0) + { + return ret; + } + + ret = spirit_qi_sqicheck(spirit, S_ENABLE); + if (ret < 0) + { + return ret; + } + + ret = spirit_qi_set_rssithreshold(spirit, SPIRIT_CCA_THRESHOLD); + if (ret < 0) + { + return ret; + } + + ret = spirit_timer_set_rxtimeout_stopcondition(spirit, + SQI_ABOVE_THRESHOLD); + if (ret < 0) + { + return ret; + } + + ret = spirit_timer_set_rxtimeout(spirit, 0); /* 0=No timeout */ + if (ret < 0) + { + return ret; + } + + ret = spirit_radio_afcfreezeonsync(spirit, S_ENABLE); + if (ret < 0) + { + return ret; + } + +#if 0 + ret = spirit_calibration_rco(spirit, S_ENABLE); + if (ret < 0) + { + return ret; + } +#endif + + /* Configure the radio to route the IRQ signal to its GPIO 3 */ + + ret = spirit_gpio_initialize(spirit, &g_gpioinit); + if (ret < 0) + { + return ret; + } + +#if 0 + /* Setup CSMA/CA */ + + ret = csma_ca_init(&g_csma_init); + if (ret < 0) + { + return ret; + } +#endif + + /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */ + + ret = spirit_command(spirit, CMD_STANDBY); + if (ret < 0) + { + return ret; + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: spirit_netdev_initialize + * + * Description: + * Initialize the IEEE802.15.4 driver and register it as a network device. + * + * Parameters: + * spi - A reference to the platform's SPI driver for the spirit1 + * lower - The MCU-specific interrupt used to control low-level MCU + * functions (i.e., spirit1 GPIO interrupts). + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + + +int spirit_netdev_initialize(FAR struct spi_dev_s *spi, + FAR const struct spirit1_lower_s *lower) +{ + FAR struct spirit_driver_s *priv; + FAR struct ieee802154_driver_s *ieee; + FAR struct net_driver_s *dev; +#if 0 + FAR uint8_t *pktbuf; +#endif + int ret; + + /* Allocate a driver state structure instance */ + + priv = (FAR struct spirit_driver_s *)kmm_zalloc(sizeof(struct spirit_driver_s)); + if (priv == NULL) + { + wlerr("ERROR: Failed to allocate device structure\n"); + return -ENOMEM; + } + + /* Allocate a packet buffer */ +#warning Missing logic +#if 0 + pktbuf = (uint8_t *)kmm_zalloc(CONFIG_SPIRIT_MTU + CONFIG_NET_GUARDSIZE); + if (priv == NULL) + { + wlerr("ERROR: Failed to allocate a packet buffer\n"); + ret = -ENOMEM; + goto errout_with_alloc; + } +#endif + + /* Attach the interface, lower driver, and devops */ + + priv->lower = lower; + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->txpoll = wd_create(); /* Create periodic poll timer */ + priv->txtimeout = wd_create(); /* Create TX timeout timer */ + + DEBUGASSERT(priv->txpoll != NULL && priv->txtimeout != NULL); + + /* Initialize the IEEE 802.15.4 network device fields */ + + ieee = &priv->ieee; + ieee->i_get_mhrlen = spirit_get_mhrlen; /* Get MAC header length */ + ieee->i_req_data = spirit_req_data; /* Enqueue frame for transmission */ + + /* Initialize the common network device fields */ + + dev = &ieee->i_dev; +#if 0 + dev->d_buf = pktbuf; /* Single packet buffer */ +#endif + dev->d_ifup = spirit_ifup; /* I/F up (new IP address) callback */ + dev->d_ifdown = spirit_ifdown; /* I/F down callback */ + dev->d_txavail = spirit_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + dev->d_addmac = spirit_addmac; /* Add multicast MAC address */ + dev->d_rmmac = spirit_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_IOCTL + dev->d_ioctl = spirit_ioctl; /* Handle network IOCTL commands */ +#endif + dev->d_private = (FAR void *)priv; /* Used to recover private state from dev */ + + /* Put the interface in the down state. This usually amounts to resetting + * the device and/or calling spirit_ifdown(). + */ + + /* Read the MAC address from the hardware into dev->d_mac.ether.ether_addr_octet */ + + /* Register the device with the OS so that socket IOCTLs can be performed. + * REVISIT: What kind of a device is this? + */ + + (void)netdev_register(dev, NET_LL_IEEE802154); + + /* Attach irq */ + + ret = lower->attach(lower, spirit_interrupt, priv); + if (ret < 0) + { + goto errout_with_pktbuf; + } + + /* Initialize device */ + + ret = spirit_hw_initialize(priv, spi); + if (ret < 0) + { + wlerr("ERROR: spirit_hw_initialize failed: %d\n", ret); + goto errout_with_attach; + } + + /* Put the Device to RX ON Mode */ + + /* Enable Radio IRQ */ + + lower->enable(lower, true); + return OK; + +errout_with_attach: + (void)lower->attach(lower, NULL, NULL); + +errout_with_pktbuf: +#if 0 + kmm_free(pktbuf); +#endif + +errout_with_alloc: + kmm_free(priv); + return ret; +} diff --git a/drivers/wireless/spirit/include/Make.defs b/drivers/wireless/spirit/include/Make.defs new file mode 100644 index 0000000000..b4091f85af --- /dev/null +++ b/drivers/wireless/spirit/include/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# drivers/wireless/spirit/include/Make.defs +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +# Add path to include Spirit header files in CFLAGS + +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" \ + $(TOPDIR)$(DELIM)drivers$(DELIM)wireless$(DELIM)spirit$(DELIM)include} diff --git a/drivers/wireless/spirit/include/spirit_commands.h b/drivers/wireless/spirit/include/spirit_commands.h new file mode 100644 index 0000000000..3124b74ded --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_commands.h @@ -0,0 +1,147 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_commands.h + * Management of SPIRIT Commands. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_COMMANDS_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_COMMANDS_H + +/* In this module can be found all the API used to strobe commands to + * Spirit. Every command strobe is an SPI transaction with a specific command + * code. + */ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_regs.h" +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in debug assertions */ + +#define IS_SPIRIT_CMD(cmd) (cmd == CMD_TX || \ + cmd == CMD_RX || \ + cmd == CMD_READY || \ + cmd == CMD_STANDBY || \ + cmd == CMD_SLEEP || \ + cmd == CMD_LOCKRX || \ + cmd == CMD_LOCKTX || \ + cmd == CMD_SABORT || \ + cmd == CMD_LDC_RELOAD || \ + cmd == CMD_SEQUENCE_UPDATE || \ + cmd == CMD_AES_ENC || \ + cmd == CMD_AES_KEY || \ + cmd == CMD_AES_DEC || \ + cmd == CMD_AES_KEY_DEC || \ + cmd == CMD_SRES || \ + cmd == CMD_FLUSHRXFIFO || \ + cmd == CMD_FLUSHTXFIFO \ + ) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* SPIRIT Commands codes enumeration */ + +enum spirit_cmd_e +{ + CMD_TX = COMMAND_TX, /* Start to transmit; valid only + * from READY */ + CMD_RX = COMMAND_RX, /* Start to receive; valid only + * from READY */ + CMD_READY = COMMAND_READY, /* Go to READY; valid only from + * STANDBY or SLEEP or LOCK */ + CMD_STANDBY = COMMAND_STANDBY, /* Go to STANDBY; valid only from + * READY */ + CMD_SLEEP = COMMAND_SLEEP, /* Go to SLEEP; valid only from + * READY */ + CMD_LOCKRX = COMMAND_LOCKRX, /* Go to LOCK state by using the + * RX configuration of the synth; + * valid only from READY */ + CMD_LOCKTX = COMMAND_LOCKTX, /* Go to LOCK state by using the + * TX configuration of the synth; + * valid only from READY */ + CMD_SABORT = COMMAND_SABORT, /* Force exit form TX or RX states + * and go to READY state; valid + * only from TX or RX */ + CMD_LDC_RELOAD = COMMAND_LDC_RELOAD, /* LDC Mode: Reload the LDC + * timer with the value stored + * in the LDC_PRESCALER / + * COUNTER registers; valid + * from all states */ + CMD_SEQUENCE_UPDATE = COMMAND_SEQUENCE_UPDATE, + /* Autoretransmission: Reload the + * Packet sequence counter with the + * value stored in the PROTOCOL[2] + * register valid from all states */ + CMD_AES_ENC = COMMAND_AES_ENC, /* Commands: Start the encryption + * routine; valid from all states; + * valid from all states */ + CMD_AES_KEY = COMMAND_AES_KEY, /* Commands: Start the procedure + * to compute the key for the + * decryption; valid from all states */ + CMD_AES_DEC = COMMAND_AES_DEC, /* Commands: Start the decryption + * routine using the current key; + * valid from all states */ + CMD_AES_KEY_DEC = COMMAND_AES_KEY_DEC, /* Commands: Compute the key and + * start the decryption; valid + * from all states */ + CMD_SRES = COMMAND_SRES, /* Reset of all digital part, + * xcept SPI registers */ + CMD_FLUSHRXFIFO = COMMAND_FLUSHRXFIFO, /* Clean the RX FIFO; valid from + * all states */ + CMD_FLUSHTXFIFO = COMMAND_FLUSHTXFIFO, /* Clean the TX FIFO; valid from + * all states */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_COMMANDS_H */ diff --git a/drivers/wireless/spirit/include/spirit_config.h b/drivers/wireless/spirit/include/spirit_config.h new file mode 100644 index 0000000000..0e03b04dee --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_config.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_config.h + * Spirit Configuration and useful defines + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_CONFIG_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_CONFIG_H + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#define DOUBLE_XTAL_THR 30000000 + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_CONFIG_H */ diff --git a/drivers/wireless/spirit/include/spirit_general.h b/drivers/wireless/spirit/include/spirit_general.h new file mode 100644 index 0000000000..5eca02a15b --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_general.h @@ -0,0 +1,135 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_general.h + * Configuration and management of SPIRIT General functionalities. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_GENERAL_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_GENERAL_H + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in debug assertions */ + +#define IS_MODE_EXT(mode) (mode == MODE_EXT_XO || mode == MODE_EXT_XIN) +#define IS_BLD_LVL(level) (level == BLD_LVL_2_7_V || level == BLD_LVL_2_5_V || \ + level == BLD_LVL_2_3_V || level == BLD_LVL_2_1_V) +#define IS_GM_CONF(mode) (mode == GM_SU_13_2 || mode == GM_SU_18_2 || \ + mode == GM_SU_21_5 || mode == GM_SU_25_6 || \ + mode == GM_SU_28_8 || mode == GM_SU_33_9 || \ + mode == GM_SU_38_5 || mode == GM_SU_43_0) +#define IS_PKT_TYPE(type) (type == PKT_BASIC || type == PKT_MBUS || \ + type == PKT_STACK) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* SPIRIT Mode external reference enumeration */ + +enum mode_extref_e +{ + MODE_EXT_XO = 0, + MODE_EXT_XIN = !MODE_EXT_XO +}; + +/* SPIRIT Battery level enumeration */ + +enum battery_level_e +{ + BLD_LVL_2_7_V = 0, + BLD_LVL_2_5_V = 1, + BLD_LVL_2_3_V = 2, + BLD_LVL_2_1_V = 3 +}; + +/* SPIRIT GM conf enumeration */ + +enum gm_conf_e +{ + GM_SU_13_2 = 0, + GM_SU_18_2, + GM_SU_21_5, + GM_SU_25_6, + GM_SU_28_8, + GM_SU_33_9, + GM_SU_38_5, + GM_SU_43_0 +}; + +/* SPIRIT packet type enumeration */ + +enum packet_type_e +{ + PKT_BASIC = 0x00, + PKT_MBUS = 0x02, + PKT_STACK +}; + +/* SPIRIT version type enumeration */ + +enum spirit_version_e +{ + SPIRIT_VERSION_2_1 = 0x01, /* Deprecated */ + SPIRIT_VERSION_3_0, /* The only version of SPIRIT1 */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * + * Input parameters: + * + * Returned Value: + * + ******************************************************************************/ + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_GENERAL_H */ diff --git a/drivers/wireless/spirit/include/spirit_gpio.h b/drivers/wireless/spirit/include/spirit_gpio.h new file mode 100644 index 0000000000..a4505b0fdb --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_gpio.h @@ -0,0 +1,238 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_gpio.h + * This file provides all the low level API to manage SPIRIT GPIO. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_GPIO_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_GPIO_H + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_regs.h" +#include "spirit_types.h" + + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in debug assertions */ + +#define IS_SPIRIT_GPIO(pin) \ + ((pin == SPIRIT_GPIO_0) || (pin == SPIRIT_GPIO_1) || \ + (pin == SPIRIT_GPIO_2) || (pin == SPIRIT_GPIO_3)) +#define IS_SPIRIT_GPIO_MODE(mode) \ + ((mode == SPIRIT_GPIO_MODE_DIGITAL_INPUT) || \ + (mode == SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP) || \ + (mode == SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_HP)) +#define IS_SPIRIT_GPIO_IO(iosel) \ + ((iosel == SPIRIT_GPIO_DIG_OUT_IRQ) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_POR_INV) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_WUT_EXP) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_LBD) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_TX_DATA) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_TX_STATE) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_TX_FIFO_ALMOST_EMPTY) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_TX_FIFO_ALMOST_FULL) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_RX_DATA) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_RX_CLOCK) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_RX_STATE) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_RX_FIFO_ALMOST_FULL) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_RX_FIFO_ALMOST_EMPTY) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_ANTENNA_SWITCH) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_VALID_PREAMBLE) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_SYNC_DETECTED) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_RSSI_THRESHOLD) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_MCU_CLOCK) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_TX_RX_MODE) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_VDD) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_GND) || \ + (iosel == SPIRIT_GPIO_DIG_OUT_SMPS_EXT) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_SLEEP_OR_STANDBY) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_READY) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_LOCK) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_LOCK_SIG) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_LOCK) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_READY2_SIG) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_PM_SET) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_WAIT_VCO_CALIBRATION) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_ENABLE_SYNTH_FULL_CIRCUIT) ||\ + (iosel == SPIRIT_GPIO_DIG_OUT_WAIT_FOR_RCCAL_OK_SIG) ||\ + (iosel == SPIRIT_GPIO_DIG_IN_TX_COMMAND) ||\ + (iosel == SPIRIT_GPIO_DIG_IN_RX_COMMAND) ||\ + (iosel == SPIRIT_GPIO_DIG_IN_TX_DATA_INPUT_FOR_DIRECTRF) ||\ + (iosel == SPIRIT_GPIO_DIG_IN_DATA_WAKEUP) ||\ + (iosel == SPIRIT_GPIO_DIG_IN_EXT_CLOCK_AT_34_7KHZ)) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* SPIRIT GPIO pin enumeration. */ + +enum spirit_gpio_pin_e +{ + SPIRIT_GPIO_0 = GPIO0_CONF_BASE, /* GPIO_0 selected */ + SPIRIT_GPIO_1 = GPIO1_CONF_BASE, /* GPIO_1 selected */ + SPIRIT_GPIO_2 = GPIO2_CONF_BASE, /* GPIO_2 selected */ + SPIRIT_GPIO_3 = GPIO3_CONF_BASE /* GPIO_3 selected */ +}; + +/* SPIRIT GPIO mode enumeration. */ + +enum spirit_gpio_mode_e +{ + SPIRIT_GPIO_MODE_DIGITAL_INPUT = 0x01, /* Digital Input on GPIO */ + SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP = 0x02, /* Digital Output on GPIO + * (low current) */ + SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_HP = 0x03 /* Digital Output on GPIO + * (high current) */ +}; + +/* SPIRIT I/O selection enumeration. */ + +enum spirit_gpio_io_e +{ + SPIRIT_GPIO_DIG_OUT_IRQ = 0x00, /* nIRQ (Interrupt Request, + * active low) , default + * configuration after POR */ + SPIRIT_GPIO_DIG_OUT_POR_INV = 0x08, /* POR inverted (active low) */ + SPIRIT_GPIO_DIG_OUT_WUT_EXP = 0x10, /* Wake-Up Timer expiration: + * "1" when WUT has expired */ + SPIRIT_GPIO_DIG_OUT_LBD = 0x18, /* Low battery detection: "1" + * when battery is below + * threshold setting */ + SPIRIT_GPIO_DIG_OUT_TX_DATA = 0x20, /* TX data internal clock + * output (TX data are sampled + * on the rising edge of it) */ + SPIRIT_GPIO_DIG_OUT_TX_STATE = 0x28, /* TX state indication: "1" + * when Spirit1 is passing in + * the TX state */ + SPIRIT_GPIO_DIG_OUT_TX_FIFO_ALMOST_EMPTY = 0x30, /* TX FIFO Almost Empty Flag */ + SPIRIT_GPIO_DIG_OUT_TX_FIFO_ALMOST_FULL = 0x38, /* TX FIFO Almost Full Flag */ + SPIRIT_GPIO_DIG_OUT_RX_DATA = 0x40, /* RX data output */ + SPIRIT_GPIO_DIG_OUT_RX_CLOCK = 0x48, /* RX clock output + * (recovered from received + * data) */ + SPIRIT_GPIO_DIG_OUT_RX_STATE = 0x50, /* RX state indication: "1" + * when Spirit1 is passing in + * the RX state */ + SPIRIT_GPIO_DIG_OUT_RX_FIFO_ALMOST_FULL = 0x58, /* RX FIFO Almost Full Flag */ + SPIRIT_GPIO_DIG_OUT_RX_FIFO_ALMOST_EMPTY = 0x60, /* RX FIFO Almost Empty Flag */ + SPIRIT_GPIO_DIG_OUT_ANTENNA_SWITCH = 0x68, /* Antenna switch used for + * antenna diversity */ + SPIRIT_GPIO_DIG_OUT_VALID_PREAMBLE = 0x70, /* Valid Preamble Detected Flag */ + SPIRIT_GPIO_DIG_OUT_SYNC_DETECTED = 0x78, /* Sync WordSync Word Detected + * Flag */ + SPIRIT_GPIO_DIG_OUT_RSSI_THRESHOLD = 0x80, /* RSSI above threshold */ + SPIRIT_GPIO_DIG_OUT_MCU_CLOCK = 0x88, /* MCU Clock */ + SPIRIT_GPIO_DIG_OUT_TX_RX_MODE = 0x90, /* TX or RX mode indicator + * (to enable an external range + * extender) */ + SPIRIT_GPIO_DIG_OUT_VDD = 0x98, /* VDD (to emulate an additional + * GPIO of the MCU, programmable + * by SPI) */ + SPIRIT_GPIO_DIG_OUT_GND = 0xa0, /* GND (to emulate an additional + * GPIO of the MCU, programmable + * by SPI) */ + SPIRIT_GPIO_DIG_OUT_SMPS_EXT = 0xa8, /* External SMPS enable + * signal (active high) */ + + SPIRIT_GPIO_DIG_OUT_SLEEP_OR_STANDBY = 0xb0, + SPIRIT_GPIO_DIG_OUT_READY = 0xb8, + SPIRIT_GPIO_DIG_OUT_LOCK = 0xc0, + SPIRIT_GPIO_DIG_OUT_WAIT_FOR_LOCK_SIG = 0xc8, + SPIRIT_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_LOCK = 0xd0, + SPIRIT_GPIO_DIG_OUT_WAIT_FOR_READY2_SIG = 0xd8, + SPIRIT_GPIO_DIG_OUT_WAIT_FOR_TIMER_FOR_PM_SET = 0xe0, + SPIRIT_GPIO_DIG_OUT_WAIT_VCO_CALIBRATION = 0xe8, + SPIRIT_GPIO_DIG_OUT_ENABLE_SYNTH_FULL_CIRCUIT = 0xf0, + SPIRIT_GPIO_DIG_OUT_WAIT_FOR_RCCAL_OK_SIG = 0xff, + + SPIRIT_GPIO_DIG_IN_TX_COMMAND = 0x00, + SPIRIT_GPIO_DIG_IN_RX_COMMAND = 0x08, + SPIRIT_GPIO_DIG_IN_TX_DATA_INPUT_FOR_DIRECTRF = 0x10, + SPIRIT_GPIO_DIG_IN_DATA_WAKEUP = 0x18, + SPIRIT_GPIO_DIG_IN_EXT_CLOCK_AT_34_7KHZ = 0x20 +}; + +/* SPIRIT GPIO Init structure definition. */ + +struct spirit_gpio_init_s +{ + enum spirit_gpio_pin_e gpiopin; /* Specifies the GPIO pins to be + * configured. This parameter can be + * any value of enum spirit_gpio_pin_e */ + enum spirit_gpio_mode_e gpiomode; /* Specifies the operating mode for + * the selected pins. This parameter + * can be a value of enum + * spirit_gpio_mode_e */ + enum spirit_gpio_io_e gpioio; /* Specifies the I/O selection for + * the selected pins. This parameter + * can be a value of enum spirit_gpio_io_e */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * Initializes the Spirit GPIOx according to the specified parameters in + * the gpioinit parameter. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * gpioinit - A pointer to a struct spirit_gpio_init_s structure that + * contains the configuration information for the specified + * SPIRIT GPIO. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_gpio_initialize(FAR struct spirit_library_s *spirit, + FAR const struct spirit_gpio_init_s *gpioinit); + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_GPIO_H*/ diff --git a/drivers/wireless/spirit/include/spirit_irq.h b/drivers/wireless/spirit/include/spirit_irq.h new file mode 100644 index 0000000000..31d6934158 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_irq.h @@ -0,0 +1,455 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_irq.h + * Configuration and management of SPIRIT IRQs. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_IRQ_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_IRQ_H + +/* On the Spirit side specific IRQs can be enabled by setting a specific bitmask. + * The Spirit libraries allow the user to do this in two different ways: + * + * The first enables the IRQs one by one, i.e. using an SPI transaction for each + * IRQ to enable. + * + * Example: + * + * spirit_irq_disableall(spirit); # this call is used to reset the IRQ mask registers + * spirit_irq_enable(spirit, RX_DATA_READY , S_ENABLE); + * spirit_irq_enable(spirit, VALID_SYNC , S_ENABLE); + * spirit_irq_enable(spirit, RX_TIMEOUT , S_ENABLE); + * + * The most applications will require a Spirit IRQ notification on an + * microcontroller EXTI line. Then, the user can check which IRQ has been + * raised using two different ways. + * + * On the ISR of the EXTI line phisically linked to the Spirit pin + * configured for IRQ: + * + * Check only one Spirit IRQ (because the Spirit IRQ status register + * automatically blanks itself after an SPI reading) into the ISR. + * + * Example: + * + * if (spirit_irq_is_pending(RX_DATA_READY)) + * { + * # do something... + * } + * + * Check more than one Spirit IRQ status by storing the entire IRQ status + * registers into a bitfields struct spirit_irqset_s structure and then + * check the interesting bits. + * + * Example: + * + * spirit_irq_get_pending(&irqStatus); + * + * if (irqStatus.IRQ_RX_DATA_READY) + * { + * # do something... + * } + * + * if (irqStatus.IRQ_VALID_SYNC) + * { + * # do something... + * } + * + * if (irqStatus.RX_TIMEOUT) + * { + * # do something... + * } + */ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_types.h" +#include "spirit_regs.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* uint32_t masks */ + +#define IRQ_TX_FIFO_ALMOST_EMPTY_MASK (0x00010000) /* (1 << 16) */ +#define IRQ_RX_FIFO_ALMOST_FULL_MASK (0x00020000) /* (1 << 17) */ +#define IRQ_VALID_SYNC_MASK (0x00200000) /* (1 << 21) */ +#define IRQ_RX_DATA_READY_MASK (0x01000000) /* (1 << 24) */ +#define IRQ_RX_DATA_DISC_MASK (0x02000000) /* (1 << 25) */ +#define IRQ_TX_DATA_SENT_MASK (0x04000000) /* (1 << 26) */ +#define IRQ_TX_FIFO_ERROR_MASK (0x20000000) /* (1 << 29) */ +#define IRQ_RX_FIFO_ERROR_MASK (0x40000000) /* (1 << 30) */ + +/* Macros used in assertions */ + +#define IS_SPIRIT_IRQ_LIST(value) \ + ((value == RX_DATA_READY) || (value == RX_DATA_DISC) || \ + (value == TX_DATA_SENT) || (value == MAX_RE_TX_REACH) || \ + (value == CRC_ERROR) || (value == TX_FIFO_ERROR) || \ + (value == RX_FIFO_ERROR) || (value == TX_FIFO_ALMOST_FULL) || \ + (value == TX_FIFO_ALMOST_EMPTY) || (value == RX_FIFO_ALMOST_FULL) || \ + (value == RX_FIFO_ALMOST_EMPTY) || (value == MAX_BO_CCA_REACH) || \ + (value == VALID_PREAMBLE) || (value == VALID_SYNC) || \ + (value == RSSI_ABOVE_TH) || (value == WKUP_TOUT_LDC) || \ + (value == READY) || (value == STANDBY_DELAYED) || \ + (value == LOW_BATT_LVL) || (value == POR) || \ + (value == BOR) || (value == LOCK) || \ + (value == PM_COUNT_EXPIRED) || (value == XO_COUNT_EXPIRED) || \ + (value == SYNTH_LOCK_TIMEOUT) || (value == SYNTH_LOCK_STARTUP) || \ + (value == SYNTH_CAL_TIMEOUT) || (value == TX_START_TIME) || \ + (value == RX_START_TIME) || (value == RX_TIMEOUT) || \ + (value == AES_END) || (value == ALL_IRQ )) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* IRQ bitfield structure for SPIRIT. This structure is used to read or write + * the single IRQ bit. During the initialization the user has to fill this + * structure setting to one the single field related to the IRQ he wants to + * enable, and to zero the single field related to all the IRQs he wants to + * disable. + * + * The same structure can be used to retrieve all the IRQ events from the IRQ + * registers IRQ_STATUS[3:0], and read if one or more specific IRQ raised. + * + * NOTE: The fields order in the structure depends on used endianness (little + * or big endian). The actual definition is valid ONLY for LITTLE ENDIAN + * mode. Be sure to change the field order when use a different endianness. + */ + +#ifndef CONFIG_ENDIAN_BIG +struct spirit_irqset_s +{ + uint8_t IRQ_SYNTH_LOCK_TIMEOUT : 1; /* IRQ: only for debug; LOCK state + * timeout */ + uint8_t IRQ_SYNTH_LOCK_STARTUP : 1; /* IRQ: only for debug; see + * CALIBR_START_COUNTER */ + uint8_t IRQ_SYNTH_CAL_TIMEOUT : 1; /* IRQ: only for debug; SYNTH + * calibration timeout */ + uint8_t IRQ_TX_START_TIME : 1; /* IRQ: only for debug; TX + * circuitry startup time; see + * TX_START_COUNTER */ + uint8_t IRQ_RX_START_TIME : 1; /* IRQ: only for debug; RX + * circuitry startup time; see + * TX_START_COUNTER */ + uint8_t IRQ_RX_TIMEOUT : 1; /* IRQ: RX operation timeout */ + uint8_t IRQ_AES_END : 1; /* IRQ: AES End of operation */ + uint8_t reserved : 1; /* Reserved bit */ + + uint8_t IRQ_READY : 1; /* IRQ: READY state */ + uint8_t IRQ_STANDBY_DELAYED : 1; /* IRQ: STANDBY state after + * MCU_CK_CONF_CLOCK_TAIL_X + * clock cycles */ + uint8_t IRQ_LOW_BATT_LVL : 1; /* IRQ: Battery level below + * threshold */ + uint8_t IRQ_POR : 1; /* IRQ: Power On Reset */ + uint8_t IRQ_BOR : 1; /* IRQ: Brown out event (both + * accurate and inaccurate) */ + uint8_t IRQ_LOCK : 1; /* IRQ: LOCK state */ + uint8_t IRQ_PM_COUNT_EXPIRED : 1; /* IRQ: only for debug; + * Power Management startup + * timer expiration (see reg + * PM_START_COUNTER, 0xB5) */ + uint8_t IRQ_XO_COUNT_EXPIRED : 1; /* IRQ: only for debug; + * Crystal oscillator settling + * time counter expired */ + + uint8_t IRQ_TX_FIFO_ALMOST_EMPTY : 1; /* IRQ: TX FIFO almost empty */ + uint8_t IRQ_RX_FIFO_ALMOST_FULL : 1; /* IRQ: RX FIFO almost full */ + uint8_t IRQ_RX_FIFO_ALMOST_EMPTY : 1; /* IRQ: RX FIFO almost empty */ + uint8_t IRQ_MAX_BO_CCA_REACH : 1; /* IRQ: Max number of back-off + * during CCA */ + uint8_t IRQ_VALID_PREAMBLE : 1; /* IRQ: Valid preamble detected */ + uint8_t IRQ_VALID_SYNC : 1; /* IRQ: Sync word detected */ + uint8_t IRQ_RSSI_ABOVE_TH : 1; /* IRQ: RSSI above threshold */ + uint8_t IRQ_WKUP_TOUT_LDC : 1; /* IRQ: Wake-up timeout in LDC mode */ + + uint8_t IRQ_RX_DATA_READY : 1; /* IRQ: RX data ready */ + uint8_t IRQ_RX_DATA_DISC : 1; /* IRQ: RX data discarded + * (upon filtering) */ + uint8_t IRQ_TX_DATA_SENT : 1; /* IRQ: TX data sent */ + uint8_t IRQ_MAX_RE_TX_REACH : 1; /* IRQ: Max re-TX reached */ + uint8_t IRQ_CRC_ERROR : 1; /* IRQ: CRC error */ + uint8_t IRQ_TX_FIFO_ERROR : 1; /* IRQ: TX FIFO underflow/overflow + * error */ + uint8_t IRQ_RX_FIFO_ERROR : 1; /* IRQ: RX FIFO underflow/overflow + * error */ + uint8_t IRQ_TX_FIFO_ALMOST_FULL : 1; /* IRQ: TX FIFO almost full */ +}; +#endif + +/* IRQ list enumeration for SPIRIT. This enumeration type can be used to + * address a specific IRQ. + */ + +enum spirit_irq_e +{ + RX_DATA_READY = 0x00000001, /* IRQ: RX data ready */ + RX_DATA_DISC = 0x00000002, /* IRQ: RX data discarded (upon + * filtering) */ + TX_DATA_SENT = 0x00000004, /* IRQ: TX data sent */ + MAX_RE_TX_REACH = 0x00000008, /* IRQ: Max re-TX reached */ + CRC_ERROR = 0x00000010, /* IRQ: CRC error */ + TX_FIFO_ERROR = 0x00000020, /* IRQ: TX FIFO underflow/overflow + * error */ + RX_FIFO_ERROR = 0x00000040, /* IRQ: RX FIFO underflow/overflow + * error */ + TX_FIFO_ALMOST_FULL = 0x00000080, /* IRQ: TX FIFO almost full */ + TX_FIFO_ALMOST_EMPTY = 0x00000100, /* IRQ: TX FIFO almost empty */ + RX_FIFO_ALMOST_FULL = 0x00000200, /* IRQ: RX FIFO almost full */ + RX_FIFO_ALMOST_EMPTY = 0x00000400, /* IRQ: RX FIFO almost empty */ + MAX_BO_CCA_REACH = 0x00000800, /* IRQ: Max number of back-off + * during CCA */ + VALID_PREAMBLE = 0x00001000, /* IRQ: Valid preamble detected */ + VALID_SYNC = 0x00002000, /* IRQ: Sync word detected */ + RSSI_ABOVE_TH = 0x00004000, /* IRQ: RSSI above threshold */ + WKUP_TOUT_LDC = 0x00008000, /* IRQ: Wake-up timeout in LDC mode */ + READY = 0x00010000, /* IRQ: READY state */ + STANDBY_DELAYED = 0x00020000, /* IRQ: STANDBY state after + * MCU_CK_CONF_CLOCK_TAIL_X clock + * cycles */ + LOW_BATT_LVL = 0x00040000, /* IRQ: Battery level below + * threshold */ + POR = 0x00080000, /* IRQ: Power On Reset */ + BOR = 0x00100000, /* IRQ: Brown out event (both accurate and + * inaccurate) */ + LOCK = 0x00200000, /* IRQ: LOCK state */ + PM_COUNT_EXPIRED = 0x00400000, /* IRQ: only for debug; Power + * Management startup timer expiration + * (see reg PM_START_COUNTER, 0xB5) */ + XO_COUNT_EXPIRED = 0x00800000, /* IRQ: only for debug; Crystal + * oscillator settling time counter + * expired */ + SYNTH_LOCK_TIMEOUT = 0x01000000, /* IRQ: only for debug; LOCK state + * timeout */ + SYNTH_LOCK_STARTUP = 0x02000000, /* IRQ: only for debug; see + * CALIBR_START_COUNTER */ + SYNTH_CAL_TIMEOUT = 0x04000000, /* IRQ: only for debug; SYNTH + * calibration timeout */ + TX_START_TIME = 0x08000000, /* IRQ: only for debug; TX circuitry + * startup time; see TX_START_COUNTER */ + RX_START_TIME = 0x10000000, /* IRQ: only for debug; RX circuitry + * startup time; see TX_START_COUNTER */ + RX_TIMEOUT = 0x20000000, /* IRQ: RX operation timeout */ + AES_END = 0x40000000, /* IRQ: AES End of operation */ + ALL_IRQ = 0x7fffffff /* All the above mentioned IRQs */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_irq_disable_all + * + * Description: + * Ssets the IRQ mask registers to 0x00000000, disabling all IRQs. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_irq_disable_all(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_irq_set_mask + * + * Description: + * Enables/disables all the IRQs according to the user defined irqset + * structure. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * irqset - Pointer to a variable of type struct spirit_irqset_s, through + * which the user enable specific IRQs. This parameter is a + * pointer to a struct spirit_irqset_s. + * + * For example suppose to enable only the two IRQ Low Battery Level + * and Tx Data Sent: + * + * struct spirit_irqset_s g_irqset = {0}; + * g_irqset.IRQ_LOW_BATT_LVL = 1; + * g_irqset.IRQ_TX_DATA_SENT = 1; + * spirit_irq_setmask(&g_irqset); + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +#ifndef CONFIG_ENDIAN_BIG +int spirit_irq_set_mask(FAR struct spirit_library_s *spirit, + FAR struct spirit_irqset_s *irqset); +#endif + +/****************************************************************************** + * Name: spirit_irq_enable + * + * Description: + * Enables or disables a specific IRQ. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * irq IRQ to enable or disable. + * newstate - new state for the IRQ. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_irq_enable(FAR struct spirit_library_s *spirit, + enum spirit_irq_e irq, + enum spirit_functional_state_e newstate); + +/****************************************************************************** + * Name: spirit_irt_get_mask + * + * Description: + * Fills a pointer to a structure of struct spirit_irqset_s type with the + * content of the IRQ_MASK registers. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * pirqmask - Pointer to a variable of type struct spirit_irqset_s, through + * which the user can read which IRQs are enabled. All the + * bitfields equals to zero correspond to enabled IRQs, while + * all the bitfields equals to one correspond to disabled IRQs. + * + * For example suppose that the Power On Reset and RX Data + * ready are the only enabled IRQs. + * + * struct spirit_irqset_s g_irqmask; + * spirit_irq_get_pending(&g_irqmask); + * + * Then g_irqmask.IRQ_POR and g_irqmask.IRQ_RX_DATA_READY are + * equal to 0 while all the other bitfields are equal to one. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +#ifndef CONFIG_ENDIAN_BIG +int spirit_irt_get_mask(FAR struct spirit_library_s *spirit, + FAR struct spirit_irqset_s *pirqmask); +#endif + +/****************************************************************************** + * Name: spirit_irq_get_pending + * + * Description: + * Fills a pointer to a structure of struct spirit_irqset_s type with the + * content of the IRQ_STATUS registers. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * pirqstatus - A pointer to a variable of type struct spirit_irqset_s, + * through which the user can receive the status of all the + * IRQs. All the bitfields equals to one correspond to the + * raised interrupts. + * + * For example suppose that the XO settling timeout is raised + * as well as the Sync word detection. + * + * struct spirit_irqset_s g_irqstatus; + * spirit_irq_get_pending(&g_irqstatus); + * + * Then g_irqstatus.IRQ_XO_COUNT_EXPIRED and + * g_irqstatus.IRQ_VALID_SYNC are equals to 1* while all the + * other bitfields are equals to zero. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +#ifndef CONFIG_ENDIAN_BIG +int spirit_irq_get_pending(FAR struct spirit_library_s *spirit, + FAR struct spirit_irqset_s *pirqstatus); +#endif + +/****************************************************************************** + * Name: spirit_irq_clr_pending + * + * Description: + * Clear the IRQ status registers. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_irq_clr_pending(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_irq_is_pending + * + * Description: + * Checks if a specific IRQ has been generated. The call resets all the + * IRQ status, so it can't be used in case of multiple raising interrupts. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * flag IRQ flag to be checked. + * This parameter can be any value of enum spirit_irq_e. + * + * Returned Value: + * true or false. + * + ******************************************************************************/ + +bool spirit_irq_is_pending(FAR struct spirit_library_s *spirit, + enum spirit_irq_e flag); + +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_IRQ_H */ diff --git a/drivers/wireless/spirit/include/spirit_management.h b/drivers/wireless/spirit/include/spirit_management.h new file mode 100644 index 0000000000..2bdf7f7c44 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_management.h @@ -0,0 +1,79 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_management.h + * The management layer for SPIRIT1 library. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_MANAGEMENT_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_MANAGEMENT_H + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_config.h" +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in assertions */ + +/****************************************************************************** + * Public Types + ******************************************************************************/ + + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_management_initcommstate + * + * Description: + * Initialize communication state + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * frequency - Desired communication frequency + * + * Returned Value: + * + ******************************************************************************/ + +void spirit_management_initcommstate(FAR struct spirit_library_s *spirit, + uint32_t frequency); + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_MANAGEMENT_H */ diff --git a/drivers/wireless/spirit/include/spirit_pktbasic.h b/drivers/wireless/spirit/include/spirit_pktbasic.h new file mode 100644 index 0000000000..831e8f9fa3 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_pktbasic.h @@ -0,0 +1,209 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_pktbasic.h + * Configuration and management of SPIRIT Basic packets. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_PKTBASIC_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_PKTBASIC_H + +/* This module can be used to manage the configuration of Spirit Basic + * packets. The user can obtain a packet configuration filling the + * structure struct pktbasic_init_s, defining in it some general + * parameters for the Spirit Basic packet format. Another structure + * the user can fill is struct struct pktbasic_addr_s to define the + * addresses which will be used during the communication. Moreover, + * functions to set the payload length and the destination address + * are provided. + * + * Example: + * + * struct pktbasic_init_s g_pkbasic_init = + * { + * PKT_PREAMBLE_LENGTH_08BYTES, # preamble length in bytes + * PKT_SYNC_LENGTH_4BYTES, # sync word length in bytes + * 0x1A2635A8, # sync word + * PKT_LENGTH_VAR, # variable or fixed payload length + * 7, # length field width in bits (used only for variable length) + * PKT_NO_CRC, # CRC mode + * PKT_CONTROL_LENGTH_0BYTES, # control field length + * S_ENABLE, # address field + * S_DISABLE, # FEC + * S_ENABLE # whitening + * }; + * + * struct struct pktbasic_addr_s g_addrinit = + * { + * S_ENABLE, # enable/disable filtering on my address + * 0x34, # my address (address of the current node) + * S_DISABLE, # enable/disable filtering on multicast address + * 0xEE, # multicast address + * S_DISABLE, # enable/disable filtering on broadcast address + * 0xFF # broadcast address + * }; + * + * ... + * + * spirit_pktbasic_initialize(spirit, &g_pkbasic_init); + * spirit_pktbasic_addrinit(spirit, &g_addrinit); + * + * ... + * + * SpiritPktBasicSetPayloadLength(spirit, 20); + * SpiritPktBasicSetDestinationAddress(spirit, 0x44); + * + * ... + * + * The module provides some other functions that can be used to modify or + * read only some configuration parameters. + */ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_types.h" +#include "spirit_pktcommon.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in assertions */ + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +/* SPIRIT Basic Packet Init structure definition. This structure allows + * users to set the main options for the Basic packet. + */ + +struct pktbasic_init_s +{ + uint32_t syncwords; /* Specifies the sync words. This parameter is + * a uint32_t word with format: + * 0x|SYNC1|SYNC2|SYNC3|SYNC4 */ + uint8_t premblen; /* Specifies the preamble length. This parameter + * can be any value from enum pkt_premblen_e */ + uint8_t synclen; /* Specifies the sync word length. The 32bit + * word passed (syncwords) will be stored in + * the SYNCx registers from the MSB until the + * number of bytes in synclen has been stored. + * This parameter can be any value of enum + * pkt_synlen_e */ + uint8_t fixedvarlen; /* Specifies if a fixed length of packet has to + * be used. This parameter can be any value of + * enum pkt_fixvar_len_e */ + uint8_t pktlenwidth; /* Specifies the size of the length of packet + * in bits. This field is useful only if the + * field fixedvarlen is set to BASIC_LENGTH_VAR. + * For Basic packets the length width is + * log2(max payload length + control length + * (0 to 4) + address length (0 or 1)). */ + uint8_t crcmode; /* Specifies the CRC word length of packet. + * This parameter can be any value of enum + * pkt_crcmode_e */ + uint8_t ctrllen; /* Specifies the length of a control field to + * be sent. This parameter can be any value + * from enum pkt_ctrllen_e */ + uint8_t txdestaddr; /* Specifies if the destination address has to + * be sent. This parameter can be S_ENABLE or + * S_DISABLE */ + uint8_t fec; /* Specifies if FEC has to be enabled. This + * parameter can be S_ENABLE or S_DISABLE */ + uint8_t datawhite; /* Specifies if data whitening has to be + * enabled. This parameter can be S_ENABLE or + * S_DISABLE */ +}; + +/* SPIRIT Basic Packet address structure definition. This structure allows + * users to specify the node/multicast/broadcast addresses and the + * correspondent filtering options. + */ + +struct pktbasic_addr_s +{ + uint8_t destfilter; /* If set RX packet is accepted if its destination + * address matches with srcaddr. This parameter + * can be S_ENABLE or S_DISABLE */ + uint8_t srcaddr; /* Specifies the TX packet source address (address + * of this node). */ + uint8_t mcastfilter; /* If set RX packet is accepted if its destination + * address matches with mcastaddr. This parameter + * can be S_ENABLE or S_DISABLE */ + uint8_t mcastaddr; /* Specifies the Multicast group address for this + * node. */ + uint8_t bcastfilter; /* If set RX packet is accepted if its destination + * address matches with bcastaddr. This parameter + * can be S_ENABLE or S_DISABLE */ + uint8_t bcastaddr; /* Specifies the Broadcast address for this node. */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_pktbasic_initialize + * + * Description: + * Initializes the Spirit Basic packet according to the specified parameters + * in the struct pktbasic_init_s. Notice that this function sets the + * autofiltering option on CRC if it is set to any value different from + * BASIC_NO_CRC. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * pktpasic - Basic packet init structure. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_pktbasic_initialize(FAR struct spirit_library_s *spirit, + FAR const struct pktbasic_init_s *pktpasic); + +/****************************************************************************** + * Name: + * + * Description: + * + * Input Parameters: + * + * Returned Value: + * + ******************************************************************************/ + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_PKTBASIC_H*/ diff --git a/drivers/wireless/spirit/include/spirit_pktcommon.h b/drivers/wireless/spirit/include/spirit_pktcommon.h new file mode 100644 index 0000000000..48eac1ed18 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_pktcommon.h @@ -0,0 +1,205 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_pktcommon.h + * Configuration and management of the common features of SPIRIT packets. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_PKTCOMMON_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_PKTCOMMON_H + +/* This module provides all the common functions and definitions used by the + * packets modules. Here are also defined all the generic enumeration types + * that are redefined in the specific packets modules, but every enumeration + * value is referred to this module. So the user who wants to configure the + * preamble of a Basic, or a STack packet has to use the enumeration values + * defined here. + * + * Example: + * + * ... + * + * spirit_pktbasic_set_preamblen(PKT_PREAMBLE_LENGTH_18BYTES); + * + * ... + */ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in assertions */ + +#define IS_PKT_PREAMBLE_LENGTH(len) \ + ((len == PKT_PREAMBLE_LENGTH_01BYTE) || (len == PKT_PREAMBLE_LENGTH_02BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_03BYTES) || (len == PKT_PREAMBLE_LENGTH_04BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_05BYTES) || (len == PKT_PREAMBLE_LENGTH_06BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_07BYTES) || (len == PKT_PREAMBLE_LENGTH_08BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_09BYTES) || (len == PKT_PREAMBLE_LENGTH_10BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_11BYTES) || (len == PKT_PREAMBLE_LENGTH_12BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_13BYTES) || (len == PKT_PREAMBLE_LENGTH_14BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_15BYTES) || (len == PKT_PREAMBLE_LENGTH_16BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_17BYTES) || (len == PKT_PREAMBLE_LENGTH_18BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_19BYTES) || (len == PKT_PREAMBLE_LENGTH_20BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_21BYTES) || (len == PKT_PREAMBLE_LENGTH_22BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_23BYTES) || (len == PKT_PREAMBLE_LENGTH_24BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_25BYTES) || (len == PKT_PREAMBLE_LENGTH_26BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_27BYTES) || (len == PKT_PREAMBLE_LENGTH_28BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_29BYTES) || (len == PKT_PREAMBLE_LENGTH_30BYTES) || \ + (len == PKT_PREAMBLE_LENGTH_31BYTES) || (len == PKT_PREAMBLE_LENGTH_32BYTES)) +#define IS_PKT_SYNC_LENGTH(len) \ + ((len == PKT_SYNC_LENGTH_1BYTE) || (len == PKT_SYNC_LENGTH_2BYTES) || \ + (len == PKT_SYNC_LENGTH_3BYTES) || (len == PKT_SYNC_LENGTH_4BYTES)) +#define IS_PKT_FIX_VAR_LENGTH(len) \ + ((len == PKT_LENGTH_FIX) || (len == PKT_LENGTH_VAR)) +#define IS_PKT_CRC_MODE(mode) \ + ((mode == PKT_NO_CRC) || (mode == PKT_CRC_MODE_8BITS) || \ + (mode == PKT_CRC_MODE_16BITS_1) || (mode == PKT_CRC_MODE_16BITS_2) || \ + (mode == PKT_CRC_MODE_24BITS)) +#define IS_PKT_CONTROL_LENGTH(len) \ + ((len == PKT_CONTROL_LENGTH_0BYTES) || (len == PKT_CONTROL_LENGTH_1BYTE) || \ + (len == PKT_CONTROL_LENGTH_2BYTES) || (len == PKT_CONTROL_LENGTH_3BYTES) || \ + (len == PKT_CONTROL_LENGTH_4BYTES)) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Preamble length in bytes enumeration. */ + +enum pkt_premblen_e +{ + PKT_PREAMBLE_LENGTH_01BYTE = 0x00, /* Preamble length 1 byte */ + PKT_PREAMBLE_LENGTH_02BYTES = 0x08, /* Preamble length 2 bytes */ + PKT_PREAMBLE_LENGTH_03BYTES = 0x10, /* Preamble length 3 bytes */ + PKT_PREAMBLE_LENGTH_04BYTES = 0x18, /* Preamble length 4 bytes */ + PKT_PREAMBLE_LENGTH_05BYTES = 0x20, /* Preamble length 5 bytes */ + PKT_PREAMBLE_LENGTH_06BYTES = 0x28, /* Preamble length 6 bytes */ + PKT_PREAMBLE_LENGTH_07BYTES = 0x30, /* Preamble length 7 bytes */ + PKT_PREAMBLE_LENGTH_08BYTES = 0x38, /* Preamble length 8 bytes */ + PKT_PREAMBLE_LENGTH_09BYTES = 0x40, /* Preamble length 9 bytes */ + PKT_PREAMBLE_LENGTH_10BYTES = 0x48, /* Preamble length 10 bytes */ + PKT_PREAMBLE_LENGTH_11BYTES = 0x50, /* Preamble length 11 bytes */ + PKT_PREAMBLE_LENGTH_12BYTES = 0x58, /* Preamble length 12 bytes */ + PKT_PREAMBLE_LENGTH_13BYTES = 0x60, /* Preamble length 13 bytes */ + PKT_PREAMBLE_LENGTH_14BYTES = 0x68, /* Preamble length 14 bytes */ + PKT_PREAMBLE_LENGTH_15BYTES = 0x70, /* Preamble length 15 bytes */ + PKT_PREAMBLE_LENGTH_16BYTES = 0x78, /* Preamble length 16 bytes */ + PKT_PREAMBLE_LENGTH_17BYTES = 0x80, /* Preamble length 17 bytes */ + PKT_PREAMBLE_LENGTH_18BYTES = 0x88, /* Preamble length 18 bytes */ + PKT_PREAMBLE_LENGTH_19BYTES = 0x90, /* Preamble length 19 bytes */ + PKT_PREAMBLE_LENGTH_20BYTES = 0x98, /* Preamble length 20 bytes */ + PKT_PREAMBLE_LENGTH_21BYTES = 0xa0, /* Preamble length 21 bytes */ + PKT_PREAMBLE_LENGTH_22BYTES = 0xa8, /* Preamble length 22 bytes */ + PKT_PREAMBLE_LENGTH_23BYTES = 0xb0, /* Preamble length 23 bytes */ + PKT_PREAMBLE_LENGTH_24BYTES = 0xb8, /* Preamble length 24 bytes */ + PKT_PREAMBLE_LENGTH_25BYTES = 0xc0, /* Preamble length 25 bytes */ + PKT_PREAMBLE_LENGTH_26BYTES = 0xc8, /* Preamble length 26 bytes */ + PKT_PREAMBLE_LENGTH_27BYTES = 0xd0, /* Preamble length 27 bytes */ + PKT_PREAMBLE_LENGTH_28BYTES = 0xd8, /* Preamble length 28 bytes */ + PKT_PREAMBLE_LENGTH_29BYTES = 0xe0, /* Preamble length 29 bytes */ + PKT_PREAMBLE_LENGTH_30BYTES = 0xe8, /* Preamble length 30 bytes */ + PKT_PREAMBLE_LENGTH_31BYTES = 0xf0, /* Preamble length 31 bytes */ + PKT_PREAMBLE_LENGTH_32BYTES = 0xf8 /* Preamble length 32 bytes */ +}; + +/* Sync length in bytes enumeration. */ + +enum pkt_synlen_e +{ + PKT_SYNC_LENGTH_1BYTE = 0x00, /* Sync length 1 byte */ + PKT_SYNC_LENGTH_2BYTES = 0x02, /* Sync length 2 bytes */ + PKT_SYNC_LENGTH_3BYTES = 0x04, /* Sync length 3 bytes */ + PKT_SYNC_LENGTH_4BYTES = 0x06, /* Sync length 4 bytes */ +}; + +/* Fixed or variable payload length enumeration. */ + +enum pkt_fixvar_len_e +{ + PKT_LENGTH_FIX = 0x00, /* Fixed payload length */ + PKT_LENGTH_VAR = 0x01 /* Variable payload length */ +}; + +/* CRC length in bytes enumeration. */ + +enum pkt_crcmode_e +{ + PKT_NO_CRC = 0x00, /* No CRC */ + PKT_CRC_MODE_8BITS = 0x20, /* CRC length 8 bits - poly: 0x07 */ + PKT_CRC_MODE_16BITS_1 = 0x40, /* CRC length 16 bits - poly: 0x8005 */ + PKT_CRC_MODE_16BITS_2 = 0x60, /* CRC length 16 bits - poly: 0x1021 */ + PKT_CRC_MODE_24BITS = 0x80, /* CRC length 24 bits - poly: 0x864CFB */ +}; + +/* Control length in bytes enumeration for SPIRIT packets. */ + +enum pkt_ctrllen_e +{ + PKT_CONTROL_LENGTH_0BYTES = 0x00, /* Control length 0 byte */ + PKT_CONTROL_LENGTH_1BYTE, /* Control length 1 byte */ + PKT_CONTROL_LENGTH_2BYTES, /* Control length 2 bytes */ + PKT_CONTROL_LENGTH_3BYTES, /* Control length 3 bytes */ + PKT_CONTROL_LENGTH_4BYTES /* Control length 4 bytes */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * + * Input Parameters: + * + * Returned Value: + * + ******************************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_PKTCOMMON_H */ diff --git a/drivers/wireless/spirit/include/spirit_qi.h b/drivers/wireless/spirit/include/spirit_qi.h new file mode 100644 index 0000000000..8000f22ceb --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_qi.h @@ -0,0 +1,194 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_qi.h + * Configuration and management of SPIRIT QI. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_QI_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_QI_H + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_regs.h" +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in debug assertions */ + +#define IS_SQI_THR(value) \ + (value == SQI_TH_0 || value == SQI_TH_1 || \ + value == SQI_TH_2 || value == SQI_TH_3) +#define IS_RSSI_FILTER_GAIN(value) \ + (value==RSSI_FG_0 || value==RSSI_FG_1 ||\ + value==RSSI_FG_2 || value==RSSI_FG_3 ||\ + value==RSSI_FG_4 || value==RSSI_FG_5 ||\ + value==RSSI_FG_6 || value==RSSI_FG_7 ||\ + value==RSSI_FG_8 || value==RSSI_FG_9 ||\ + value==RSSI_FG_10 || value==RSSI_FG_11 ||\ + value==RSSI_FG_12 || value==RSSI_FG_13 ||\ + value==RSSI_FG_14 || value==RSSI_FG_15) + +/* Range for the RSSI Threshold in dBm */ + +#define IS_RSSI_THR_DBM(value) (value >= -130 && value <= -2) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* SQI threshold value enumeration. */ + +enum spirit_sqi_threshold_e +{ + SQI_TH_0 = 0x00, + SQI_TH_1 = 0x40, + SQI_TH_2 = 0x80, + SQI_TH_3 = 0xC0 +}; + +/* RSSI filter gain value enumeration. */ + +enum spirit_rssi_filtergain_e +{ + RSSI_FG_0 = 0x00, + RSSI_FG_1 = 0x10, + RSSI_FG_2 = 0x20, + RSSI_FG_3 = 0x30, + RSSI_FG_4 = 0x40, + RSSI_FG_5 = 0x50, + RSSI_FG_6 = 0x60, + RSSI_FG_7 = 0x70, + RSSI_FG_8 = 0x80, + RSSI_FG_9 = 0x90, + RSSI_FG_10 = 0xa0, + RSSI_FG_11 = 0xb0, + RSSI_FG_12 = 0xc0, + RSSI_FG_13 = 0xd0, + RSSI_FG_14 = 0xe0, /* Recommended value */ + RSSI_FG_15 = 0xf0 +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_qi_sqicheck + * + * Description: + * Enables/Disables the Synchronization Quality Indicator check. The + * running peak SQI is compared to a threshold value and the sync valid + * IRQ is asserted as soon as the threshold is passed. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - new state for SQI check. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_qi_sqicheck(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate); + +/****************************************************************************** + * Name: spirit_qi_set_sqithreshold + * + * Description: + * Sets the SQI threshold. The synchronization quality threshold is equal to + * 8 * SYNC_LEN - 2 * SQI_TH with SQI_TH = 0..3. When SQI_TH is 0 perfect + * match is required; when SQI_TH = 1, 2, 3 then 1, 2, or 3 bit errors are + * respectively accepted. It is recommended that the SQI check is always + * enabled. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * sqithr - parameter of the formula above. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_qi_set_sqithreshold(FAR struct spirit_library_s *spirit, + enum spirit_sqi_threshold_e sqithr); + +/****************************************************************************** + * Name: spirit_qi_get_sqithreshold + * + * Description: + * Returns the SQI threshold. The synchronization quality threshold is equal + * to 8 * SYNC_LEN - 2 * SQI_TH with SQI_TH = 0..3. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * SQI threshold (SQI_TH of the formula above). Errors are not reported. + * + ******************************************************************************/ + +enum spirit_sqi_threshold_e + spirit_qi_get_sqithreshold(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_qi_set_rssithreshold + * + * Description: + * Sets the RSSI threshold from its dBm value according to the formula: + * (RSSI[Dbm] + 130)/0.5. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * dbmvalue - RSSI threshold reported in dBm. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_qi_set_rssithreshold(FAR struct spirit_library_s *spirit, + int dbmvalue); + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_GENERAL_H*/ diff --git a/drivers/wireless/spirit/include/spirit_radio.h b/drivers/wireless/spirit/include/spirit_radio.h new file mode 100644 index 0000000000..8b91b2fa90 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_radio.h @@ -0,0 +1,720 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_radio.h + * This file provides all the low level API to manage Analog and Digital radio + * part of SPIRIT. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_RADIO_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_RADIO_H + +/* In order to configure the Radio main parameters, the user can fit struct + * radio_init_s structure the and call the spirit_radio_initialize() + * function passing its pointer* as an argument. + * + * Example: + * + * struct radio_init_s g_radio_init = + * { + * 433.4e6, # base frequency + * 20e3, # channel space + * 0, # Xtal offset in ppm + * 0, # channel number + * FSK, # modulation select + * 38400, # datarate + * 20e3, # frequency deviation + * 100.5e3 # channel filter bandwidth + * }; + * + * ... + * + * spirit_radio_initialize(spirit, &g_radio_init); + */ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Radio_Band */ + +#define FBASE_DIVIDER 262144 /* 2^18 factor dividing fxo in fbase + * formula */ + +#define HIGH_BAND_FACTOR 6 /* Band select factor for high band. + * Factor B in the equation 2 */ +#define MIDDLE_BAND_FACTOR 12 /* Band select factor for middle + * band. Factor B in the equation 2 */ +#define LOW_BAND_FACTOR 16 /* Band select factor for low band. + * Factor B in the equation 2 */ +#define VERY_LOW_BAND_FACTOR 32 /* Band select factor for very low + * band. Factor B in the equation 2 */ + +#define HIGH_BAND_LOWER_LIMIT 778000000 /* Lower limit of the high + * band: 779 MHz */ +#define HIGH_BAND_UPPER_LIMIT 957100000 /* Upper limit of the high + * band: 956 MHz */ +#define MIDDLE_BAND_LOWER_LIMIT 386000000 /* Lower limit of the middle + * band: 387 MHz */ +#define MIDDLE_BAND_UPPER_LIMIT 471100000 /* Upper limit of the middle + * band: 470 MHz */ +#define LOW_BAND_LOWER_LIMIT 299000000 /* Lower limit of the low + * band: 300 MHz */ +#define LOW_BAND_UPPER_LIMIT 349100000 /* Upper limit of the low + * band: 348 MHz */ +#define VERY_LOW_BAND_LOWER_LIMIT 149000000 /* Lower limit of the very + * low band: 150 MHz */ +#define VERY_LOW_BAND_UPPER_LIMIT 175100000 /* Upper limit of the very + * low band: 174 MHz */ + +#define IS_FREQUENCY_BAND_HIGH(frequency) \ + ((frequency) >= HIGH_BAND_LOWER_LIMIT && (frequency) <= HIGH_BAND_UPPER_LIMIT) +#define IS_FREQUENCY_BAND_MIDDLE(frequency) \ + ((frequency) >= MIDDLE_BAND_LOWER_LIMIT && (frequency) <= MIDDLE_BAND_UPPER_LIMIT) +#define IS_FREQUENCY_BAND_LOW(frequency) \ + ((frequency) >= LOW_BAND_LOWER_LIMIT && (frequency) <= LOW_BAND_UPPER_LIMIT) +#define IS_FREQUENCY_BAND_VERY_LOW(frequency) \ + ((frequency) >= VERY_LOW_BAND_LOWER_LIMIT && (frequency)<=VERY_LOW_BAND_UPPER_LIMIT) + +#define IS_FREQUENCY_BAND(frequency) \ + (IS_FREQUENCY_BAND_HIGH(frequency)|| IS_FREQUENCY_BAND_MIDDLE(frequency)|| \ + IS_FREQUENCY_BAND_LOW(frequency) || IS_FREQUENCY_BAND_VERY_LOW(frequency)) + +/* Radio_IF_Offset. + * + * This represents the IF_OFFSET_ANA inorder to have an intermediate frequency + * of 480 kHz. + */ + +#define IF_OFFSET_ANA(fxo) (lroundf(480140.0 / (fxo) * 12288 - 64.0)) + +/* Radio_FC_Offset */ + +#define F_OFFSET_DIVIDER 262144 /* 2^18 factor dividing fxo + * in foffset formula */ +#define PPM_FACTOR 1000000 /* 10^6 factor to use with + * Xtal_offset_ppm */ + +#define F_OFFSET_LOWER_LIMIT(fxo) ((-(int32_t)fxo) / F_OFFSET_DIVIDER * 2048) +#define F_OFFSET_UPPER_LIMIT(fxo) ((int32_t)(fxo / F_OFFSET_DIVIDER * 2047)) + +#define IS_FREQUENCY_OFFSET(offset, fxo) \ + (offset >= F_OFFSET_LOWER_LIMIT(fxo) && offset <= F_OFFSET_UPPER_LIMIT(fxo)) + +/* Radio_Channel_Space */ + +#define CHSPACE_DIVIDER 32768 /* 2^15 factor dividing fxo in + * channel space formula */ + +#define IS_CHANNEL_SPACE(chspace, fxo) \ + (chspace <= (fxo / 32768 * 255)) + +/* Radio_Datarate */ + +#define MINIMUM_DATARATE 100 /* Minimum datarate + * supported by SPIRIT1 100 bps */ +#define MAXIMUM_DATARATE 510000 /* Maximum datarate + * supported by SPIRIT1 500 kbps */ + +#define IS_DATARATE(datarate) \ + (datarate >= MINIMUM_DATARATE && datarate <= MAXIMUM_DATARATE) + +/* Radio_Frequency_Deviation */ + +#define F_DEV_MANTISSA_UPPER_LIMIT 7 /* Maximum value for the + * mantissa in frequency + * deviation formula */ +#define F_DEV_EXPONENT_UPPER_LIMIT 9 /* Maximum value for the + * exponent in frequency + * deviation formula */ + +#define F_DEV_LOWER_LIMIT(fxo) (fxo >> 16) +#define F_DEV_UPPER_LIMIT(fxo) ((fxo * 15) >> 10) + +#define IS_F_DEV(fdev,fxo) \ + (fdev >= F_DEV_LOWER_LIMIT(fxo) && fdev <= F_DEV_UPPER_LIMIT(fxo)) + +/* Radio_Channel_Bandwidth + * + * CH_BW_LOWER_LIMIT - Minimum value of the channel filter bandwidth + * CH_BW_UPPER_LIMIT - Maximum value of the channel filter bandwidth + */ + +#define CH_BW_LOWER_LIMIT(fxo) 1100 * (fxo / 1000000) / 26 +#define CH_BW_UPPER_LIMIT(fxo) 800100*(fxo / 1000000) / 26 + +#define IS_CH_BW(bw,fxo) \ + ((bw) >= CH_BW_LOWER_LIMIT(fxo) && (bw) <= CH_BW_UPPER_LIMIT(fxo)) + +/* Radio_Power_Amplifier */ + +#define IS_PA_MAX_INDEX(index) ((index) <= 7) +#define IS_PAPOWER_DBM(patable) ((patable) >= (-31) && (patable) <= (12)) +#define IS_PAPOWER(patable) ((patable) <= 90) +#define IS_PA_STEP_WIDTH(width) ((width) >= 1 && (width) <= 4) + +/* Radio_Automatic_Frequency_Correction */ + +#define IS_AFC_FAST_GAIN(gain) ((gain) <= 5) +#define IS_AFC_SLOW_GAIN(gain) ((gain) <= 15) +#define IS_AFC_PD_LEAKAGE(leakage) ((leakage) <= 31) + +/* Radio_Automatic_Gain_Control */ + +#define AGC_MEASURE_TIME_UPPER_LIMIT_US(fxo) \ + (393216.0 / fxo) + +#define IS_AGC_MEASURE_TIME_US(time, fxo) \ + (time <= AGC_MEASURE_TIME_UPPER_LIMIT_US(fxo)) + +#define IS_AGC_MEASURE_TIME(time) (time<=15) + +#define AGC_HOLD_TIME_UPPER_LIMIT_US(fxo) \ + (756.0 / fxo) + +#define IS_AGC_HOLD_TIME_US(time,fxo) \ + (time <= AGC_HOLD_TIME_UPPER_LIMIT_US(fxo)) + +#define IS_AGC_HOLD_TIME(time) (time <= 63) + +#define IS_AGC_THRESHOLD(threshold) (threshold <=1 5) + +/* Radio_Clock_Recovery */ + +#define IS_CLK_REC_P_GAIN(gain) ((gain) <= 7) +#define IS_CLK_REC_I_GAIN(gain) ((gain) <= 15) + +/* Other acros used in assertions */ + +#define IS_XTAL_FLAG(flag) \ + (((flag) == XTAL_FLAG_24_MHz) || ((flag) == XTAL_FLAG_26_MHz)) +#define IS_BAND_SELECTED(band) \ + (((band) == HIGH_BAND) || ((band) == MIDDLE_BAND) || \ + ((band) == LOW_BAND) || ((band) == VERY_LOW_BAND)) +#define IS_MODULATION_SELECTED(mod) \ + (((mod) == FSK) || ((mod) == GFSK_BT05) || \ + ((mod) == GFSK_BT1) || ((mod) == ASK_OOK) || \ + ((mod) == MSK)) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +/* SPIRIT XTAL frequency enumeration */ + +enum xtal_flag_e +{ + XTAL_FLAG_24_MHz = 0x00, /* 24 MHz Xtal selected */ + XTAL_FLAG_26_MHz = 0x01 /* 26 MHz Xtal selected */ +}; + +/* SPIRIT Band enumeration */ + +enum spirit_bandselect_e +{ + HIGH_BAND = 0x00, /* High_Band selected: from 779 MHz to 915 MHz */ + MIDDLE_BAND = 0x01, /* Middle Band selected: from 387 MHz to 470 MHz */ + LOW_BAND = 0x02, /* Low Band selected: from 300 MHz to 348 MHz */ + VERY_LOW_BAND = 0x03 /* Vary low Band selected: from 150 MHz to 174 MHz */ +}; + +/* SPIRIT Modulation enumeration */ + +enum modulation_select_e +{ + FSK = 0x00, /* 2-FSK modulation selected */ + GFSK_BT05 = 0x50, /* GFSK modulation selected with BT=0.5 */ + GFSK_BT1 = 0x10, /* GFSK modulation selected with BT=1 */ + ASK_OOK = 0x20, /* ASK or OOK modulation selected. ASK will + * use power ramping */ + MSK = 0x30 /* MSK modulation selected */ +}; + +/* SPIRIT Radio initialization structure definition */ + +struct radio_init_s +{ + uint32_t base_frequency; /* Specifies the base carrier frequency (in + * Hz), i.e. the carrier frequency of channel + * #0. This parameter can be in one of the + * following ranges: High_Band: from 779 MHz to + * 915 MHz Middle Band: from 387 MHz to 470 MHz + * Low Band: from 300 MHz to 348 MHz */ + uint32_t chspace; /* Specifies the channel spacing expressed + * in Hz. The channel spacing is expressed as: + * NxFREQUENCY_STEPS, where frequency STEPS is + * F_Xo/2^15. This parameter can be in the + * range: [0, F_Xo/2^15*255] Hz */ + int16_t xtal_offset_ppm; /* Specifies the offset frequency (in ppm) + * to compensate crystal inaccuracy expressed + * as signed value. */ + uint8_t chnum; /* Specifies the channel number. This value + * is multiplied by the channel spacing and + * added to synthesizer base frequency to + * generate the actual RF carrier frequency */ + uint8_t modselect; /* Specifies the modulation. This parameter can + * be any value from enum modulation_select_e */ + uint32_t datarate; /* Specifies the datarate expressed in bps. + * This parameter can be in the range between + * 100 bps and 500 kbps */ + uint32_t freqdev; /* Specifies the frequency deviation + * expressed in Hz. This parameter can be in + * the range: [F_Xo*8/2^18, F_Xo*7680/2^18] Hz */ + uint32_t bandwidth; /* Specifies the channel filter bandwidth + * expressed in Hz. This parameter can be in + * the range between 1100 and 800100 Hz */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_radio_initialize + * + * Description: + * Initializes the SPIRIT analog and digital radio part according to the + * specified parameters in the radioinit. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * radioinit - Pointer to a struct radio_init_s that contains the + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_initialize(FAR struct spirit_library_s *spirit, + FAR const struct radio_init_s *radioinit); + +/****************************************************************************** + * Name: spirit_radio_set_xtalflag + * + * Description: + * Sets the Xtal configuration in the ANA_FUNC_CONF0 register. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * xtalflag one of the possible value of the enum type xtal_flag_e. + * XTAL_FLAG_24_MHz: in case of 24 MHz crystal + * XTAL_FLAG_26_MHz: in case of 26 MHz crystal + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_set_xtalflag(FAR struct spirit_library_s *spirit, + enum xtal_flag_e xtalflag); + +/****************************************************************************** + * Name: spirit_radio_get_xtalflag + * + * Description: + * Returns the Xtal configuration in the ANA_FUNC_CONF0 register. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * XtalFrequency Settled Xtal configuration. + * + ******************************************************************************/ + +enum xtal_flag_e spirit_radio_get_xtalflag(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_get_synthword + * + * Description: + * Returns the synth word. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * 32-bit Synth word. Errors are not reported. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_synthword(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_set_synthword + * + * Description: + * Sets the SYNTH registers. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * synthword - The synth word to write in the SYNTH[3:0] registers. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_set_synthword(FAR struct spirit_library_s *spirit, + uint32_t synthword); + +/****************************************************************************** + * Name: spirit_radio_set_band + * + * Description: + * Sets the operating band. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * band - The band to set. This parameter can be one of following values: + * HIGH_BAND High_Band selected: from 779 MHz to 915 MHz + * MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz + * LOW_BAND: Low Band selected: from 300 MHz to 348 MHz + * VERY_LOW_BAND: Very low Band selected: from 150 MHz to 174 MHz + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_set_band(FAR struct spirit_library_s *spirit, + enum spirit_bandselect_e band); + +/****************************************************************************** + * Name: spirit_radio_get_band + * + * Description: + * Returns the operating band. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * BandSelect Settled band. This returned value may be one of the + * following values: + * HIGH_BAND High_Band selected: from 779 MHz to 915 MHz + * MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz + * LOW_BAND: Low Band selected: from 300 MHz to 348 MHz + * VERY_LOW_BAND: Very low Band selected: from 150 MHz to 174 MHz + * + ******************************************************************************/ + +enum spirit_bandselect_e + spirit_radio_get_band(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_set_basefrequency + * + * Description: + * Sets the Synth word and the Band Select register according to desired + * base carrier frequency. In this API the Xtal configuration is read out + * from the corresponding register. The user shall fix it before call this + * API. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fbase - The base carrier frequency expressed in Hz as unsigned word. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_set_basefrequency(FAR struct spirit_library_s *spirit, + uint32_t fbase); + +/****************************************************************************** + * Name: + * + * Description: + * Returns the base carrier frequency. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Base carrier frequency expressed in Hz as unsigned word. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_basefrequency(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_convert_datarate + * + * Description: + * Returns the mantissa and exponent, whose value used in the datarate + * formula will give the datarate value closer to the given datarate. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * datarate - datarate expressed in bps. This parameter ranging between 100 and 500000. + * pcm - pointer to the returned mantissa value. + * pce - pointer to the returned exponent value. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_convert_datarate(FAR struct spirit_library_s *spirit, + uint32_t datarate, FAR uint8_t *pcm, + FAR uint8_t *pce); + +/****************************************************************************** + * Name: spirit_radio_convert_freqdev + * + * Description: + * Returns the mantissa and exponent, whose value used in the frequency + * deviation formula will give a frequency deviation value most closer to + * the given frequency deviation. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fdev - Frequency deviation expressed in Hz. This parameter can be a + * value in the range [F_Xo*8/2^18, F_Xo*7680/2^18]. + * pcm - pointer to the returned mantissa value. + * pce - pointer to the returned exponent value. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_convert_freqdev(FAR struct spirit_library_s *spirit, + uint32_t fdev, FAR uint8_t *pcm, + FAR uint8_t *pce); + +/****************************************************************************** + * Name: + * + * Description: + * Returns the mantissa and exponent for a given bandwidth. Even if it is + * possible to pass as parameter any value in the below mentioned range, the + * API will search the closer value according to a fixed table of channel + * bandwidth values (@ref s_vectnBandwidth), as defined in the datasheet, + * returning the corresponding mantissa and exponent value. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * bandwidth - bandwidth expressed in Hz. This parameter ranging between + * 1100 and 800100. + * pcm - pointer to the returned mantissa value. + * pce - pointer to the returned exponent value. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_convert_chbandwidth(FAR struct spirit_library_s *spirit, + uint32_t bandwidth, FAR uint8_t *pcm, + FAR uint8_t *pce); + +/****************************************************************************** + * Name: spirit_radio_dbm2reg + * + * Description: + * Returns the PA register value that corresponds to the passed dBm power. + * + * NOTE: The power interpolation curves used by this function have been + * extracted by measurements done on the divisional evaluation boards. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fbase Frequency base expressed in Hz. + * powerdbm Desired power in dBm. + * + * Returned Value: + * Register value as byte. + * + ******************************************************************************/ + +uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, + uint32_t fbase, float powerdbm); + +/****************************************************************************** + * Name: spirit_radio_set_palevel + * + * Description: + * Sets a specific PA_LEVEL register, with a value given in dBm. + * + * NOTE: This function makes use of the @ref spirit_radio_dbm2reg fcn to + * interpolate the power value. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * ndx - PA_LEVEL to set. This parameter shall be in the range [0:7]. + * powerdbm - PA value to write expressed in dBm . Be sure that this values + * is in the correct range [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dBm. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_set_palevel(FAR struct spirit_library_s *spirit, + uint8_t ndx, float powerdbm); + +/****************************************************************************** + * Name: spirit_radio_set_palevel_maxindex + * + * Description: + * Sets a specific PA_LEVEL_MAX_INDEX. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * ndx - PA_LEVEL_MAX_INDEX to set. This parameter must be in the range + * [0:7]. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_set_palevel_maxindex(FAR struct spirit_library_s *spirit, + uint8_t ndx); + +/****************************************************************************** + * Name: spirit_radio_afcfreezeonsync + * + * Description: + * Enables or Disables the AFC freeze on sync word detection. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - new state for AFC freeze on sync word detection. + * This parameter can be: S_ENABLE or S_DISABLE. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_afcfreezeonsync(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate); + +/****************************************************************************** + * Name: spirit_radio_persistentrx + * + * Description: + * Enables or Disables the persistent RX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state of this mode. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_persistentrx(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate); + +/****************************************************************************** + * Name: spirit_radio_set_refdiv + * + * Description: + * Enables or Disables the synthesizer reference divider. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate new state for synthesizer reference divider. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_set_refdiv(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate); + +/****************************************************************************** + * Name: spirit_radio_get_refdiv + * + * Description: + * Get the the synthesizer reference divider state. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * S_ENABLE or S_DISABLE. Errors are not reported. + * + ******************************************************************************/ + +enum spirit_functional_state_e + spirit_radio_get_refdiv(FAR struct spirit_library_s *spirit); + +/****************************************************************************** + * Name: spirit_radio_enable_digdivider + * + * Description: + * Enables or Disables the synthesizer reference divider. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for synthesizer reference divider. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_enable_digdivider(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate); + +/****************************************************************************** + * Name: spirit_radio_isenabled_digdivider + * + * Description: + * Get the the synthesizer reference divider state. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * S_ENABLE or S_DISABLE. Error conditions are not detected. + * + ******************************************************************************/ + +enum spirit_functional_state_e + spirit_radio_isenabled_digdivider(FAR struct spirit_library_s *spirit); + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_RADIO_H*/ diff --git a/drivers/wireless/spirit/include/spirit_regs.h b/drivers/wireless/spirit/include/spirit_regs.h new file mode 100644 index 0000000000..872df1e318 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_regs.h @@ -0,0 +1,2379 @@ +/********************************************************************************************** + * include/nuttx/wireless/spirit/spirit_regs.h + * This file contains all the SPIRIT registers address and masks. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + **********************************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_REGS_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_REGS_H + +/********************************************************************************************** + * Pre-processor Definitions + **********************************************************************************************/ + +/* General_Configuration_Registers */ + +/* ANA_FUNC_CONF register 1 + * + * Read Write + * Default value: 0x0c + * 7:5 NUM_EN_PIPES: Number of enabled pipes (starting from Data Pipe 0). + * 4:2 GM_CONF[2:0]: Sets the driver gm of the XO at start-up: + * GM_CONF2 | GM_CONF1 | GM_CONF0 | GM [mS] + * ------------------------------------------ + * 0 | 0 | 0 | 13.2 + * 0 | 0 | 1 | 18.2 + * 0 | 1 | 0 | 21.5 + * 0 | 1 | 1 | 25.6 + * 1 | 0 | 0 | 28.8 + * 1 | 0 | 1 | 33.9 + * 1 | 1 | 0 | 38.5 + * 1 | 1 | 1 | 43.0 + * 1:0 SET_BLD_LVL[1:0]: Sets the Battery Level Detector threshold: + * SET_BLD_LVL1 | SET_BLD_LVL0 | Threshold [V] + * ------------------------------------------ + * 0 | 0 | 2.7 + * 0 | 1 | 2.5 + * 1 | 0 | 2.3 + * 1 | 1 | 2.1 + */ + +#define ANA_FUNC_CONF1_BASE ((uint8_t)0x00) /* ANA_FUNC_CONF1 Address (R/W) */ + +#define ANA_FUNC_CONF1_NUM_PIPES_MASK ((uint8_t)0xe0) /* Mask for number of enabled pipes */ +#define ANA_FUNC_CONF1_GMCONF_MASK ((uint8_t)0x1c) /* Mask of the GmConf field of + * ANA_FUNC_CONF1 register (R/W) */ +# define GM_13_2 ((uint8_t)0x00) /* Transconducatance Gm at start-up 13.2 mS */ +# define GM_18_2 ((uint8_t)0x04) /* Transconducatance Gm at start-up 18.2 mS */ +# define GM_21_5 ((uint8_t)0x08) /* Transconducatance Gm at start-up 21.5 mS */ +# define GM_25_6 ((uint8_t)0x0c) /* Transconducatance Gm at start-up 25.6 mS */ +# define GM_28_8 ((uint8_t)0x10) /* Transconducatance Gm at start-up 28.8 mS */ +# define GM_33_9 ((uint8_t)0x14) /* Transconducatance Gm at start-up 33.9 mS */ +# define GM_38_5 ((uint8_t)0x18) /* Transconducatance Gm at start-up 38.5 mS */ +# define GM_43_0 ((uint8_t)0x1c) /* Transconducatance Gm at start-up 43.0 mS */ +#define ANA_FUNC_CONF1_SET_BLD_LVL_MASK ((uint8_t)0x03) /* Mask of the SET_BLD_LV field of + * ANA_FUNC_CONF1 register (R/W) */ +#define BLD_LVL_2_7 ((uint8_t)0x00) /* Sets the Battery Level Detector threshold + * to + 2.7V */ +#define BLD_LVL_2_5 ((uint8_t)0x01) /* Sets the Battery Level Detector threshold + * to 2.5V */ +#define BLD_LVL_2_3 ((uint8_t)0x02) /* Sets the Battery Level Detector threshold + * to 2.3V */ +#define BLD_LVL_2_1 ((uint8_t)0x03) /* Sets the Battery Level Detector threshold + * to 2.1V */ + +/* ANA_FUNC_CONF register 0 + * + * Read Write + * Default value: 0xc0 + * 7 Reserved. + * 6 24_26_MHz_SELECT: 1 - 26 MHz configuration + * 0 - 24 MHz configuration + * 5 AES_ON: 1 - AES engine enabled + * 0 - AES engine disabled + * 4 EXT_REF: 1 - Reference signal from XIN pin + * 0 - Reference signal from XO circuit + * 3 HIGH_POWER_MODE: 1 - SET_SMPS_LEVEL word will be set to the value to + * PM_TEST register in RX state, while in TX state it + * will be fixed to 111 (which programs the SMPS output + * at max value 1.8V) + * 0 - SET_SMPS_LEVEL word will hold the value written in the + * PM_TEST register both in RX and TX state + * 2 BROWN_OUT: 1 - Brown_Out Detection enabled + * 0 - Brown_Out Detection disabled + * 1 BATTERY_LEVEL: 1 - Battery level detector enabled + * 0 - Battery level detector disabled + * 0 TS: 1 - Enable the "Temperature Sensor" function + * 0 - Disable the "Temperature Sensor" function + */ + +#define ANA_FUNC_CONF0_BASE ((uint8_t)0x01) /* ANA_FUNC_CONF0 Address (R/W) */ + +#define SELECT_24_26_MHZ_MASK ((uint8_t)0x40) /* Configure the RCO if using 26 MHz or + * 24 MHz master clock/reference signal */ +#define AES_MASK ((uint8_t)0x20) /* AES engine on/off */ +#define EXT_REF_MASK ((uint8_t)0x10) /* Reference signal from XIN pin + * (oscillator external) or from XO + * circuit (oscillator internal) */ +#define HIGH_POWER_MODE_MASK ((uint8_t)0x08) /* SET_SMPS_LEVEL word will be set to the + * value to PM_TEST register in RX state, + * while in TX state it will be fixed to + * 111 (which programs the SMPS output at + * max value, 1.8V) */ +#define BROWN_OUT_MASK ((uint8_t)0x04) /* Accurate Brown-Out detection on/off */ +#define BATTERY_LEVEL_MASK ((uint8_t)0x02) /* Battery level detector circuit on/off */ +#define TEMPERATURE_SENSOR_MASK ((uint8_t)0x01) /* The Temperature Sensor (available on + * GPIO0) on/off */ + +/* ANT_SELECT_CONF register + * + * Read Write + * Default value: 0x05 + * + * 7:5 Reserved. + * 4 CS_BLANKING: Blank received data if signal is below the CS threshold + * 3 AS_ENABLE: Enable antenna switching + * 1 - Enable + * 0 - Disable + * 2:0 AS_MEAS_TIME[2:0]: Measurement time according to the formula + * Tmeas = 24*2^(EchFlt)*2^AS_MEAS_TIME/fxo + */ + +#define ANT_SELECT_CONF_BASE ((uint8_t)0x27) /* Antenna diversity (works only in + * static carrier sense mode) */ + +#define ANT_SELECT_CS_BLANKING_MASK ((uint8_t)0x10) /* CS data blanking on/off */ +#define ANT_SELECT_CONF_AS_MASK ((uint8_t)0x08) /* Antenna diversity on/off */ + +/* DEVICE_INFO1[7:0] registers + * + * Default value: 0x01 + * Read + * + * 7:0 PARTNUM[7:0]: Device part number + */ + +#define DEVICE_INFO1_PARTNUM ((uint8_t)0xf0) /* Device part number [7:0] */ + +/* DEVICE_INFO0_Register */ + +/* DEVICE_INFO0[7:0] registers + * + * Read + * + * 7:0 VERSION[7:0]: Device version number + */ + +#define DEVICE_INFO0_VERSION ((uint8_t)0xf1) /* Device version [7:0]; (0x55 + * in CUT1.0) */ + +/* GPIO_Registers */ +/* GPIOx_CONF_Registers */ + +/* GPIOx registers + * + * Read Write + * Default value: 0x03 + * 7:3 GPIO_SELECT[4:0]: Specify the I/O signal. + * GPIO_SELECT[4:0] | I/O | Signal + * ------------------------------------------------ + * 0 | Output | nIRQ + * 0 | Input | TX command + * 1 | Output | POR inverted + * 1 | Input | RX command + * 2 | Output | Wake-Up timer expiration + * 2 | Input | TX data for direct modulation + * 3 | Output | Low Battery Detection + * 3 | Input | Wake-up from external input + * 4 | Output | TX clock output + * 5 | Output | TX state + * 6 | Output | TX FIFO Almost Empty Flag + * 7 | Output | TX FIFO ALmost Full Flag + * 8 | Output | RX data output + * 9 | Output | RX clock output + * 10 | Output | RX state + * 11 | Output | RX FIFO Almost Full Flag + * 12 | Output | RX FIFO Almost Empty Flag + * 13 | Output | Antenna switch + * 14 | Output | Valid preamble detected + * 15 | Output | Sync word detected + * 16 | Output | RSSI above threshold + * 17 | Output | MCU clock + * 18 | Output | TX or RX mode indicator + * 19 | Output | VDD + * 20 | Output | GND + * 21 | Output | External SMPS enable signal + * 22-31 | Not Used | Not Used + * 2 Reserved + * 1:0 GpioMode[1:0]: Specify the mode: + * GPIO_MODE1 | GPIO_MODE0 | MODE + * ------------------------------------------------------------ + * 0 | 0 | Analog (valid only for GPIO_0) + * 0 | 1 | Digital Input + * 1 | 0 | Digital Output Low Power + * 1 | 1 | Digital Output High Power + * + * Note: The Analog mode is used only for temperature sensor indication. This is available only + * on GPIO_0 by setting the TS bit in the ANA_FUNC_CONF_0_Register. + */ + +#define GPIO3_CONF_BASE ((uint8_t)0x02) /* GPIO_3 register address */ +#define GPIO2_CONF_BASE ((uint8_t)0x03) /* GPIO_2 register address */ +#define GPIO1_CONF_BASE ((uint8_t)0x04) /* GPIO_1 register address */ +#define GPIO0_CONF_BASE ((uint8_t)0x05) /* GPIO_0 register address */ + +#define CONF_GPIO_IN_TX_Command ((uint8_t)0x00) /* TX command direct from PIN (rising + * edge, width min=50ns) */ +#define CONF_GPIO_IN_RX_Command ((uint8_t)0x08) /* RX command direct from PIN (rising + * edge, width min=50ns) */ +#define CONF_GPIO_IN_TX_Data ((uint8_t)0x10) /* TX data input for direct modulation */ +#define CONF_GPIO_IN_WKUP_Ext ((uint8_t)0x18) /* Wake up from external input */ +#define CONF_GPIO_OUT_nIRQ ((uint8_t)0x00) /* nIRQ (Interrupt Request, active + * low), default configuration after POR */ +#define CONF_GPIO_OUT_POR_Inv ((uint8_t)0x08) /* POR inverted (active low) */ +#define CONF_GPIO_OUT_WUT_Exp ((uint8_t)0x10) /* Wake-Up Timer expiration: + * ‘1’ when WUT has expired */ +#define CONF_GPIO_OUT_LBD ((uint8_t)0x18) /* Low battery detection: ‘1’ when + * battery is below threshold setting */ +#define CONF_GPIO_OUT_TX_Data ((uint8_t)0x20) /* TX data internal clock output (TX + * data are sampled on the rising edge + * of it) */ +#define CONF_GPIO_OUT_TX_State ((uint8_t)0x28) /* TX state indication: ‘1’ when + * Spirit1 is transiting in the TX state */ +#define CONF_GPIO_OUT_TX_FIFO_ALMOST_EMPTY ((uint8_t)0x30) /* TX FIFO Almost Empty Flag */ +#define CONF_GPIO_OUT_TX_FIFO_AMOST_FULL ((uint8_t)0x38) /* TX FIFO Almost Full Flag */ +#define CONF_GPIO_OUT_RX_Data ((uint8_t)0x40) /* RX data output */ +#define CONF_GPIO_OUT_RX_Clock ((uint8_t)0x48) /* RX clock output (recovered from + * received data) */ +#define CONF_GPIO_OUT_RX_State ((uint8_t)0x50) /* RX state indication: ‘1’ when + * Spirit1 is transiting in the RX state */ +#define CONF_GPIO_OUT_RX_FIFO_ALMOST_FULL ((uint8_t)0x58) /* RX FIFO Almost Full Flag */ +#define CONF_GPIO_OUT_RX_FIFO_ALMOST_EMPTY ((uint8_t)0x60) /* RX FIFO Almost Empty Flag */ +#define CONF_GPIO_OUT_Antenna_Switch ((uint8_t)0x68) /* Antenna switch used for antenna + * diversity */ +#define CONF_GPIO_OUT_Valid_Preamble ((uint8_t)0x70) /* Valid Preamble Detected Flag */ +#define CONF_GPIO_OUT_Sync_Detected ((uint8_t)0x78) /* Sync WordSync Word Detected Flag */ +#define CONF_GPIO_OUT_RSSI_Threshold ((uint8_t)0x80) /* CCA Assessment Flag */ +#define CONF_GPIO_OUT_MCU_Clock ((uint8_t)0x88) /* MCU Clock */ +#define CONF_GPIO_OUT_TX_RX_Mode ((uint8_t)0x90) /* TX or RX mode indicator (to enable + * an external range extender) */ +#define CONF_GPIO_OUT_VDD ((uint8_t)0x98) /* VDD (to emulate an additional GPIO + * of the MCU, programmable by SPI) */ +#define CONF_GPIO_OUT_GND ((uint8_t)0xa0) /* GND (to emulate an additional GPIO + * of the MCU, programmable by SPI) */ +#define CONF_GPIO_OUT_SMPS_Ext ((uint8_t)0xa8) /* External SMPS enable signal (active + * high) */ +#define CONF_GPIO_MODE_ANALOG ((uint8_t)0x00) /* Analog test BUS on GPIO; used only + * in test mode (except for temperature + * sensor) */ +#define CONF_GPIO_MODE_DIG_IN ((uint8_t)0x01) /* Digital Input on GPIO */ +#define CONF_GPIO_MODE_DIG_OUTL ((uint8_t)0x02) /* Digital Output on GPIO (low current) */ +#define CONF_GPIO_MODE_DIG_OUTH ((uint8_t)0x03) /* Digital Output on GPIO (high current) */ + +/* MCU_CK_CONF register + * + * Read Write + * Default value: 0x00 + * 7 Reserved. + * 6:5 CLOCK_TAIL[1:0]: Specifies the number of extra cylces provided before entering in STANDBY state. + * CLOCK_TAIL1 | CLOCK_TAIL0 | Number of Extra Cycles + * ------------------------------------------------------------ + * 0 | 0 | 0 + * 0 | 1 | 64 + * 1 | 0 | 256 + * 1 | 1 | 512 + * 4:1 XO_RATIO[3:0]: Specifies the division ratio when XO oscillator is the clock source + * XO_RATIO[3:0] | Division Ratio + * ----------------------------------- + * 0 | 1 + * 1 | 2/3 + * 2 | 1/2 + * 3 | 1/3 + * 4 | 1/4 + * 5 | 1/6 + * 6 | 1/8 + * 7 | 1/12 + * 8 | 1/16 + * 9 | 1/24 + * 10 | 1/36 + * 11 | 1/48 + * 12 | 1/64 + * 13 | 1/96 + * 14 | 1/128 + * 15 | 1/256 + * 0 RCO_RATIO: Specifies the divsion ratio when RC oscillator is the clock source + * 0 - Division Ratio equal to 0 + * 1 - Division Ratio equal to 1/128 + */ + +#define MCU_CK_CONF_BASE ((uint8_t)0x06) /* MCU Clock Config register address */ + +#define MCU_CK_ENABLE ((uint8_t)0x80) /* MCU clock enable bit */ +#define MCU_CK_CONF_CLOCK_TAIL_0 ((uint8_t)0x00) /* 0 extra clock cycles provided to the + * MCU before switching to STANDBY state */ +#define MCU_CK_CONF_CLOCK_TAIL_64 ((uint8_t)0x20) /* 64 extra clock cycles provided to the + * MCU before switching to STANDBY state */ +#define MCU_CK_CONF_CLOCK_TAIL_256 ((uint8_t)0x40) /* 256 extra clock cycles provided to the + * MCU before switching to STANDBY state */ +#define MCU_CK_CONF_CLOCK_TAIL_512 ((uint8_t)0x60) /* 512 extra clock cycles provided to the + * MCU before switching to STANDBY state */ +#define MCU_CK_CONF_XO_RATIO_1 ((uint8_t)0x00) /* XO Clock signal available on the GPIO + * divided by 1 */ +#define MCU_CK_CONF_XO_RATIO_2_3 ((uint8_t)0x02) /* XO Clock signal available on the GPIO + * divided by 2/3 */ +#define MCU_CK_CONF_XO_RATIO_1_2 ((uint8_t)0x04) /* XO Clock signal available on the GPIO + * divided by 1/2 */ +#define MCU_CK_CONF_XO_RATIO_1_3 ((uint8_t)0x06) /* XO Clock signal available on the GPIO + * divided by 1/3 */ +#define MCU_CK_CONF_XO_RATIO_1_4 ((uint8_t)0x08) /* XO Clock signal available on the GPIO + * divided by 1/4 */ +#define MCU_CK_CONF_XO_RATIO_1_6 ((uint8_t)0x0a) /* XO Clock signal available on the GPIO + * divided by 1/6 */ +#define MCU_CK_CONF_XO_RATIO_1_8 ((uint8_t)0x0c) /* XO Clock signal available on the GPIO + * divided by 1/8 */ +#define MCU_CK_CONF_XO_RATIO_1_12 ((uint8_t)0x0e) /* XO Clock signal available on the GPIO + * divided by 1/12 */ +#define MCU_CK_CONF_XO_RATIO_1_16 ((uint8_t)0x10) /* XO Clock signal available on the GPIO + * divided by 1/16 */ +#define MCU_CK_CONF_XO_RATIO_1_24 ((uint8_t)0x12) /* XO Clock signal available on the GPIO + * divided by 1/24 */ +#define MCU_CK_CONF_XO_RATIO_1_36 ((uint8_t)0x14) /* XO Clock signal available on the GPIO + * divided by 1/36 */ +#define MCU_CK_CONF_XO_RATIO_1_48 ((uint8_t)0x16) /* XO Clock signal available on the GPIO + * divided by 1/48 */ +#define MCU_CK_CONF_XO_RATIO_1_64 ((uint8_t)0x18) /* XO Clock signal available on the GPIO + * divided by 1/64 */ +#define MCU_CK_CONF_XO_RATIO_1_96 ((uint8_t)0x1a) /* XO Clock signal available on the GPIO + * divided by 1/96 */ +#define MCU_CK_CONF_XO_RATIO_1_128 ((uint8_t)0x1c) /* XO Clock signal available on the GPIO + * divided by 1/128 */ +#define MCU_CK_CONF_XO_RATIO_1_192 ((uint8_t)0x1e) /* XO Clock signal available on the GPIO + * divided by 1/196 */ +#define MCU_CK_CONF_RCO_RATIO_1 ((uint8_t)0x00) /* RCO Clock signal available on the GPIO + * divided by 1 */ +#define MCU_CK_CONF_RCO_RATIO_1_128 ((uint8_t)0x01) /* RCO Clock signal available on the GPIO + * divided by 1/128 */ + +/* Radio_Configuration_Registers */ + +/* SYNT3 register + * + * Read Write + * Default value: 0x0c + * + * 7:5 WCP[2:0]: Set the charge pump current according to the VCO frequency in RX mode. + * + * VCO Frequency | WCP2 | WCP1 | WCP0 | Charge Pump Current (uA) + * ------------------------------------------------------------------------------------------------------------ + * 4644-4678 | 0 | 0 | 0 | 378.4 + * 4708-4772 | 0 | 0 | 1 | 368.9 + * 4772-4836 | 0 | 1 | 0 | 359.5 + * 4836-4902 | 0 | 1 | 1 | 350 + * 4902-4966 | 1 | 0 | 0 | 340.5 + * 4966-5030 | 1 | 0 | 1 | 331.1 + * 5030-5095 | 1 | 1 | 0 | 321.6 + * 5095-5161 | 1 | 1 | 1 | 312.2 + * 5161-5232 | 0 | 0 | 0 | 378.4 + * 5232-5303 | 0 | 0 | 1 | 368.9 + * 5303-5375 | 0 | 1 | 0 | 359.5 + * 5375-5448 | 0 | 1 | 1 | 350 + * 5448-5519 | 1 | 0 | 0 | 340.5 + * 5519-5592 | 1 | 0 | 1 | 331.1 + * 5592-5663 | 1 | 1 | 0 | 321.6 + * 5663-5736 | 1 | 1 | 1 | 312.2 + * + * + * 4:0 SYNT[25:21]: highest 5 bits of the PLL programmable divider + * The valid range depends on fXO and REFDIV settings; for + * fXO=26MHz + * REFDIV = 0 - SYNT[25:21] = 11...13 + * REFDIV = 1 - SYNT[25:21] = 22…27 + */ + +#define SYNT3_BASE ((uint8_t)0x08) /* [4:0] -> SYNT[25:21], highest 5 + * bits of the PLL programmable divider */ + +#define WCP_CONF_WCP_378UA ((uint8_t)0x00) /* Charge pump current nominal value = + * 378uA [VCO 4644-4708]&[VCO 5161-5232] */ +#define WCP_CONF_WCP_369UA ((uint8_t)0x01) /* Charge pump current nominal value = + * 369uA [VCO 4708-4772]&[VCO 5232-5303] */ +#define WCP_CONF_WCP_359UA ((uint8_t)0x02) /* Charge pump current nominal value = + * 359uA [VCO 4772-4836]&[VCO 5303-5375] */ +#define WCP_CONF_WCP_350UA ((uint8_t)0x03) /* Charge pump current nominal value = + * 350uA [VCO 4836-4902]&[VCO 5375-5448] */ +#define WCP_CONF_WCP_340UA ((uint8_t)0x04) /* Charge pump current nominal value = + * 340uA [VCO 4902-4966]&[VCO 5448-5519] */ +#define WCP_CONF_WCP_331UA ((uint8_t)0x05) /* Charge pump current nominal value = + * 331uA [VCO 4966-5030]&[VCO 5519-5592] */ +#define WCP_CONF_WCP_321UA ((uint8_t)0x06) /* Charge pump current nominal value = + * 321uA [VCO 5030-5095]&[VCO 5592-5563] */ +#define WCP_CONF_WCP_312UA ((uint8_t)0x07) /* Charge pump current nominal value = + * 312uA [VCO 5095-5160]&[VCO 5563-5736] */ + +/* SYNT2 register + * + * Read Write + * Default value: 0x84 + * 7:0 SYNT[20:13]: intermediate bits of the PLL programmable divider. + * + */ + +#define SYNT2_BASE ((uint8_t)0x09) /* SYNT[20:13], intermediate bits of + * the PLL programmable divider */ + +/* SYNT1 register + * + * Read Write + * Default value: 0xec + * 7:0 SYNT[12:5]: intermediate bits of the PLL programmable divider. + * + */ + +#define SYNT1_BASE ((uint8_t)0x0a) /* SYNT[12:5], intermediate bits of + * the PLL programmable divider */ + +/* SYNT0 register + * + * Read Write + * Default value: 0x51 + * 7:3 SYNT[4:0]: lowest bits of the PLL programmable divider. + * 2:0 BS[2:0]: Synthesizer band select. This parameter selects the out-of-loop divide + * factor of the synthesizer according to the formula fxo/(B/2)/D*SYNT/2^18 + * + * BS2 | BS1 | BS0 | value of B + * --------------------------------------------------------------------------- + * 0 | 0 | 1 | 6 + * 0 | 1 | 0 | 8 + * 0 | 1 | 1 | 12 + * 1 | 0 | 0 | 16 + * 1 | 0 | 1 | 32 + * + */ + +#define SYNT0_BASE ((uint8_t)0x0b) /* [7:3] -> SYNT[4:0], lowest bits of + * the PLL programmable divider */ + +#define SYNT0_BS_6 ((uint8_t)0x01) /* Synthesizer band select (out-of-loop + * divide factor of the synthesizer)=6 + * (779-956MHz) */ +#define SYNT0_BS_8 ((uint8_t)0x02) /* Synthesizer band select (out-of-loop + * divide factor of the synthesizer)=8 + * (387-470MHz) */ +#define SYNT0_BS_12 ((uint8_t)0x03) /* Synthesizer band select (out-of-loop + * divide factor of the synthesizer)=12 + * (387-470MHz) */ +#define SYNT0_BS_16 ((uint8_t)0x04) /* Synthesizer band select (out-of-loop + * divide factor of the synthesizer)=16 + * (300-348MHz) */ +#define SYNT0_BS_32 ((uint8_t)0x05) /* Synthesizer band select (out-of-loop + * divide factor of the synthesizer)=32 + * (150-174MHz) */ + +/* CHSPACE register + * + * Read Write + * Default value: 0xfc + * 7:0 CH_SPACING[7:0]: Channel spacing. From ~793Hz to ~200KHz in 793Hz steps + * (in general, frequency step is fXO/215=26MHz/215~793Hz). + */ + +#define CHSPACE_BASE ((uint8_t)0x0c) /* Channel spacing. From ~0.8KHz to + * ~200KHz in (fXO/2^15)Hz (793Hz for + * 26MHz XO) steps */ + +/* IF_OFFSET_DIG register + * + * Read Write + * Default value: 0xa3 + * + * 7:0 IF_OFFSET_DIG[7:0]: Intermediate frequency setting for the digital shift-to-baseband + * circuits. According to the formula: + * fIF = fXO*(IF_OFFSET_ANA+64)/(12*2^10) = fCLK*(IF_OFFSET_DIG+64)/(12*2^10) Hz. + */ + +#define IF_OFFSET_DIG_BASE ((uint8_t)0x0d) /* Intermediate frequency fIF= + * fXO*(IF_OFFSET_ANA+64)/(12*2^10)= + * fCLK*(IF_OFFSET_DIG+64)/(12*2^10) Hz */ + +/* IF_OFFSET_ANA register + * + * Read Write + * Default value: 0xa3 + * + * 7:0 IF_OFFSET_ANA[7:0]: Intermediate frequency setting for the digital shift-to-baseband + * circuits. According to the formula: + * fIF = fXO*(IF_OFFSET_ANA+64)/(12*2^10) = fCLK*(IF_OFFSET_DIG+64)/(12*2^10) Hz. + */ + +#define IF_OFFSET_ANA_BASE ((uint8_t)0x07) /* Intermediate frequency fIF= + * fXO*(IF_OFFSET_ANA+64)/(12*2^10)= + * fCLK*(IF_OFFSET_DIG+64)/(12*2^10) Hz */ + +/* FC_OFFSET1 registers + * + * Read Write + * Default value: 0xa3 + * + * 7:4 Reserved. + * 3:0 FC_OFFSET[11:8]: Carrier offset. This value is the higher part of a 12-bit 2’s complement integer + * representing an offset in 99Hz(2) units added/subtracted to the + * carrier frequency set by registers SYNT3…SYNT0. + * This register can be used to set a fixed correction value + * obtained e.g. from crystal measurements. + */ + +#define FC_OFFSET1_BASE ((uint8_t)0x0e) /* [3:0] -> [11:8] Carrier offset + * (upper part) */ + +/* FC_OFFSET0 registers + * + * Default value: 0x00 + * Read Write + * 7:0 FC_OFFSET[7:0]: Carrier offset. This value is the lower part of a 12-bit 2’s + * complement integer representing an offset in 99Hz(2) units + * added/subtracted to the carrier frequency set by registers + * SYNT3…SYNT0. This register can be used to set a fixed correction + * value obtained e.g. from crystal measurements. + */ + +#define FC_OFFSET0_BASE ((uint8_t)0x0f) /* [7:0] -> [7:0] Carrier offset + * (lower part). This value is a 12-bit + * 2’s complement integer representing + * an offset in fXO/2^18 (99Hz for 26 + * MHz XO) units added/subtracted to + * the carrier frequency set by registers + * SYNT3…SYNT0. Range is +/-200kHz with 26 + * MHz XO */ + +/* PA_LEVEL_x_Registers */ + +/* PA_POWER_x[8:1] registers + * + * Default values from 8 to 1: [0x03, 0x0e, 0x1a, 0x25, 0x35, 0x40, 0x4e, 0x00] + * Read Write + * + * 7 Reserved. + * 6:0 PA_LEVEL_(x-1)[6:0]: Output power level for x-th slot. + */ + +#define PA_POWER8_BASE ((uint8_t)0x10) /* PA Power level for 8th slot of PA + * ramping or ASK modulation */ +#define PA_POWER7_BASE ((uint8_t)0x11) /* PA Power level for 7th slot of PA + * ramping or ASK modulation */ +#define PA_POWER6_BASE ((uint8_t)0x12) /* PA Power level for 6th slot of PA + * ramping or ASK modulation */ +#define PA_POWER5_BASE ((uint8_t)0x13) /* PA Power level for 5th slot of PA + * ramping or ASK modulation */ +#define PA_POWER4_BASE ((uint8_t)0x14) /* PA Power level for 4th slot of PA + * ramping or ASK modulation */ +#define PA_POWER3_BASE ((uint8_t)0x15) /* PA Power level for 3rd slot of PA + * ramping or ASK modulation */ +#define PA_POWER2_BASE ((uint8_t)0x16) /* PA Power level for 2nd slot of PA + * ramping or ASK modulation */ +#define PA_POWER1_BASE ((uint8_t)0x17) /* PA Power level for 1st slot of PA + * ramping or ASK modulation */ + +/* PA_POWER_CONF_Registers + * + * Default value:0x07 + * Read Write + * + * 7:6 CWC[1:0]: Output stage additional load capacitors bank (to be used to + * optimize the PA for different sub-bands). + * + * CWC1 | CWC0 | Total capacity in pF + * --------------------------------------------------------- + * 0 | 0 | 0 + * 0 | 1 | 1.2 + * 1 | 0 | 2.4 + * 1 | 1 | 3.6 + * + * 5 PA_RAMP_ENABLE: + * 1 - Enable the power ramping + * 0 - Disable the power ramping + * 4:3 PA_RAMP_STEP_WIDTH[1:0]: Step width in bit period + * + * PA_RAMP_STEP_WIDTH1 | PA_RAMP_STEP_WIDTH0 | PA ramping time step + * ------------------------------------------------------------------------------------------- + * 0 | 0 | 1/8 Bit period + * 0 | 1 | 2/8 Bit period + * 1 | 0 | 3/8 Bit period + * 1 | 1 | 4/8 Bit period + * + * 2:0 PA_LEVEL_MAX_INDEX[2:0]: Fixes the MAX PA LEVEL in PA ramping or ASK modulation + */ + +#define PA_POWER0_BASE ((uint8_t)0x18) /* PA ramping settings and additional + * load capacitor banks used for PA + * optimization in different sub bands */ + +#define PA_POWER0_CWC_MASK ((uint8_t)0x20) /* Output stage additional load + * capacitors bank */ +#define PA_POWER0_CWC_0 ((uint8_t)0x00) /* No additional PA load capacitor */ +#define PA_POWER0_CWC_1_2P ((uint8_t)0x40) /* 1.2pF additional PA load capacitor */ +#define PA_POWER0_CWC_2_4P ((uint8_t)0x80) /* 2.4pF additional PA load capacitor */ +#define PA_POWER0_CWC_3_6P ((uint8_t)0xc0) /* 3.6pF additional PA load capacitor */ +#define PA_POWER0_PA_RAMP_MASK ((uint8_t)0x20) /* The PA power ramping */ +#define PA_POWER0_PA_RAMP_STEP_WIDTH_MASK ((uint8_t)0x20) /* The step width */ +#define PA_POWER0_PA_RAMP_STEP_WIDTH_TB_8 ((uint8_t)0x00) /* PA ramping time step = 1/8 Bit period */ +#define PA_POWER0_PA_RAMP_STEP_WIDTH_TB_4 ((uint8_t)0x08) /* PA ramping time step = 2/8 Bit period */ +#define PA_POWER0_PA_RAMP_STEP_WIDTH_3TB_8 ((uint8_t)0x10) /* PA ramping time step = 3/8 Bit period */ +#define PA_POWER0_PA_RAMP_STEP_WIDTH_TB_2 ((uint8_t)0x18) /* PA ramping time step = 4/8 Bit period */ +#define PA_POWER0_PA_LEVEL_MAX_INDEX ((uint8_t)0x20) /* Final level for power ramping */ +#define PA_POWER0_PA_LEVEL_MAX_INDEX_0 ((uint8_t)0x00) /* */ +#define PA_POWER0_PA_LEVEL_MAX_INDEX_1 ((uint8_t)0x01) /* Fixes the MAX PA LEVEL in PA ramping or + * ASK modulation */ +#define PA_POWER0_PA_LEVEL_MAX_INDEX_2 ((uint8_t)0x02) /* */ +#define PA_POWER0_PA_LEVEL_MAX_INDEX_3 ((uint8_t)0x03) /* _________ */ +#define PA_POWER0_PA_LEVEL_MAX_INDEX_4 ((uint8_t)0x04) /* PA_LVL2 _| <--| */ +#define PA_POWER0_PA_LEVEL_MAX_INDEX_5 ((uint8_t)0x05) /* _| | */ +#define PA_POWER0_PA_LEVEL_MAX_INDEX_6 ((uint8_t)0x06) /* PA_LVL1 _| | */ +#define PA_POWER0_PA_LEVEL_MAX_INDEX_7 ((uint8_t)0x07) /* PA_LVL0 _| MAX_INDEX- */ + +/* MOD1 register + * + * Read Write + * Default value: 0x83 + * 7:0 DATARATE_M[7:0]: The Mantissa of the specified data rate + */ + +#define MOD1_BASE ((uint8_t)0x1a) /* The Mantissa of the specified data rate */ + +/* MOD0 register + * + * Read Write + * Default value: 0x1a + * 7 CW: 1 - CW Mode enabled - enables the generation of a continous wave + * carrier without any modulation + * 0 - CW Mode disabled + * + * 6 BT_SEL: Select BT value for GFSK + * 1 - BT=0.5 + * 0 - BT=1 + * + * 5:4 MOD_TYPE[1:0]: Modulation type + * + * + * MOD_TYPE1 | MOD_TYPE0 | Modulation + * --------------------------------------------------------- + * 0 | 0 | 2-FSK,MSK + * 0 | 1 | GFSK,GMSK + * 1 | 0 | ASK/OOK + * + * 3:0 DATARATE_E[3:0]: The Exponent of the specified data rate + */ + +#define MOD0_BASE ((uint8_t)0x1b) /* Modulation Settings, Exponent of the + * specified data rate, CW mode */ + +#define MOD0_MOD_TYPE_2_FSK ((uint8_t)0x00) /* Modulation type 2-FSK (MSK if the + * frequency deviation is identical to a + * quarter of the data rate) */ +#define MOD0_MOD_TYPE_GFSK ((uint8_t)0x10) /* Modulation type GFSK (GMSK if the + * frequency deviation is identical to a + * quarter of the data rate) */ +#define MOD0_MOD_TYPE_ASK ((uint8_t)0x20) /* Modulation type ASK (OOK the PA is + * switched off for symbol "0") */ +#define MOD0_MOD_TYPE_MSK ((uint8_t)0x00) /* Modulation type MSK (the frequency + * deviation must be identical to a + * quarter of the data rate) */ +#define MOD0_MOD_TYPE_GMSK ((uint8_t)0x10) /* Modulation type GMSK (the frequency + * deviation must be identical to a + * quarter of the data rate) */ +#define MOD0_BT_SEL_BT_MASK ((uint8_t)0x00) /* Select the BT = 1 or BT = 0.5 + * valid only for GFSK or GMSK + * modulation */ +#define MOD0_CW ((uint8_t)0x80) /* Set the Continous Wave (no + * modulation) transmit mode */ + +/* FDEV0 register + * + * Read Write + * Default value: 0x45 + * 7:4 FDEV_E[3:0]: Exponent of the frequency deviation (allowed values from 0 to 9) + * + * 3 CLOCK_REC_ALGO_SEL: Select PLL or DLL mode for clock recovery + * 1 - DLL mode + * 0 - PLL mode + * + * 2:0 FDEV_M[1:0]: Mantissa of the frequency deviation (allowed values from 0 to 7) + */ + +#define FDEV0_BASE ((uint8_t)0x1c) /* Sets the Mantissa and exponent of + * frequency deviation (frequency + * separation/2) and PLL or DLL + * alogrithm from clock + * recovery in RX digital demod */ + +#define FDEV0_CLOCK_REG_ALGO_SEL_MASK ((uint8_t)0x08) /* Can be DLL or PLL algorithm for + * clock recovery in RX digital demod + * (see CLOCKREC reg) */ +#define FDEV0_CLOCK_REG_ALGO_SEL_PLL ((uint8_t)0x00) /* Sets PLL alogrithm for clock + * recovery in RX digital demod (see + * CLOCKREC reg) */ +#define FDEV0_CLOCK_REG_ALGO_SEL_DLL ((uint8_t)0x08) /* Sets DLL alogrithm for clock + * recovery in RX digital demod (see + * CLOCKREC reg) */ + +/* CHFLT register + * + * Read Write + * Default value: 0x23 + * 7:4 CHFLT_M[3:0]: Mantissa of the channel filter BW (allowed values from 0 to 8) + * + * 3:0 CHFLT_E[3:0]: Exponent of the channel filter BW (allowed values from 0 to 9) + * + * M\E | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | + * -----+-------+-------+-------+-------+------+------+------+-----+-----+-----+ + * 0 | 800.1 | 450.9 | 224.7 | 112.3 | 56.1 | 28.0 | 14.0 | 7.0 | 3.5 | 1.8 | + * 1 | 795.1 | 425.9 | 212.4 | 106.2 | 53.0 | 26.5 | 13.3 | 6.6 | 3.3 | 1.7 | + * 2 | 768.4 | 403.2 | 201.1 | 100.5 | 50.2 | 25.1 | 12.6 | 6.3 | 3.1 | 1.6 | + * 3 | 736.8 | 380.8 | 190.0 | 95.0 | 47.4 | 23.7 | 11.9 | 5.9 | 3.0 | 1.5 | + * 4 | 705.1 | 362.1 | 180.7 | 90.3 | 45.1 | 22.6 | 11.3 | 5.6 | 2.8 | 1.4 | + * 5 | 670.9 | 341.7 | 170.6 | 85.3 | 42.6 | 21.3 | 10.6 | 5.3 | 2.7 | 1.3 | + * 6 | 642.3 | 325.4 | 162.4 | 81.2 | 40.6 | 20.3 | 10.1 | 5.1 | 2.5 | 1.3 | + * 7 | 586.7 | 294.5 | 147.1 | 73.5 | 36.7 | 18.4 | 9.2 | 4.6 | 2.3 | 1.2 | + * 8 | 541.4 | 270.3 | 135.0 | 67.5 | 33.7 | 16.9 | 8.4 | 4.2 | 2.1 | 1.1 | + */ + +#define CHFLT_BASE ((uint8_t)0x1d) /* RX Channel Filter Bandwidth */ + +#define CHFLT_800_1 ((uint8_t)0x00) /* RX Channel Filter Bandwidth = 800.1 kHz */ +#define CHFLT_795_1 ((uint8_t)0x10) /* RX Channel Filter Bandwidth = 795.1 kHz */ +#define CHFLT_768_4 ((uint8_t)0x20) /* RX Channel Filter Bandwidth = 768.4 kHz */ +#define CHFLT_736_8 ((uint8_t)0x30) /* RX Channel Filter Bandwidth = 736.8 kHz */ +#define CHFLT_705_1 ((uint8_t)0x40) /* RX Channel Filter Bandwidth = 705.1 kHz */ +#define CHFLT_670_9 ((uint8_t)0x50) /* RX Channel Filter Bandwidth = 670.9 kHz */ +#define CHFLT_642_3 ((uint8_t)0x60) /* RX Channel Filter Bandwidth = 642.3 kHz */ +#define CHFLT_586_7 ((uint8_t)0x70) /* RX Channel Filter Bandwidth = 586.7 kHz */ +#define CHFLT_541_4 ((uint8_t)0x80) /* RX Channel Filter Bandwidth = 541.4 kHz */ +#define CHFLT_450_9 ((uint8_t)0x01) /* RX Channel Filter Bandwidth = 450.9 kHz */ +#define CHFLT_425_9 ((uint8_t)0x11) /* RX Channel Filter Bandwidth = 425.9 kHz */ +#define CHFLT_403_2 ((uint8_t)0x21) /* RX Channel Filter Bandwidth = 403.2 kHz */ +#define CHFLT_380_8 ((uint8_t)0x31) /* RX Channel Filter Bandwidth = 380.8 kHz */ +#define CHFLT_362_1 ((uint8_t)0x41) /* RX Channel Filter Bandwidth = 362.1 kHz */ +#define CHFLT_341_7 ((uint8_t)0x51) /* RX Channel Filter Bandwidth = 341.7 kHz */ +#define CHFLT_325_4 ((uint8_t)0x61) /* RX Channel Filter Bandwidth = 325.4 kHz */ +#define CHFLT_294_5 ((uint8_t)0x71) /* RX Channel Filter Bandwidth = 294.5 kHz */ +#define CHFLT_270_3 ((uint8_t)0x81) /* RX Channel Filter Bandwidth = 270.3 kHz */ +#define CHFLT_224_7 ((uint8_t)0x02) /* RX Channel Filter Bandwidth = 224.7 kHz */ +#define CHFLT_212_4 ((uint8_t)0x12) /* RX Channel Filter Bandwidth = 212.4 kHz */ +#define CHFLT_201_1 ((uint8_t)0x22) /* RX Channel Filter Bandwidth = 201.1 kHz */ +#define CHFLT_190 ((uint8_t)0x32) /* RX Channel Filter Bandwidth = 190.0 kHz */ +#define CHFLT_180_7 ((uint8_t)0x42) /* RX Channel Filter Bandwidth = 180.7 kHz */ +#define CHFLT_170_6 ((uint8_t)0x52) /* RX Channel Filter Bandwidth = 170.6 kHz */ +#define CHFLT_162_4 ((uint8_t)0x62) /* RX Channel Filter Bandwidth = 162.4 kHz */ +#define CHFLT_147_1 ((uint8_t)0x72) /* RX Channel Filter Bandwidth = 147.1 kHz */ +#define CHFLT_135 ((uint8_t)0x82) /* RX Channel Filter Bandwidth = 135.0 kHz */ +#define CHFLT_112_3 ((uint8_t)0x03) /* RX Channel Filter Bandwidth = 112.3 kHz */ +#define CHFLT_106_2 ((uint8_t)0x13) /* RX Channel Filter Bandwidth = 106.2 kHz */ +#define CHFLT_100_5 ((uint8_t)0x23) /* RX Channel Filter Bandwidth = 100.5 kHz */ +#define CHFLT_95 ((uint8_t)0x33) /* RX Channel Filter Bandwidth = 95.0 kHz */ +#define CHFLT_90_3 ((uint8_t)0x43) /* RX Channel Filter Bandwidth = 90.3 kHz */ +#define CHFLT_85_3 ((uint8_t)0x53) /* RX Channel Filter Bandwidth = 85.3 kHz */ +#define CHFLT_81_2 ((uint8_t)0x63) /* RX Channel Filter Bandwidth = 81.2 kHz */ +#define CHFLT_73_5 ((uint8_t)0x73) /* RX Channel Filter Bandwidth = 73.5 kHz */ +#define CHFLT_67_5 ((uint8_t)0x83) /* RX Channel Filter Bandwidth = 67.5 kHz */ +#define CHFLT_56_1 ((uint8_t)0x04) /* RX Channel Filter Bandwidth = 56.1 kHz */ +#define CHFLT_53 ((uint8_t)0x14) /* RX Channel Filter Bandwidth = 53.0 kHz */ +#define CHFLT_50_2 ((uint8_t)0x24) /* RX Channel Filter Bandwidth = 50.2 kHz */ +#define CHFLT_47_4 ((uint8_t)0x34) /* RX Channel Filter Bandwidth = 47.4 kHz */ +#define CHFLT_45_1 ((uint8_t)0x44) /* RX Channel Filter Bandwidth = 45.1 kHz */ +#define CHFLT_42_6 ((uint8_t)0x54) /* RX Channel Filter Bandwidth = 42.6 kHz */ +#define CHFLT_40_6 ((uint8_t)0x64) /* RX Channel Filter Bandwidth = 40.6 kHz */ +#define CHFLT_36_7 ((uint8_t)0x74) /* RX Channel Filter Bandwidth = 36.7 kHz */ +#define CHFLT_33_7 ((uint8_t)0x84) /* RX Channel Filter Bandwidth = 33.7 kHz */ +#define CHFLT_28 ((uint8_t)0x05) /* RX Channel Filter Bandwidth = 28.0 kHz */ +#define CHFLT_26_5 ((uint8_t)0x15) /* RX Channel Filter Bandwidth = 26.5 kHz */ +#define CHFLT_25_1 ((uint8_t)0x25) /* RX Channel Filter Bandwidth = 25.1 kHz */ +#define CHFLT_23_7 ((uint8_t)0x35) /* RX Channel Filter Bandwidth = 23.7 kHz */ +#define CHFLT_22_6 ((uint8_t)0x45) /* RX Channel Filter Bandwidth = 22.6 kHz */ +#define CHFLT_21_3 ((uint8_t)0x55) /* RX Channel Filter Bandwidth = 21.3 kHz */ +#define CHFLT_20_3 ((uint8_t)0x65) /* RX Channel Filter Bandwidth = 20.3 kHz */ +#define CHFLT_18_4 ((uint8_t)0x75) /* RX Channel Filter Bandwidth = 18.4 kHz */ +#define CHFLT_16_9 ((uint8_t)0x85) /* RX Channel Filter Bandwidth = 16.9 kHz */ +#define CHFLT_14 ((uint8_t)0x06) /* RX Channel Filter Bandwidth = 14.0 kHz */ +#define CHFLT_13_3 ((uint8_t)0x16) /* RX Channel Filter Bandwidth = 13.3 kHz */ +#define CHFLT_12_6 ((uint8_t)0x26) /* RX Channel Filter Bandwidth = 12.6 kHz */ +#define CHFLT_11_9 ((uint8_t)0x36) /* RX Channel Filter Bandwidth = 11.9 kHz */ +#define CHFLT_11_3 ((uint8_t)0x46) /* RX Channel Filter Bandwidth = 11.3 kHz */ +#define CHFLT_10_6 ((uint8_t)0x56) /* RX Channel Filter Bandwidth = 10.6 kHz */ +#define CHFLT_10_1 ((uint8_t)0x66) /* RX Channel Filter Bandwidth = 10.1 kHz */ +#define CHFLT_9_2 ((uint8_t)0x76) /* RX Channel Filter Bandwidth = 9.2 kHz */ +#define CHFLT_8_4 ((uint8_t)0x86) /* RX Channel Filter Bandwidth = 8.4 kHz */ +#define CHFLT_7 ((uint8_t)0x07) /* RX Channel Filter Bandwidth = 7.0 kHz */ +#define CHFLT_6_6 ((uint8_t)0x17) /* RX Channel Filter Bandwidth = 6.6 kHz */ +#define CHFLT_6_3 ((uint8_t)0x27) /* RX Channel Filter Bandwidth = 6.3 kHz */ +#define CHFLT_5_9 ((uint8_t)0x37) /* RX Channel Filter Bandwidth = 5.9 kHz */ +#define CHFLT_5_6 ((uint8_t)0x47) /* RX Channel Filter Bandwidth = 5.6 kHz */ +#define CHFLT_5_3 ((uint8_t)0x57) /* RX Channel Filter Bandwidth = 5.3 kHz */ +#define CHFLT_5_1 ((uint8_t)0x67) /* RX Channel Filter Bandwidth = 5.1 kHz */ +#define CHFLT_4_6 ((uint8_t)0x77) /* RX Channel Filter Bandwidth = 4.6 kHz */ +#define CHFLT_4_2 ((uint8_t)0x87) /* RX Channel Filter Bandwidth = 4.2 kHz */ +#define CHFLT_3_5 ((uint8_t)0x08) /* RX Channel Filter Bandwidth = 3.5 kHz */ +#define CHFLT_3_3 ((uint8_t)0x18) /* RX Channel Filter Bandwidth = 3.3 kHz */ +#define CHFLT_3_1 ((uint8_t)0x28) /* RX Channel Filter Bandwidth = 3.1 kHz */ +#define CHFLT_3 ((uint8_t)0x38) /* RX Channel Filter Bandwidth = 3.0 kHz */ +#define CHFLT_2_8 ((uint8_t)0x48) /* RX Channel Filter Bandwidth = 2.8 kHz */ +#define CHFLT_2_7 ((uint8_t)0x58) /* RX Channel Filter Bandwidth = 2.7 kHz */ +#define CHFLT_2_5 ((uint8_t)0x68) /* RX Channel Filter Bandwidth = 2.5 kHz */ +#define CHFLT_2_3 ((uint8_t)0x78) /* RX Channel Filter Bandwidth = 2.3 kHz */ +#define CHFLT_2_1 ((uint8_t)0x88) /* RX Channel Filter Bandwidth = 2.1 kHz */ +#define CHFLT_1_8 ((uint8_t)0x09) /* RX Channel Filter Bandwidth = 1.8 kHz */ +#define CHFLT_1_7 ((uint8_t)0x19) /* RX Channel Filter Bandwidth = 1.7 kHz */ +#define CHFLT_1_6 ((uint8_t)0x29) /* RX Channel Filter Bandwidth = 1.6 kHz */ +#define CHFLT_1_5 ((uint8_t)0x39) /* RX Channel Filter Bandwidth = 1.5 kHz */ +#define CHFLT_1_4 ((uint8_t)0x49) /* RX Channel Filter Bandwidth = 1.4 kHz */ +#define CHFLT_1_3a ((uint8_t)0x59) /* RX Channel Filter Bandwidth = 1.3 kHz */ +#define CHFLT_1_3 ((uint8_t)0x69) /* RX Channel Filter Bandwidth = 1.3 kHz */ +#define CHFLT_1_2 ((uint8_t)0x79) /* RX Channel Filter Bandwidth = 1.2 kHz */ +#define CHFLT_1_1 ((uint8_t)0x89) /* RX Channel Filter Bandwidth = 1.1 kHz */ + +/* AFC2 register + * + * Read Write + * Default value: 0x48 + * 7 AFC Freeze on Sync: Freeze AFC correction upon sync word detection. + * 1 - AFC Freeze enabled + * 0 - AFC Freeze disabled + * + * 6 AFC Enabled: Enable AFC + * 1 - AFC enabled + * 0 - AFC disabled + * + * 5 AFC Mode: Select AFC mode + * 1 - AFC Loop closed on 2nd conversion stage. + * 0 - AFC Loop closed on slicer + * + * 4:0 AFC PD leakage[4:0]: Peak detector leakage. This parameter sets the decay speed of + * the min/max frequency peak detector (AFC2 register), the range allowed is 0..31 (0 - + * no leakage, 31 - high leakage). The recommended value for this parameter is 4. + */ + +#define AFC2_BASE ((uint8_t)0x1e) /* Automatic frequency compensation + * algorithm parameters (FSK/GFSK/MSK) */ + +#define AFC2_AFC_FREEZE_ON_SYNC_MASK ((uint8_t)0x80) /* The frequency correction value is + * frozen when SYNC word is detected */ +#define AFC2_AFC_MASK ((uint8_t)0x40) /* Mask of Automatic Frequency Correction */ +#define AFC2_AFC_MODE_MASK ((uint8_t)0x20) /* Automatic Frequency Correction can + * be in Main MODE or Auxiliary MODE */ +#define AFC2_AFC_MODE_SLICER ((uint8_t)0x00) /* Automatic Frequency Correction Main + * MODE */ +#define AFC2_AFC_MODE_MIXER ((uint8_t)0x20) /* Automatic Frequency Correction + * Auxiliary MODE */ + +/* AFC1 register + * + * Read Write + * Default value: 0x18 + * + * 7:0 AFC_FAST_PERIOD: Length of the AFC fast period. this parameter sets the length of the + * fast period in number of samples (AFC1 register), the range allowed + * is 0..255. The recommended setting for this parameter is such that + * the fast period equals the preamble length. Since the algorithm + * operates typically on 2 samples per symbol, the programmed value + * should be twice the number of preamble symbols. + */ + +#define AFC1_BASE ((uint8_t)0x1f) /* Length of the AFC fast period */ + +/* AFC0 register + * + * Read Write + * Default value: 0x25 + * + * 7:4 AFC_FAST_GAIN_LOG2[3:0]: AFC loop gain in fast mode (2's log) + * 3:0 AFC_SLOW_GAIN_LOG2[3:0]: AFC loop gain in slow mode (2's log) + */ + +#define AFC0_BASE ((uint8_t)0x20) /* AFC loop gain in fast and slow modes + * (2's log) */ + +/* CLOCKREC register + * + * Read Write + * Default value: 0x58 + * + * 7:5 CLK_REC_P_GAIN [2:0]: Clock recovery loop gain (log2) + * 4 PSTFLT_LEN: Set Postfilter length + * 1 - 16 symbols + * 0 - 8 symbols + * 3:0 CLK_REC_I_GAIN[3:0]: Integral gain for the clock recovery loop + */ + +#define CLOCKREC_BASE ((uint8_t)0x23) /* Gain of clock recovery loop - + * Postfilter length 0-8 symbols, 1-16 + * symbols */ + +/* AGCCTRL2 register + * + * Read Write + * Default value: 0x22 + * + * 7 Reserved + * 6 FREEZE_ON_STEADY: Enable freezing on steady state + * 1 - Enable + * 0 - Disable + * 5 FREEZE_ON_SYNC: Enable freezing on sync detection + * 1 - Enable + * 0 - Disable + * 4 START_MAX_ATTENUATION: Start with max attenuation + * 1 - Enable + * 0 - Disable + * 3:0 MEAS_TIME[3:0]: Measure time during which the signal peak is detected (according to + * the formula 12/fxo*2^MEAS_TIME) + */ + +#define AGCCTRL2_BASE ((uint8_t)0x24) /* AGC freeze strategy, AGC attenuation + * strategy, AGC measure time */ + +#define AGCCTRL2_FREEZE_ON_STEADY_MASK ((uint8_t)0x40) /* The attenuation settings will be + * frozen as soon as signal level is + * betweeen min and max threshold (see + * AGCCTRL1) */ +#define AGCCTRL2_FREEZE_ON_SYNC_MASK ((uint8_t)0x20) /* The attenuation settings will be + * frozen as soon sync word is detected */ +#define AGCCTRL2_START_MAX_ATTENUATION_MASK ((uint8_t)0x10) + /* The AGC algorithm can start with MAX + * attenuation or MIN attenuation */ + +/* AGCCTRL1 register + * + * Read Write + * Default value: 0x65 + * + * 7:4 THRESHOLD_HIGH[3:0]: High threshold for the AGC + * 3:0 THRESHOLD_LOW[3:0]: Low threshold for the AGC + */ + +#define AGCCTRL1_BASE ((uint8_t)0x25) /* Sets low and high threshold for AGC */ + +/* AGCCTRL0 register + * + * Read Write + * Default value: 0x8a + * + * 7 AGC S_ENABLE: Enable AGC + * 1 - Enable + * 0 - Disable + * 6 AGC_MODE: Set linear-Binary AGC mode + * 1 - Enable + * 0 - Disable + * 5:0 HOLD_TIME[5:0]: Hold time after gain adjustment according to formula 12/fxo*HOLD_TIME + */ + +#define AGCCTRL0_BASE ((uint8_t)0x26) /* Enables AGC, set AGC algo between + * linear/binary mode, set hold time to + * account signal propagation through + * RX chain */ + +#define AGCCTRL0_AGC_MASK ((uint8_t)0x80) /* AGC on/off */ +#define AGCCTRL0_AGC_MODE_MASK ((uint8_t)0x40) /* AGC search correct attenuation in + * binary mode or sequential mode */ +#define AGCCTRL0_AGC_MODE_LINEAR ((uint8_t)0x00) /* AGC search correct attenuation in + * sequential mode (recommended) */ +#define AGCCTRL0_AGC_MODE_BINARY ((uint8_t)0x40) /* AGC search correct attenuation in + * binary mode */ + +/* CHNUM registers + * + * Default value: 0x00 + * Read Write + * 7:0 CH_NUM[7:0]: Channel number. This value is multiplied by the channel spacing and + * added to the synthesizer base frequency to generate the actual RF + * carrier frequency. + */ + +#define CHNUM_BASE ((uint8_t)0x6c) /* Channel number. This value is + * multiplied by the channel spacing + * and added to the synthesizer base + * frequency to generate the actual + * RF carrier frequency */ + +/* AFC_CORR registers + * + * Default value: 0x00 + * Read + * + * 7:0 AFC_CORR[7:0]: AFC word of the received packet + */ + +#define AFC_CORR_BASE ((uint8_t)0xc4) /* AFC word of the received packet */ + +/* Packet_Configuration_Registers */ + +/* PCKTCTRL4 register + * + * Read Write + * Default value: 0x00 + * + * 7:5 NOT_USED. + * 4:3 ADDRESS_LEN[1:0]: length of address field in bytes + * 2:0 control_len[2:0]: length of control field in bytes + */ + +#define PCKTCTRL4_BASE ((uint8_t)0x30) /* lenghts of address and control field */ + +#define PCKTCTRL4_ADDRESS_LEN_MASK ((uint8_t)0x18) +#define PCKTCTRL4_CONTROL_LEN_MASK ((uint8_t)0x07) + +/* PCKTCTRL3 register + * + * Read Write + * Default value: 0x07 + * + * 7:6 PCKT_FRMT[1:0]: format of packet + * + * PCKT_FRMT1 | PCKT_FRMT0 | Format + * ---------------------------------------------------------------------- + * 0 | 0 | BASIC + * 1 | 0 | MBUS + * 1 | 1 | STACK + * + * 5:4 RX_MODE[1:0]: length of address 0x30 field in bytes + * + * RX_MODE1 | RX_MODE0 | Rx Mode + * -------------------------------------------------------------------- + * 0 | 0 | normal + * 0 | 1 | direct through FIFO + * 1 | 0 | direct through GPIO + * + * 3:0 LEN_WID[3:0]: length of length field in bits + */ + +#define PCKTCTRL3_BASE ((uint8_t)0x31) /* Packet format, RX mode, length of + * length field */ + +#define PCKTCTRL3_PCKT_FRMT_BASIC ((uint8_t)0x00) /* Basic Packet Format */ +#define PCKTCTRL3_PCKT_FRMT_MBUS ((uint8_t)0x80) /* Wireless M-BUS Packet Format */ +#define PCKTCTRL3_PCKT_FRMT_STACK ((uint8_t)0xc0) /* STack Packet Format */ +#define PCKTCTRL3_RX_MODE_NORMAL ((uint8_t)0x00) /* Normal RX Mode */ +#define PCKTCTRL3_RX_MODE_DIRECT_FIFO ((uint8_t)0x10) /* RX Direct Mode; data available + * through FIFO */ +#define PCKTCTRL3_RX_MODE_DIRECT_GPIO ((uint8_t)0x20) /* RX Direct Mode; data available + * through selected GPIO */ +#define PCKTCTRL3_PKT_FRMT_MASK ((uint8_t)0xc0) +#define PCKTCTRL3_RX_MODE_MASK ((uint8_t)0x30) +#define PCKTCTRL3_LEN_WID_MASK ((uint8_t)0x0f) + +/* PCKTCTRL2 register + * + * Read Write + * Default value: 0x1e + * + * 7:3 PREAMBLE_LENGTH[4:0]: length of preamble field in bytes (0..31) + * 2:1 SYNC_LENGTH[1:0]: length of sync field in bytes + * 0 FIX_VAR_LEN: fixed/variable packet length + * 1 - Variable + * 0 - Fixed + */ + +#define PCKTCTRL2_BASE ((uint8_t)0x32) /* length of preamble and sync fields + * (in bytes), fix or variable packet + * length */ + +#define PCKTCTRL2_FIX_VAR_LEN_MASK ((uint8_t)0x01) /* Enable/disable the length mode */ +#define PCKTCTRL2_PREAMBLE_LENGTH_MASK ((uint8_t)0xf8) +#define PCKTCTRL2_SYNC_LENGTH_MASK ((uint8_t)0x06) + +/* PCKTCTRL1 register + * + * Read Write + * Default value: 0x20 + * + * 7:5 CRC_MODE[2:0]: CRC type (0, 8, 16, 24 bits) + * + * CRC_MODE2 | CRC_MODE1 | CRC_MODE0 | CRC Mode (n. bits - poly) + * ------------------------------------------------------------------------------------------------- + * 0 | 0 | 1 | 8 - 0x07 + * 0 | 1 | 0 | 16 - 0x8005 + * 0 | 1 | 1 | 16 - 0x1021 + * 1 | 0 | 0 | 24 - 0x864CBF + * + * 4 WHIT_EN[0]: Enable Whitening + * 1 - Enable + * 0 - Disable + * + * 3:2 TX_SOURCE[1:0]: length of sync field in bytes + * + * TX_SOURCE1 | TX_SOURCE0 | Tx Mode + * -------------------------------------------------------------------- + * 0 | 0 | normal + * 0 | 1 | direct through FIFO + * 1 | 0 | direct through GPIO + * 1 | 1 | pn9 + * + * 1 NOT_USED + * + * 0 FEC_EN: enable FEC + * 1 - FEC in TX , Viterbi decoding in RX + * 0 - Disabled + */ + +#define PCKTCTRL1_BASE ((uint8_t)0x33) /* CRC type, whitening enable, TX mode */ + +#define PCKTCTRL1_FEC_MASK ((uint8_t)0x01) /* Enable/disable the Forward Error Correction */ +#define PCKTCTRL1_TX_SOURCE_MASK ((uint8_t)0x0c) /* TX source mode */ +#define PCKTCTRL1_CRC_MODE_MASK ((uint8_t)0xe0) /* CRC type */ +#define PCKTCTRL1_WHIT_MASK ((uint8_t)0x10) /* Enable/disable the Whitening */ + +/* PCKTLEN1 register + * + * Read Write + * Default value: 0x00 + * + * 7:0 pktlen1[7:0]: length of packet in bytes (upper field) LENGHT/256 + */ + +#define PCKTLEN1_BASE ((uint8_t)0x34) /* length of packet in bytes (upper field) */ + +/* PCKTLEN0 register + * + * Read Write + * Default value: 0x14 + * + * 7:0 pktlen0[7:0]: length of packet in bytes (lower field) LENGHT%256 + */ + +#define PCKTLEN0_BASE ((uint8_t)0x35) /* length of packet in bytes (lower field) + * [PCKTLEN=PCKTLEN1x256+PCKTLEN0] */ + +/* SYNCx[4:1] Registers + * + * Read Write + * Default value: 0x88 + * + * 7:0 SYNCx[7:0]: xth sync word + */ + +#define SYNC4_BASE ((uint8_t)0x36) /* Sync word 4 */ +#define SYNC3_BASE ((uint8_t)0x37) /* Sync word 3 */ +#define SYNC2_BASE ((uint8_t)0x38) /* Sync word 2 */ +#define SYNC1_BASE ((uint8_t)0x39) /* Sync word 1 */ + +/* MBUS_PRMBL register + * + * Read Write + * Default value: 0x20 + * + * 7:0 MBUS_PRMBL[7:0]: MBUS preamble control + */ + +#define MBUS_PRMBL_BASE ((uint8_t)0x3b) /* MBUS preamble length (in 01 bit pairs) */ + +/* MBUS_PSTMBL register + * + * Read Write + * Default value: 0x20 + * + * 7:0 MBUS_PSTMBL[7:0]: MBUS postamble control + */ + +#define MBUS_PSTMBL_BASE ((uint8_t)0x3c) /* MBUS postamble length (in 01 bit pairs) */ + +/* MBUS_CTRL register + * + * Read Write + * Default value: 0x00 + * + * 7:4 NOT_USED + * 3:1 MBUS_SUBMODE[2:0]: MBUS submode (allowed values are 0,1,3,5) + * 0 NOT_USED + */ + +#define MBUS_CTRL_BASE ((uint8_t)0x3d) /* MBUS sub-modes (S1, S2 short/long + * header, T1, T2, R2) */ + +#define MBUS_CTRL_MBUS_SUBMODE_S1_S2L ((uint8_t)0x00) /* MBUS sub-modes S1 & S2L, header + * length min 279, sync 0x7696, + * Manchester */ +#define MBUS_CTRL_MBUS_SUBMODE_S2_S1M_T2_OTHER ((uint8_t)0x02) + /* MBUS sub-modes S2, S1-m, T2 (only + * other to meter) short header, header + * length min 15, sync 0x7696, Manchester */ +#define MBUS_CTRL_MBUS_SUBMODE_T1_T2_METER ((uint8_t)0x06) + /* MBUS sub-modes T1, T2 (only meter + * to other), header length min 19, sync + * 0x3d, 3 out of 6 */ +#define MBUS_CTRL_MBUS_SUBMODE_R2 ((uint8_t)0x0a) /* MBUS sub-mode R2, header length min + * 39, sync 0x7696, Manchester */ + +/* PCKT_FLT_GOALS_CONTROLx_MASK registers + * + * Default value: 0x00 + * Read Write + * 7:0 CONTROLx_MASK[7:0]: All 0s - no filtering + */ + +#define PCKT_FLT_GOALS_CONTROL0_MASK_BASE ((uint8_t)0x42) + /* Packet control field #3 mask, all 0s + * -> no filtering */ +#define PCKT_FLT_GOALS_CONTROL1_MASK_BASE ((uint8_t)0x43) + /* Packet control field #2 mask, all 0s + * -> no filtering */ +#define PCKT_FLT_GOALS_CONTROL2_MASK_BASE ((uint8_t)0x44) + /* Packet control field #1 mask, all 0s + * -> no filtering */ +#define PCKT_FLT_GOALS_CONTROL3_MASK_BASE ((uint8_t)0x45) + /* Packet control field #0 mask, all 0s + * -> no filtering */ + +/* PCKT_FLT_GOALS_CONTROLx_FIELD registers + * + * Default value: 0x00 + * Read Write + * 7:0 CONTROLx_FIELD[7:0]: Control field (byte x) to be used as reference + */ + +#define PCKT_FLT_GOALS_CONTROL0_FIELD_BASE ((uint8_t)0x46) /* Control field (byte #3) */ +#define PCKT_FLT_GOALS_CONTROL1_FIELD_BASE ((uint8_t)0x47) /* Control field (byte #2) */ +#define PCKT_FLT_GOALS_CONTROL2_FIELD_BASE ((uint8_t)0x48) /* Control field (byte #1) */ +#define PCKT_FLT_GOALS_CONTROL3_FIELD_BASE ((uint8_t)0x49) /* Control field (byte #0) */ + +/* PCKT_FLT_GOALS_SOURCE_MASK register + * + * Default value: 0x00 + * Read Write + * 7:0 RX_SOURCE_MASK[7:0]: For received packet only: all 0s - no filtering + */ + +#define PCKT_FLT_GOALS_SOURCE_MASK_BASE ((uint8_t)0x4a) /* Source address mask, valid + * in RX mode */ + +/* PCKT_FLT_GOALS_SOURCE_ADDR register + * + * Default value: 0x00 + * Read Write + * 7:0 RX_SOURCE_ADDR[7:0]: RX packet source / TX packet destination fields + */ + +#define PCKT_FLT_GOALS_SOURCE_ADDR_BASE ((uint8_t)0x4b) /* Source address */ + +/* PCKT_FLT_GOALS_BROADCAST register + * + * Default value: 0x00 + * Read Write + * 7:0 BROADCAST[7:0]: Address shared for broadcast communication link + */ + +#define PCKT_FLT_GOALS_BROADCAST_BASE ((uint8_t)0x4c) /* Address shared for broadcast + * communication links */ + +/* PCKT_FLT_GOALS_MULTICAST register + * + * Default value: 0x00 + * Read Write + * 7:0 MULTICAST[7:0]: Address shared for multicast communication links + */ + +#define PCKT_FLT_GOALS_MULTICAST_BASE ((uint8_t)0x4d) /* Address shared for multicast + * communication links */ + +/* PCKT_FLT_GOALS_TX_SOURCE_ADDR register + * + * Default value: 0x00 + * Read Write + * 7:0 TX_SOURCE_ADDR[7:0]: TX packet source / RX packet destination fields + */ + +#define PCKT_FLT_GOALS_TX_ADDR_BASE ((uint8_t)0x4e) /* Address of the destination (also + * device own address) +*/ + +/* PCKT_FLT_OPTIONS register + * + * Default value: 0x70 + * Read Write + * 7 Reserved. + * + * 6 RX_TIMEOUT_AND_OR_SELECT[0]: 1 - ‘OR’ logical function applied to CS/SQI/PQI + * values (masked by 7:5 bits in PROTOCOL register) + * 5 CONTROL_FILTERING[0]: 1 - RX packet accepted if its control fields matches + * with masked CONTROLx_FIELD registers. + * 4 SOURCE_FILTERING[0]: 1 - RX packet accepted if its source field + * matches w/ masked RX_SOURCE_ADDR register. + * 3 DEST_VS_ SOURCE _ADDR[0]: 1 - RX packet accepted if its destination + * address matches with TX_SOURCE_ADDR reg. + * 2 DEST_VS_MULTICAST_ADDR[0]: 1 - RX packet accepted if its destination + * address matches with MULTICAST register + * 1 DEST_VS_BROADCAST_ADDR[0]: 1 - RX packet accepted if its destination + * address matches with BROADCAST register. + * 0 CRC_CHECK[0]: 1 - packet discarded if CRC not valid. + */ + +#define PCKT_FLT_OPTIONS_BASE ((uint8_t)0x4f) /* Options relative to packet filtering */ + +#define PCKT_FLT_OPTIONS_CRC_CHECK_MASK ((uint8_t)0x01) /* Enable/disable of CRC check: packet + * is discarded if CRC is not valid [RX] */ +#define PCKT_FLT_OPTIONS_DEST_VS_BROADCAST_ADDR_MASK ((uint8_t)0x02) + /* Packet discarded if destination address + * differs from BROADCAST register [RX] */ +#define PCKT_FLT_OPTIONS_DEST_VS_MULTICAST_ADDR_MASK ((uint8_t)0x04) + /* Packet discarded if destination address + * differs from MULTICAST register [RX] */ +#define PCKT_FLT_OPTIONS_DEST_VS_TX_ADDR_MASK ((uint8_t)0x08) + /* Packet discarded if destination address + * differs from TX_ADDR register [RX] */ +#define PCKT_FLT_OPTIONS_SOURCE_FILTERING_MASK ((uint8_t)0x10) + /* Packet discarded if source address + * (masked by the SOURCE_MASK register) + * differs from SOURCE_ADDR register + * [RX] */ +#define PCKT_FLT_OPTIONS_CONTROL_FILTERING_MASK ((uint8_t)0x20) + /* Packet discarded if the x-byte + * (x=1¸4) control field (masked by + * the CONTROLx_MASK register) differs + * from CONTROLx_FIELD register [RX] */ +#define PCKT_FLT_OPTIONS_RX_TIMEOUT_AND_OR_SELECT ((uint8_t)0x40) + /* Logical function applied to CS/SQI/PQI + * values (masked by [7:5] bits i + * PROTOCOL[2] register) */ + +/* TX_CTRL_FIELDx registers + * + * Default value: 0x00 + * Read Write + * 7:0 TX_CTRLx[7:0]: Control field value to be used in TX packet as byte n.x + */ + +#define TX_CTRL_FIELD3_BASE ((uint8_t)0x68) /* Control field value to be used in + * TX packet as byte n.3 */ +#define TX_CTRL_FIELD2_BASE ((uint8_t)0x69) /* Control field value to be used in + * TX packet as byte n.2 */ +#define TX_CTRL_FIELD1_BASE ((uint8_t)0x6a) /* Control field value to be used in + * TX packet as byte n.1 */ +#define TX_CTRL_FIELD0_BASE ((uint8_t)0x6b) /* Control field value to be used in + * TX packet as byte n.0 */ + +/* TX_PCKT_INFO registers + * + * Default value: 0x00 + * Read + * + * 7:6 Not used. + * + * 5:4 TX_SEQ_NUM: Current TX packet sequence number + * + * 0 N_RETX[3:0]: Number of retransmissions done on the + * last TX packet + */ + +#define TX_PCKT_INFO_BASE ((uint8_t)0xc2) /* Current TX packet sequence number + * [5:4]; Number of retransmissions done + * on the last TX packet [3:0] */ + +/* RX_PCKT_INFO registers + * + * Default value: 0x00 + * Read + * + * 7:3 Not used. + * + * 2 NACK_RX: NACK field of the received packet + * + * 1:0 RX_SEQ_NUM[1:0]: Sequence number of the received packet + */ + +#define RX_PCKT_INFO_BASE ((uint8_t)0xc3) /* NO_ACK field of the received packet + * [2]; sequence number of the received + * packet [1:0] */ + +#define TX_PCKT_INFO_NACK_RX ((uint8_t)0x04) /* NACK field of the received packet */ + +/* RX_PCKT_LEN1 registers + * + * Default value: 0x00 + * Read + * + * 7:0 RX_PCKT_LEN1[7:0]: Length (number of bytes) of the received packet: + * RX_PCKT_LEN=RX_PCKT_LEN1 × 256 + RX_PCKT_LEN0 + * This value is packet_length/256 + */ + +#define RX_PCKT_LEN1_BASE ((uint8_t)0xc9) /* Length (number of bytes) of the + * received packet */ + +/* RX_PCKT_LEN0 registers + * + * Default value: 0x00 + * Read + * + * 7:0 RX_PCKT_LEN0[7:0]: Length (number of bytes) of the received packet: + * RX_PCKT_LEN=RX_PCKT_LEN1 × 256 + RX_PCKT_LEN0 + * This value is packet_length%256 + */ +#define RX_PCKT_LEN0_BASE ((uint8_t)0xca) /* RX_PCKT_LEN=RX_PCKT_LEN1 + * × 256 + RX_PCKT_LEN0 */ + +/* CRC_FIELD[2:0] registers + * + * Default value: 0x00 + * Read + * + * 7:0 CRC_FIELDx[7:0]: upper(x=2), middle(x=1) and lower(x=0) part of the crc field of + * the received packet + */ + +#define CRC_FIELD2_BASE ((uint8_t)0xcb) /* CRC2 field of the received packet */ +#define CRC_FIELD1_BASE ((uint8_t)0xcc) /* CRC1 field of the received packet */ +#define CRC_FIELD0_BASE ((uint8_t)0xcd) /* CRC0 field of the received packet */ + +/* RX_CTRL_FIELD[3:0] registers + * + * Default value: 0x00 + * Read + * + * 7:0 RX_CTRL_FIELDx[7:0]: upper(x=3), middle(x=2), middle(x=1) and lower(x=0) part of the control field of the received packet + */ + +#define RX_CTRL_FIELD0_BASE ((uint8_t)0xce) /* CRTL3 Control field of the received packet */ +#define RX_CTRL_FIELD1_BASE ((uint8_t)0xcf) /* CRTL2 Control field of the received packet */ +#define RX_CTRL_FIELD2_BASE ((uint8_t)0xd0) /* CRTL1 Control field of the received packet */ +#define RX_CTRL_FIELD3_BASE ((uint8_t)0xd1) /* CRTL0 Control field of the received packet */ + +/* RX_ADDR_FIELD[1:0] registers + * + * Default value: 0x00 + * Read + * + * 7:0 RX_ADDR_FIELDx[7:0]: source(x=1) and destination(x=0) address field of the received packet + */ + +#define RX_ADDR_FIELD1_BASE ((uint8_t)0xd2) /* ADDR1 Address field of the received packet */ +#define RX_ADDR_FIELD0_BASE ((uint8_t)0xd3) /* ADDR0 Address field of the received packet */ + +/* Protocol_Registers */ + +/* PROTOCOL2 register + * + * Default value: 0x06 + * Read Write + * 7 CS_TIMEOUT_MASK: 1 - CS value contributes to timeout disabling + * 6 SQI_TIMEOUT_MASK: 1 - SQI value contributes to timeout disabling + * 5 PQI_TIMEOUT_MASK: 1 - PQI value contributes to timeout disabling + * 4:3 TX_SEQ_NUM_RELOAD[1:0]: TX sequence number to be used when counting reset is + * required using the related command. + * 2 RCO_CALIBRATION[0]: 1 - Enables the automatic RCO calibration + * 1 VCO_CALIBRATION[0]: 1 - Enables the automatic VCO calibration + * 0 LDCR_MODE[0]: 1 - LDCR mode enabled + */ + +#define PROTOCOL2_BASE ((uint8_t)0x50) /* Protocol2 regisetr address */ + +#define PROTOCOL2_LDC_MODE_MASK ((uint8_t)0x01) /* Enable/disable Low duty Cycle mode */ +#define PROTOCOL2_VCO_CALIBRATION_MASK ((uint8_t)0x02) /* Enable/disable VCO automatic + * calibration */ +#define PROTOCOL2_RCO_CALIBRATION_MASK ((uint8_t)0x04) /* Enable/disable RCO automatic + * calibration */ +#define PROTOCOL2_PQI_TIMEOUT_MASK ((uint8_t)0x20) /* PQI value contributes to timeout + * disabling */ +#define PROTOCOL2_SQI_TIMEOUT_MASK ((uint8_t)0x40) /* SQI value contributes to timeout + * disabling */ +#define PROTOCOL2_CS_TIMEOUT_MASK ((uint8_t)0x80) /* CS value contributes to timeout + * disabling */ + +/* PROTOCOL1 register + * + * Default value: 0x00 + * Read Write + * 7 LDCR_RELOAD_ON_SYNC: 1 - LDCR timer will be reloaded with the value stored in + * the LDCR_RELOAD registers + * 6 PIGGYBACKING: 1 - PIGGYBACKING enabled + * 5:4 Reserved. + * 3 SEED_RELOAD[0]: 1 - Reload the back-off random generator + * seed using the value written in the + * BU_COUNTER_SEED_MSByte / LSByte registers + * 2 CSMA_ON [0]: 1 - CSMA channel access mode enabled + * 1 CSMA_PERS_ON[0]: 1 - CSMA persistent (no back-off) enabled + * 0 AUTO_PCKT_FLT[0]: 1 - automatic packet filtering mode enabled + */ + +#define PROTOCOL1_BASE ((uint8_t)0x51) /* Protocol1 register address */ + +#define PROTOCOL1_AUTO_PCKT_FLT_MASK ((uint8_t)0x01) /* Enable/disable automatic packet + * filtering mode */ +#define PROTOCOL1_CSMA_PERS_ON_MASK ((uint8_t)0x02) /* Enable/disable CSMA persistent + * (no back-off) */ +#define PROTOCOL1_CSMA_ON_MASK ((uint8_t)0x04) /* Enable/disable CSMA channel + * access mode */ +#define PROTOCOL1_SEED_RELOAD_MASK ((uint8_t)0x08) /* Reloads the seed of the PN generator + * for CSMA procedure */ +#define PROTOCOL1_PIGGYBACKING_MASK ((uint8_t)0x40) /* Enable/disable Piggybacking */ +#define PROTOCOL1_LDC_RELOAD_ON_SYNC_MASK ((uint8_t)0x80) + /* LDC timer will be reloaded with the + * value stored in the LDC_RELOAD + * registers */ + +/* PROTOCOL0 register + * + * Default value: 0x08 + * Read Write + * 7:4 NMAX_RETX[3:0]: Max number of re-TX. 0 - re-transmission is not performed + * 3 NACK_TX[0]: 1 - field NO_ACK=1 on transmitted packet + * 2 AUTO_ACK[0]: 1 - automatic ack after RX + * 1 PERS_RX[0]: 1 - persistent reception enabled + * 0 PERS_TX[0]: 1 - persistent transmission enabled + */ + +#define PROTOCOL0_BASE ((uint8_t)0x52) /* Persistent RX/TX, autoack, Max + * number of retransmissions */ + +#define PROTOCOL0_PERS_TX_MASK ((uint8_t)0x01) /* Enables persistent transmission */ +#define PROTOCOL0_PERS_RX_MASK ((uint8_t)0x02) /* Enables persistent reception */ +#define PROTOCOL0_AUTO_ACK_MASK ((uint8_t)0x04) /* Enables auto acknowlegment */ +#define PROTOCOL0_NACK_TX_MASK ((uint8_t)0x08) /* Writes field NO_ACK=1 on + * transmitted packet */ +#define PROTOCOL0_NMAX_RETX_MASK ((uint8_t)0xf0) /* Retransmission mask */ + +/* TIMERS5 register + * + * Default value: 0x00 + * Read Write + * 7:0 RX_TIMEOUT_PRESCALER[7:0] : RX operation timeout: prescaler value + */ + +#define TIMERS5_RX_TIMEOUT_PRESCALER_BASE ((uint8_t)0x53) + /* RX operation timeout: prescaler + * value */ + +/* TIMERS4 register + * + * Default value: 0x00 + * Read Write + * 7:0 RX_TIMEOUT_COUNTER[7:0] : RX operation timeout: counter value + */ + +#define TIMERS4_RX_TIMEOUT_COUNTER_BASE ((uint8_t)0x54) /* RX operation timeout: counter value */ + +/* TIMERS3 register + * + * Default value: 0x00 + * Read Write + * 7:0 LDCR_PRESCALER[7:0] : LDC Mode: Prescaler part of the wake-up value + */ + +#define TIMERS3_LDC_PRESCALER_BASE ((uint8_t)0x55) /* LDC Mode: Prescaler of the wake-up + * timer */ + +/* TIMERS2 register + * + * Default value: 0x00 + * Read Write + * 7:0 LDCR_COUNTER[7:0] : LDC Mode: counter part of the wake-up value + */ + +#define TIMERS2_LDC_COUNTER_BASE ((uint8_t)0x56) /* LDC Mode: counter of the wake-up timer */ + +/* TIMERS1 register + * + * Default value: 0x00 + * Read Write + * 7:0 LDCR_RELOAD_PRESCALER[7:0] : LDC Mode: Prescaler part of the reload value + */ + +#define TIMERS1_LDC_RELOAD_PRESCALER_BASE ((uint8_t)0x57) + /* LDC Mode: Prescaler part of the + * reload value */ + +/* TIMERS0 register + * + * Default value: 0x00 + * Read Write + * 7:0 LDCR_RELOAD_COUNTER[7:0] : LDC Mode: Counter part of the reload value + */ + +#define TIMERS0_LDC_RELOAD_COUNTER_BASE ((uint8_t)0x58) /* LDC Mode: Counter part of the + * reload value */ + +/* CSMA_CONFIG3 registers + * + * Default value: 0xff + * Read Write + * 7:0 BU_COUNTER_SEED_MSByte: Seed of the random number generator used to apply the BEB + & (Binary Exponential Backoff) algorithm (MSB) + */ + +#define CSMA_CONFIG3_BASE ((uint8_t)0x64) /* CSMA/CA: Seed of the random number + * generator used to apply the BEB + * (Binary Exponential Backoff) + * algorithm (MSB) */ + +/* CSMA_CONFIG2 registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 BU_COUNTER_SEED_LSByte: Seed of the random number generator used to apply + * the BEB (Binary Exponential Backoff) algorithm (LSB) + */ + +#define CSMA_CONFIG2_BASE ((uint8_t)0x65) /* CSMA/CA: Seed of the random + * number generator used to apply + * the BEB (Binary Exponential + * Backoff) algorithm (LSB)*/ + +/* CSMA_CONFIG1 registers + * + * Default value: 0x04 + * Read Write + * 7:2 BU_PRESCALER[5:0]: Used to program the back-off unit BU + * 1:0 CCA_PERIOD[1:0]: Used to program the Tcca time (64 / 128 /256 / 512 × Tbit. + */ + +#define CSMA_CONFIG1_BASE ((uint8_t)0x66) /* CSMA/CA: Prescaler of the back-off + * time unit (BU); CCA period */ + +#define CSMA_CCA_PERIOD_64TBIT ((uint8_t)0x00) /* CSMA/CA: Sets CCA period to 64*TBIT */ +#define CSMA_CCA_PERIOD_128TBIT ((uint8_t)0x01) /* CSMA/CA: Sets CCA period to 128*TBIT */ +#define CSMA_CCA_PERIOD_256TBIT ((uint8_t)0x02) /* CSMA/CA: Sets CCA period to 256*TBIT */ +#define CSMA_CCA_PERIOD_512TBIT ((uint8_t)0x03) /* CSMA/CA: Sets CCA period to 512*TBIT */ + +/* CSMA_CONFIG0 registers + * + * Default value: 0x00 + * Read Write + * 7:4 CCA_LENGTH[3:0]: Used to program the Tlisten time + * 3 Reserved. + * 2:0 NBACKOFF_MAX[2:0]: Max number of back-off cycles. + */ + +#define CSMA_CONFIG0_BASE ((uint8_t)0x67) /* CSMA/CA: CCA length; Max number + * of backoff cycles */ + +/* Link_Quality_Registers */ + +/* QI register + * + * Read Write + * Default value: 0x02 + * + * 7:6 SQI_TH[1:0]: SQI threshold according to the formula: 8*SYNC_LEN - 2*SQI_TH + * 5:2 PQI_TH[3:0]: PQI threshold according to the formula: 4*PQI_THR + * 1 SQI_EN[0]: SQI enable + * 1 - Enable + * 0 - Disable + * 0 PQI_EN[0]: PQI enable + * 1 - Enable + * 0 - Disable + */ + +#define QI_BASE ((uint8_t)0x3a) /* QI register */ + +#define QI_PQI_MASK ((uint8_t)0x01) /* PQI enable/disable */ +#define QI_SQI_MASK ((uint8_t)0x02) /* SQI enable/disable */ + +/* LINK_QUALIF2 registers + * + * Default value: 0x00 + * Read + * + * 7:0 PQI[7:0]: PQI value of the received packet + */ + +#define LINK_QUALIF2_BASE ((uint8_t)0xc5) /* PQI value of the received packet */ + +/* LINK_QUALIF1 registers + * + * Default value: 0x00 + * Read + * + * 7 CS: Carrier Sense indication + * 6:0 SQI[6:0]: SQI value of the received packet + */ + +#define LINK_QUALIF1_BASE ((uint8_t)0xc6) /* Carrier sense indication [7]; SQI + * value of the received packet */ + +#define LINK_QUALIF1_CS ((uint8_t)0x80) /* Carrier sense indication [7] */ + +/* LINK_QUALIF0 registers + * + * Default value: 0x00 + * Read + * + * 7:4 LQI [3:0]: LQI value of the received packet + * 3:0 AGC_WORD[3:0]: AGC word of the received packet + */ + +#define LINK_QUALIF0_BASE ((uint8_t)0xc7) /* LQI value of the received packet + * [7:4]; AGC word of the received + * packet [3:0] */ + +/* RSSI_LEVEL registers + * + * Default value: 0x00 + * Read + * + * 7:0 RSSI_LEVEL[7:0]: RSSI level of the received packet + */ + +#define RSSI_LEVEL_BASE ((uint8_t)0xc8) /* RSSI level of the received packet */ + +/* RSSI_FLT register + * + * Read Write + * Default value: 0xf3 + * 7:4 RSSI_FLT[3:0]: Gain of the RSSI filter + * 3:2 CS_MODE[1:0]: AFC loop gain in slow mode (2's log) + * + * CS_MODE1 | CS_MODE0 | CS Mode + * ----------------------------------------------------------------------------------------- + * 0 | 0 | Static CS + * 0 | 1 | Dynamic CS with 6dB dynamic threshold + * 1 | 0 | Dynamic CS with 12dB dynamic threshold + * 1 | 1 | Dynamic CS with 18dB dynamic threshold + * + * 1:0 OOK_PEAK_DECAY[1:0]: Peak decay control for OOK: 3 slow decay; 0 fast decay + */ + +#define RSSI_FLT_BASE ((uint8_t)0x21) /* Gain of the RSSI filter; lower value + * is fast but inaccurate, higher value + * is slow and more accurate */ + +#define RSSI_FLT_CS_MODE_MASK ((uint8_t)0x0c) /* Carrier sense mode mask */ +#define RSSI_FLT_CS_MODE_STATIC ((uint8_t)0x00) /* Carrier sense mode; static carrier + * sensing */ +#define RSSI_FLT_CS_MODE_DYNAMIC_6 ((uint8_t)0x04) /* Carrier sense mode; dynamic carrier + * sensing with 6dB threshold */ +#define RSSI_FLT_CS_MODE_DYNAMIC_12 ((uint8_t)0x08) /* Carrier sense mode; dynamic carrier + * sensing with 12dB threshold */ +#define RSSI_FLT_CS_MODE_DYNAMIC_18 ((uint8_t)0x0c) /* Carrier sense mode; dynamic carrier + * sensing with 18dB threshold */ +#define RSSI_FLT_OOK_PEAK_DECAY_MASK ((uint8_t)0x03) /* Peak decay control for OOK mask */ +#define RSSI_FLT_OOK_PEAK_DECAY_FAST ((uint8_t)0x00) /* Peak decay control for OOK: fast + * decay */ +#define RSSI_FLT_OOK_PEAK_DECAY_MEDIUM_FAST ((uint8_t)0x01) + /* Peak decay control for OOK: + * medium_fast decay */ +#define RSSI_FLT_OOK_PEAK_DECAY_MEDIUM_SLOW ((uint8_t)0x02) + /* Peak decay control for OOK: + * medium_slow decay */ +#define RSSI_FLT_OOK_PEAK_DECAY_SLOW ((uint8_t)0x03) /* Peak decay control for OOK: slow + * decay */ + +/* RSSI_TH register + * + * Read Write + * Default value: 0x24 + * + * 7:0 RSSI_THRESHOLD [7:0]: Signal detect threshold in 0.5dB. -120dBm corresponds to 20 + */ + +#define RSSI_TH_BASE ((uint8_t)0x22) /* Signal detect threshold in 0.5dB + * stp. 20 correspond to -120 dBm */ + +/* FIFO_Registers */ + +/* FIFO_CONFIG3 registers + * + * Default value: 0x30 + * Read Write + * + * 7 Reserved. + * 6:0 rxafthr [6:0]: FIFO Almost Full threshold for rx fifo. + */ + +#define FIFO_CONFIG3_RXAFTHR_BASE ((uint8_t)0x3e) /* FIFO Almost Full threshold for rx + * fifo [6:0] */ + +/* FIFO_CONFIG2 registers + * + * Default value: 0x30 + * Read Write + * + * 7 Reserved. + * 6:0 rxaethr [6:0]: FIFO Almost Empty threshold for rx fifo. + */ + +#define FIFO_CONFIG2_RXAETHR_BASE ((uint8_t)0x3f) /* FIFO Almost Empty threshold for rx + * fifo [6:0] */ + +/* FIFO_CONFIG1 registers + * + * Default value: 0x30 + * Read Write + * + * 7 Reserved. + * 6:0 txafthr [6:0]: FIFO Almost Full threshold for tx fifo. + */ + +#define FIFO_CONFIG1_TXAFTHR_BASE ((uint8_t)0x40) /* FIFO Almost Full threshold for tx + * fifo [6:0] */ + +/* FIFO_CONFIG0 registers + * + * Default value: 0x30 + * Read Write + * + * 7 Reserved. + * 6:0 txaethr [6:0]: FIFO Almost Empty threshold for tx fifo. + */ + +#define FIFO_CONFIG0_TXAETHR_BASE ((uint8_t)0x41) /* FIFO Almost Empty threshold for tx + * fifo [6:0] */ + +/* LINEAR_FIFO_STATUS1 registers + * + * Default value: 0x00 + * Read + * + * 7 Reserved. + * 6:0 elem_txfifo[6:0]: Number of elements in the linear TXFIFO (<=96) + */ + +#define LINEAR_FIFO_STATUS1_BASE ((uint8_t)0xe6) /* Number of elements in the linear TX + * FIFO [6:0] (<=96) */ + +/* LINEAR_FIFO_STATUS0 registers + * + * Default value: 0x00 + * Read + * + * 7 Reserved. + * + * 6:0 elem_rxfifo[6:0]: Number of elements in the linear RXFIFO (<=96) + */ + +#define LINEAR_FIFO_STATUS0_BASE ((uint8_t)0xe7) /* Number of elements in the linear RX + * FIFO [6:0] (<=96) */ + +/* Calibration_Registers */ + +/* RCO_VCO_CALIBR_IN2 registers + * + * Default value: 0x70 + * Read Write + * + * 7:4 RWT_IN[3:0]: RaWThermometric word value for the RCO [7:4] + * 3:0 RFB_IN[4:1]: ResistorFineBit word value for the RCO (first 4 bits) + */ + +#define RCO_VCO_CALIBR_IN2_BASE ((uint8_t)0x6d) /* RaWThermometric word value for the + * RCO [7:4]; ResistorFineBit word value + * for the RCO [3:0] */ + +/* RCO_VCO_CALIBR_IN1 registers + * + * Default value: 0x48 + * Read Write + * + * 7 RFB_IN[0]: ResistorFineBit word value for the RCO (LSb) + * 6:0 VCO_CALIBR_TX[6:0]: Word value for the VCO to be used in TX mode + */ + +#define RCO_VCO_CALIBR_IN1_BASE ((uint8_t)0x6e) /* ResistorFineBit word value for the + * RCO [7]; Word value for the VCO to + * be used in TX mode [6:0] */ + +/* RCO_VCO_CALIBR_IN0 registers + * + * Default value: 0x48 + * Read Write + * + * 7 Reserved. + * 6:0 VCO_CALIBR_RX[6:0]: Word value for the VCO to be used in RX mode + */ + +#define RCO_VCO_CALIBR_IN0_BASE ((uint8_t)0x6f) /* Word value for the VCO to be used + * in RX mode [6:0] */ + +/* RCO_VCO_CALIBR_OUT1 registers + * + * Default value: 0x00 + * Read + * + * 7:4 RWT_OUT[3:0]: RWT word from internal RCO calibrator + * 3:0 RFB_OUT[4:1]: RFB word from internal RCO calibrator (upper part) + */ + + #define RCO_VCO_CALIBR_OUT1_BASE ((uint8_t)0xe4) /* RaWThermometric RWT word from + * internal RCO calibrator [7]; + * ResistorFineBit RFB word from + * internal RCO oscillator [6:0] */ + +/* RCO_VCO_CALIBR_OUT0 registers + * + * Default value: 0x00 + * Read + * + * 7 RFB_OUT[0]: RFB word from internal RCO calibrator (last bit LSB) + * 6:0 VCO_CALIBR_DATA[6:0]: Output word from internal VCO calibrator + */ + +#define RCO_VCO_CALIBR_OUT0_BASE ((uint8_t)0xe5) /* ResistorFineBit RFB word from + * internal RCO oscillator [0]; Output + * word from internal calibrator [6:0]; */ + +/* AES_Registers */ + +/* AES_KEY_INx registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 AES_KEY_INx[7:0]: AES engine key input (total - 128 bits) + */ + +#define AES_KEY_IN_15_BASE ((uint8_t)0x70) /* AES engine key input 15 */ +#define AES_KEY_IN_14_BASE ((uint8_t)0x71) /* AES engine key input 14 */ +#define AES_KEY_IN_13_BASE ((uint8_t)0x72) /* AES engine key input 13 */ +#define AES_KEY_IN_12_BASE ((uint8_t)0x73) /* AES engine key input 12 */ +#define AES_KEY_IN_11_BASE ((uint8_t)0x74) /* AES engine key input 11 */ +#define AES_KEY_IN_10_BASE ((uint8_t)0x75) /* AES engine key input 10 */ +#define AES_KEY_IN_9_BASE ((uint8_t)0x76) /* AES engine key input 9 */ +#define AES_KEY_IN_8_BASE ((uint8_t)0x77) /* AES engine key input 8 */ +#define AES_KEY_IN_7_BASE ((uint8_t)0x78) /* AES engine key input 7 */ +#define AES_KEY_IN_6_BASE ((uint8_t)0x79) /* AES engine key input 6 */ +#define AES_KEY_IN_5_BASE ((uint8_t)0x7a) /* AES engine key input 5 */ +#define AES_KEY_IN_4_BASE ((uint8_t)0x7b) /* AES engine key input 4 */ +#define AES_KEY_IN_3_BASE ((uint8_t)0x7c) /* AES engine key input 3 */ +#define AES_KEY_IN_2_BASE ((uint8_t)0x7d) /* AES engine key input 2 */ +#define AES_KEY_IN_1_BASE ((uint8_t)0x7e) /* AES engine key input 1 */ +#define AES_KEY_IN_0_BASE ((uint8_t)0x7f) /* AES engine key input 0 */ + +/* AES_DATA_INx registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 AES_DATA_INx[7:0]: AES engine data input (total - 128 bits) + */ + +#define AES_DATA_IN_15_BASE ((uint8_t)0x80) /* AES engine data input 15 Take care: + * Address is in reverse order respect + * data numbering; eg.: 0x81 -> + * AES_data14[7:0] */ +#define AES_DATA_IN_14_BASE ((uint8_t)0x81) /* AES engine data input 14 */ +#define AES_DATA_IN_13_BASE ((uint8_t)0x82) /* AES engine data input 13 */ +#define AES_DATA_IN_12_BASE ((uint8_t)0x83) /* AES engine data input 12 */ +#define AES_DATA_IN_11_BASE ((uint8_t)0x84) /* AES engine data input 11 */ +#define AES_DATA_IN_10_BASE ((uint8_t)0x85) /* AES engine data input 10 */ +#define AES_DATA_IN_9_BASE ((uint8_t)0x86) /* AES engine data input 9 */ +#define AES_DATA_IN_8_BASE ((uint8_t)0x87) /* AES engine data input 8 */ +#define AES_DATA_IN_7_BASE ((uint8_t)0x88) /* AES engine data input 7 */ +#define AES_DATA_IN_6_BASE ((uint8_t)0x89) /* AES engine data input 6 */ +#define AES_DATA_IN_5_BASE ((uint8_t)0x8a) /* AES engine data input 5 */ +#define AES_DATA_IN_4_BASE ((uint8_t)0x8b) /* AES engine data input 4 */ +#define AES_DATA_IN_3_BASE ((uint8_t)0x8c) /* AES engine data input 3 */ +#define AES_DATA_IN_2_BASE ((uint8_t)0x8d) /* AES engine data input 2 */ +#define AES_DATA_IN_1_BASE ((uint8_t)0x8e) /* AES engine data input 1 */ +#define AES_DATA_IN_0_BASE ((uint8_t)0x8f) /* AES engine data input 0 */ + +/* AES_DATA_OUT[15:0] registers + * + * Default value: 0x00 + * Read + * + * 7:0 AES_DATA_OUTx[7:0]: AES engine data output (128 bits) + */ + +#define AES_DATA_OUT_15_BASE ((uint8_t)0xd4) /* AES engine data output 15 */ +#define AES_DATA_OUT_14_BASE ((uint8_t)0xd5) /* AES engine data output 14 */ +#define AES_DATA_OUT_13_BASE ((uint8_t)0xd6) /* AES engine data output 13 */ +#define AES_DATA_OUT_12_BASE ((uint8_t)0xd7) /* AES engine data output 12 */ +#define AES_DATA_OUT_11_BASE ((uint8_t)0xd8) /* AES engine data output 11 */ +#define AES_DATA_OUT_10_BASE ((uint8_t)0xd9) /* AES engine data output 10 */ +#define AES_DATA_OUT_9_BASE ((uint8_t)0xda) /* AES engine data output 9 */ +#define AES_DATA_OUT_8_BASE ((uint8_t)0xdb) /* AES engine data output 8 */ +#define AES_DATA_OUT_7_BASE ((uint8_t)0xdc) /* AES engine data output 7 */ +#define AES_DATA_OUT_6_BASE ((uint8_t)0xdd) /* AES engine data output 6 */ +#define AES_DATA_OUT_5_BASE ((uint8_t)0xde) /* AES engine data output 5 */ +#define AES_DATA_OUT_4_BASE ((uint8_t)0xdf) /* AES engine data output 4 */ +#define AES_DATA_OUT_3_BASE ((uint8_t)0xe0) /* AES engine data output 3 */ +#define AES_DATA_OUT_2_BASE ((uint8_t)0xe1) /* AES engine data output 2 */ +#define AES_DATA_OUT_1_BASE ((uint8_t)0xe2) /* AES engine data output 1 */ +#define AES_DATA_OUT_0_BASE ((uint8_t)0xe3) /* AES engine data output 0 */ + +/* IRQ_Registers */ + +/* IRQ_MASK0 registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 INT_MASK0: IRQ mask, if the correspondent bit is set and IRQ can be generated + * (according to the next table) + * + * Bit | Events Group Interrupt Event + * ------------------------------------------------------- + * 0 | RX data ready + * 1 | RX data discarded (upon filtering) + * 2 | TX data sent + * 3 | Max re-TX reached + * 4 | CRC error + * 5 | TX FIFO underflow/overflow error + * 6 | RX FIFO underflow/overflow error + * 7 | TX FIFO almost full + */ + +#define IRQ_MASK0_BASE ((uint8_t)0x93) /* IRQ_MASK is split into 4 registers */ + +#define IRQ_MASK0_RX_DATA_READY ((uint8_t)0x01) /* IRQ: RX data ready */ +#define IRQ_MASK0_RX_DATA_DISC ((uint8_t)0x02) /* IRQ: RX data discarded (upon filtering) */ +#define IRQ_MASK0_TX_DATA_SENT ((uint8_t)0x04) /* IRQ: TX data sent */ +#define IRQ_MASK0_MAX_RE_TX_REACH ((uint8_t)0x08) /* IRQ: Max re-TX reached */ +#define IRQ_MASK0_CRC_ERROR ((uint8_t)0x10) /* IRQ: CRC error */ +#define IRQ_MASK0_TX_FIFO_ERROR ((uint8_t)0x20) /* IRQ: TX FIFO underflow/overflow error */ +#define IRQ_MASK0_RX_FIFO_ERROR ((uint8_t)0x40) /* IRQ: RX FIFO underflow/overflow error */ +#define IRQ_MASK0_TX_FIFO_ALMOST_FULL ((uint8_t)0x80) /* IRQ: TX FIFO almost full */ + +/* IRQ_MASK1 registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 INT_MASK1: IRQ mask, if the correspondent bit is set and IRQ can be generated + * (according to the next table) + * + * Bit | Events Group Interrupt Event + * ------------------------------------------------------- + * 8 | TX FIFO almost empty + * 9 | RX FIFO almost full + * 10 | RX FIFO almost empty + * 11 | Max number of back-off during CCA + * 12 | Valid preamble detected + * 13 | Sync word detected + * 14 | RSSI above threshold (Carrier Sense) + * 15 | Wake-up timeout in LDCR mode13 + */ + +#define IRQ_MASK1_BASE ((uint8_t)0x92) /* IRQ_MASK is split into 4 registers */ + +#define IRQ_MASK1_TX_FIFO_ALMOST_EMPTY ((uint8_t)0x01) /* IRQ: TX FIFO almost empty */ +#define IRQ_MASK1_RX_FIFO_ALMOST_FULL ((uint8_t)0x02) /* IRQ: RX FIFO almost full */ +#define IRQ_MASK1_RX_FIFO_ALMOST_EMPTY ((uint8_t)0x04) /* IRQ: RX FIFO almost empty */ +#define IRQ_MASK1_MAX_BO_CCA_REACH ((uint8_t)0x08) /* IRQ: Max number of back-off during CCA */ +#define IRQ_MASK1_VALID_PREAMBLE ((uint8_t)0x10) /* IRQ: Valid preamble detected */ +#define IRQ_MASK1_VALID_SYNC ((uint8_t)0x20) /* IRQ: Sync word detected */ +#define IRQ_MASK1_RSSI_ABOVE_TH ((uint8_t)0x40) /* IRQ: RSSI above threshold */ +#define IRQ_MASK1_WKUP_TOUT_LDC ((uint8_t)0x80) /* IRQ: Wake-up timeout in LDC mode */ + +/* IRQ_MASK2 registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 INT_MASK2: IRQ mask, if the correspondent bit is set and IRQ can be generated + * (according to the next table) + * + * Bit | Events Group Interrupt Event + * ------------------------------------------------------- + * 16 | READY state in steady condition14 + * 17 | STANDBY state switching in progress + * 18 | Low battery level + * 19 | Power-On reset + * 20 | Brown-Out event + * 21 | LOCK state in steady condition + * 22 | PM start-up timer expiration + * 23 | XO settling timeout + */ +#define IRQ_MASK2_BASE ((uint8_t)0x91) /* IRQ_MASK is split into 4 registers */ + +#define IRQ_MASK2_READY ((uint8_t)0x01) /* IRQ: READY state */ +#define IRQ_MASK2_STANDBY_DELAYED ((uint8_t)0x02) /* IRQ: STANDBY state after + * MCU_CK_CONF_CLOCK_TAIL_X clock cycles */ +#define IRQ_MASK2_LOW_BATT_LVL ((uint8_t)0x04) /* IRQ: Battery level below threshold */ +#define IRQ_MASK2_POR ((uint8_t)0x08) /* IRQ: Power On Reset */ +#define IRQ_MASK2_BOR ((uint8_t)0x10) /* IRQ: Brown out event (both accurate + * and inaccurate) */ +#define IRQ_MASK2_LOCK ((uint8_t)0x20) /* IRQ: LOCK state */ +#define IRQ_MASK2_PM_COUNT_EXPIRED ((uint8_t)0x40) /* IRQ: only for debug; Power Management + * startup timer expiration (see reg + * PM_START_COUNTER, 0xb5) */ +#define IRQ_MASK2_XO_COUNT_EXPIRED ((uint8_t)0x80) /* IRQ: only for debug; Crystal + * oscillator settling time counter + * expired */ + +/* IRQ_MASK3 registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 INT_MASK3: IRQ mask, if the correspondent bit is set and IRQ can be generated + * (according to the next table) + * + * Bit | Events Group Interrupt Event + * ------------------------------------------------------- + * 24 | SYNTH locking timeout + * 25 | SYNTH calibration start-up time + * 26 | SYNTH calibration timeout + * 27 | TX circuitry start-up time + * 28 | RX circuitry start-up time + * 29 | RX operation timeout + * 30 | Others AES End–of –Operation + * 31 | Reserved + */ + +#define IRQ_MASK3_BASE ((uint8_t)0x90) /* IRQ_MASK is split into 4 registers */ + +#define IRQ_MASK3_SYNTH_LOCK_TIMEOUT ((uint8_t)0x01) /* IRQ: only for debug; LOCK state + * timeout */ +#define IRQ_MASK3_SYNTH_LOCK_STARTUP ((uint8_t)0x02) /* IRQ: only for debug; see + * CALIBR_START_COUNTER */ +#define IRQ_MASK3_SYNTH_CAL_TIMEOUT ((uint8_t)0x04) /* IRQ: only for debug; SYNTH + * calibration timeout */ +#define IRQ_MASK3_TX_START_TIME ((uint8_t)0x08) /* IRQ: only for debug; TX circuitry + * startup time; see TX_START_COUNTER */ +#define IRQ_MASK3_RX_START_TIME ((uint8_t)0x10) /* IRQ: only for debug; RX circuitry + * startup time; see TX_START_COUNTER */ +#define IRQ_MASK3_RX_TIMEOUT ((uint8_t)0x20) /* IRQ: RX operation timeout */ +#define IRQ_MASK3_AES_END ((uint8_t)0x40) /* IRQ: AES End of operation */ + +/* IRQ_STATUS0 registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 INT_STATUS0: IRQ status, if the correspondent bit is set and IRQ has been generated + * (according to the next table) + * + * Bit | Events Group Interrupt Event + * ------------------------------------------------------- + * 0 | RX data ready + * 1 | RX data discarded (upon filtering) + * 2 | TX data sent + * 3 | Max re-TX reached + * 4 | CRC error + * 5 | TX FIFO underflow/overflow error + * 6 | RX FIFO underflow/overflow error + * 7 | TX FIFO almost full + */ + +#define IRQ_STATUS0_BASE ((uint8_t)0xfd) /* IRQ Events(RR, split into 4 registers) */ + +#define IRQ_STATUS0_SYNTH_LOCK_TIMEOUT ((uint8_t)0x01) /* IRQ: LOCK state timeout */ +#define IRQ_STATUS0_SYNTH_LOCK_STARTUP ((uint8_t)0x02) /* IRQ: only for debug; see + * CALIBR_START_COUNTER */ +#define IRQ_STATUS0_SYNTH_CAL_TIMEOUT ((uint8_t)0x04) /* IRQ: SYNTH locking timeout */ +#define IRQ_STATUS0_TX_START_TIME ((uint8_t)0x08) /* IRQ: only for debug; TX circuitry + * startup time; see TX_START_COUNTER */ +#define IRQ_STATUS0_RX_START_TIME ((uint8_t)0x10) /* IRQ: only for debug; RX circuitry + * startup time; see TX_START_COUNTER */ +#define IRQ_STATUS0_RX_TIMEOUT ((uint8_t)0x20) /* IRQ: RX operation timeout expiration */ +#define IRQ_STATUS0_AES_END ((uint8_t)0x40) /* IRQ: AES End of operation */ + +/* IRQ_STATUS1 registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 INT_STATUS1: IRQ status, if the correspondent bit is set and IRQ has been generated + * (according to the next table) + * + * Bit | Events Group Interrupt Event + * ------------------------------------------------------- + * 8 | TX FIFO almost empty + * 9 | RX FIFO almost full + * 10 | RX FIFO almost empty + * 11 | Max number of back-off during CCA + * 12 | Valid preamble detected + * 13 | Sync word detected + * 14 | RSSI above threshold (Carrier Sense) + * 15 | Wake-up timeout in LDCR mode13 + */ + +#define IRQ_STATUS1_BASE ((uint8_t)0xfc) /* IRQ Events(RR, split into 4 registers) */ + +#define IRQ_STATUS1_READY ((uint8_t)0x01) /* IRQ: READY state in steady condition */ +#define IRQ_STATUS1_STANDBY_DELAYED ((uint8_t)0x02) /* IRQ: STANDBY state after + * MCU_CK_CONF_CLOCK_TAIL_X clock cycles */ +#define IRQ_STATUS1_LOW_BATT_LVL ((uint8_t)0x04) /* IRQ: Battery level below threshold */ +#define IRQ_STATUS1_POR ((uint8_t)0x08) /* IRQ: Power On Reset */ +#define IRQ_STATUS1_BOR ((uint8_t)0x10) /* IRQ: Brown out event (both accurate + * and inaccurate) */ +#define IRQ_STATUS1_LOCK ((uint8_t)0x20) /* IRQ: LOCK state in steady condition */ +#define IRQ_STATUS1_PM_COUNT_EXPIRED ((uint8_t)0x40) /* IRQ: Power Management startup timer + * expiration (see reg PM_START_COUNTER, + * 0xb5) */ +#define IRQ_STATUS1_XO_COUNT_EXPIRED ((uint8_t)0x80) /* IRQ: Crystal oscillator settling + * time counter expired */ + +/* IRQ_STATUS2 registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 INT_STATUS2: IRQ status, if the correspondent bit is set and IRQ has been generated + * (according to the next table) + * + * Bit | Events Group Interrupt Event + * ------------------------------------------------------- + * 16 | READY state in steady condition14 + * 17 | STANDBY state switching in progress + * 18 | Low battery level + * 19 | Power-On reset + * 20 | Brown-Out event + * 21 | LOCK state in steady condition + * 22 | PM start-up timer expiration + * 23 | XO settling timeout + */ + +#define IRQ_STATUS2_BASE ((uint8_t)0xfb) /* IRQ Events(RR, split into 4 registers) */ + +#define IRQ_STATUS2_TX_FIFO_ALMOST_EMPTY ((uint8_t)0x01) /* IRQ: TX FIFO almost empty */ +#define IRQ_STATUS2_RX_FIFO_ALMOST_FULL ((uint8_t)0x02) /* IRQ: RX FIFO almost full */ +#define IRQ_STATUS2_RX_FIFO_ALMOST_EMPTY ((uint8_t)0x04) /* IRQ: RX FIFO almost empty */ +#define IRQ_STATUS2_MAX_BO_CCA_REACH ((uint8_t)0x08) /* IRQ: Max number of back-off during + * CCA */ +#define IRQ_STATUS2_VALID_PREAMBLE ((uint8_t)0x10) /* IRQ: Valid preamble detected */ +#define IRQ_STATUS2_VALID_SYNC ((uint8_t)0x20) /* IRQ: Sync word detected */ +#define IRQ_STATUS2_RSSI_ABOVE_TH ((uint8_t)0x40) /* IRQ: RSSI above threshold */ +#define IRQ_STATUS2_WKUP_TOUT_LDC ((uint8_t)0x80) /* IRQ: Wake-up timeout in LDC mode */ + +/* IRQ_STATUS3 registers + * + * Default value: 0x00 + * Read Write + * + * 7:0 INT_STATUS3: IRQ status, if the correspondent bit is set and IRQ has been generated + * (according to the next table) + * + * Bit | Events Group Interrupt Event + * ------------------------------------------------------- + * 24 | SYNTH locking timeout + * 25 | SYNTH calibration start-up time + * 26 | SYNTH calibration timeout + * 27 | TX circuitry start-up time + * 28 | RX circuitry start-up time + * 29 | RX operation timeout + * 30 | Others AES End–of –Operation + * 31 | Reserved + */ + +#define IRQ_STATUS3_BASE ((uint8_t)0xfa) /* IRQ Events(RR, split into 4 registers) */ + +#define IRQ_STATUS3_RX_DATA_READY ((uint8_t)0x01) /* IRQ: RX data ready */ +#define IRQ_STATUS3_RX_DATA_DISC ((uint8_t)0x02) /* IRQ: RX data discarded (upon filtering) */ +#define IRQ_STATUS3_TX_DATA_SENT ((uint8_t)0x04) /* IRQ: TX data sent */ +#define IRQ_STATUS3_MAX_RE_TX_REACH ((uint8_t)0x08) /* IRQ: Max re-TX reached */ +#define IRQ_STATUS3_CRC_ERROR ((uint8_t)0x10) /* IRQ: CRC error */ +#define IRQ_STATUS3_TX_FIFO_ERROR ((uint8_t)0x20) /* IRQ: TX FIFO underflow/overflow error */ +#define IRQ_STATUS3_RX_FIFO_ERROR ((uint8_t)0x40) /* IRQ: RX FIFO underflow/overflow error */ +#define IRQ_STATUS3_TX_FIFO_ALMOST_FULL ((uint8_t)0x80) /* IRQ: TX FIFO almost full */ + +/* MC_STATE_Registers */ + +/* MC_STATE1 registers + * + * Default value: 0x50 + * Read + * + * 7:4 Reserved. + * 3 ANT_SELECT: Currently selected antenna + * 2 TX_FIFO_Full: 1 - TX FIFO is full + * 1 RX_FIFO_Empty: 1 - RX FIFO is empty + * 0 ERROR_LOCK: 1 - RCO calibrator error + */ + +#define MC_STATE1_BASE ((uint8_t)0xc0) /* MC_STATE1 register address (see the + * struct spirit_status_s */ + +/* MC_STATE0 registers + * + * Default value: 0x00 + * Read + * + * 7:1 STATE[6:0]: Current MC state. + * + * REGISTER VALUE | STATE + * -------------------------------------------- + * 0x40 | STANDBY + * 0x36 | SLEEP + * 0x03 | READY + * 0x3b | PM setup + * 0x23 | XO settling + * 0x53 | SYNTH setup + * 0x1f | PROTOCOL + * 0x4f | SYNTH calibration + * 0x0f | LOCK + * 0x33 | RX + * 0x5f | TX + * + * 0 XO_ON: 1 - XO is operating + */ + +#define MC_STATE0_BASE ((uint8_t)0xc1) /* MC_STATE0 register address. In this + * version ALL existing states have + * been inserted and are still to be + * verified */ + +/* Engineering-Test_Registers */ + +#define SYNTH_CONFIG1_BASE ((uint8_t)0x9e) /* Synthesizier registers: M, A, K + * data sync on positive/negative + * clock edges [4], Enable Linearization + * of the charge pump [3], split time + * 1.75/3.45ns [2], VCO calibration window + * 16,32,64,128 clock cycles [1:0] */ +#define SYNTH_CONFIG0_BASE ((uint8_t)0x9f) /* Enable DSM randomizer [7], Window width + * 1.2-7.5ns (Down-up) of lock detector */ +#define VCOTH_BASE ((uint8_t)0xa0) /* Controls the threshold frequency + * between VCO low and VCO high [7:0] VCOth + * frequency=2*fXO*(96+VCO_TH/16), + * fmin=4992 MHz, fmax=5820 MHz */ +#define PM_CONFIG2_BASE ((uint8_t)0xa4) /* Enables high current buffer on + * Temperature sensor, sets SMPS options */ +#define PM_CONFIG1_BASE ((uint8_t)0xa5) /* Set SMPS options */ +#define PM_CONFIG0_BASE ((uint8_t)0xa6) /* Set SMPS options */ +#define VCO_CONFIG_BASE ((uint8_t)0xa1) /* Set VCO current [5:2]part and [1:0] part */ +#define XO_CONFIG_BASE ((uint8_t)0xa7) /* Clock management options from XO to + * digital part */ +#define XO_RCO_TEST_BASE ((uint8_t)0xb4) /* Test of XO and RCO */ + +/* Commands */ + +#define COMMAND_TX ((uint8_t)0x60) /* Start to transmit; valid only from + * READY */ +#define COMMAND_RX ((uint8_t)0x61) /* Start to receive; valid only from + * READY */ +#define COMMAND_READY ((uint8_t)0x62) /* Go to READY; valid only from STANDBY + * or SLEEP or LOCK */ +#define COMMAND_STANDBY ((uint8_t)0x63) /* Go to STANDBY; valid only from READY */ +#define COMMAND_SLEEP ((uint8_t)0x64) /* Go to SLEEP; valid only from READY */ +#define COMMAND_LOCKRX ((uint8_t)0x65) /* Go to LOCK state by using the RX + * configuration of the synth; valid + * only from READY */ +#define COMMAND_LOCKTX ((uint8_t)0x66) /* Go to LOCK state by using the TX + * configuration of the synth; valid + * only from READY */ +#define COMMAND_SABORT ((uint8_t)0x67) /* Force exit form TX or RX states and + * go to READY state; valid only from + * TX or RX */ +#define COMMAND_LDC_RELOAD ((uint8_t)0x68) /* LDC Mode: Reload the LDC timer with + * the value stored in the LDC_PRESCALER + * / COUNTER registers; valid from all + * states */ +#define COMMAND_SEQUENCE_UPDATE ((uint8_t)0x69) /* Autoretransmission: Reload the + * Packet sequence counter with the + * value stored in the PROTOCOL[2] + * register valid from all states */ +#define COMMAND_AES_ENC ((uint8_t)0x6a) /* AES: Start the encryption routine; + * valid from all states */ +#define COMMAND_AES_KEY ((uint8_t)0x6b) /* AES: Start the procedure to compute + * the key for the decryption; valid + * from all states */ +#define COMMAND_AES_DEC ((uint8_t)0x6c) /* AES: Start the decryption routine + * using the current key; valid from + * all states */ +#define COMMAND_AES_KEY_DEC ((uint8_t)0x6d) /* AES: Compute the key and start the + * decryption; valid from all states */ +#define COMMAND_SRES ((uint8_t)0x70) /* Reset of all digital part, except + * SPI registers */ +#define COMMAND_FLUSHRXFIFO ((uint8_t)0x71) /* Clean the RX FIFO; valid from all + * states */ +#define COMMAND_FLUSHTXFIFO ((uint8_t)0x72) /* Clean the TX FIFO; valid from all + * states */ + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_REGS_H */ diff --git a/drivers/wireless/spirit/include/spirit_spi.h b/drivers/wireless/spirit/include/spirit_spi.h new file mode 100644 index 0000000000..7aa39f2b19 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_spi.h @@ -0,0 +1,204 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/include/spirit_spi.h + * Header file for NuttX SPIRIT SPI driver interface. + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Derives loosely from similarly licensed SPI interface definitions from + * STMicro: + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __DRIVERS_WIRELESS_SPIRIT_INCLUDE_SPIRIT_SPI_H +#define __DRIVERS_WIRELESS_SPIRIT_INCLUDE_SPIRIT_SPI_H + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Defintiions + ******************************************************************************/ + +/* SPIRIT1 SPI Headers */ + +#define HEADER_WRITE_MASK 0x00 /* Write mask for header byte */ +#define HEADER_READ_MASK 0x01 /* Read mask for header byte */ +#define HEADER_ADDRESS_MASK 0x00 /* Address mask for header byte */ +#define HEADER_COMMAND_MASK 0x80 /* Command mask for header byte */ +#define LINEAR_FIFO_ADDRESS 0xff /* Linear FIFO address */ + +/* SPIRIT macros to construct headers */ + +#define __MKHEADER(a,rw) (a | rw) +#define WRITE_HEADER __MKHEADER(HEADER_ADDRESS_MASK, HEADER_WRITE_MASK) +#define READ_HEADER __MKHEADER(HEADER_ADDRESS_MASK, HEADER_READ_MASK) +#define COMMAND_HEADER __MKHEADER(HEADER_COMMAND_MASK, HEADER_WRITE_MASK) + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct spi_dev_s; /* Forward reference */ + +/****************************************************************************** + * Name: spirit_reg_read + * + * Description: + * Read single or multiple SPIRIT1 register + * + * Input parameters: + * regaddr: Base register's address to be read + * buffer: Pointer to the buffer of registers' values to be read + * buflen: Number of register values to be read + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_reg_read(FAR struct spirit_library_s *spirit, uint8_t regaddr, + FAR uint8_t *buffer, unsigned int buflen); + +/****************************************************************************** + * Name: spirit_reg_write + * + * Description: + * Read single or multiple SPIRIT1 register. + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * regaddr - Base register's address to write + * buffer - Pointer to the buffer of register values to write + * buflen - Number of registers values to be written. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_reg_write(FAR struct spirit_library_s *spirit, uint8_t regaddr, + FAR const uint8_t *buffer, unsigned int buflen); + +/****************************************************************************** + * Name: spirit_command + * + * Description: + * Send a command + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * cmd - Command code to be sent + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_command(FAR struct spirit_library_s *spirit, uint8_t cmd); + +/****************************************************************************** + * Name: spirt_fifo_read + * + * Description: + * Read data from RX FIFO + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * buffer - Pointer to the buffer of data values to write + * buflen - Number of bytes to be written + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirt_fifo_read(FAR struct spirit_library_s *spirit, FAR uint8_t *buffer, + unsigned int buflen); + +/****************************************************************************** + * Name: spirt_fifo_write + * + * Description: + * Write data into TX FIFO. + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * buffer - Pointer to the buffer of data values to write + * buflen - Number of data values to be written. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirt_fifo_write(FAR struct spirit_library_s *spirit, + FAR const uint8_t *buffer, unsigned int buflen); + +/****************************************************************************** + * Name: spirit_update_status + * + * Description: + * Updates the state field in the driver instance by reading the MC_STATE + * register of SPIRIT. + * + * Input Parameters: + * spirit - Reference to an instance of the driver state stucture. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_update_status(FAR struct spirit_library_s *spirit); + +#ifdef __cplusplus +} +#endif + +#endif /* __DRIVERS_WIRELESS_SPIRIT_INCLUDE_SPIRIT_SPI_H */ diff --git a/drivers/wireless/spirit/include/spirit_timer.h b/drivers/wireless/spirit/include/spirit_timer.h new file mode 100644 index 0000000000..4cec9656da --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_timer.h @@ -0,0 +1,146 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/spirit_timer.h + * Configuration and management of SPIRIT timers. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_TIMER_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_TIMER_H + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_regs.h" +#include "spirit_types.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in debug assertions */ + +#define IS_RX_TIMEOUT_STOP_CONDITION(cond) \ + (cond == NO_TIMEOUT_STOP || cond == TIMEOUT_ALWAYS_STOPPED || \ + cond == RSSI_ABOVE_THRESHOLD || cond == SQI_ABOVE_THRESHOLD || \ + cond == PQI_ABOVE_THRESHOLD || cond == RSSI_AND_SQI_ABOVE_THRESHOLD || \ + cond == RSSI_AND_PQI_ABOVE_THRESHOLD || cond == SQI_AND_PQI_ABOVE_THRESHOLD || \ + cond == ALL_ABOVE_THRESHOLD || cond == RSSI_OR_SQI_ABOVE_THRESHOLD || \ + cond == RSSI_OR_PQI_ABOVE_THRESHOLD || cond == SQI_OR_PQI_ABOVE_THRESHOLD || \ + cond == ANY_ABOVE_THRESHOLD) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* All the possible RX timeout stop conditions enumeration. */ + +enum spirit_rxtimeout_stopcondition_e +{ + NO_TIMEOUT_STOP = 0x00, /* Timeout never stopped */ + TIMEOUT_ALWAYS_STOPPED = 0x08, /* Timeout always stopped (default) */ + RSSI_ABOVE_THRESHOLD = 0x04, /* Timeout stopped on RSSI above + * threshold */ + SQI_ABOVE_THRESHOLD = 0x02, /* Timeout stopped on SQI above + * threshold */ + PQI_ABOVE_THRESHOLD = 0x01, /* Timeout stopped on PQI above + * threshold */ + RSSI_AND_SQI_ABOVE_THRESHOLD = 0x06, /* Timeout stopped on both + * RSSI and SQI above threshold */ + RSSI_AND_PQI_ABOVE_THRESHOLD = 0x05, /* Timeout stopped on both + * RSSI and PQI above threshold */ + SQI_AND_PQI_ABOVE_THRESHOLD = 0x03, /* Timeout stopped on both + * SQI and PQI above threshold */ + ALL_ABOVE_THRESHOLD = 0x07, /* Timeout stopped only if RSSI, SQI + * and PQI are above threshold */ + RSSI_OR_SQI_ABOVE_THRESHOLD = 0x0e, /* Timeout stopped if one + * between RSSI or SQI are + * above threshold */ + RSSI_OR_PQI_ABOVE_THRESHOLD = 0x0d, /* Timeout stopped if one + * between RSSI or PQI are + * above threshold */ + SQI_OR_PQI_ABOVE_THRESHOLD = 0x0b, /* Timeout stopped if one + * between SQI or PQI are above + * threshold */ + ANY_ABOVE_THRESHOLD = 0x0f /* Timeout stopped if one among + * RSSI, SQI or SQI are above threshold */ +}; + +/****************************************************************************** + * Public Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_timer_set_rxtimeout + * + * Description: + * Sets the RX timeout timer counter. If 'counter' is equal to 0 the + * timeout is disabled. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * counter - value for the timer counter. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_timer_set_rxtimeout(FAR struct spirit_library_s *spirit, + uint8_t counter); + +/****************************************************************************** + * Name: spirit_timer_set_rxtimeout_stopcondition + * + * Description: + * Sets the RX timeout stop conditions. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * stopcondition - New stop condition. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_timer_set_rxtimeout_stopcondition(FAR struct spirit_library_s *spirit, + enum spirit_rxtimeout_stopcondition_e + stopcondition); + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_SPIRIT_TIMER_H */ diff --git a/drivers/wireless/spirit/include/spirit_types.h b/drivers/wireless/spirit/include/spirit_types.h new file mode 100644 index 0000000000..7ea341e0c9 --- /dev/null +++ b/drivers/wireless/spirit/include/spirit_types.h @@ -0,0 +1,162 @@ +/****************************************************************************** + * include/nuttx/wireless/spirit/include/spirit_types.h + * Header file for SPIRIT types. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted and extended for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +#ifndef __INCLUDE_NUTT_WIRELESS_SPIRIT_INCLUDE_SPIRIT_TYPES_H +#define __INCLUDE_NUTT_WIRELESS_SPIRIT_INCLUDE_SPIRIT_TYPES_H + +/* This module provide some types definitions which will be used in + * all the modules of this library. Here is defined also the global + * variable spirit->state which contains the status of Spirit and + * is updated every time an SPI transaction occurs. + */ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include +#include + +#include "spirit_regs.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Macros used in assertions */ + +#define IS_SPIRIT_FUNCTIONAL_STATE(STATE) \ + (STATE == S_DISABLE || STATE == S_ENABLE) + +#define IS_SPIRIT_FLAG_STATUS(STATUS) \ + (STATUS == S_RESET || STATUS == S_SET) + +/****************************************************************************** + * Public Types + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Spirit Functional state. Used to enable or disable a specific option. */ + +enum spirit_functional_state_e +{ + S_DISABLE = 0, + S_ENABLE = 1 +}; + +/* Spirit Flag status. Used to control the state of a flag. */ + +enum spirit_flag_status_e +{ + S_RESET = 0, + S_SET = 1 +}; + +/* SPIRIT States enumeration. */ + +enum spirit_state_e +{ + MC_STATE_STANDBY = 0x40, /* STANDBY */ + MC_STATE_SLEEP = 0x36, /* SLEEP */ + MC_STATE_READY = 0x03, /* READY */ + MC_STATE_PM_SETUP = 0x3d, /* PM_SETUP */ + MC_STATE_XO_SETTLING = 0x23, /* XO_SETTLING */ + MC_STATE_SYNTH_SETUP = 0x53, /* SYNT_SETUP */ + MC_STATE_PROTOCOL = 0x1f, /* PROTOCOL */ + MC_STATE_SYNTH_CALIBRATION = 0x4f, /* SYNTH */ + MC_STATE_LOCK = 0x0f, /* LOCK */ + MC_STATE_RX = 0x33, /* RX */ + MC_STATE_TX = 0x5f /* TX */ +}; + +/* SPIRIT Status. This definition represents the single field of the SPIRIT + * status returned on each SPI transaction, equal also to the MC_STATE registers. + * This field-oriented structure allows user to address in simple way the single + * field of the SPIRIT status. + * The user shall define a variable of SpiritStatus type to access on SPIRIT status fields. + * @note The fields order in the structure depends on used endianness (little or big + * endian). The actual definition is valid ONLY for LITTLE ENDIAN mode. Be sure to + * change opportunely the fields order when use a different endianness. + */ + +struct spirit_status_s +{ + uint8_t XO_ON : 1; /* Notifies if XO is operating (XO_ON is + * 1) or not (XO_On is 0) */ + uint8_t MC_STATE : 7; /* Indicates the state of the Main Controller + * of SPIRIT. The possible states and their + * corresponding values are defined in enum + * spirit_state_e */ + uint8_t ERROR_LOCK : 1; /* Notifies if there is an error on RCO + * calibration (ERROR_LOCK is 1) or not + * (ERROR_LOCK is 0) */ + uint8_t RX_FIFO_EMPTY : 1; /* Notifies if RX FIFO is empty (RX_FIFO_EMPTY + * is 1) or not (RX_FIFO_EMPTY is 0) */ + uint8_t TX_FIFO_FULL : 1; /* Notifies if TX FIFO is full (TX_FIFO_FULL + * is 1) or not (TX_FIFO_FULL is 0) */ + uint8_t ANT_SELECT : 1; /* Notifies the currently selected antenna */ + uint8_t reserved : 4; /* Reserved and equal to 5 */ +}; + +/* An instance of this structure represents the overall state of one Spirit + * device from the standpoint of the library. Multiple spirit devices may be + * supported by the library with multiple instances of this structure. + */ + +struct spirit_library_s +{ + FAR struct spi_dev_s *spi; /* SPI: Contained SPI device instance */ + uint32_t xtal_frequency; /* RADIO: Crystal frequency */ + uint32_t commfrequency; /* MANAGEMENT: Desired communication frequency */ + + union spirit_struct_u + { + struct spirit_status_s state; /* State of the Spirit device */ + uint16_t u16; /* For alternative accesses */ + } u; + + uint8_t commstate; /* MANAGEMENT: Communication state */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTT_WIRELESS_SPIRIT_INCLUDE_SPIRIT_TYPES_H */ diff --git a/drivers/wireless/spirit/lib/Make.defs b/drivers/wireless/spirit/lib/Make.defs new file mode 100644 index 0000000000..9cd2382355 --- /dev/null +++ b/drivers/wireless/spirit/lib/Make.defs @@ -0,0 +1,44 @@ +############################################################################ +# drivers/wireless/spirit/lib//Make.defs +# +# Copyright (C) 2017 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +#- +############################################################################ + +# Include Spirit driver source files in the build + +CSRCS += spirit_radio.c spirit_pktbasic.c spirit_qi.c spirit_management.c +CSRCS += spirit_irq.c spirit_timer.c spirit_gpio.c spirit_spi.c + +# Include Spirit driver build support + +DEPPATH += --dep-path wireless$(DELIM)spirit$(DELIM)lib +VPATH += :wireless$(DELIM)spirit$(DELIM)lib diff --git a/drivers/wireless/spirit/lib/spirit_gpio.c b/drivers/wireless/spirit/lib/spirit_gpio.c new file mode 100644 index 0000000000..4021e785c5 --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_gpio.c @@ -0,0 +1,101 @@ +/****************************************************************************** + * drivers/wireless/spirit/lib/spirit_gpio.c + * This file provides all the low level API to manage SPIRIT GPIO. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include +#include + +#include "spirit_gpio.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/****************************************************************************** + * Private Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * + * Parameters: + * + * Returned Value: + * + ******************************************************************************/ + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * Initializes the Spirit GPIOx according to the specified parameters in + * the gpioinit parameter. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * gpioinit - A pointer to a struct spirit_gpio_init_s structure that + * contains the configuration information for the specified + * SPIRIT GPIO. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_gpio_initialize(FAR struct spirit_library_s *spirit, + FAR const struct spirit_gpio_init_s *gpioinit) +{ + uint8_t regval = 0x00; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_GPIO(gpioinit->gpiopin)); + DEBUGASSERT(IS_SPIRIT_GPIO_MODE(gpioinit->gpiomode)); + DEBUGASSERT(IS_SPIRIT_GPIO_IO(gpioinit->gpioio)); + + regval = ((uint8_t)(gpioinit->gpiomode) | (uint8_t)(gpioinit->gpioio)); + return spirit_reg_write(spirit, gpioinit->gpiopin, ®val, 1); +} diff --git a/drivers/wireless/spirit/lib/spirit_irq.c b/drivers/wireless/spirit/lib/spirit_irq.c new file mode 100644 index 0000000000..1663790d83 --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_irq.c @@ -0,0 +1,324 @@ +/****************************************************************************** + * drivers/wireless/spirit/lib/spirit_irq.c + * Configuration and management of SPIRIT IRQs. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include + +#include "spirit_types.h" +#include "spirit_spi.h" +#include "spirit_irq.h" + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_irq_disable_all + * + * Description: + * Ssets the IRQ mask registers to 0x00000000, disabling all IRQs. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_irq_disable_all(FAR struct spirit_library_s *spirit) +{ + uint8_t regval[4] = { 0x00, 0x00, 0x00, 0x00 }; + + /* Writes the IRQ_MASK registers */ + + return spirit_reg_write(spirit, IRQ_MASK3_BASE, regval, 4); +} + +/****************************************************************************** + * Name: spirit_irq_set_mask + * + * Description: + * Enables/disables all the IRQs according to the user defined irqset + * structure. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * irqset - Pointer to a variable of type struct spirit_irqset_s, through + * which the user enable specific IRQs. This parameter is a + * pointer to a struct spirit_irqset_s. + * + * For example suppose to enable only the two IRQ Low Battery Level + * and Tx Data Sent: + * + * struct spirit_irqset_s g_irqset = {0}; + * g_irqset.IRQ_LOW_BATT_LVL = 1; + * g_irqset.IRQ_TX_DATA_SENT = 1; + * spirit_irq_setmask(&g_irqset); + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +#ifndef CONFIG_ENDIAN_BIG +int spirit_irq_set_mask(FAR struct spirit_library_s *spirit, + FAR struct spirit_irqset_s *irqset) +{ + /* Writes the IRQ_MASK registers */ + + return spirit_reg_write(spirit, IRQ_MASK3_BASE, (FAR uint8_t *)irqset, 4); +} +#endif + +/****************************************************************************** + * Name: spirit_irq_enable + * + * Description: + * Enables or disables a specific IRQ. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * irq IRQ to enable or disable. + * newstate - new state for the IRQ. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_irq_enable(FAR struct spirit_library_s *spirit, + enum spirit_irq_e irq, + enum spirit_functional_state_e newstate) +{ + uint8_t regval[4]; + uint32_t dwirqs = 0; + int ret; + int i; + int j; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_IRQ_LIST(irq)); + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); + + /* Reads the IRQ_MASK registers */ + + ret = spirit_reg_read(spirit, IRQ_MASK3_BASE, regval, 4); + if (ret < 0) + { + return ret; + } + + /* Build the IRQ mask word */ + + for (i = 0; i < 4; i++) + { + dwirqs += ((uint32_t) regval[i]) << (8 * (3 - i)); + } + + /* Rebuild the new mask according to user request */ + + if (newstate == S_DISABLE) + { + dwirqs &= (~irq); + } + else + { + dwirqs |= (irq); + } + + /* Build the array of bytes to write in the IRQ_MASK registers */ + + for (j = 0; j < 4; j++) + { + regval[j] = (uint8_t)(dwirqs >> (8 * (3 - j))); + } + + /* Writes the new IRQ mask in the corresponding registers */ + + return spirit_reg_write(spirit, IRQ_MASK3_BASE, regval, 4); +} + +/****************************************************************************** + * Name: spirit_irt_get_mask + * + * Description: + * Fills a pointer to a structure of struct spirit_irqset_s type with the + * content of the IRQ_MASK registers. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * pirqmask - Pointer to a variable of type struct spirit_irqset_s, through + * which the user can read which IRQs are enabled. All the + * bitfields equals to zero correspond to enabled IRQs, while + * all the bitfields equals to one correspond to disabled IRQs. + * + * For example suppose that the Power On Reset and RX Data + * ready are the only enabled IRQs. + * + * struct spirit_irqset_s g_irqmask; + * spirit_irq_get_pending(&g_irqmask); + * + * Then g_irqmask.IRQ_POR and g_irqmask.IRQ_RX_DATA_READY are + * equal to 0 while all the other bitfields are equal to one. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +#ifndef CONFIG_ENDIAN_BIG +int spirit_irt_get_mask(FAR struct spirit_library_s *spirit, + FAR struct spirit_irqset_s *pirqmask) +{ + /* Reads IRQ_MASK registers */ + + return spirit_reg_read(spirit, IRQ_MASK3_BASE, (FAR uint8_t *)pirqmask, 4); +} +#endif + +/****************************************************************************** + * Name: spirit_irq_get_pending + * + * Description: + * Fills a pointer to a structure of struct spirit_irqset_s type with the + * content of the IRQ_STATUS registers. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * pirqstatus - A pointer to a variable of type struct spirit_irqset_s, + * through which the user can receive the status of all the + * IRQs. All the bitfields equals to one correspond to the + * raised interrupts. + * + * For example suppose that the XO settling timeout is raised + * as well as the Sync word detection. + * + * struct spirit_irqset_s g_irqstatus; + * spirit_irq_get_pending(&g_irqstatus); + * + * Then g_irqstatus.IRQ_XO_COUNT_EXPIRED and + * g_irqstatus.IRQ_VALID_SYNC are equals to 1* while all the + * other bitfields are equals to zero. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +#ifndef CONFIG_ENDIAN_BIG +int spirit_irq_get_pending(FAR struct spirit_library_s *spirit, + FAR struct spirit_irqset_s *pirqstatus) +{ + /* Reads IRQ_STATUS registers */ + + return spirit_reg_read(spirit, IRQ_STATUS3_BASE, (FAR uint8_t *)pirqstatus, 4); +} +#endif + +/****************************************************************************** + * Name: spirit_irq_clr_pending + * + * Description: + * Clear the IRQ status registers. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_irq_clr_pending(FAR struct spirit_library_s *spirit) +{ + uint8_t regval[4]; + + /* Reads the IRQ_STATUS registers clearing all the flags */ + + return spirit_reg_read(spirit, IRQ_STATUS3_BASE, regval, 4); +} + +/****************************************************************************** + * Name: spirit_irq_is_pending + * + * Description: + * Checks if a specific IRQ has been generated. The call resets all the + * IRQ status, so it can't be used in case of multiple raising interrupts. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * flag IRQ flag to be checked. + * This parameter can be any value of enum spirit_irq_e. + * + * Returned Value: + * true or false. + * + ******************************************************************************/ + +bool spirit_irq_is_pending(FAR struct spirit_library_s *spirit, + enum spirit_irq_e flag) +{ + uint8_t regval[4]; + uint32_t dwirqs = 0; + int ret; + int i; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_IRQ_LIST(flag)); + + /* Read status registers */ + + ret = spirit_reg_read(spirit, IRQ_STATUS3_BASE, regval, 4); + if (ret < 0) + { + return ret; + } + + /* Build the status word */ + + for (i = 0; i < 4; i++) + { + dwirqs |= ((uint32_t)regval[i]) << (8 * (3 - i)); + } + + return ((dwirqs & flag) != 0); +} diff --git a/drivers/wireless/spirit/lib/spirit_management.c b/drivers/wireless/spirit/lib/spirit_management.c new file mode 100644 index 0000000000..a4b130921d --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_management.c @@ -0,0 +1,89 @@ +/****************************************************************************** + * drivers/wireless/spirit/lib/spirit_management.c + * The management layer for SPIRIT1 library. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include "spirit_management.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +#define COMMUNICATION_STATE_TX 0 +#define COMMUNICATION_STATE_RX 1 +#define COMMUNICATION_STATE_NONE 2 + +/****************************************************************************** + * Private Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * + * Parameters: + * + * Returned Value: + * + ******************************************************************************/ + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_management_initcommstate + * + * Description: + * Initialize communication state + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * frequency - Desired communication frequency + * + * Returned Value: + * + ******************************************************************************/ + +void spirit_management_initcommstate(FAR struct spirit_library_s *spirit, + uint32_t frequency) +{ + spirit->commstate = COMMUNICATION_STATE_NONE; + spirit->commfrequency = frequency; +} diff --git a/drivers/wireless/spirit/lib/spirit_pktbasic.c b/drivers/wireless/spirit/lib/spirit_pktbasic.c new file mode 100644 index 0000000000..e6a58c3a8f --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_pktbasic.c @@ -0,0 +1,92 @@ +/****************************************************************************** + * drivers/wireless/spirit/lib/spirit_pktbasic.c + * Configuration and management of SPIRIT Basic packets. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include + +#include "spirit_pktbasic.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/****************************************************************************** + * Private Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * + * Parameters: + * + * Returned Value: + * + ******************************************************************************/ + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_pktbasic_initialize + * + * Description: + * Initializes the Spirit Basic packet according to the specified parameters + * in the struct pktbasic_init_s. Notice that this function sets the + * autofiltering option on CRC if it is set to any value different from + * BASIC_NO_CRC. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * pktpasic - Basic packet init structure. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_pktbasic_initialize(FAR struct spirit_library_s *spirit, + FAR const struct pktbasic_init_s *pktpasic) +{ +#warning Missing logic + return -ENOSYS; +} \ No newline at end of file diff --git a/drivers/wireless/spirit/lib/spirit_qi.c b/drivers/wireless/spirit/lib/spirit_qi.c new file mode 100644 index 0000000000..8adaff0a4e --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_qi.c @@ -0,0 +1,224 @@ +/****************************************************************************** + * drivers/wireless/spirit/lib/spirit_qi.c + * Configuration and management of SPIRIT QI. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include + +#include "spirit_qi.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/****************************************************************************** + * Private Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * + * Parameters: + * + * Returned Value: + * + ******************************************************************************/ + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_qi_sqicheck + * + * Description: + * Enables/Disables the Synchronization Quality Indicator check. The + * running peak SQI is compared to a threshold value and the sync valid + * IRQ is asserted as soon as the threshold is passed. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - new state for SQI check. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_qi_sqicheck(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); + + /* Reads the QI register value */ + + ret = spirit_reg_read(spirit, QI_BASE, ®val, 1); + if (ret >= 0) + { + /* Enables or disables the SQI Check bit on the QI_BASE register */ + + if (newstate == S_ENABLE) + { + regval |= QI_SQI_MASK; + } + else + { + regval &= ~QI_SQI_MASK; + } + + /* Write the value to the QI register */ + + ret = spirit_reg_write(spirit, QI_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_qi_set_sqithreshold + * + * Description: + * Sets the SQI threshold. The synchronization quality threshold is equal to + * 8 * SYNC_LEN - 2 * SQI_TH with SQI_TH = 0..3. When SQI_TH is 0 perfect + * match is required; when SQI_TH = 1, 2, 3 then 1, 2, or 3 bit errors are + * respectively accepted. It is recommended that the SQI check is always + * enabled. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * sqithr - parameter of the formula above. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_qi_set_sqithreshold(FAR struct spirit_library_s *spirit, + enum spirit_sqi_threshold_e sqithr) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SQI_THR(sqithr)); + + /* Reads the QI register value */ + + ret = spirit_reg_read(spirit, QI_BASE, ®val, 1); + if (ret >= 0) + { + /* Build the SQI threshold value to be written */ + + regval &= 0x3f; + regval |= (uint8_t)sqithr; + + /* Write the new value to the QI register */ + + ret = spirit_reg_write(spirit, QI_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_qi_get_sqithreshold + * + * Description: + * Returns the SQI threshold. The synchronization quality threshold is equal + * to 8 * SYNC_LEN - 2 * SQI_TH with SQI_TH = 0..3. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * SQI threshold (SQI_TH of the formula above). Errors are not reported. + * + ******************************************************************************/ + +enum spirit_sqi_threshold_e + spirit_qi_get_sqithreshold(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Read the QI register value */ + + (void)spirit_reg_read(spirit, QI_BASE, ®val, 1); + + /* Return the SQI threshold value */ + + return (enum spirit_sqi_threshold_e)(regval & 0xc0); +} + +/****************************************************************************** + * Name: spirit_qi_set_rssithreshold + * + * Description: + * Sets the RSSI threshold from its dBm value according to the formula: + * (RSSI[Dbm] + 130)/0.5. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * dbmvalue - RSSI threshold reported in dBm. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_qi_set_rssithreshold(FAR struct spirit_library_s *spirit, + int dbmvalue) +{ + uint8_t regval = 2 * (dbmvalue + 130); + + /* Check the parameters */ + + DEBUGASSERT(IS_RSSI_THR_DBM(dbmvalue)); + + /* Writes the new value on the RSSI_TH register */ + + return spirit_reg_write(spirit, RSSI_TH_BASE, ®val, 1); +} diff --git a/drivers/wireless/spirit/lib/spirit_radio.c b/drivers/wireless/spirit/lib/spirit_radio.c new file mode 100644 index 0000000000..e5267305d0 --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_radio.c @@ -0,0 +1,1449 @@ +/****************************************************************************** + * drivers/wireless/spirit/lib/spirit_radio.c + * This file provides all the low level API to manage Analog and Digital radio + * part of SPIRIT. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include +#include +#include +#include +#include + +#include "spirit_config.h" +#include "spirit_types.h" +#include "spirit_management.h" +#include "spirit_radio.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +#define XTAL_FLAG(xtalFrequency) \ + (xtalFrequency >= 25e6) ? XTAL_FLAG_26_MHz : XTAL_FLAG_24_MHz +#define ROUND(a) \ + (((a - (uint32_t)a) > 0.5) ? (uint32_t)a + 1 : (uint32_t)a) + +/* Returns the absolute value. */ + +#define S_ABS(a) ((a) > 0 ? (a) : -(a)) + +/****************************************************************************** + * Private Data + ******************************************************************************/ + +/* Factor is: B/2 used in the formula for SYNTH word calculation */ + +static const uint8_t g_vectc_bhalf[4] = +{ + (HIGH_BAND_FACTOR / 2), + (MIDDLE_BAND_FACTOR / 2), + (LOW_BAND_FACTOR / 2), + (VERY_LOW_BAND_FACTOR / 2) +}; + +/* BS value to write in the SYNT0 register according to the selected band */ + +static const uint8_t g_vectc_bandval[4] = +{ + SYNT0_BS_6, SYNT0_BS_12, SYNT0_BS_16, SYNT0_BS_32 +}; + +/* It represents the available channel bandwidth times 10 for 26 Mhz xtal. + * NOTE: The channel bandwidth for others xtal frequencies can be computed + * since this table multiplying the current table by a factor + * xtal_frequency/26e6. + */ + +static const uint16_t g_vectn_bandwidth[90] = +{ + 8001, 7951, 7684, 7368, 7051, 6709, 6423, 5867, 5414, + 4509, 4259, 4032, 3808, 3621, 3417, 3254, 2945, 2703, + 2247, 2124, 2015, 1900, 1807, 1706, 1624, 1471, 1350, + 1123, 1062, 1005, 950, 903, 853, 812, 735, 675, + 561, 530, 502, 474, 451, 426, 406, 367, 337, + 280, 265, 251, 237, 226, 213, 203, 184, 169, + 140, 133, 126, 119, 113, 106, 101, 92, 84, + 70, 66, 63, 59, 56, 53, 51, 46, 42, + 35, 33, 31, 30, 28, 27, 25, 23, 21, + 18, 17, 16, 15, 14, 13, 13, 12, 11 +}; + +/* These values are used to interpolate the power curves. Interpolation + * curves are linear in the following 3 regions: + * + * - reg value: 1 to 13 (up region) + * - reg value: 13 to 40 (mid region) + * - reg value: 41 to 90 (low region) + * + * power_reg = m*power_dBm + q + * + * For each band the order is: {m-up, q-up, m-mid, q-mid, m-low, q-low}. + * + * NOTE: The power interpolation curves have been extracted by + * measurements done on the divisional evaluation boards. + */ + +static const float g_power_factors[5][6] = +{ + {-2.11, 25.66, -2.11, 25.66, -2.00, 31.28}, /* 915 */ + {-2.04, 23.45, -2.04, 23.45, -1.95, 27.66}, /* 868 */ + {-3.48, 38.45, -1.89, 27.66, -1.92, 30.23}, /* 433 */ + {-3.27, 35.43, -1.80, 26.31, -1.89, 29.61}, /* 315 */ + {-4.18, 50.66, -1.80, 30.04, -1.86, 32.22}, /* 169 */ +}; + +/****************************************************************************** + * Private Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * + * Parameters: + * + * Returned Value: + * + ******************************************************************************/ + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_radio_initialize + * + * Description: + * Initializes the SPIRIT analog and digital radio part according to the + * specified parameters in the radioinit. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * radioinit - Pointer to a struct radio_init_s that contains the + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_initialize(FAR struct spirit_library_s *spirit, + FAR const struct radio_init_s *radioinit) +{ + float ifoff; + int32_t offset; + int16_t fcoffset; + uint8_t anaoffset; + uint8_t digregs[4]; + uint8_t anaregs[8]; + uint8_t drm; + uint8_t dre; + uint8_t fdevm; + uint8_t fdeve; + uint8_t bwm; + uint8_t bwe; + uint8_t regval; + uint8_t value; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_FREQUENCY_BAND(radioinit->base_frequency)); + DEBUGASSERT(IS_MODULATION_SELECTED(radioinit->modselect)); + DEBUGASSERT(IS_DATARATE(radioinit->datarate)); + DEBUGASSERT(IS_FREQUENCY_OFFSET(offset, spirit->xtal_frequency)); + DEBUGASSERT(IS_CHANNEL_SPACE + (radioinit->chspace, spirit->xtal_frequency)); + DEBUGASSERT(IS_F_DEV(radioinit->freqdev, spirit->xtal_frequency)); + + /* Workaround for Vtune */ + + value = 0xa0; + ret = spirit_reg_write(spirit, 0x9F, &value, 1); + if (ret < 0) + { + return ret; + } + + /* Calculates the offset respect to RF frequency and according to xtal_ppm + * parameter: (xtal_ppm*FBase)/10^6 + */ + + offset = (int32_t)(((float)radioinit->xtal_offset_ppm * + radioinit->base_frequency) / PPM_FACTOR); + + /* Disable the digital, ADC, SMPS reference clock divider if fXO > 24MHz or + * fXO < 26MHz + */ + + ret = spirit_command(spirit, COMMAND_STANDBY); + if (ret < 0) + { + return ret; + } + + do + { + volatile uint8_t i; + + /* Delay for state transition */ + + for (i = 0; i != 0xff; i++); + + /* Reads the MC_STATUS register */ + + ret = spirit_update_status(spirit); + if (ret < 0) + { + return ret; + } + } + while (spirit->u.state.MC_STATE != MC_STATE_STANDBY); + + if (spirit->xtal_frequency < DOUBLE_XTAL_THR) + { + ret = spirit_radio_enable_digdivider(spirit, S_DISABLE); + DEBUGASSERT(IS_CH_BW(radioinit->bandwidth, spirit->xtal_frequency)); + } + else + { + ret = spirit_radio_enable_digdivider(spirit, S_ENABLE); + DEBUGASSERT(IS_CH_BW(radioinit->bandwidth, (spirit->xtal_frequency >> 1))); + } + + if (ret < 0) + { + return ret; + } + + /* Go to READY state */ + + ret = spirit_command(spirit, COMMAND_READY); + if (ret < 0) + { + return ret; + } + + do + { + volatile uint8_t i; + + /* Delay for state transition */ + + for (i = 0; i != 0xff; i++); + + /* Reads the MC_STATUS register */ + + ret = spirit_update_status(spirit); + if (ret < 0) + { + return ret; + } + } + while (spirit->u.state.MC_STATE != MC_STATE_READY); + + /* Calculates the FC_OFFSET parameter and cast as signed int: offset = + * (Fxtal/2^18)*FC_OFFSET + */ + + fcoffset = (int16_t)(((float)offset * FBASE_DIVIDER) / + spirit->xtal_frequency); + anaregs[2] = (uint8_t)((((uint16_t)fcoffset) >> 8) & 0x0f); + anaregs[3] = (uint8_t)fcoffset; + + /* Calculates the channel space factor */ + + anaregs[0] = ((uint32_t)radioinit->chspace << 9) / + (spirit->xtal_frequency >> 6) + 1; + + spirit_management_initcommstate(spirit, radioinit->base_frequency); + + /* 2nd order DEM algorithm enabling */ + + ret = spirit_reg_read(spirit, 0xa3, ®val, 1); + if (ret < 0) + { + return ret; + } + + regval &= ~0x02; + ret = spirit_reg_write(spirit, 0xa3, ®val, 1); + if (ret < 0) + { + return ret; + } + + /* Check the channel center frequency is in one of the possible range */ + + DEBUGASSERT(IS_FREQUENCY_BAND((radioinit->base_frequency + + ((fcoffset * spirit->xtal_frequency) / FBASE_DIVIDER) + + radioinit->chspace * radioinit->chnum))); + + /* Calculates the datarate mantissa and exponent */ + + ret = spirit_radio_convert_datarate(spirit, radioinit->datarate, + &drm, &dre); + if (ret < 0) + { + return ret; + } + + digregs[0] = (uint8_t)(drm); + digregs[1] = (uint8_t)(radioinit->modselect | dre); + + /* Read the fdev register to preserve the clock recovery algo bit */ + + ret = spirit_reg_read(spirit, 0x1c, ®val, 1); + if (ret < 0) + { + return ret; + } + + /* Calculates the frequency deviation mantissa and exponent */ + + ret = spirit_radio_convert_freqdev(spirit, radioinit->freqdev, + &fdevm, &fdeve); + if (ret < 0) + { + return ret; + } + + digregs[2] = (uint8_t)((fdeve << 4) | (regval & 0x08) | fdevm); + + /* Calculates the channel filter mantissa and exponent */ + + ret = spirit_radio_convert_chbandwidth(spirit, radioinit->bandwidth, &bwm, &bwe); + if (ret < 0) + { + return ret; + } + + digregs[3] = (uint8_t) ((bwm << 4) | bwe); + + ifoff = (3.0 * 480140) / (spirit->xtal_frequency >> 12) - 64; + anaoffset = ROUND(ifoff); + + if (spirit->xtal_frequency < DOUBLE_XTAL_THR) + { + /* if offset digital is the same in case of single xtal */ + + anaregs[1] = anaoffset; + } + else + { + ifoff = (3.0 * 480140) / (spirit->xtal_frequency >> 13) - 64; + + /* ... otherwise recompute it */ + + anaregs[1] = ROUND(ifoff); + } + +#if 0 + if (spirit->xtal_frequency == 24000000) + { + anaoffset = 0xb6; + anaregs[1] = 0xb6; + } + + if (spirit->xtal_frequency == 25000000) + { + anaoffset = 0xac; + anaregs[1] = 0xac; + } + + if (spirit->xtal_frequency == 26000000) + { + anaoffset = 0xa3; + anaregs[1] = 0xa3; + } + + if (spirit->xtal_frequency == 48000000) + { + anaoffset = 0x3b; + anaregs[1] = 0xb6; + } + + if (spirit->xtal_frequency == 50000000) + { + anaoffset = 0x36; + anaregs[1] = 0xac; + } + + if (spirit->xtal_frequency == 52000000) + { + anaoffset = 0x31; + anaregs[1] = 0xa3; + } +#endif + + ret = spirit_reg_write(spirit, IF_OFFSET_ANA_BASE, &anaoffset, 1); + if (ret < 0) + { + return ret; + } + + /* Set Xtal configuration */ + + if (spirit->xtal_frequency > DOUBLE_XTAL_THR) + { + enum xtal_flag_e xtlflag = XTAL_FLAG((spirit->xtal_frequency / 2)); + ret = spirit_radio_set_xtalflag(spirit, xtlflag); + } + else + { + enum xtal_flag_e xtlflag = XTAL_FLAG(spirit->xtal_frequency); + ret = spirit_radio_set_xtalflag(spirit, xtlflag); + } + + if (ret < 0) + { + return ret; + } + + /* Sets the channel number in the corresponding register */ + + ret = spirit_reg_write(spirit, CHNUM_BASE, &radioinit->chnum, 1); + if (ret < 0) + { + return ret; + } + + /* Configures the Analog Radio registers */ + + ret = spirit_reg_write(spirit, CHSPACE_BASE, anaregs, 4); + if (ret < 0) + { + return ret; + } + + /* Configures the Digital Radio registers */ + + ret = spirit_reg_write(spirit, MOD1_BASE, digregs, 4); + if (ret < 0) + { + return ret; + } + + /* Enable the freeze option of the AFC on the SYNC word */ + + ret = spirit_radio_afcfreezeonsync(spirit, S_ENABLE); + if (ret < 0) + { + return ret; + } + + /* Set the IQC correction optimal value */ + + anaregs[0] = 0x80; + anaregs[1] = 0xe3; + + ret = spirit_reg_write(spirit, 0x99, anaregs, 2); + if (ret < 0) + { + return ret; + } + + return spirit_radio_set_basefrequency(spirit, radioinit->base_frequency); +} + +/****************************************************************************** + * Name: spirit_radio_set_xtalflag + * + * Description: + * Sets the Xtal configuration in the ANA_FUNC_CONF0 register. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * xtalflag one of the possible value of the enum type xtal_flag_e. + * XTAL_FLAG_24_MHz: in case of 24 MHz crystal + * XTAL_FLAG_26_MHz: in case of 26 MHz crystal + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_set_xtalflag(FAR struct spirit_library_s *spirit, + enum xtal_flag_e xtalflag) +{ + uint8_t regval = 0; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_XTAL_FLAG(xtalflag)); + + /* Reads the ANA_FUNC_CONF_0 register */ + + ret = spirit_reg_read(spirit, ANA_FUNC_CONF0_BASE, ®val, 1); + if (ret >= 0) + { + if (xtalflag == XTAL_FLAG_26_MHz) + { + regval |= SELECT_24_26_MHZ_MASK; + } + else + { + regval &= (~SELECT_24_26_MHZ_MASK); + } + + /* Sets the 24_26MHz_SELECT field in the ANA_FUNC_CONF_0 register */ + + ret = spirit_reg_write(spirit, ANA_FUNC_CONF0_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_get_xtalflag + * + * Description: + * Returns the Xtal configuration in the ANA_FUNC_CONF0 register. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * XtalFrequency Settled Xtal configuration. + * + ******************************************************************************/ + +enum xtal_flag_e spirit_radio_get_xtalflag(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the Xtal configuration in the ANA_FUNC_CONF_0 register and return + * the value. + */ + + (void)spirit_reg_read(spirit, ANA_FUNC_CONF0_BASE, ®val, 1); + + return (enum xtal_flag_e)((regval & 0x40) >> 6); +} + +/****************************************************************************** + * Name: spirit_radio_get_synthword + * + * Description: + * Returns the synth word. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * 32-bit Synth word. Errors are not reported. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_synthword(FAR struct spirit_library_s *spirit) +{ + uint8_t regvalues[4]; + + /* Reads the SYNTH registers, build the synth word and return it */ + + (void)spirit_reg_read(spirit, SYNT3_BASE, regvalues, 4); + return ((((uint32_t) (regvalues[0] & 0x1f)) << 21) + + (((uint32_t) (regvalues[1])) << 13) + + (((uint32_t) (regvalues[2])) << 5) + + (((uint32_t) (regvalues[3])) >> 3)); +} + +/****************************************************************************** + * Name: spirit_radio_set_synthword + * + * Description: + * Sets the SYNTH registers. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * synthword - The synth word to write in the SYNTH[3:0] registers. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_set_synthword(FAR struct spirit_library_s *spirit, + uint32_t synthword) +{ + uint8_t regvalues[4]; + uint8_t synt0; + int ret; + + /* Reads the SYNT0 register */ + + ret = spirit_reg_read(spirit, SYNT0_BASE, &synt0, 1); + if (ret < 0) + { + return ret; + } + + /* Mask the Band selected field */ + + synt0 &= 0x07; + + /* Build the array for SYNTH registers */ + + regvalues[0] = (uint8_t)((synthword >> 21) & (0x0000001f)); + regvalues[1] = (uint8_t)((synthword >> 13) & (0x000000ff)); + regvalues[2] = (uint8_t)((synthword >> 5) & (0x000000ff)); + regvalues[3] = (uint8_t)(((synthword & 0x0000001f) << 3) | synt0); + + /* Write the synth word to the SYNTH registers */ + + ret = spirit_reg_write(spirit, SYNT3_BASE, regvalues, 4); + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_set_band + * + * Description: + * Sets the operating band. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * band - The band to set. This parameter can be one of following values: + * HIGH_BAND High_Band selected: from 779 MHz to 915 MHz + * MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz + * LOW_BAND: Low Band selected: from 300 MHz to 348 MHz + * VERY_LOW_BAND: Very low Band selected: from 150 MHz to 174 MHz + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_set_band(FAR struct spirit_library_s *spirit, + enum spirit_bandselect_e band) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_BAND_SELECTED(band)); + + /* Reads the SYNT0 register */ + + ret = spirit_reg_read(spirit, SYNT0_BASE, ®val, 1); + if (ret >= 0) + { + /* Mask the SYNTH[4;0] field and write the BS value */ + + regval &= 0xf8; + regval |= g_vectc_bandval[band]; + + /* Configures the SYNT0 register setting the operating band */ + + ret = spirit_reg_write(spirit, SYNT0_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_get_band + * + * Description: + * Returns the operating band. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * BandSelect Settled band. This returned value may be one of the + * following values: + * HIGH_BAND High_Band selected: from 779 MHz to 915 MHz + * MIDDLE_BAND: Middle Band selected: from 387 MHz to 470 MHz + * LOW_BAND: Low Band selected: from 300 MHz to 348 MHz + * VERY_LOW_BAND: Very low Band selected: from 150 MHz to 174 MHz + * + ******************************************************************************/ + +enum spirit_bandselect_e + spirit_radio_get_band(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + /* Reads the SYNT0 register */ + + (void)spirit_reg_read(spirit, SYNT0_BASE, ®val, 1); + + /* Mask the Band selected field */ + + if ((regval & 0x07) == SYNT0_BS_6) + { + return HIGH_BAND; + } + else if ((regval & 0x07) == SYNT0_BS_12) + { + return MIDDLE_BAND; + } + else if ((regval & 0x07) == SYNT0_BS_16) + { + return LOW_BAND; + } + else + { + return VERY_LOW_BAND; + } +} + +/****************************************************************************** + * Name: spirit_radio_set_basefrequency + * + * Description: + * Sets the Synth word and the Band Select register according to desired + * base carrier frequency. In this API the Xtal configuration is read out + * from the corresponding register. The user shall fix it before call this + * API. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fbase - The base carrier frequency expressed in Hz as unsigned word. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_set_basefrequency(FAR struct spirit_library_s *spirit, + uint32_t fbase) +{ +#warning Missing logic + return -ENOSYS; +} + +/****************************************************************************** + * Name: spirit_radio_get_basefrequency + * + * Description: + * Returns the base carrier frequency. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * Base carrier frequency expressed in Hz as unsigned word. + * + ******************************************************************************/ + +uint32_t spirit_radio_get_basefrequency(FAR struct spirit_library_s *spirit) +{ + enum spirit_bandselect_e band; + uint32_t synthword; + uint8_t refdiv; + + /* Read the synth word */ + + synthword = spirit_radio_get_synthword(spirit); + + /* Read the operating band */ + + band = spirit_radio_get_band(spirit); + + refdiv = (uint8_t)spirit_radio_get_refdiv(spirit) + 1; + + /* Calculates the frequency base and return it */ + + return (uint32_t) round(synthword * (((double)spirit->xtal_frequency) / + (FBASE_DIVIDER * refdiv * + g_vectc_bhalf[band]))); +} + +/****************************************************************************** + * Name: spirit_radio_convert_datarate + * + * Description: + * Returns the mantissa and exponent, whose value used in the datarate + * formula will give the datarate value closer to the given datarate. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * datarate - datarate expressed in bps. This parameter ranging between 100 and 500000. + * pcm - pointer to the returned mantissa value. + * pce - pointer to the returned exponent value. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_convert_datarate(FAR struct spirit_library_s *spirit, + uint32_t datarate, FAR uint8_t *pcm, + FAR uint8_t *pce) +{ + int16_t intermediate[3]; + uint16_t delta; + uint8_t mantissa; + uint8_t divider = 0; + int8_t i = 15; + uint8_t j; + volatile bool find = false; + + /* Check the parameters */ + + DEBUGASSERT(IS_DATARATE(datarate)); + + divider = (uint8_t)spirit_radio_isenabled_digdivider(spirit); + + /* Search in the datarate array the exponent value */ + + while (!find && i >= 0) + { + if (datarate >= (spirit->xtal_frequency >> (20 - i + divider))) + { + find = true; + } + else + { + i--; + } + } + + i < 0 ? i = 0 : i; + *pce = i; + + /* Calculates the mantissa value according to the datarate formula */ + + mantissa = (datarate * ((uint32_t)1 << (23 - i))) / + (spirit->xtal_frequency >> (5 + divider)) - 256; + + /* Finds the mantissa value with less approximation */ + + for (j = 0; j < 3; j++) + { + if ((mantissa + j - 1)) + { + intermediate[j] = datarate - (((256 + mantissa + j - 1) * + (spirit->xtal_frequency >> (5 + divider))) >> + (23 - i)); + } + else + { + intermediate[j] = 0x7fff; + } + } + + delta = 0xffff; + for (j = 0; j < 3; j++) + { + if (S_ABS(intermediate[j]) < delta) + { + delta = S_ABS(intermediate[j]); + *pcm = mantissa + j - 1; + } + } + + return OK; +} + +/****************************************************************************** + * Name: spirit_radio_convert_freqdev + * + * Description: + * Returns the mantissa and exponent, whose value used in the frequency + * deviation formula will give a frequency deviation value most closer to + * the given frequency deviation. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fdev - Frequency deviation expressed in Hz. This parameter can be a + * value in the range [F_Xo*8/2^18, F_Xo*7680/2^18]. + * pcm - pointer to the returned mantissa value. + * pce - pointer to the returned exponent value. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_convert_freqdev(FAR struct spirit_library_s *spirit, + uint32_t fdev, FAR uint8_t *pcm, + FAR uint8_t *pce) +{ + uint32_t a; + uint32_t bp; + uint32_t b = 0; + uint8_t i; + float xtalDivtmp = (float)spirit->xtal_frequency / (((uint32_t) 1) << 18); + + /* Check the parameters */ + + DEBUGASSERT(IS_F_DEV(fdev, spirit->xtal_frequency)); + + for (i = 0; i < 10; i++) + { + a = (uint32_t) (xtalDivtmp * (uint32_t) (7.5 * (1 << i))); + if (fdev < a) + { + break; + } + } + + *pce = i; + + for (i = 0; i < 8; i++) + { + bp = b; + b = (uint32_t)(xtalDivtmp * (uint32_t)((8.0 + i) / 2 * (1 << (*pce)))); + if (fdev < b) + { + break; + } + } + + if ((fdev - bp) < (b - fdev)) + { + i--; + } + + *pcm = i; + return OK; +} + +/****************************************************************************** + * Name: + * + * Description: + * Returns the mantissa and exponent for a given bandwidth. Even if it is + * possible to pass as parameter any value in the below mentioned range, the + * API will search the closer value according to a fixed table of channel + * bandwidth values (@ref s_vectnBandwidth), as defined in the datasheet, + * returning the corresponding mantissa and exponent value. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * bandwidth - bandwidth expressed in Hz. This parameter ranging between + * 1100 and 800100. + * pcm - pointer to the returned mantissa value. + * pce - pointer to the returned exponent value. + * + * Returned Value: + * Error code: 0=no error, <0=error during calibration of VCO. + * + ******************************************************************************/ + +int spirit_radio_convert_chbandwidth(FAR struct spirit_library_s *spirit, + uint32_t bandwidth, FAR uint8_t *pcm, + FAR uint8_t *pce) +{ + uint32_t chfltfactor; + int16_t intermediate[3]; + uint16_t delta; + uint8_t divider = 1; + int8_t tmp; + int8_t i; + int8_t j; + + /* Search in the channel filter bandwidth table the exponent value */ + + if (spirit_radio_isenabled_digdivider(spirit) != S_DISABLE) + { + divider = 2; + } + else + { + divider = 1; + } + + DEBUGASSERT(IS_CH_BW(bandwidth, spirit->xtal_frequency / divider)); + + chfltfactor = (spirit->xtal_frequency / divider) / 100; + + for (i = 0; + i < 90 && (bandwidth < (uint32_t)((g_vectn_bandwidth[i] * + chfltfactor) / 2600)); + i++); + + if (i != 0) + { + /* Finds the mantissa value with less approximation */ + + tmp = i; + for (j = 0; j < 3; j++) + { + if (((tmp + j - 1) >= 0) || ((tmp + j - 1) <= 89)) + { + intermediate[j] = bandwidth - + (uint32_t)((g_vectn_bandwidth[tmp + j - 1] * + chfltfactor) / 2600); + } + else + { + intermediate[j] = 0x7fff; + } + } + + delta = 0xFFFF; + + for (j = 0; j < 3; j++) + { + if (S_ABS(intermediate[j]) < delta) + { + delta = S_ABS(intermediate[j]); + i = tmp + j - 1; + } + } + } + + *pce = (uint8_t)(i / 9); + *pcm = (uint8_t)(i % 9); + return OK; +} + +/****************************************************************************** + * Name: spirit_radio_dbm2reg + * + * Description: + * Returns the PA register value that corresponds to the passed dBm power. + * + * NOTE: The power interpolation curves used by this function have been + * extracted by measurements done on the divisional evaluation boards. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * fbase Frequency base expressed in Hz. + * powerdbm Desired power in dBm. + * + * Returned Value: + * Register value as byte. + * + ******************************************************************************/ + +uint8_t spirit_radio_dbm2reg(FAR struct spirit_library_s *spirit, + uint32_t fbase, float powerdbm) +{ + float pavalue; + uint8_t i = 0; + uint8_t j = 0; + + if (IS_FREQUENCY_BAND_HIGH(fbase)) + { + i = 0; + if (fbase < 900000000) + { + i = 1; /* 868 */ + } + } + else if (IS_FREQUENCY_BAND_MIDDLE(fbase)) + { + i = 2; + } + else if (IS_FREQUENCY_BAND_LOW(fbase)) + { + i = 3; + } + else if (IS_FREQUENCY_BAND_VERY_LOW(fbase)) + { + i = 4; + } + + j = 1; + if (powerdbm > 0 && + 13.0 / g_power_factors[i][2] - g_power_factors[i][3] / + g_power_factors[i][2] < powerdbm) + { + j = 0; + } + else if (powerdbm <= 0 && + 40.0 / g_power_factors[i][2] - g_power_factors[i][3] / + g_power_factors[i][2] > powerdbm) + { + j = 2; + } + + pavalue = g_power_factors[i][2 * j] * powerdbm + + g_power_factors[i][2 * j + 1]; + + if (pavalue < 1) + { + pavalue = 1; + } + else if (pavalue > 90) + { + pavalue = 90; + } + + return (uint8_t)pavalue; +} + +/****************************************************************************** + * Name: spirit_radio_set_palevel + * + * Description: + * Sets a specific PA_LEVEL register, with a value given in dBm. + * + * NOTE: This function makes use of the @ref spirit_radio_dbm2reg fcn to + * interpolate the power value. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * ndx - PA_LEVEL to set. This parameter shall be in the range [0:7]. + * powerdbm - PA value to write expressed in dBm . Be sure that this values + * is in the correct range [-PA_LOWER_LIMIT: PA_UPPER_LIMIT] dBm. + * + * Returned Value: + * None. + * + ******************************************************************************/ + +int spirit_radio_set_palevel(FAR struct spirit_library_s *spirit, + uint8_t ndx, float powerdbm) +{ + uint32_t basefrequency; + uint8_t address; + uint8_t level; + + /* Check the parameters */ + + DEBUGASSERT(IS_PA_MAX_INDEX(ndx)); + DEBUGASSERT(IS_PAPOWER_DBM(powerdbm)); + + /* Interpolate the power level */ + + basefrequency = spirit_radio_get_basefrequency(spirit); + level = spirit_radio_dbm2reg(spirit, basefrequency, powerdbm); + + /* Sets the base address */ + + address = PA_POWER8_BASE + 7 - ndx; + + /* Configures the PA_LEVEL register */ + + return spirit_reg_write(spirit, address, &level, 1); +} + +/****************************************************************************** + * Name: spirit_radio_set_palevel_maxindex + * + * Description: + * Sets a specific PA_LEVEL_MAX_INDEX. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * ndx - PA_LEVEL_MAX_INDEX to set. This parameter must be in the range + * [0:7]. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_set_palevel_maxindex(FAR struct spirit_library_s *spirit, + uint8_t ndx) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_PA_MAX_INDEX(ndx)); + + /* Reads the PA_POWER_0 register */ + + ret = spirit_reg_read(spirit, PA_POWER0_BASE, ®val, 1); + if (ret >= 0) + { + /* Mask the PA_LEVEL_MAX_INDEX[1:0] field and write the new value */ + + regval &= 0xf8; + regval |= ndx; + + /* Configures the PA_POWER_0 register */ + + ret = spirit_reg_write(spirit, PA_POWER0_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_afcfreezeonsync + * + * Description: + * Enables or Disables the AFC freeze on sync word detection. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - new state for AFC freeze on sync word detection. + * This parameter can be: S_ENABLE or S_DISABLE. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_afcfreezeonsync(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate) +{ + uint8_t regval = 0; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); + + /* Reads the AFC_2 register and configure the AFC Freeze on Sync field */ + + ret = spirit_reg_read(spirit, AFC2_BASE, ®val, 1); + if (ret >= 0) + { + if (newstate == S_ENABLE) + { + regval |= AFC2_AFC_FREEZE_ON_SYNC_MASK; + } + else + { + regval &= (~AFC2_AFC_FREEZE_ON_SYNC_MASK); + } + + /* Sets the AFC_2 register */ + + ret = spirit_reg_write(spirit, AFC2_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_persistentrx + * + * Description: + * Enables or Disables the persistent RX mode. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state of this mode. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_persistentrx(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate) +{ + uint8_t regval = 0; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); + + /* Reads the PROTOCOL0_BASE and mask the PROTOCOL0_PERS_RX_MASK bitfield */ + + ret = spirit_reg_read(spirit, PROTOCOL0_BASE, ®val, 1); + if (ret >= 0) + { + if (newstate == S_ENABLE) + { + regval |= PROTOCOL0_PERS_RX_MASK; + } + else + { + regval &= (~PROTOCOL0_PERS_RX_MASK); + } + + /* Writes the new value in the PROTOCOL0_BASE register */ + + ret = spirit_reg_write(spirit, PROTOCOL0_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_set_refdiv + * + * Description: + * Enables or Disables the synthesizer reference divider. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate new state for synthesizer reference divider. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_set_refdiv(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); + + /* Reads the SYNTH_CONFIG1_BASE and mask the REFDIV bit field */ + + ret = spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1); + if (ret >= 0) + { + if (newstate == S_ENABLE) + { + regval |= 0x80; + } + else + { + regval &= 0x7f; + } + + /* Writes the new value in the SYNTH_CONFIG1_BASE register */ + + ret = spirit_reg_write(spirit, SYNTH_CONFIG1_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_get_refdiv + * + * Description: + * Get the the synthesizer reference divider state. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * S_ENABLE or S_DISABLE. Errors are not reported. + * + ******************************************************************************/ + +enum spirit_functional_state_e + spirit_radio_get_refdiv(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + (void)spirit_reg_read(spirit, SYNTH_CONFIG1_BASE, ®val, 1); + + if (((regval >> 7) & 0x1) != 0) + { + return S_ENABLE; + } + else + { + return S_DISABLE; + } +} + +/****************************************************************************** + * Name: spirit_radio_enable_digdivider + * + * Description: + * Enables or Disables the synthesizer reference divider. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * newstate - New state for synthesizer reference divider. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_radio_enable_digdivider(FAR struct spirit_library_s *spirit, + enum spirit_functional_state_e newstate) +{ + uint8_t regval; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_SPIRIT_FUNCTIONAL_STATE(newstate)); + + /* Reads the XO_RCO_TEST_BASE and mask the PD_CLKDIV bit field */ + + ret = spirit_reg_read(spirit, XO_RCO_TEST_BASE, ®val, 1); + if (ret > 0) + { + if (newstate == S_ENABLE) + { + regval &= 0xf7; + } + else + { + regval |= 0x08; + } + + /* Write the new value to the XO_RCO_TEST_BASE register */ + + ret = spirit_reg_write(spirit, XO_RCO_TEST_BASE, ®val, 1); + } + + return ret; +} + +/****************************************************************************** + * Name: spirit_radio_isenabled_digdivider + * + * Description: + * Get the the synthesizer reference divider state. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * + * Returned Value: + * S_ENABLE or S_DISABLE. Error conditions are not detected. + * + ******************************************************************************/ + +enum spirit_functional_state_e + spirit_radio_isenabled_digdivider(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + (void)spirit_reg_read(spirit, XO_RCO_TEST_BASE, ®val, 1); + + if (((regval >> 3) & 0x1) != 0) + { + return S_DISABLE; + } + else + { + return S_ENABLE; + } +} diff --git a/drivers/wireless/spirit/lib/spirit_spi.c b/drivers/wireless/spirit/lib/spirit_spi.c new file mode 100644 index 0000000000..079210e5d5 --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_spi.c @@ -0,0 +1,421 @@ +/****************************************************************************** + * drivers/wireless/spirit/lib//spirit_spi.c + * NuttX SPIRIT SPI driver interface. + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * + * Derives loosely from simlilarly licensed, platform-specific, example + * implementations from STMicro: + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include + +#include + +#include "spirit_regs.h" +#include "spirit_types.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +#ifndef CONFIG_WL_SPIRIT_SPIFREQUENCY +# define CONFIG_WL_SPIRIT_SPIFREQUENCY (10000000) +#endif + +/****************************************************************************** + * Private Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_lock + * + * Description: + * Lock the SPI bus before each transfer, setting the correct SPI + * characteristics for the Spirit device. These must be set if there are + * multiple devices on the bus because while the bus was unlocked, another + * device may have re-configured the SPIO. + * + * Parameters: + * spi - Reference to the SPI driver structure + * + * Returned Value: + * None + * + * Assumptions: + * + ******************************************************************************/ + +static void spirit_lock(FAR struct spi_dev_s *spi) +{ + /* Lock the SPI bus because there are multiple devices competing for the + * SPI bus + */ + + (void)SPI_LOCK(spi, true); + + /* We have the lock. Now make sure that the SPI bus is configured for the + * Spirit (it might have gotten configured for a different device while + * unlocked) + * + * NOTES: + * - The SPIRIT1 SPI is mode 0 (CPOL=0, CPHA=0) + * - Data word is 8-bits + * - Maximum clock frequency is 10MHz + * - Transfers are MS bit first + */ + + SPI_SETMODE(spi, SPIDEV_MODE0); + SPI_SETBITS(spi, 8); + (void)SPI_HWFEATURES(spi, 0); + (void)SPI_SETFREQUENCY(spi, CONFIG_WL_SPIRIT_SPIFREQUENCY); +} + +/****************************************************************************** + * Name: spirit_unlock + * + * Description: + * Un-lock the SPI bus after each transfer, possibly losing the current + * configuration if we are sharing the SPI bus with other devices. + * + * Parameters: + * spi - Reference to the SPI driver structure + * + * Returned Value: + * None + * + * Assumptions: + * + ******************************************************************************/ + +static void spirit_unlock(FAR struct spi_dev_s *spi) +{ + /* Relinquish the SPI bus. */ + + (void)SPI_LOCK(spi, false); +} + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_reg_read + * + * Description: + * Read single or multiple SPIRIT1 register + * + * Input parameters: + * + * regaddr: Base register's address to be read + * buffer: Pointer to the buffer of registers' values to be read + * buflen: Number of register values to be read + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_reg_read(FAR struct spirit_library_s *spirit, uint8_t regaddr, + FAR uint8_t *buffer, unsigned int buflen) +{ + uint8_t header[2]; + uint8_t status[2]; + + /* Setup the header bytes */ + + header[0] = READ_HEADER; + header[1] = regaddr; + + /* Lock the SPI bus and select the Spirit device */ + + spirit_lock(spirit->spi); + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), true); + + /* Write the header bytes and read the SPIRIT1 status bytes */ + + SPI_EXCHANGE(spirit->spi, header, status, 2); + + /* Update Spirit status. 16-bit status is returned MS bit first */ + + spirit->u.u16 = ((uint16_t)status[0] << 8) | (uint16_t)status[1]; + + /* Read the register values */ + + SPI_RECVBLOCK(spirit->spi, buffer, buflen); + + /* Deselect the Spirit device and return the result */ + + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), false); + spirit_unlock(spirit->spi); + return OK; +} + +/****************************************************************************** + * Name: spirit_reg_write + * + * Description: + * Read single or multiple SPIRIT1 register. + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * regaddr - Base register's address to write + * buffer - Pointer to the buffer of register values to write + * buflen - Number of registers values to be written. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_reg_write(FAR struct spirit_library_s *spirit, uint8_t regaddr, + FAR const uint8_t *buffer, unsigned int buflen) +{ + uint8_t header[2]; + uint8_t status[2]; + + /* Setup the header bytes */ + + header[0] = WRITE_HEADER; + header[1] = regaddr; + + /* Lock the SPI bus and select the Spirit device */ + + spirit_lock(spirit->spi); + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), true); + + /* Write the header bytes and read the SPIRIT1 status bytes */ + + SPI_EXCHANGE(spirit->spi, header, status, 2); + + /* Update Spirit status. 16-bit status is returned MS bit first */ + + spirit->u.u16 = ((uint16_t)status[0] << 8) | (uint16_t)status[1]; + + /* Write the register values */ + + SPI_SNDBLOCK(spirit->spi, buffer, buflen); + + /* Deselect the Spirit device and return the result */ + + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), false); + spirit_unlock(spirit->spi); + return OK; +} + +/****************************************************************************** + * Name: spirit_command + * + * Description: + * Send a command + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * cmd - Command code to be sent + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_command(FAR struct spirit_library_s *spirit, uint8_t cmd) +{ + uint8_t header[2]; + uint8_t status[2]; + + /* Setup the header bytes */ + + header[0] = COMMAND_HEADER; + header[1] = cmd; + + /* Lock the SPI bus and select the Spirit device */ + + spirit_lock(spirit->spi); + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), true); + + /* Write the header bytes and read the SPIRIT1 status bytes */ + + SPI_EXCHANGE(spirit->spi, header, status, 2); + + /* Update Spirit status. 16-bit status is returned MS bit first */ + + spirit->u.u16 = ((uint16_t)status[0] << 8) | (uint16_t)status[1]; + + /* Deselect the Spirit device and return the result */ + + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), false); + spirit_unlock(spirit->spi); + return OK; +} + +/****************************************************************************** + * Name: spirt_fifo_read + * + * Description: + * Read data from RX FIFO + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * buffer - Pointer to the buffer of data values to write + * buflen - Number of bytes to be written + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirt_fifo_read(FAR struct spirit_library_s *spirit, FAR uint8_t *buffer, + unsigned int buflen) +{ + uint8_t header[2]; + uint8_t status[2]; + + /* Setup the header bytes */ + + header[0] = READ_HEADER; + header[1] = LINEAR_FIFO_ADDRESS; + + /* Lock the SPI bus and select the Spirit device */ + + spirit_lock(spirit->spi); + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), true); + + /* Write the header bytes and read the SPIRIT1 status bytes */ + + SPI_EXCHANGE(spirit->spi, header, status, 2); + + /* Update Spirit status. 16-bit status is returned MS bit first */ + + spirit->u.u16 = ((uint16_t)status[0] << 8) | (uint16_t)status[1]; + + /* Read the register values */ + + SPI_RECVBLOCK(spirit->spi, buffer, buflen); + + /* Deselect the Spirit device and return the result */ + + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), false); + spirit_unlock(spirit->spi); + return OK; +} + +/****************************************************************************** + * Name: spirt_fifo_write + * + * Description: + * Write data into TX FIFO. + * + * Input parameters: + * spirit - Reference to an instance of the driver state stucture. + * buffer - Pointer to the buffer of data values to write + * buflen - Number of data values to be written. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirt_fifo_write(FAR struct spirit_library_s *spirit, + FAR const uint8_t *buffer, unsigned int buflen) +{ + uint8_t header[2]; + uint8_t status[2]; + + /* Setup the header bytes */ + + header[0] = WRITE_HEADER; + header[1] = LINEAR_FIFO_ADDRESS; + + /* Lock the SPI bus and select the Spirit device */ + + spirit_lock(spirit->spi); + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), true); + + /* Write the header bytes and read the SPIRIT1 status bytes */ + + SPI_EXCHANGE(spirit->spi, header, status, 2); + + /* Update Spirit status. 16-bit status is returned MS bit first */ + + spirit->u.u16 = ((uint16_t)status[0] << 8) | (uint16_t)status[1]; + + /* Write the fifo values */ + + SPI_SNDBLOCK(spirit->spi, buffer, buflen); + + /* Deselect the Spirit device and return the result */ + + SPI_SELECT(spirit->spi, SPIDEV_WIRELESS(0), false); + spirit_unlock(spirit->spi); + return OK; +} + +/****************************************************************************** + * Name: spirit_update_status + * + * Description: + * Updates the state field in the driver instance, reading the MC_STATE + * register of SPIRIT. + * + * Input Parameters: + * spirit - Reference to an instance of the driver state stucture. + * + * Returned Value: + * Zero (OK) is returned on success. A negated errno value is returned on + * any failure. On success, spirit->state is updated. + * + ******************************************************************************/ + +int spirit_update_status(FAR struct spirit_library_s *spirit) +{ + uint8_t regval; + + DEBUGASSERT(spirit != NULL); + + /* Reads the MC_STATUS register to update the spirit->state */ + + return spirit_reg_read(spirit, MC_STATE1_BASE, ®val, 1); +} diff --git a/drivers/wireless/spirit/lib/spirit_timer.c b/drivers/wireless/spirit/lib/spirit_timer.c new file mode 100644 index 0000000000..7a3e909442 --- /dev/null +++ b/drivers/wireless/spirit/lib/spirit_timer.c @@ -0,0 +1,141 @@ +/****************************************************************************** + * drivers/wireless/spirit/lib/spirit_timer.c + * Configuration and management of SPIRIT timers. + * + * Copyright(c) 2015 STMicroelectronics + * Author: VMA division - AMS + * Version 3.2.2 08-July-2015 + * + * Adapted for NuttX by: + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ******************************************************************************/ + +/****************************************************************************** + * Included Files + ******************************************************************************/ + +#include + +#include "spirit_timer.h" +#include "spirit_radio.h" +#include "spirit_spi.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Returns the absolute value. */ + +#define S_ABS(a) ((a) > 0 ? (a) : -(a)) + +/****************************************************************************** + * Private Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: + * + * Description: + * + * Parameters: + * + * Returned Value: + * + ******************************************************************************/ + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: spirit_timer_set_rxtimeout + * + * Description: + * Sets the RX timeout timer counter. If 'counter' is equal to 0 the + * timeout is disabled. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * counter - value for the timer counter. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_timer_set_rxtimeout(FAR struct spirit_library_s *spirit, + uint8_t counter) +{ + /* Writes the counter value for RX timeout in the corresponding register */ + + return spirit_reg_write(spirit, TIMERS4_RX_TIMEOUT_COUNTER_BASE, &counter, 1); +} + +/****************************************************************************** + * Name: spirit_timer_set_rxtimeout_stopcondition + * + * Description: + * Sets the RX timeout stop conditions. + * + * Input Parameters: + * spirit - Reference to a Spirit library state structure instance + * stopcondition - New stop condition. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ******************************************************************************/ + +int spirit_timer_set_rxtimeout_stopcondition(FAR struct spirit_library_s *spirit, + enum spirit_rxtimeout_stopcondition_e + stopcondition) +{ + uint8_t regval[2]; + int ret; + + /* Check the parameters */ + + DEBUGASSERT(IS_RX_TIMEOUT_STOP_CONDITION(stopcondition)); + + /* Reads value on the PKT_FLT_OPTIONS and PROTOCOL2 register */ + + ret = spirit_reg_read(spirit, PCKT_FLT_OPTIONS_BASE, regval, 2); + if (ret >= 0) + { + regval[0] &= 0xbf; + regval[0] |= ((stopcondition & 0x08) << 3); + + regval[1] &= 0x1f; + regval[1] |= (stopcondition << 5); + + /* Write value to the PKT_FLT_OPTIONS and PROTOCOL2 register */ + + ret = spirit_reg_write(spirit, PCKT_FLT_OPTIONS_BASE, regval, 2); + } + + return ret; +} diff --git a/include/nuttx/usb/composite.h b/include/nuttx/usb/composite.h index be728423cb..7d5f90c01d 100644 --- a/include/nuttx/usb/composite.h +++ b/include/nuttx/usb/composite.h @@ -52,24 +52,6 @@ /* Configuration ************************************************************/ /* CONFIG_USBDEV_COMPOSITE * Enables USB composite device support - * CONFIG_CDCACM_COMPOSITE - * Configure the CDC serial driver as part of a composite driver - * (only if CONFIG_USBDEV_COMPOSITE is also defined) - * CONFIG_COMPOSITE_COMPOSITE - * Configure the mass storage driver as part of a composite driver - * (only if CONFIG_USBDEV_COMPOSITE is also defined) - * CONFIG_COMPOSITE_EP0MAXPACKET - * Max packet size for endpoint 0 - * CONFIG_COMPOSITE_VENDORID and CONFIG_COMPOSITE_VENDORSTR - * The vendor ID code/string - * CONFIG_COMPOSITE_PRODUCTID and CONFIG_COMPOSITE_PRODUCTSTR - * The product ID code/string - * CONFIG_COMPOSITE_SERIALSTR - * Device serial number string - * CONFIG_COMPOSITE_CONFIGSTR - * Configuration string - * CONFIG_COMPOSITE_VERSIONNO - * Interface version number. */ #define COMPOSITE_NSTRIDS (5) /* The numer of String-IDs to diff --git a/include/nuttx/wireless/spirit.h b/include/nuttx/wireless/spirit.h new file mode 100644 index 0000000000..a6741ac308 --- /dev/null +++ b/include/nuttx/wireless/spirit.h @@ -0,0 +1,104 @@ +/**************************************************************************** + * include/nuttx/wireless/spirit.h + * + * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_WIRELESS_SPIRIT_H +#define __INCLUDE_NUTTX_WIRELESS_SPIRIT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* The Spirit provides interrupts to the MCU via a GPIO pin. The + * following structure provides an MCU-independent mechanixm for controlling + * the Spirit GPIO interrupt. + */ + +struct spirit_lower_s +{ + int (*reset)(FAR const struct spirit_lower_s *lower); + int (*attach)(FAR const struct spirit_lower_s *lower, xcpt_t handler, + FAR void *arg); + void (*enable)(FAR const struct spirit_lower_s *lower, bool state); +}; + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct spi_dev_s; /* Forward reference */ + +/**************************************************************************** + * Function: spirit_netdev_initialize + * + * Description: + * Initialize the IEEE802.15.4 driver and register it as a network device. + * + * Parameters: + * spi - A reference to the platform's SPI driver for the spirit + * lower - The MCU-specific interrupt used to control low-level MCU + * functions (i.e., spirit GPIO interrupts). + * + * Returned Value: + * OK on success; Negated errno on failure. + * + ****************************************************************************/ + +int spirit_netdev_initialize(FAR struct spi_dev_s *spi, + FAR const struct spirit_lower_s *lower); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __INCLUDE_NUTTX_IEEE802154__AT86RF23X_H */