diff --git a/Documentation/NuttXCCodingStandard.html b/Documentation/NuttXCCodingStandard.html
index f867fb3782a..7d65a766a26 100644
--- a/Documentation/NuttXCCodingStandard.html
+++ b/Documentation/NuttXCCodingStandard.html
@@ -12,7 +12,7 @@
NuttX C Coding Standard
- Last Updated: April 18, 2017
+ Last Updated: May 6, 2017
@@ -405,8 +405,11 @@
Line Spacing
A single blank line should precede and follow each comment.
- The only exception is for the file header block comment that begins on line one;
+ The only exceptions are (1) for the file header block comment that begins on line one;
there is no preceding blank line in that case.
+ And (2) for conditional compilation.
+ Conditional compilation should include the conditional logic and all comments associated with the conditional logic.
+ In this case, the blank line appears before the conditional, not after it.
|
@@ -416,6 +419,12 @@
a = b;
/* set b equal to c */
b = c;
+
+ /* Do the impossible */
+
+#ifdef CONFIG_THE_IMPOSSIBLE
+ the_impossible();
+#endif
|
|
@@ -430,6 +439,11 @@
b = c;
+#ifdef CONFIG_THE_IMPOSSIBLE
+ /* Do the impossible */
+
+ the_impossible();
+#endif
|
@@ -1611,7 +1625,7 @@ enum xyz_state_e
Lowercase Exceptions.
- There are3 a few lower case values in NuttX macro names. Such as a lower-case p for a period or decimal point (such as VOLTAGE_3p3V).
+ There are a few lower case values in NuttX macro names. Such as a lower-case p for a period or decimal point (such as VOLTAGE_3p3V).
I have also used lower-case v for a version number (such as CONFIG_NET_IPv6).
However, these are exceptions to the rule rather than illustrating a rule.
diff --git a/Documentation/README.html b/Documentation/README.html
index 727b2f36848..726f4aa3cfc 100644
--- a/Documentation/README.html
+++ b/Documentation/README.html
@@ -208,6 +208,8 @@ nuttx/
| | `- README.txt
| |- pic32mz-starterkit/
| | `- README.txt
+ | |- photon/
+ | | `- README.txt
| |- qemu-i486/
| | `- README.txt
| |- sabre-6quad/
diff --git a/Kconfig b/Kconfig
index 451b22206d6..d2157939e8f 100644
--- a/Kconfig
+++ b/Kconfig
@@ -756,7 +756,7 @@ config DEBUG_WIRELESS
default n
depends on WIRELESS || DRIVERS_WIRELESS
---help---
- Enable DEBUG_WIRELESS debug features.
+ Enable wireless debug features.
if DEBUG_WIRELESS
diff --git a/README.txt b/README.txt
index f06800339fe..334b501e514 100644
--- a/README.txt
+++ b/README.txt
@@ -1580,6 +1580,8 @@ nuttx/
| | `- README.txt
| |- pic32mz-starterkit/
| | `- README.txt
+ | |- photon/
+ | | `- README.txt
| |- qemu-i486/
| | `- README.txt
| |- sabre-6quad/
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c71fc987736..c8964e3c813 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -76,6 +76,7 @@ config ARCH_CHIP_KINETIS
select ARCH_HAVE_FPU
select ARCH_HAVE_RAMFUNCS
select ARCH_HAVE_CMNVECTOR
+ select ARCH_HAVE_I2CRESET
---help---
Freescale Kinetis Architectures (ARM Cortex-M4)
diff --git a/arch/arm/include/kinetis/chip.h b/arch/arm/include/kinetis/chip.h
index 5c6cc76a082..cc50674e97d 100644
--- a/arch/arm/include/kinetis/chip.h
+++ b/arch/arm/include/kinetis/chip.h
@@ -1438,8 +1438,9 @@
# define KINETIS_NDAC6 4 /* Four 6-bit DAC */
# define KINETIS_NDAC12 2 /* Two 12-bit DAC */
# define KINETIS_NVREF 1 /* Voltage reference */
-# define KINETIS_NTIMERS8 2 /* ? Two 8 channel timers */
-# define KINETIS_NTIMERS2 2 /* ? Two 2 channel timers */
+# define KINETIS_NTIMERS8 2 /* Two 8 channel FTM timers */
+# define KINETIS_NTIMERS2 2 /* Two 2 channel FTM timers */
+# define KINETIS_NTPMTIMERS2 2 /* Two 2 channel TPM timers */
# define KINETIS_NRTC 1 /* Real time clock */
# define KINETIS_NRNG 1 /* Random number generator */
# define KINETIS_NMMCAU 1 /* Hardware encryption */
diff --git a/arch/arm/include/stm32l4/chip.h b/arch/arm/include/stm32l4/chip.h
index 7cd275e2806..589d88f675b 100644
--- a/arch/arm/include/stm32l4/chip.h
+++ b/arch/arm/include/stm32l4/chip.h
@@ -68,7 +68,7 @@
* Parts STM32L4x6xE have 512Kb of FLASH
* Parts STM32L4x6xG have 1024Kb of FLASH
*
- * The correct FLASH size must be set with a CONFIG_STM32L4_FLASH_*KB
+ * The correct FLASH size must be set with a CONFIG_STM32L4_FLASH_CONFIG_*
* selection.
*/
@@ -78,10 +78,18 @@
#elif defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX)
# define STM32L4_SRAM1_SIZE (96*1024) /* 96Kb SRAM1 on AHB bus Matrix */
# define STM32L4_SRAM2_SIZE (32*1024) /* 32Kb SRAM2 on AHB bus Matrix */
+#elif defined(CONFIG_STM32L4_STM32L451XX) || defined(CONFIG_STM32L4_STM32L452XX) || \
+ defined(CONFIG_STM32L4_STM32L462XX)
+# define STM32L4_SRAM1_SIZE (128*1024) /* 128Kb SRAM1 on AHB bus Matrix */
+# define STM32L4_SRAM2_SIZE (32*1024) /* 32Kb SRAM2 on AHB bus Matrix */
+#elif defined(CONFIG_STM32L4_STM32L432XX)
+# define STM32L4_SRAM1_SIZE (48*1024) /* 48Kb SRAM1 on AHB bus Matrix */
+# define STM32L4_SRAM2_SIZE (16*1024) /* 16Kb SRAM2 on AHB bus Matrix */
#else
# error "Unsupported STM32L4 chip"
#endif
+#if defined(CONFIG_STM32L4_STM32L4X6)
# define STM32L4_NFSMC 1 /* Have FSMC memory controller */
# define STM32L4_NATIM 2 /* Two advanced timers TIM1 and 8 */
# define STM32L4_NGTIM32 2 /* 32-bit general timers TIM2 and 5 with DMA */
@@ -100,6 +108,7 @@
# define STM32L4_NI2C 3 /* I2C1-3 */
#endif
# define STM32L4_NUSBOTGFS 1 /* USB OTG FS */
+# define STM32L4_NUSBFS 0 /* No USB FS */
#if defined(CONFIG_STM32L4_STM32L496XX)
# define STM32L4_NCAN 2 /* CAN1-2 */
#else
@@ -118,6 +127,72 @@
# define STM32L4_NCRC 1 /* CRC */
# define STM32L4_NCOMP 2 /* Comparators */
# define STM32L4_NOPAMP 2 /* Operational Amplifiers */
+#endif /* CONFIG_STM32L4_STM32L4X6 */
+
+#if defined(CONFIG_STM32L4_STM32L451XX) || defined(CONFIG_STM32L4_STM32L452XX) || \
+ defined(CONFIG_STM32L4_STM32L462XX)
+# define STM32L4_NFSMC 0 /* No FSMC memory controller */
+# define STM32L4_NATIM 1 /* One advanced timer TIM1 */
+# define STM32L4_NGTIM32 1 /* 32-bit general timer TIM2 with DMA */
+# define STM32L4_NGTIM16 3 /* 16-bit general timers TIM3, TIM15-16 with DMA */
+# define STM32L4_NGTIMNDMA 0 /* No 16-bit general timers without DMA */
+# define STM32L4_NBTIM 1 /* One basic timer, TIM6 */
+# define STM32L4_NLPTIM 2 /* Two low-power timers, LPTIM1-2 */
+# define STM32L4_NRNG 1 /* Random number generator (RNG) */
+# define STM32L4_NUART 1 /* UART 4 */
+# define STM32L4_NUSART 3 /* USART 1-3 */
+# define STM32L4_NLPUART 1 /* LPUART 1 */
+# define STM32L4_NSPI 3 /* SPI1-3 */
+# define STM32L4_NI2C 4 /* I2C1-4 */
+# define STM32L4_NUSBOTGFS 0 /* No USB OTG FS */
+#if defined(CONFIG_STM32L4_STM32L451XX)
+# define STM32L4_NUSBFS 0 /* No USB FS */
+#else
+# define STM32L4_NUSBFS 1 /* USB FS */
+#endif
+# define STM32L4_NCAN 1 /* CAN1 */
+# define STM32L4_NSAI 1 /* SAI1 */
+#if defined(CONFIG_STM32L4_HAVE_SDMMC1)
+# define STM32L4_NSDMMC 1 /* SDMMC interface */
+#else
+# define STM32L4_NSDMMC 0 /* No SDMMC interface */
+#endif
+# define STM32L4_NDMA 2 /* DMA1-2 */
+# define STM32L4_NPORTS 8 /* 8 GPIO ports, GPIOA-H */
+# define STM32L4_NADC 1 /* 12-bit ADC1, 16 channels (10 in CE,CV) */
+# define STM32L4_NDAC 1 /* 12-bit DAC1 */
+# define STM32L4_NCRC 1 /* CRC */
+# define STM32L4_NCOMP 2 /* Comparators */
+# define STM32L4_NOPAMP 1 /* Operational Amplifiers */
+#endif /* CONFIG_STM32L4_STM32L451XX */
+
+#if defined(CONFIG_STM32L4_STM32L432XX)
+# define STM32L4_NFSMC 0 /* No FSMC memory controller */
+# define STM32L4_NATIM 1 /* One advanced timer TIM1 */
+# define STM32L4_NGTIM32 1 /* 32-bit general timer TIM2 with DMA */
+# define STM32L4_NGTIM16 2 /* 16-bit general timers TIM15-16 with DMA */
+# define STM32L4_NGTIMNDMA 0 /* No 16-bit general timers without DMA */
+# define STM32L4_NBTIM 2 /* Two basic timers, TIM6-7 */
+# define STM32L4_NLPTIM 2 /* Two low-power timers, LPTIM1-2 */
+# define STM32L4_NRNG 1 /* Random number generator (RNG) */
+# define STM32L4_NUART 0 /* No UART */
+# define STM32L4_NUSART 2 /* USART 1-2 */
+# define STM32L4_NLPUART 1 /* LPUART 1 */
+# define STM32L4_NSPI 2 /* SPI1, SPI3 */
+# define STM32L4_NI2C 2 /* I2C1, I2C3 */
+# define STM32L4_NUSBOTGFS 0 /* No USB OTG FS */
+# define STM32L4_NUSBFS 1 /* USB FS */
+# define STM32L4_NCAN 1 /* CAN1 */
+# define STM32L4_NSAI 1 /* SAI1 */
+# define STM32L4_NSDMMC 0 /* No SDMMC interface */
+# define STM32L4_NDMA 2 /* DMA1-2 */
+# define STM32L4_NPORTS 8 /* 8 GPIO ports, GPIOA-H */
+# define STM32L4_NADC 1 /* 12-bit ADC1, 10 channels */
+# define STM32L4_NDAC 2 /* 12-bit DAC1-2 */
+# define STM32L4_NCRC 1 /* CRC */
+# define STM32L4_NCOMP 2 /* Comparators */
+# define STM32L4_NOPAMP 1 /* Operational Amplifiers */
+#endif /* CONFIG_STM32L4_STM32L432XX */
/* NVIC priority levels *************************************************************/
/* 16 Programmable interrupt levels */
diff --git a/arch/arm/include/stm32l4/irq.h b/arch/arm/include/stm32l4/irq.h
index abb543bc723..480b7d693a4 100644
--- a/arch/arm/include/stm32l4/irq.h
+++ b/arch/arm/include/stm32l4/irq.h
@@ -76,9 +76,10 @@
#define STM32L4_IRQ_FIRST (16) /* Vector number of the first external interrupt */
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
+#if defined(CONFIG_STM32L4_STM32L4X6)
# include
+#elif defined(CONFIG_STM32L4_STM32L4X3)
+# include
#else
# error "Unsupported STM32 L4 chip"
#endif
diff --git a/arch/arm/include/stm32l4/stm32l4x3xx_irq.h b/arch/arm/include/stm32l4/stm32l4x3xx_irq.h
new file mode 100644
index 00000000000..e3c3c8cf17d
--- /dev/null
+++ b/arch/arm/include/stm32l4/stm32l4x3xx_irq.h
@@ -0,0 +1,185 @@
+/****************************************************************************************************
+ * arch/arm/include/stm32l4/stm32l4x3xx_irq.h
+ *
+ * Copyright (C) 2015 Sebastien Lorquet. All rights reserved.
+ * Authors: Sebastien Lorquet
+ * Juha Niskanen
+ *
+ * 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.
+ *
+ ****************************************************************************************************/
+
+/* This file should never be included directed but, rather, only indirectly through arch/irq.h */
+
+#ifndef __ARCH_ARM_INCLUDE_STM32L4_STM32L4X3XX_IRQ_H
+#define __ARCH_ARM_INCLUDE_STM32L4_STM32L4X3XX_IRQ_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include
+
+/****************************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************************/
+
+/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to bits in the
+ * NVIC. This does, however, waste several words of memory in the IRQ to handle mapping tables.
+ *
+ * Processor Exceptions (vectors 0-15). These common definitions can be found in the file
+ * nuttx/arch/arm/include/stm32f7/irq.h which includes this file
+ *
+ * External interrupts (vectors >= 16)
+ */
+
+#define STM32L4_IRQ_WWDG (STM32L4_IRQ_FIRST+0) /* 0: Window Watchdog interrupt */
+#define STM32L4_IRQ_PVD (STM32L4_IRQ_FIRST+1) /* 1: PVD through EXTI Line detection interrupt */
+#define STM32L4_IRQ_TAMPER (STM32L4_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */
+#define STM32L4_IRQ_TIMESTAMP (STM32L4_IRQ_FIRST+2) /* 2: Tamper and time stamp interrupts */
+#define STM32L4_IRQ_RTC_WKUP (STM32L4_IRQ_FIRST+3) /* 3: RTC global interrupt */
+#define STM32L4_IRQ_FLASH (STM32L4_IRQ_FIRST+4) /* 4: Flash global interrupt */
+#define STM32L4_IRQ_RCC (STM32L4_IRQ_FIRST+5) /* 5: RCC global interrupt */
+#define STM32L4_IRQ_EXTI0 (STM32L4_IRQ_FIRST+6) /* 6: EXTI Line 0 interrupt */
+#define STM32L4_IRQ_EXTI1 (STM32L4_IRQ_FIRST+7) /* 7: EXTI Line 1 interrupt */
+#define STM32L4_IRQ_EXTI2 (STM32L4_IRQ_FIRST+8) /* 8: EXTI Line 2 interrupt */
+#define STM32L4_IRQ_EXTI3 (STM32L4_IRQ_FIRST+9) /* 9: EXTI Line 3 interrupt */
+#define STM32L4_IRQ_EXTI4 (STM32L4_IRQ_FIRST+10) /* 10: EXTI Line 4 interrupt */
+#define STM32L4_IRQ_DMA1CH1 (STM32L4_IRQ_FIRST+11) /* 12: DMA1 Channel 1 global interrupt */
+#define STM32L4_IRQ_DMA1CH2 (STM32L4_IRQ_FIRST+12) /* 13: DMA1 Channel 2 global interrupt */
+#define STM32L4_IRQ_DMA1CH3 (STM32L4_IRQ_FIRST+13) /* 14: DMA1 Channel 3 global interrupt */
+#define STM32L4_IRQ_DMA1CH4 (STM32L4_IRQ_FIRST+14) /* 15: DMA1 Channel 4 global interrupt */
+#define STM32L4_IRQ_DMA1CH5 (STM32L4_IRQ_FIRST+15) /* 16: DMA1 Channel 5 global interrupt */
+#define STM32L4_IRQ_DMA1CH6 (STM32L4_IRQ_FIRST+16) /* 17: DMA1 Channel 6 global interrupt */
+#define STM32L4_IRQ_DMA1CH7 (STM32L4_IRQ_FIRST+17) /* 17: DMA1 Channel 7 global interrupt */
+#define STM32L4_IRQ_ADC1 (STM32L4_IRQ_FIRST+18) /* 18: ADC1 global interrupt */
+#define STM32L4_IRQ_CAN1TX (STM32L4_IRQ_FIRST+19) /* 19: CAN1 TX interrupts */
+#define STM32L4_IRQ_CAN1RX0 (STM32L4_IRQ_FIRST+20) /* 20: CAN1 RX0 interrupts */
+#define STM32L4_IRQ_CAN1RX1 (STM32L4_IRQ_FIRST+21) /* 21: CAN1 RX1 interrupt */
+#define STM32L4_IRQ_CAN1SCE (STM32L4_IRQ_FIRST+22) /* 22: CAN1 SCE interrupt */
+#define STM32L4_IRQ_EXTI95 (STM32L4_IRQ_FIRST+23) /* 23: EXTI Line[9:5] interrupts */
+#define STM32L4_IRQ_TIM1BRK (STM32L4_IRQ_FIRST+24) /* 24: TIM1 Break interrupt */
+#define STM32L4_IRQ_TIM15 (STM32L4_IRQ_FIRST+24) /* 24: TIM15 global interrupt */
+#define STM32L4_IRQ_TIM1UP (STM32L4_IRQ_FIRST+25) /* 25: TIM1 Update interrupt */
+#define STM32L4_IRQ_TIM16 (STM32L4_IRQ_FIRST+25) /* 25: TIM16 global interrupt */
+#define STM32L4_IRQ_TIM1TRGCOM (STM32L4_IRQ_FIRST+26) /* 26: TIM1 Trigger and Commutation interrupts */
+#define STM32L4_IRQ_TIM1CC (STM32L4_IRQ_FIRST+27) /* 27: TIM1 Capture Compare interrupt */
+#define STM32L4_IRQ_TIM2 (STM32L4_IRQ_FIRST+28) /* 28: TIM2 global interrupt */
+#define STM32L4_IRQ_TIM3 (STM32L4_IRQ_FIRST+29) /* 29: TIM3 global interrupt */
+/* Reserved */ /* 30: TIM4 global interrupt */
+#define STM32L4_IRQ_I2C1EV (STM32L4_IRQ_FIRST+31) /* 31: I2C1 event interrupt */
+#define STM32L4_IRQ_I2C1ER (STM32L4_IRQ_FIRST+32) /* 32: I2C1 error interrupt */
+#define STM32L4_IRQ_I2C2EV (STM32L4_IRQ_FIRST+33) /* 33: I2C2 event interrupt */
+#define STM32L4_IRQ_I2C2ER (STM32L4_IRQ_FIRST+34) /* 34: I2C2 error interrupt */
+#define STM32L4_IRQ_SPI1 (STM32L4_IRQ_FIRST+35) /* 35: SPI1 global interrupt */
+#define STM32L4_IRQ_SPI2 (STM32L4_IRQ_FIRST+36) /* 36: SPI2 global interrupt */
+#define STM32L4_IRQ_USART1 (STM32L4_IRQ_FIRST+37) /* 37: USART1 global interrupt */
+#define STM32L4_IRQ_USART2 (STM32L4_IRQ_FIRST+38) /* 38: USART2 global interrupt */
+#define STM32L4_IRQ_USART3 (STM32L4_IRQ_FIRST+39) /* 39: USART3 global interrupt */
+#define STM32L4_IRQ_EXTI1510 (STM32L4_IRQ_FIRST+40) /* 40: EXTI Line[15:10] interrupts */
+#define STM32L4_IRQ_RTCALRM (STM32L4_IRQ_FIRST+41) /* 41: RTC alarm through EXTI line interrupt */
+/* Reserved */ /* 42-48: reserved */
+#define STM32L4_IRQ_SDMMC1 (STM32L4_IRQ_FIRST+49) /* 49: SDMMC1 global interrupt */
+/* Reserved */ /* 50: TIM5 global interrupt */
+#define STM32L4_IRQ_SPI3 (STM32L4_IRQ_FIRST+51) /* 51: SPI3 global interrupt */
+#define STM32L4_IRQ_UART4 (STM32L4_IRQ_FIRST+52) /* 52: UART4 global interrupt */
+/* Reserved */ /* 53: UART5 global interrupt */
+#define STM32L4_IRQ_TIM6 (STM32L4_IRQ_FIRST+54) /* 54: TIM6 global interrupt */
+#define STM32L4_IRQ_DAC (STM32L4_IRQ_FIRST+54) /* 54: DAC1 underrun error interrupts */
+#define STM32L4_IRQ_TIM7 (STM32L4_IRQ_FIRST+55) /* 55: TIM7 global interrupt */
+#define STM32L4_IRQ_DMA2CH1 (STM32L4_IRQ_FIRST+56) /* 56: DMA2 Channel 1 global interrupt */
+#define STM32L4_IRQ_DMA2CH2 (STM32L4_IRQ_FIRST+57) /* 57: DMA2 Channel 2 global interrupt */
+#define STM32L4_IRQ_DMA2CH3 (STM32L4_IRQ_FIRST+58) /* 58: DMA2 Channel 3 global interrupt */
+#define STM32L4_IRQ_DMA2CH4 (STM32L4_IRQ_FIRST+59) /* 59: DMA2 Channel 4 global interrupt */
+#define STM32L4_IRQ_DMA2CH5 (STM32L4_IRQ_FIRST+60) /* 60: DMA2 Channel 5 global interrupt */
+#define STM32L4_IRQ_DFSDM0 (STM32L4_IRQ_FIRST+61) /* 61: DFSDM0 global interrupt */
+#define STM32L4_IRQ_DFSDM1 (STM32L4_IRQ_FIRST+62) /* 62: DFSDM1 global interrupt*/
+/* Reserved */ /* 63: DFSDM2 global interrupt */
+#define STM32L4_IRQ_COMP (STM32L4_IRQ_FIRST+64) /* 64: COMP1/COMP2 interrupts */
+#define STM32L4_IRQ_LPTIM1 (STM32L4_IRQ_FIRST+65) /* 65: LPTIM1 global interrupt */
+#define STM32L4_IRQ_LPTIM2 (STM32L4_IRQ_FIRST+66) /* 66: LPTIM2 global interrupt */
+#define STM32L4_IRQ_USB_FS (STM32L4_IRQ_FIRST+67) /* 67: USB event interrupt through EXTI line 17 */
+#define STM32L4_IRQ_DMA2CH6 (STM32L4_IRQ_FIRST+68) /* 68: DMA2 Channel 6 global interrupt */
+#define STM32L4_IRQ_DMA2CH7 (STM32L4_IRQ_FIRST+69) /* 69: DMA2 Channel 7 global interrupt */
+#define STM32L4_IRQ_LPUART1 (STM32L4_IRQ_FIRST+70) /* 70: Low power UART 1 global interrupt */
+#define STM32L4_IRQ_QUADSPI (STM32L4_IRQ_FIRST+71) /* 71: QUADSPI global interrupt */
+#define STM32L4_IRQ_I2C3EV (STM32L4_IRQ_FIRST+72) /* 72: I2C3 event interrupt */
+#define STM32L4_IRQ_I2C3ER (STM32L4_IRQ_FIRST+73) /* 73: I2C3 error interrupt */
+#define STM32L4_IRQ_SAI1 (STM32L4_IRQ_FIRST+74) /* 74: SAI1 global interrupt */
+/* Reserved */ /* 75: SAI2 global interrupt */
+#define STM32L4_IRQ_SWPMI1 (STM32L4_IRQ_FIRST+76) /* 76: SWPMI1 global interrupt */
+#define STM32L4_IRQ_TSC (STM32L4_IRQ_FIRST+77) /* 77: TSC global interrupt */
+#define STM32L4_IRQ_LCD (STM32L4_IRQ_FIRST+78) /* 78: LCD global interrupt */
+#define STM32L4_IRQ_AES (STM32L4_IRQ_FIRST+79) /* 79: AES crypto global interrupt */
+#define STM32L4_IRQ_RNG (STM32L4_IRQ_FIRST+80) /* 80: RNG global interrupt */
+#define STM32L4_IRQ_FPU (STM32L4_IRQ_FIRST+81) /* 81: FPU global interrupt */
+#define STM32L4_IRQ_CRS (STM32L4_IRQ_FIRST+82) /* 82: CRS global interrupt */
+#define STM32L4_IRQ_I2C4EV (STM32L4_IRQ_FIRST+83) /* 83: I2C4 event interrupt */
+#define STM32L4_IRQ_I2C4ER (STM32L4_IRQ_FIRST+84) /* 84: I2C4 error interrupt */
+
+#if defined(CONFIG_STM32L4_STM32L4X3)
+# define NR_INTERRUPTS 85
+#else
+# error "Unsupported STM32L4 chip"
+#endif
+
+#define NR_VECTORS (STM32L4_IRQ_FIRST+NR_INTERRUPTS)
+
+/* EXTI interrupts (Do not use IRQ numbers) */
+
+#define NR_IRQS NR_VECTORS
+
+/****************************************************************************************************
+ * Public Types
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Public Data
+ ****************************************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************************************
+ * Public Functions
+ ****************************************************************************************************/
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __ARCH_ARM_INCLUDE_STM32L4_STM32L4X3XX_IRQ_H */
diff --git a/arch/arm/src/kinetis/Kconfig b/arch/arm/src/kinetis/Kconfig
index 271921a9ef6..646e7254faa 100644
--- a/arch/arm/src/kinetis/Kconfig
+++ b/arch/arm/src/kinetis/Kconfig
@@ -239,6 +239,10 @@ config KINETIS_HAVE_LPUART1
# will automatically be selected and will represent the 'OR' of the
# instances selected.
+config KINETIS_SERIALDRIVER
+ bool
+ default n
+
config KINETIS_LPUART
bool
default n
@@ -268,15 +272,23 @@ config ARCH_FAMILY_K60
config ARCH_FAMILY_K64
bool
default n
+ select KINETIS_HAVE_FTM3
select KINETIS_HAVE_UART5
config ARCH_FAMILY_K66
bool
default n
+ select KINETIS_HAVE_FTM3
select KINETIS_HAVE_LPUART0
+ select KINETIS_HAVE_TPM1
+ select KINETIS_HAVE_TPM2
menu "Kinetis Peripheral Support"
+config KINETIS_HAVE_FTM3
+ bool
+ default n
+
config KINETIS_HAVE_I2C1
bool
default n
@@ -297,6 +309,14 @@ config KINETIS_HAVE_SPI2
bool
default n
+config KINETIS_HAVE_TPM1
+ bool
+ default n
+
+config KINETIS_HAVE_TPM2
+ bool
+ default n
+
config KINETIS_TRACE
bool "Trace"
default n
@@ -314,6 +334,8 @@ config KINETIS_UART0
default n
select UART0_SERIALDRIVER
select KINETIS_UART
+ select KINETIS_SERIALDRIVER
+ select ARCH_HAVE_SERIAL_TERMIOS
---help---
Support UART0
@@ -322,6 +344,8 @@ config KINETIS_UART1
default n
select UART1_SERIALDRIVER
select KINETIS_UART
+ select KINETIS_SERIALDRIVER
+ select ARCH_HAVE_SERIAL_TERMIOS
---help---
Support UART1
@@ -330,6 +354,8 @@ config KINETIS_UART2
default n
select UART2_SERIALDRIVER
select KINETIS_UART
+ select KINETIS_SERIALDRIVER
+ select ARCH_HAVE_SERIAL_TERMIOS
---help---
Support UART2
@@ -338,6 +364,8 @@ config KINETIS_UART3
default n
select UART3_SERIALDRIVER
select KINETIS_UART
+ select KINETIS_SERIALDRIVER
+ select ARCH_HAVE_SERIAL_TERMIOS
---help---
Support UART3
@@ -346,6 +374,8 @@ config KINETIS_UART4
default n
select UART4_SERIALDRIVER
select KINETIS_UART
+ select KINETIS_SERIALDRIVER
+ select ARCH_HAVE_SERIAL_TERMIOS
---help---
Support UART4
@@ -355,6 +385,8 @@ config KINETIS_UART5
depends on KINETIS_HAVE_UART5
select UART5_SERIALDRIVER
select KINETIS_UART
+ select KINETIS_SERIALDRIVER
+ select ARCH_HAVE_SERIAL_TERMIOS
---help---
Support UART5
@@ -364,6 +396,8 @@ config KINETIS_LPUART0
depends on KINETIS_HAVE_LPUART0
select OTHER_UART_SERIALDRIVER
select KINETIS_LPUART
+ select KINETIS_SERIALDRIVER
+ select ARCH_HAVE_SERIAL_TERMIOS
---help---
Support the low power UART0
@@ -373,6 +407,8 @@ config KINETIS_LPUART1
depends on KINETIS_HAVE_LPUART1
select OTHER_UART_SERIALDRIVER
select KINETIS_LPUART
+ select KINETIS_SERIALDRIVER
+ select ARCH_HAVE_SERIAL_TERMIOS
---help---
Support the low power UART1
@@ -531,10 +567,24 @@ config KINETIS_FTM2
config KINETIS_FTM3
bool "FTM3"
default n
- depends on ARCH_FAMILY_K64 || ARCH_FAMILY_K66
+ depends on KINETIS_HAVE_FTM3
---help---
Support FlexTimer 3
+config KINETIS_TPM1
+ bool "TPM1"
+ default n
+ depends on KINETIS_HAVE_TPM1
+ ---help---
+ Support TPM module 1
+
+config KINETIS_TPM2
+ bool "TPM2"
+ default n
+ depends on KINETIS_HAVE_TPM2
+ ---help---
+ Support TPM module 2
+
config KINETIS_LPTIMER
bool "Low power timer (LPTIMER)"
default n
@@ -903,6 +953,43 @@ endmenu # Kinetis SDHC Configuration
#
menu "Kinetis UART Configuration"
+if KINETIS_SERIALDRIVER || OTHER_SERIALDRIVER
+
+comment "Serial Driver Configuration"
+
+config KINETIS_UART_BREAKS
+ bool "Add TIOxSBRK to support sending Breaks"
+ depends on KINETIS_UART || KINETIS_LPUART
+ default n
+ ---help---
+ Add TIOCxBRK routines to send a line break per the Kinetis manual, the
+ break will be a pulse based on the value M. This is not a BSD compatible
+ break.
+
+config KINETIS_UART_EXTEDED_BREAK
+ bool "Selects a longer transmitted break character length"
+ depends on KINETIS_UART_BREAKS
+ default n
+ ---help---
+ Sets BRK13 to send a longer transmitted break character.
+
+config KINETIS_SERIALBRK_BSDCOMPAT
+ bool "BSD compatible break the break asserted until released"
+ depends on (KINETIS_UART || KINETIS_LPUART) && KINETIS_UART_BREAKS
+ default n
+ ---help---
+ Enable using a BSD compatible break: TIOCSBRK will start the break
+ and TIOCCBRK will end the break.
+
+config KINETIS_UART_SINGLEWIRE
+ bool "Single Wire Support"
+ default n
+ depends on KINETIS_UART || KINETIS_LPUART
+ ---help---
+ Enable single wire UART and LPUART support. The option enables support
+ for the TIOCSSINGLEWIRE ioctl in the Kineteis serial drivers.
+
+endif # KINETIS_SERIALDRIVER || OTHER_SERIALDRIVER
config KINETIS_UARTFIFOS
bool "Enable UART0 FIFO"
diff --git a/arch/arm/src/kinetis/chip/kinetis_k20pinmux.h b/arch/arm/src/kinetis/chip/kinetis_k20pinmux.h
index ca708acfdf8..d77ea962704 100644
--- a/arch/arm/src/kinetis/chip/kinetis_k20pinmux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_k20pinmux.h
@@ -1,8 +1,9 @@
/********************************************************************************************
* arch/arm/src/kinetis/chip/kinetis_k20pinmux.h
*
- * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt
+ * Copyright (C) 2015-2017 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -159,14 +160,14 @@
# define PIN_FTM2_QD_PHA (PIN_ALT6 | PIN_PORTB | PIN18)
# define PIN_FTM2_QD_PHB (PIN_ALT6 | PIN_PORTB | PIN19)
-# define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0)
-# define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2)
-# define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1)
-# define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3)
-# define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTC | PIN10)
-# define PIN_I2C1_SCL_2 (PIN_ALT6 | PIN_PORTE | PIN1)
-# define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTC | PIN11)
-# define PIN_I2C1_SDA_2 (PIN_ALT6 | PIN_PORTE | PIN0)
+# define PIN_I2C0_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN0)
+# define PIN_I2C0_SCL_2 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN2)
+# define PIN_I2C0_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN1)
+# define PIN_I2C0_SDA_2 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN3)
+# define PIN_I2C1_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN10)
+# define PIN_I2C1_SCL_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN1)
+# define PIN_I2C1_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN11)
+# define PIN_I2C1_SDA_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN0)
# define PIN_I2S0_MCLK_1 (PIN_ALT4 | PIN_PORTC | PIN8)
# define PIN_I2S0_MCLK_2 (PIN_ALT6 | PIN_PORTC | PIN6)
diff --git a/arch/arm/src/kinetis/chip/kinetis_k40pinmux.h b/arch/arm/src/kinetis/chip/kinetis_k40pinmux.h
index 7083b0caf7c..c7570edaf9a 100644
--- a/arch/arm/src/kinetis/chip/kinetis_k40pinmux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_k40pinmux.h
@@ -1,8 +1,9 @@
/********************************************************************************************
* arch/arm/src/kinetis/chip/kinetis_k40pinmux.h
*
- * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt
+ * Copyright (C) 2011, 2016-2017 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -160,7 +161,7 @@
#define PIN_ADC0_SE8 (PIN_ANALOG | PIN_PORTB | PIN0)
#define PIN_ADC1_SE8 (PIN_ANALOG | PIN_PORTB | PIN0)
#define PIN_TSI0_CH0 (PIN_ANALOG | PIN_PORTB | PIN0)
-#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0)
+#define PIN_I2C0_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN0)
#define PIN_FTM1_CH0_3 (PIN_ALT3 | PIN_PORTB | PIN0)
#define PIN_FTM1_QD_PHA_3 (PIN_ALT6 | PIN_PORTB | PIN0)
#define PIN_LCD_P0F (PIN_ALT7 | PIN_PORTB | PIN0)
@@ -168,21 +169,21 @@
#define PIN_ADC0_SE9 (PIN_ANALOG | PIN_PORTB | PIN1)
#define PIN_ADC1_SE9 (PIN_ANALOG | PIN_PORTB | PIN1)
#define PIN_TSI0_CH6 (PIN_ANALOG | PIN_PORTB | PIN1)
-#define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1)
+#define PIN_I2C0_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN1)
#define PIN_FTM1_CH1_3 (PIN_ALT3 | PIN_PORTB | PIN1)
#define PIN_FTM1_QD_PHB (PIN_ALT6 | PIN_PORTB | PIN1)
#define PIN_LCD_P1F (PIN_ALT7 | PIN_PORTB | PIN1)
#define PIN_LCD_P2 (PIN_ANALOG | PIN_PORTB | PIN2)
#define PIN_ADC0_SE12 (PIN_ANALOG | PIN_PORTB | PIN2)
#define PIN_TSI0_CH7 (PIN_ANALOG | PIN_PORTB | PIN2)
-#define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2)
+#define PIN_I2C0_SCL_2 (PIN_ALT2_OPENDRAIN| PIN_PORTB | PIN2)
#define PIN_UART0_RTS_3 (PIN_ALT3 | PIN_PORTB | PIN2)
#define PIN_FTM0_FLT3 (PIN_ALT6 | PIN_PORTB | PIN2)
#define PIN_LCD_P2F (PIN_ALT7 | PIN_PORTB | PIN2)
#define PIN_LCD_P3 (PIN_ANALOG | PIN_PORTB | PIN3)
#define PIN_ADC0_SE13 (PIN_ANALOG | PIN_PORTB | PIN3)
#define PIN_TSI0_CH8 (PIN_ANALOG | PIN_PORTB | PIN3)
-#define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3)
+#define PIN_I2C0_SDA_2 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN3)
#define PIN_UART0_CTS_3 (PIN_ALT3 | PIN_PORTB | PIN3)
#define PIN_FTM0_FLT0_1 (PIN_ALT6 | PIN_PORTB | PIN3)
#define PIN_LCD_P3F (PIN_ALT7 | PIN_PORTB | PIN3)
@@ -325,12 +326,12 @@
#define PIN_LCD_P30 (PIN_ANALOG | PIN_PORTC | PIN10)
#define PIN_ADC1_SE6B (PIN_ANALOG | PIN_PORTC | PIN10)
#define PIN_CMP0_IN4 (PIN_ANALOG | PIN_PORTC | PIN10)
-#define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTC | PIN10)
+#define PIN_I2C1_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN10)
#define PIN_I2S0_RX_FS_2 (PIN_ALT4 | PIN_PORTC | PIN10)
#define PIN_LCD_P30F (PIN_ALT7 | PIN_PORTC | PIN10)
#define PIN_LCD_P31 (PIN_ANALOG | PIN_PORTC | PIN11)
#define PIN_ADC1_SE7B (PIN_ANALOG | PIN_PORTC | PIN11)
-#define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTC | PIN11)
+#define PIN_I2C1_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN11)
#define PIN_I2S0_RXD_2 (PIN_ALT4 | PIN_PORTC | PIN11)
#define PIN_LCD_P31F (PIN_ALT7 | PIN_PORTC | PIN11)
#define PIN_LCD_P32 (PIN_ANALOG | PIN_PORTC | PIN12)
@@ -427,13 +428,13 @@
#define PIN_UART1_TX_2 (PIN_ALT3 | PIN_PORTE | PIN0)
#define PIN_SDHC0_D1 (PIN_ALT4 | PIN_PORTE | PIN0)
#define PIN_FB_AD27 (PIN_ALT5 | PIN_PORTE | PIN0)
-#define PIN_I2C1_SDA_2 (PIN_ALT6 | PIN_PORTE | PIN0)
+#define PIN_I2C1_SDA_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN0)
#define PIN_ADC1_SE5A (PIN_ANALOG | PIN_PORTE | PIN1)
#define PIN_SPI1_SOUT_2 (PIN_ALT2 | PIN_PORTE | PIN1)
#define PIN_UART1_RX_2 (PIN_ALT3 | PIN_PORTE | PIN1)
#define PIN_SDHC0_D0 (PIN_ALT4 | PIN_PORTE | PIN1)
#define PIN_FB_AD26 (PIN_ALT5 | PIN_PORTE | PIN1)
-#define PIN_I2C1_SCL_2 (PIN_ALT6 | PIN_PORTE | PIN1)
+#define PIN_I2C1_SCL_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN1)
#define PIN_ADC1_SE6A (PIN_ANALOG | PIN_PORTE | PIN2)
#define PIN_SPI1_SCK_2 (PIN_ALT2 | PIN_PORTE | PIN2)
#define PIN_UART1_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN2)
diff --git a/arch/arm/src/kinetis/chip/kinetis_k60pinmux.h b/arch/arm/src/kinetis/chip/kinetis_k60pinmux.h
index 888a5955840..b1ca87746f3 100644
--- a/arch/arm/src/kinetis/chip/kinetis_k60pinmux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_k60pinmux.h
@@ -1,8 +1,9 @@
/********************************************************************************************
* arch/arm/src/kinetis/chip/kinetis_k60pinset.h
*
- * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt
+ * Copyright (C) 2011, 2016-2017 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -172,7 +173,7 @@
#define PIN_ADC0_SE8 (PIN_ANALOG | PIN_PORTB | PIN0)
#define PIN_ADC1_SE8 (PIN_ANALOG | PIN_PORTB | PIN0)
#define PIN_TSI0_CH0 (PIN_ANALOG | PIN_PORTB | PIN0)
-#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0)
+#define PIN_I2C0_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN0)
#define PIN_FTM1_CH0_3 (PIN_ALT3 | PIN_PORTB | PIN0)
#ifdef CONFIG_KINETIS_ENET_MDIOPULLUP
# define PIN_RMII0_MDIO (PIN_ALT4_PULLUP | PIN_PORTB | PIN0)
@@ -184,20 +185,20 @@
#define PIN_ADC0_SE9 (PIN_ANALOG | PIN_PORTB | PIN1)
#define PIN_ADC1_SE9 (PIN_ANALOG | PIN_PORTB | PIN1)
#define PIN_TSI0_CH6 (PIN_ANALOG | PIN_PORTB | PIN1)
-#define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1)
+#define PIN_I2C0_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN1)
#define PIN_FTM1_CH1_3 (PIN_ALT3 | PIN_PORTB | PIN1)
#define PIN_RMII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1)
#define PIN_MII0_MDC (PIN_ALT4 | PIN_PORTB | PIN1)
#define PIN_FTM1_QD_PHB_3 (PIN_ALT6 | PIN_PORTB | PIN1)
#define PIN_ADC0_SE12 (PIN_ANALOG | PIN_PORTB | PIN2)
#define PIN_TSI0_CH7 (PIN_ANALOG | PIN_PORTB | PIN2)
-#define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2)
+#define PIN_I2C0_SCL_2 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN2)
#define PIN_UART0_RTS_3 (PIN_ALT3 | PIN_PORTB | PIN2)
#define PIN_ENET0_1588_TMR0_1 (PIN_ALT4 | PIN_PORTB | PIN2)
#define PIN_FTM0_FLT3 (PIN_ALT6 | PIN_PORTB | PIN2)
#define PIN_ADC0_SE13 (PIN_ANALOG | PIN_PORTB | PIN3)
#define PIN_TSI0_CH8 (PIN_ANALOG | PIN_PORTB | PIN3)
-#define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3)
+#define PIN_I2C0_SDA_2 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN3)
#define PIN_UART0_CTS_3 (PIN_ALT3 | PIN_PORTB | PIN3)
#define PIN_ENET0_1588_TMR1_1 (PIN_ALT4 | PIN_PORTB | PIN3)
#define PIN_FTM0_FLT0_2 (PIN_ALT6 | PIN_PORTB | PIN3)
@@ -313,11 +314,11 @@
#define PIN_FTM2_FLT0_2 (PIN_ALT6 | PIN_PORTC | PIN9)
#define PIN_ADC1_SE6B (PIN_ANALOG | PIN_PORTC | PIN10)
#define PIN_CMP0_IN4 (PIN_ANALOG | PIN_PORTC | PIN10)
-#define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTC | PIN10)
+#define PIN_I2C1_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN10)
#define PIN_I2S0_RX_FS_2 (PIN_ALT4 | PIN_PORTC | PIN10)
#define PIN_FB_AD5 (PIN_ALT5 | PIN_PORTC | PIN10)
#define PIN_ADC1_SE7B (PIN_ANALOG | PIN_PORTC | PIN11)
-#define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTC | PIN11)
+#define PIN_I2C1_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN11)
#define PIN_I2S0_RXD_2 (PIN_ALT4 | PIN_PORTC | PIN11)
#define PIN_FB_RW (PIN_ALT5 | PIN_PORTC | PIN11)
#define PIN_UART4_RTS_1 (PIN_ALT3 | PIN_PORTC | PIN12)
@@ -387,10 +388,10 @@
#define PIN_UART0_TX_4 (PIN_ALT3 | PIN_PORTD | PIN7)
#define PIN_FTM0_CH7_2 (PIN_ALT4 | PIN_PORTD | PIN7)
#define PIN_FTM0_FLT1_2 (PIN_ALT6 | PIN_PORTD | PIN7)
-#define PIN_I2C0_SCL_3 (PIN_ALT2 | PIN_PORTD | PIN8)
+#define PIN_I2C0_SCL_3 (PIN_ALT2_OPENDRAIN | PIN_PORTD | PIN8)
#define PIN_UART5_RX_1 (PIN_ALT3 | PIN_PORTD | PIN8)
#define PIN_FB_A16 (PIN_ALT6 | PIN_PORTD | PIN8)
-#define PIN_I2C0_SDA_3 (PIN_ALT2 | PIN_PORTD | PIN9)
+#define PIN_I2C0_SDA_3 (PIN_ALT2_OPENDRAIN | PIN_PORTD | PIN9)
#define PIN_UART5_TX_1 (PIN_ALT3 | PIN_PORTD | PIN9)
#define PIN_FB_A17 (PIN_ALT6 | PIN_PORTD | PIN9)
#define PIN_UART5_RTS_1 (PIN_ALT3 | PIN_PORTD | PIN10)
@@ -416,12 +417,12 @@
#define PIN_SPI1_PCS1_2 (PIN_ALT2 | PIN_PORTE | PIN0)
#define PIN_UART1_TX_2 (PIN_ALT3 | PIN_PORTE | PIN0)
#define PIN_SDHC0_D1 (PIN_ALT4 | PIN_PORTE | PIN0)
-#define PIN_I2C1_SDA_2 (PIN_ALT6 | PIN_PORTE | PIN0)
+#define PIN_I2C1_SDA_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN0)
#define PIN_ADC1_SE5A (PIN_ANALOG | PIN_PORTE | PIN1)
#define PIN_SPI1_SOUT_2 (PIN_ALT2 | PIN_PORTE | PIN1)
#define PIN_UART1_RX_2 (PIN_ALT3 | PIN_PORTE | PIN1)
#define PIN_SDHC0_D0 (PIN_ALT4 | PIN_PORTE | PIN1)
-#define PIN_I2C1_SCL_2 (PIN_ALT6 | PIN_PORTE | PIN1)
+#define PIN_I2C1_SCL_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN1)
#define PIN_ADC1_SE6A (PIN_ANALOG | PIN_PORTE | PIN2)
#define PIN_SPI1_SCK_2 (PIN_ALT2 | PIN_PORTE | PIN2)
#define PIN_UART1_CTS_2 (PIN_ALT3 | PIN_PORTE | PIN2)
diff --git a/arch/arm/src/kinetis/chip/kinetis_k64pinmux.h b/arch/arm/src/kinetis/chip/kinetis_k64pinmux.h
index 3479099bf6c..d9894b3ff70 100644
--- a/arch/arm/src/kinetis/chip/kinetis_k64pinmux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_k64pinmux.h
@@ -1,8 +1,9 @@
/********************************************************************************************
* arch/arm/src/kinetis/chip/kinetis_k64pinmux.h
*
- * Copyright (C) 2016 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt
+ * Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -305,26 +306,26 @@
/* I2C */
-#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0)
-#define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2)
-#define PIN_I2C0_SCL_3 (PIN_ALT2 | PIN_PORTD | PIN8)
-#define PIN_I2C0_SCL_4 (PIN_ALT5 | PIN_PORTE | PIN24)
-#define PIN_I2C0_SCL_5 (PIN_ALT7 | PIN_PORTD | PIN2)
-#define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1)
-#define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3)
-#define PIN_I2C0_SDA_3 (PIN_ALT2 | PIN_PORTD | PIN9)
-#define PIN_I2C0_SDA_4 (PIN_ALT5 | PIN_PORTE | PIN25)
-#define PIN_I2C0_SDA_5 (PIN_ALT7 | PIN_PORTD | PIN3)
+#define PIN_I2C0_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN0)
+#define PIN_I2C0_SCL_2 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN2)
+#define PIN_I2C0_SCL_3 (PIN_ALT2_OPENDRAIN | PIN_PORTD | PIN8)
+#define PIN_I2C0_SCL_4 (PIN_ALT5_OPENDRAIN | PIN_PORTE | PIN24)
+#define PIN_I2C0_SCL_5 (PIN_ALT7_OPENDRAIN | PIN_PORTD | PIN2)
+#define PIN_I2C0_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN1)
+#define PIN_I2C0_SDA_2 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN3)
+#define PIN_I2C0_SDA_3 (PIN_ALT2_OPENDRAIN | PIN_PORTD | PIN9)
+#define PIN_I2C0_SDA_4 (PIN_ALT5_OPENDRAIN | PIN_PORTE | PIN25)
+#define PIN_I2C0_SDA_5 (PIN_ALT7_OPENDRAIN | PIN_PORTD | PIN3)
-#define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTC | PIN10)
-#define PIN_I2C1_SCL_2 (PIN_ALT6 | PIN_PORTE | PIN1)
-#define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTC | PIN11)
-#define PIN_I2C1_SDA_2 (PIN_ALT6 | PIN_PORTE | PIN0)
+#define PIN_I2C1_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN10)
+#define PIN_I2C1_SCL_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN1)
+#define PIN_I2C1_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN11)
+#define PIN_I2C1_SDA_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN0)
-#define PIN_I2C2_SCL_1 (PIN_ALT5 | PIN_PORTA | PIN12)
-#define PIN_I2C2_SCL_2 (PIN_ALT5 | PIN_PORTA | PIN14)
-#define PIN_I2C2_SDA_1 (PIN_ALT5 | PIN_PORTA | PIN11)
-#define PIN_I2C2_SDA_2 (PIN_ALT5 | PIN_PORTA | PIN13)
+#define PIN_I2C2_SCL_1 (PIN_ALT5_OPENDRAIN | PIN_PORTA | PIN12)
+#define PIN_I2C2_SCL_2 (PIN_ALT5_OPENDRAIN | PIN_PORTA | PIN14)
+#define PIN_I2C2_SDA_1 (PIN_ALT5_OPENDRAIN | PIN_PORTA | PIN11)
+#define PIN_I2C2_SDA_2 (PIN_ALT5_OPENDRAIN | PIN_PORTA | PIN13)
/* I2S */
diff --git a/arch/arm/src/kinetis/chip/kinetis_k66pinmux.h b/arch/arm/src/kinetis/chip/kinetis_k66pinmux.h
index b549f5c76d1..ad15c5ac024 100644
--- a/arch/arm/src/kinetis/chip/kinetis_k66pinmux.h
+++ b/arch/arm/src/kinetis/chip/kinetis_k66pinmux.h
@@ -317,31 +317,31 @@
/* I2C */
-#define PIN_I2C0_SCL_1 (PIN_ALT2 | PIN_PORTB | PIN0)
-#define PIN_I2C0_SCL_2 (PIN_ALT2 | PIN_PORTB | PIN2)
-#define PIN_I2C0_SCL_3 (PIN_ALT2 | PIN_PORTD | PIN8)
-#define PIN_I2C0_SCL_4 (PIN_ALT5 | PIN_PORTE | PIN24)
-#define PIN_I2C0_SCL_5 (PIN_ALT7 | PIN_PORTD | PIN2)
-#define PIN_I2C0_SDA_1 (PIN_ALT2 | PIN_PORTB | PIN1)
-#define PIN_I2C0_SDA_2 (PIN_ALT2 | PIN_PORTB | PIN3)
-#define PIN_I2C0_SDA_3 (PIN_ALT2 | PIN_PORTD | PIN9)
-#define PIN_I2C0_SDA_4 (PIN_ALT5 | PIN_PORTE | PIN25)
-#define PIN_I2C0_SDA_5 (PIN_ALT7 | PIN_PORTD | PIN3)
+#define PIN_I2C0_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN0)
+#define PIN_I2C0_SCL_2 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN2)
+#define PIN_I2C0_SCL_3 (PIN_ALT2_OPENDRAIN | PIN_PORTD | PIN8)
+#define PIN_I2C0_SCL_4 (PIN_ALT5_OPENDRAIN | PIN_PORTE | PIN24)
+#define PIN_I2C0_SCL_5 (PIN_ALT7_OPENDRAIN | PIN_PORTD | PIN2)
+#define PIN_I2C0_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN1)
+#define PIN_I2C0_SDA_2 (PIN_ALT2_OPENDRAIN | PIN_PORTB | PIN3)
+#define PIN_I2C0_SDA_3 (PIN_ALT2_OPENDRAIN | PIN_PORTD | PIN9)
+#define PIN_I2C0_SDA_4 (PIN_ALT5_OPENDRAIN | PIN_PORTE | PIN25)
+#define PIN_I2C0_SDA_5 (PIN_ALT7_OPENDRAIN | PIN_PORTD | PIN3)
-#define PIN_I2C1_SCL_1 (PIN_ALT2 | PIN_PORTC | PIN10)
-#define PIN_I2C1_SCL_2 (PIN_ALT6 | PIN_PORTE | PIN1)
-#define PIN_I2C1_SDA_1 (PIN_ALT2 | PIN_PORTC | PIN11)
-#define PIN_I2C1_SDA_2 (PIN_ALT6 | PIN_PORTE | PIN0)
+#define PIN_I2C1_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN10)
+#define PIN_I2C1_SCL_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN1)
+#define PIN_I2C1_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTC | PIN11)
+#define PIN_I2C1_SDA_2 (PIN_ALT6_OPENDRAIN | PIN_PORTE | PIN0)
-#define PIN_I2C2_SCL_1 (PIN_ALT5 | PIN_PORTA | PIN12)
-#define PIN_I2C2_SCL_2 (PIN_ALT5 | PIN_PORTA | PIN14)
-#define PIN_I2C2_SDA_1 (PIN_ALT5 | PIN_PORTA | PIN11)
-#define PIN_I2C2_SDA_2 (PIN_ALT5 | PIN_PORTA | PIN13)
+#define PIN_I2C2_SCL_1 (PIN_ALT5_OPENDRAIN | PIN_PORTA | PIN12)
+#define PIN_I2C2_SCL_2 (PIN_ALT5_OPENDRAIN | PIN_PORTA | PIN14)
+#define PIN_I2C2_SDA_1 (PIN_ALT5_OPENDRAIN | PIN_PORTA | PIN11)
+#define PIN_I2C2_SDA_2 (PIN_ALT5_OPENDRAIN | PIN_PORTA | PIN13)
-#define PIN_I2C3_SCL_1 (PIN_ALT2 | PIN_PORTE | PIN11)
-#define PIN_I2C3_SCL_2 (PIN_ALT4 | PIN_PORTA | PIN2)
-#define PIN_I2C3_SDA_1 (PIN_ALT2 | PIN_PORTE | PIN10)
-#define PIN_I2C3_SDA_2 (PIN_ALT4 | PIN_PORTA | PIN1)
+#define PIN_I2C3_SCL_1 (PIN_ALT2_OPENDRAIN | PIN_PORTE | PIN11)
+#define PIN_I2C3_SCL_2 (PIN_ALT4_OPENDRAIN | PIN_PORTA | PIN2)
+#define PIN_I2C3_SDA_1 (PIN_ALT2_OPENDRAIN | PIN_PORTE | PIN10)
+#define PIN_I2C3_SDA_2 (PIN_ALT4_OPENDRAIN | PIN_PORTA | PIN1)
/* I2S */
diff --git a/arch/arm/src/kinetis/chip/kinetis_kx6tpm.h b/arch/arm/src/kinetis/chip/kinetis_kx6tpm.h
new file mode 100644
index 00000000000..2dd103c6566
--- /dev/null
+++ b/arch/arm/src/kinetis/chip/kinetis_kx6tpm.h
@@ -0,0 +1,211 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/chip/kinetis_kx6tpm.h
+ *
+ * Copyright (C) 2017 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_KX6TPM_H
+#define __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_KX6TPM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/****************************************************************************
+ * Pre-processor Declarations
+ ****************************************************************************/
+
+#define KINETIS_TPM_SC_OFFSET 0x0000 /* Status and Control offset*/
+#define KINETIS_TPM_CNT_OFFSET 0x0004 /* Counter offset */
+#define KINETIS_TPM_MOD_OFFSET 0x0008 /* Modulo offset */
+#define KINETIS_TPM_C0SC_OFFSET 0x000C /* Channel 0 Status and Control offset */
+#define KINETIS_TPM_C0V_OFFSET 0x0010 /* Channel 0 Value offset */
+#define KINETIS_TPM_C1SC_OFFSET 0x0014 /* Channel 1 Status and Control offset */
+#define KINETIS_TPM_C1V_OFFSET 0x0018 /* Channel 1 Value offset */
+#define KINETIS_TPM_STATUS_OFFSET 0x0050 /* Capture and Compare Status offset */
+#define KINETIS_TPM_COMBINE_OFFSET 0x0064 /* Combine Channel Register offset */
+#define KINETIS_TPM_POL_OFFSET 0x0070 /* Channel Polarity offset */
+#define KINETIS_TPM_FILTER_OFFSET 0x0078 /* Filter Control offset */
+#define KINETIS_TPM_QDCTRL_OFFSET 0x0080 /* Quadrature Decoder Control and Status offset */
+#define KINETIS_TPM_CONF_OFFSET 0x0084 /* Configuration offset */
+
+#define KINETIS_TPM1_SC (KINETIS_TPM1_BASE + KINETIS_TPM_SC_OFFSET) /* TPM1 Status and Control */
+#define KINETIS_TPM1_CNT (KINETIS_TPM1_BASE + KINETIS_TPM_CNT_OFFSET) /* TPM1 Counter */
+#define KINETIS_TPM1_MOD (KINETIS_TPM1_BASE + KINETIS_TPM_MOD_OFFSET) /* TPM1 Modulo */
+#define KINETIS_TPM1_C0SC (KINETIS_TPM1_BASE + KINETIS_TPM_C0SC_OFFSET) /* TPM1 Channel 0 Status and Control */
+#define KINETIS_TPM1_C0V (KINETIS_TPM1_BASE + KINETIS_TPM_C0V_OFFSET) /* TPM1 Channel 0 Value */
+#define KINETIS_TPM1_C1SC (KINETIS_TPM1_BASE + KINETIS_TPM_C1SC_OFFSET) /* TPM1 Channel 1 Status and Control */
+#define KINETIS_TPM1_C1V (KINETIS_TPM1_BASE + KINETIS_TPM_C1V_OFFSET) /* TPM1 Channel 1 Value */
+#define KINETIS_TPM1_C2SC (KINETIS_TPM1_BASE + KINETIS_TPM_C2SC_OFFSET) /* TPM1 Channel 2 Status and Control */
+#define KINETIS_TPM1_C2V (KINETIS_TPM1_BASE + KINETIS_TPM_C2V_OFFSET) /* TPM1 Channel 2 Value */
+#define KINETIS_TPM1_STATUS (KINETIS_TPM1_BASE + KINETIS_TPM_STATUS_OFFSET) /* TPM1 Capture and Compare Status */
+#define KINETIS_TPM1_COMBINE (KINETIS_TPM1_BASE + KINETIS_TPM_COMBINE_OFFSET) /* TPM1 Combine Channel Register offset */
+#define KINETIS_TPM1_POL (KINETIS_TPM1_BASE + KINETIS_TPM_POL_OFFSET) /* TPM1 Channel Polarity offset */
+#define KINETIS_TPM1_FILTER (KINETIS_TPM1_BASE + KINETIS_TPM_FILTER_OFFSET) /* TPM1 Filter Control offset */
+#define KINETIS_TPM1_QDCTRL (KINETIS_TPM1_BASE + KINETIS_TPM_QDCTRL_OFFSET) /* TPM1 Quadrature Decoder Control and Status offset */
+#define KINETIS_TPM1_CONF (KINETIS_TPM1_BASE + KINETIS_TPM_CONF_OFFSET) /* TPM1 Configuration */
+
+#define KINETIS_TPM2_SC (KINETIS_TPM2_BASE + KINETIS_TPM_SC_OFFSET) /* TPM2 Status and Control */
+#define KINETIS_TPM2_CNT (KINETIS_TPM2_BASE + KINETIS_TPM_CNT_OFFSET) /* TPM2 Counter */
+#define KINETIS_TPM2_MOD (KINETIS_TPM2_BASE + KINETIS_TPM_MOD_OFFSET) /* TPM2 Modulo */
+#define KINETIS_TPM2_C0SC (KINETIS_TPM2_BASE + KINETIS_TPM_C0SC_OFFSET) /* TPM2 Channel 0 Status and Control */
+#define KINETIS_TPM2_C0V (KINETIS_TPM2_BASE + KINETIS_TPM_C0V_OFFSET) /* TPM2 Channel 0 Value */
+#define KINETIS_TPM2_C1SC (KINETIS_TPM2_BASE + KINETIS_TPM_C1SC_OFFSET) /* TPM2 Channel 1 Status and Control */
+#define KINETIS_TPM2_C1V (KINETIS_TPM2_BASE + KINETIS_TPM_C1V_OFFSET) /* TPM2 Channel 1 Value */
+#define KINETIS_TPM2_C2SC (KINETIS_TPM2_BASE + KINETIS_TPM_C2SC_OFFSET) /* TPM2 Channel 2 Status and Control */
+#define KINETIS_TPM2_C2V (KINETIS_TPM2_BASE + KINETIS_TPM_C2V_OFFSET) /* TPM2 Channel 2 Value */
+#define KINETIS_TPM2_STATUS (KINETIS_TPM2_BASE + KINETIS_TPM_STATUS_OFFSET) /* TPM2 Capture and Compare Status */
+#define KINETIS_TPM2_COMBINE (KINETIS_TPM2_BASE + KINETIS_TPM_COMBINE_OFFSET) /* TPM2 Combine Channel Register offset */
+#define KINETIS_TPM2_POL (KINETIS_TPM2_BASE + KINETIS_TPM_POL_OFFSET) /* TPM2 Channel Polarity offset */
+#define KINETIS_TPM2_FILTER (KINETIS_TPM2_BASE + KINETIS_TPM_FILTER_OFFSET) /* TPM2 Filter Control offset */
+#define KINETIS_TPM2_QDCTRL (KINETIS_TPM2_BASE + KINETIS_TPM_QDCTRL_OFFSET) /* TPM2 Quadrature Decoder Control and Status offset */
+#define KINETIS_TPM2_CONF (KINETIS_TPM2_BASE + KINETIS_TPM_CONF_OFFSET) /* TPM2 Configuration */
+
+#define TPM_SC_PS_SHIFT 0 /* Bits 0-2: Prescale Factor Selection */
+#define TPM_SC_PS_MASK (7 << TPM_SC_PS_SHIFT)
+# define TPM_SC_PS_DIV1 (0 << TPM_SC_PS_SHIFT) /* Divide Clock by 1 */
+# define TPM_SC_PS_DIV2 (1 << TPM_SC_PS_SHIFT) /* Divide Clock by 2 */
+# define TPM_SC_PS_DIV4 (2 << TPM_SC_PS_SHIFT) /* Divide Clock by 4 */
+# define TPM_SC_PS_DIV8 (3 << TPM_SC_PS_SHIFT) /* Divide Clock by 8 */
+# define TPM_SC_PS_DIV16 (4 << TPM_SC_PS_SHIFT) /* Divide Clock by 16 */
+# define TPM_SC_PS_DIV32 (5 << TPM_SC_PS_SHIFT) /* Divide Clock by 32 */
+# define TPM_SC_PS_DIV64 (6 << TPM_SC_PS_SHIFT) /* Divide Clock by 64 */
+# define TPM_SC_PS_DIV128 (7 << TPM_SC_PS_SHIFT) /* Divide Clock by 128 */
+
+#define TPM_SC_CMOD_SHIFT 3 /* Bits 3-4: Clock Mode Selection */
+#define TPM_SC_CMOD_MASK (3 << TPM_SC_CMOD_SHIFT)
+# define TPM_SC_CMOD_DIS (0 << TPM_SC_CMOD_SHIFT) /* TPM counter is disabled */
+# define TPM_SC_CMOD_LPTPM_CLK (1 << TPM_SC_CMOD_SHIFT) /* TPM increments on every counter clock */
+# define TPM_SC_CMOD_LPTPM_EXTCLK (2 << TPM_SC_CMOD_SHIFT) /* TPM increments on rising edge of EXTCLK */
+
+#define TPM_SC_CPWMS (1 << 5) /* Bit 5: Center-aligned PWM Select */
+#define TPM_SC_TOIE (1 << 6) /* Bit 6: Timer Overflow Interrupt Enable */
+#define TPM_SC_TOF (1 << 7) /* Bit 7: Timer Overflow Flag*/
+#define TPM_SC_DMA (1 << 8) /* Bit 8: DMA Enable*/
+ /* Bits 9-31: Reserved */
+
+#define TPM_CNT_SHIFT 0 /* Bits 0-15: Counter value */
+#define TPM_CNT_MASK (0xffff << TPM_COUNT_SHIFT) /* Any write clears Count */
+ /* Bits 16-31: Reserved */
+
+#define TPM_MOD_SHIFT 0 /* Bits 0-15: Mod value */
+#define TPM_MOD_MASK (0xffff << TPM_MOD_SHIFT) /* This field must be written with single 16 or 32-bit access */
+ /* Bits 16-31: Reserved */
+
+#define TPM_CnSC_DMA (1 << 0) /* Bit 0: Enables DMA transfers for the channel */
+ /* Bit 1: Reserved*/
+#define TPM_CnSC_ELSA (1 << 2) /* Bit 2: Edge or Level Select */
+#define TPM_CnSC_ELSB (1 << 3) /* Bit 3: Edge or Level Select */
+#define TPM_CnSC_MSA (1 << 4) /* Bit 4: Channel Mode Select */
+#define TPM_CnSC_MSB (1 << 5) /* Bit 5: Channel Mode Select */
+#define TPM_CnSC_CHIE (1 << 6) /* Bit 6: Channel Interrupt Enable */
+#define TPM_CnSC_CHF (1 << 7) /* Bit 7: Channel Flag */
+ /* Bits 8-31: Reserved */
+
+#define TPM_VAL_SHIFT 0 /* Bits 0-15: Channel value */
+#define TPM_VAL_MASK (0xffff << TPM_VAL_SHIFT) /* Captured TPM counter value of the input modes or
+ * the match value for the output modes. This field
+ * must be written with single 16 or 32-bit access.*/
+ /* Bits 16-31: Reserved */
+
+#define TPM_STATUS_CH0F (1 << 0) /* Bit 0: Channel 0 Flag */
+#define TPM_STATUS_CH1F (1 << 1) /* Bit 1: Channel 1 Flag */
+ /* Bits 2-7: Reserved */
+#define TPM_STATUS_TOF (1 << 8) /* Bit 8: Timer Overflow Flag */
+ /* Bits 9-31: Reserved */
+
+#define TPM_COMBINE_COMBINE0 (1 << 0) /* Bit 0: Combine Channels 0 and 1 */
+#define TPM_COMBINE_COMSWAP0 (1 << 1) /* Bit 1: Combine Channel 0 and 1 Swap */
+ /* Bits 2-7: Reserved */
+ /* Bits 8-31: Reserved */
+
+#define TPM_POL_POL0 (1 << 0) /* Bit 0: Channel 0 Polarity */
+#define TPM_POL_POL1 (1 << 1) /* Bit 1: Channel 1 Polarity */
+ /* Bits 2-31: Reserved */
+
+#define TPM_FILTER_CH0FVAL_SHIFT 0 /* Bits 0-3: Channel 0 Filter Value */
+#define TPM_FILTER_CH0FVAL_MASK (0xf << TPM_FILTER_CH0FVAL_SHIFT)
+#define TPM_FILTER_CH1FVAL_SHIFT 4 /* Bits 4-7: Channel 1 Filter Value */
+#define TPM_FILTER_CH1FVAL_MASK (0xf << TPM_FILTER_CH1FVAL_SHIFT)
+
+#define TPM_QDCTRL_QDCTRL (1 << 0) /* Bit 0: Enables the quadrature decoder mode */
+#define TPM_QDCTRL_TOFDIR (1 << 1) /* Bit 1: Indicates if the TOF bit was set (Read Only) */
+#define TPM_QDCTRL_QUADIR (1 << 2) /* Bit 2: Counter Direction in Quadrature Decode Mode (Read Only) */
+#define TPM_QDCTRL_QUADMODE (1 << 3) /* Bit 3: Quadrature Decoder Mode */
+ /* Bits 4-31: Reserved */
+
+#define TPM_CONF_DOZEEN (1 << 5) /* Bit 5: Doze Enable */
+#define TPM_CONF_DBGMODE_SHIFT 6 /* Bits 6-7: Debug Mode */
+#define TPM_CONF_DBGMODE_MASK (3 << TPM_CONF_DBGMODE_SHIFT)
+# define TPM_CONF_DBGMODE_PAUSE (0 << TPM_CONF_DBGMODE_SHIFT) /* TPM counter will pause during DEBUG mode */
+# define TPM_CONF_DBGMODE_CONT (3 << TPM_CONF_DBGMODE_SHIFT) /* TPM counter continue working in DEBUG mode */
+#define TPM_CONF_GTBSYNC (1 << 8) /* Bit 8: Global Time Base Synchronization */
+#define TPM_CONF_GTBEEN (1 << 9) /* Bit 9: Global Time Base Enable */
+ /* Bits 10-15: Reserved */
+#define TPM_CONF_CSOT (1 << 16) /* Bit 16: Counter Start On Trigger */
+#define TPM_CONF_CSOO (1 << 17) /* Bit 17: Counter Stop On Overflow */
+#define TPM_CONF_CROT (1 << 18) /* Bit 18: Counter Reload On Trigger */
+#define TPM_CONF_CPOT (1 << 19) /* Bit 19: Counter Pause On Trigger */
+ /* Bits 20-21: Reserved */
+#define TPM_CONF_TRGPOL (1 << 22) /* Bit 22: Trigger Polarity */
+#define TPM_CONF_TRGSRC (1 << 23) /* Bit 23: Trigger Source */
+
+#define TPM_CONF_TRGSEL_SHIFT 24 /* Bits 24-27: Trigger Select */
+#define TPM_CONF_TRGSEL_MASK (0xf << TPM_CONF_TRGSEL_SHIFT)
+ /* Internal TPM_CONF_TRGSRC set */
+# define TPM_CONF_TRGSEL_INTC0 (0 << TPM_CONF_TRGSEL_SHIFT) /* Internal Channel 0 pin input capture */
+# define TPM_CONF_TRGSEL_INTC1 (2 << TPM_CONF_TRGSEL_SHIFT) /* Internal Channel 1 pin input capture */
+# define TPM_CONF_TRGSEL_INTC01 (3 << TPM_CONF_TRGSEL_SHIFT) /* Internal Channel 0 or 1 pin input capture */
+
+# define TPM_CONF_TRGSEL_EXTRG_IN (0 << TPM_CONF_TRGSEL_SHIFT) /* External trigger pin input */
+# define TPM_CONF_TRGSEL_CMP0 (1 << TPM_CONF_TRGSEL_SHIFT) /* CPM0 output */
+# define TPM_CONF_TRGSEL_CMP1 (2 << TPM_CONF_TRGSEL_SHIFT) /* CPM1 output */
+# define TPM_CONF_TRGSEL_CMP2 (3 << TPM_CONF_TRGSEL_SHIFT) /* CPM2 output */
+# define TPM_CONF_TRGSEL_PIT0 (4 << TPM_CONF_TRGSEL_SHIFT) /* PIT trigger 0 */
+# define TPM_CONF_TRGSEL_PIT1 (5 << TPM_CONF_TRGSEL_SHIFT) /* PIT trigger 1 */
+# define TPM_CONF_TRGSEL_PIT2 (6 << TPM_CONF_TRGSEL_SHIFT) /* PIT trigger 2 */
+# define TPM_CONF_TRGSEL_PIT3 (7 << TPM_CONF_TRGSEL_SHIFT) /* PIT trigger 3 */
+# define TPM_CONF_TRGSEL_FTM0 (8 << TPM_CONF_TRGSEL_SHIFT) /* FTM0 initialization trigger and channel triggers */
+# define TPM_CONF_TRGSEL_FTM1 (9 << TPM_CONF_TRGSEL_SHIFT) /* FTM1 initialization trigger and channel triggers */
+# define TPM_CONF_TRGSEL_FTM2 (10 << TPM_CONF_TRGSEL_SHIFT) /* FTM2 initialization trigger and channel triggers */
+# define TPM_CONF_TRGSEL_FTM3 (11 << TPM_CONF_TRGSEL_SHIFT) /* FTM3 initialization trigger and channel triggers */
+# define TPM_CONF_TRGSEL_RTC_ALRM (12 << TPM_CONF_TRGSEL_SHIFT) /* RTC Alarm */
+# define TPM_CONF_TRGSEL_RTC_SECS (13 << TPM_CONF_TRGSEL_SHIFT) /* RTC Seconds */
+# define TPM_CONF_TRGSEL_LPTMR (14 << TPM_CONF_TRGSEL_SHIFT) /* LPTMR trigger */
+# define TPM_CONF_TRGSEL_SW (15 << TPM_CONF_TRGSEL_SHIFT) /* Software Trigger */
+
+#endif /* __ARCH_ARM_SRC_KINETIS_CHIP_KINETIS_KX6TPM_H */
diff --git a/arch/arm/src/kinetis/chip/kinetis_osc.h b/arch/arm/src/kinetis/chip/kinetis_osc.h
index 69a7b8a30c8..e61f0a8c1c6 100644
--- a/arch/arm/src/kinetis/chip/kinetis_osc.h
+++ b/arch/arm/src/kinetis/chip/kinetis_osc.h
@@ -1,7 +1,7 @@
/********************************************************************************************
* arch/arm/src/kinetis/chip/kinetis_osc.h
*
- * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2011, 2016-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -51,10 +51,12 @@
/* Register Offsets *************************************************************************/
#define KINETIS_OSC_CR_OFFSET 0x0000 /* OSC Control Register */
+#define KINETIS_OSC_DIV_OFFSET 0x0002 /* OSC CLock divider register */
/* Register Addresses ***********************************************************************/
#define KINETIS_OSC_CR (KINETIS_OSC_BASE+KINETIS_OSC_CR_OFFSET)
+#define KINETIS_OSC_DIV (KINETIS_OSC_BASE+KINETIS_OSC_DIV_OFFSET)
/* Register Bit Definitions *****************************************************************/
@@ -69,6 +71,15 @@
#define OSC_CR_SC8P (1 << 1) /* Bit 1: Oscillator 8 pF Capacitor Load Configure */
#define OSC_CR_SC16P (1 << 0) /* Bit 0: Oscillator 16 pF Capacitor Load Configure */
+/* OSC Control Register (8-bit) */
+ /* Bits 0-5: Reserved */
+#define OSC_DIV_ERPS_SHIFT 6 /* Bits 6-7: ERCLK prescaler */
+#define OSC_DIV_ERPS_MASK (3 << OSC_DIV_ERPS_SHIFT)
+# define OSC_DIV_ERPS_DIV1 (0 << OSC_DIV_ERPS_SHIFT) /* The divisor ratio is 1 */
+# define OSC_DIV_ERPS_DIV2 (1 << OSC_DIV_ERPS_SHIFT) /* The divisor ratio is 2 */
+# define OSC_DIV_ERPS_DIV3 (2 << OSC_DIV_ERPS_SHIFT) /* The divisor ratio is 4 */
+# define OSC_DIV_ERPS_DIV8 (3 << OSC_DIV_ERPS_SHIFT) /* The divisor ratio is 8 */
+
/********************************************************************************************
* Public Types
********************************************************************************************/
diff --git a/arch/arm/src/kinetis/chip/kinetis_sim.h b/arch/arm/src/kinetis/chip/kinetis_sim.h
index 3e6cb6a6efb..a1ffe6721e3 100644
--- a/arch/arm/src/kinetis/chip/kinetis_sim.h
+++ b/arch/arm/src/kinetis/chip/kinetis_sim.h
@@ -328,7 +328,7 @@
divided by the PLLFLLCLK fractional divider
as configured by SIM_CLKDIV3[PLLFLLFRAC, PLLFLLDIV] */
# define SIM_SOPT2_TPMSRC_OCSERCLK (2 << SIM_SOPT2_TPMSRC_SHIFT) /* OSCERCLK clock */
-# define SIM_SOPT2_TPMSRC_EXTBYP (3 << SIM_SOPT2_TPMSRC_SHIFT) /* MCGIRCLK clock */
+# define SIM_SOPT2_TPMSRC_MCGIRCLK (3 << SIM_SOPT2_TPMSRC_SHIFT) /* MCGIRCLK clock */
# endif
# if defined(KINETIS_SIM_HAS_SOPT2_I2SSRC)
# define SIM_SOPT2_I2SSRC_SHIFT (24) /* Bits 24-25: I2S master clock source select */
@@ -348,7 +348,7 @@
divided by the PLLFLLCLK fractional divider
as configured by SIM_CLKDIV3[PLLFLLFRAC, PLLFLLDIV] */
# define SIM_SOPT2_LPUARTSRC_OCSERCLK (2 << SIM_SOPT2_LPUARTSRC_SHIFT) /* OSCERCLK clock */
-# define SIM_SOPT2_LPUARTSRC_EXTBYP (3 << SIM_SOPT2_LPUARTSRC_SHIFT) /* MCGIRCLK clock */
+# define SIM_SOPT2_LPUARTSRC_MCGIRCLK (3 << SIM_SOPT2_LPUARTSRC_SHIFT) /* MCGIRCLK clock */
# endif
# if defined(KINETIS_SIM_HAS_SOPT2_SDHCSRC)
# define SIM_SOPT2_SDHCSRC_SHIFT (28) /* Bits 28-29: SDHC clock source select */
diff --git a/arch/arm/src/kinetis/kinetis.h b/arch/arm/src/kinetis/kinetis.h
index 3f171e223b5..89ab7917411 100644
--- a/arch/arm/src/kinetis/kinetis.h
+++ b/arch/arm/src/kinetis/kinetis.h
@@ -468,7 +468,8 @@ void kinetis_lpuartreset(uintptr_t uart_base);
#ifdef HAVE_UART_DEVICE
void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud, uint32_t clock,
unsigned int parity, unsigned int nbits,
- unsigned int stop2);
+ unsigned int stop2,
+ bool iflow, bool oflow);
#endif
/****************************************************************************
@@ -482,7 +483,8 @@ void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud, uint32_t clock,
#ifdef HAVE_LPUART_DEVICE
void kinetis_lpuartconfigure(uintptr_t uart_base, uint32_t baud, uint32_t clock,
unsigned int parity, unsigned int nbits,
- unsigned int stop2);
+ unsigned int stop2,
+ bool iflow, bool oflow);
#endif
/************************************************************************************
diff --git a/arch/arm/src/kinetis/kinetis_clockconfig.c b/arch/arm/src/kinetis/kinetis_clockconfig.c
index b954f33be2e..28218fcd86c 100644
--- a/arch/arm/src/kinetis/kinetis_clockconfig.c
+++ b/arch/arm/src/kinetis/kinetis_clockconfig.c
@@ -49,6 +49,7 @@
#include "chip/kinetis_pmc.h"
#include "chip/kinetis_llwu.h"
#include "chip/kinetis_pinmux.h"
+#include "chip/kinetis_osc.h"
#include
@@ -199,6 +200,18 @@ void kinetis_pllconfig(void)
#endif
uint8_t regval8;
+#if defined(BOARD_OSC_CR)
+ /* Use complete BOARD_OSC_CR settings */
+
+ putreg8(BOARD_OSC_CR, KINETIS_OSC_CR);
+#endif
+
+#if defined(BOARD_OSC_DIV)
+ /* Use complete BOARD_OSC_DIV settings */
+
+ putreg8(BOARD_OSC_DIV, KINETIS_OSC_DIV);
+#endif
+
#if defined(BOARD_MCG_C2)
/* Use complete BOARD_MCG_C2 settings */
diff --git a/arch/arm/src/kinetis/kinetis_lowputc.c b/arch/arm/src/kinetis/kinetis_lowputc.c
index 31bb32f697b..bfc56dd069f 100644
--- a/arch/arm/src/kinetis/kinetis_lowputc.c
+++ b/arch/arm/src/kinetis/kinetis_lowputc.c
@@ -41,6 +41,7 @@
#include
#include
+#include
#include
#include
@@ -59,6 +60,58 @@
* Pre-processor Definitions
****************************************************************************/
+/* Default hardware flow control */
+
+#if !defined(CONFIG_UART0_IFLOWCONTROL)
+# define CONFIG_UART0_IFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART0_OFLOWCONTROL)
+# define CONFIG_UART0_OFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART1_IFLOWCONTROL)
+# define CONFIG_UART1_IFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART1_OFLOWCONTROL)
+# define CONFIG_UART1_OFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART2_IFLOWCONTROL)
+# define CONFIG_UART2_IFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART2_OFLOWCONTROL)
+# define CONFIG_UART2_OFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART3_IFLOWCONTROL)
+# define CONFIG_UART3_IFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART3_OFLOWCONTROL)
+# define CONFIG_UART3_OFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART4_IFLOWCONTROL)
+# define CONFIG_UART4_IFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART4_OFLOWCONTROL)
+# define CONFIG_UART4_OFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART5_IFLOWCONTROL)
+# define CONFIG_UART5_IFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_UART5_OFLOWCONTROL)
+# define CONFIG_UART5_OFLOWCONTROL 0
+#endif
+
+#if !defined(CONFIG_LPUART0_IFLOWCONTROL)
+# define CONFIG_LPUART0_IFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_LPUART0_OFLOWCONTROL)
+# define CONFIG_LPUART0_OFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_LPUART1_IFLOWCONTROL)
+# define CONFIG_LPUART1_IFLOWCONTROL 0
+#endif
+#if !defined(CONFIG_LPUART1_OFLOWCONTROL)
+# define CONFIG_LPUART1_OFLOWCONTROL 0
+#endif
+
/* Select UART parameters for the selected console */
#if defined(HAVE_UART_CONSOLE)
@@ -69,6 +122,8 @@
# define CONSOLE_BITS CONFIG_UART0_BITS
# define CONSOLE_2STOP CONFIG_UART0_2STOP
# define CONSOLE_PARITY CONFIG_UART0_PARITY
+# define CONSOLE_IFLOW CONFIG_UART0_IFLOWCONTROL
+# define CONSOLE_OFLOW CONFIG_UART0_OFLOWCONTROL
# elif defined(CONFIG_UART1_SERIAL_CONSOLE)
# define CONSOLE_BASE KINETIS_UART1_BASE
# define CONSOLE_FREQ BOARD_CORECLK_FREQ
@@ -76,6 +131,8 @@
# define CONSOLE_BITS CONFIG_UART1_BITS
# define CONSOLE_2STOP CONFIG_UART1_2STOP
# define CONSOLE_PARITY CONFIG_UART1_PARITY
+# define CONSOLE_IFLOW CONFIG_UART1_IFLOWCONTROL
+# define CONSOLE_OFLOW CONFIG_UART1_OFLOWCONTROL
# elif defined(CONFIG_UART2_SERIAL_CONSOLE)
# define CONSOLE_BASE KINETIS_UART2_BASE
# define CONSOLE_FREQ BOARD_BUS_FREQ
@@ -83,6 +140,8 @@
# define CONSOLE_BITS CONFIG_UART2_BITS
# define CONSOLE_2STOP CONFIG_UART2_2STOP
# define CONSOLE_PARITY CONFIG_UART2_PARITY
+# define CONSOLE_IFLOW CONFIG_UART2_IFLOWCONTROL
+# define CONSOLE_OFLOW CONFIG_UART2_OFLOWCONTROL
# elif defined(CONFIG_UART3_SERIAL_CONSOLE)
# define CONSOLE_BASE KINETIS_UART3_BASE
# define CONSOLE_FREQ BOARD_BUS_FREQ
@@ -90,6 +149,8 @@
# define CONSOLE_BITS CONFIG_UART3_BITS
# define CONSOLE_2STOP CONFIG_UART3_2STOP
# define CONSOLE_PARITY CONFIG_UART3_PARITY
+# define CONSOLE_IFLOW CONFIG_UART3_IFLOWCONTROL
+# define CONSOLE_OFLOW CONFIG_UART3_OFLOWCONTROL
# elif defined(CONFIG_UART4_SERIAL_CONSOLE)
# define CONSOLE_BASE KINETIS_UART4_BASE
# define CONSOLE_FREQ BOARD_BUS_FREQ
@@ -97,6 +158,8 @@
# define CONSOLE_BITS CONFIG_UART4_BITS
# define CONSOLE_2STOP CONFIG_UART4_2STOP
# define CONSOLE_PARITY CONFIG_UART4_PARITY
+# define CONSOLE_IFLOW CONFIG_UART4_IFLOWCONTROL
+# define CONSOLE_OFLOW CONFIG_UART4_OFLOWCONTROL
# elif defined(CONFIG_UART5_SERIAL_CONSOLE)
# define CONSOLE_BASE KINETIS_UART5_BASE
# define CONSOLE_FREQ BOARD_BUS_FREQ
@@ -104,6 +167,8 @@
# define CONSOLE_BITS CONFIG_UART5_BITS
# define CONSOLE_2STOP CONFIG_UART5_2STOP
# define CONSOLE_PARITY CONFIG_UART5_PARITY
+# define CONSOLE_IFLOW CONFIG_UART5_IFLOWCONTROL
+# define CONSOLE_OFLOW CONFIG_UART5_OFLOWCONTROL
# elif defined(HAVE_UART_CONSOLE)
# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting"
# endif
@@ -115,6 +180,8 @@
# define CONSOLE_PARITY CONFIG_LPUART0_PARITY
# define CONSOLE_BITS CONFIG_LPUART0_BITS
# define CONSOLE_2STOP CONFIG_LPUART0_2STOP
+# define CONSOLE_IFLOW CONFIG_LPUART0_IFLOWCONTROL
+# define CONSOLE_OFLOW CONFIG_LPUART0_OFLOWCONTROL
# elif defined(CONFIG_LPUART1_SERIAL_CONSOLE)
# define CONSOLE_BASE KINETIS_LPUART1_BASE
# define CONSOLE_FREQ BOARD_LPUART1_FREQ
@@ -122,6 +189,8 @@
# define CONSOLE_PARITY CONFIG_LPUART1_PARITY
# define CONSOLE_BITS CONFIG_LPUART1_BITS
# define CONSOLE_2STOP CONFIG_LPUART1_2STOP
+# define CONSOLE_IFLOW CONFIG_LPUART1_IFLOWCONTROL
+# define CONSOLE_OFLOW CONFIG_LPUART1_OFLOWCONTROL
# else
# error "No LPUART console is selected"
# endif
@@ -271,26 +340,62 @@ void kinetis_lowsetup(void)
# ifdef CONFIG_KINETIS_UART0
kinetis_pinconfig(PIN_UART0_TX);
kinetis_pinconfig(PIN_UART0_RX);
+# if CONFIG_UART0_IFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART0_RTS);
+# endif
+# if CONFIG_UART0_OFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART0_CTS);
+# endif
# endif
# ifdef CONFIG_KINETIS_UART1
kinetis_pinconfig(PIN_UART1_TX);
kinetis_pinconfig(PIN_UART1_RX);
+# if CONFIG_UART1_IFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART1_RTS);
+# endif
+# if CONFIG_UART1_OFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART1_CTS);
+# endif
# endif
# ifdef CONFIG_KINETIS_UART2
kinetis_pinconfig(PIN_UART2_TX);
kinetis_pinconfig(PIN_UART2_RX);
+# if CONFIG_UART2_IFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART2_RTS);
+# endif
+# if CONFIG_UART2_OFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART2_CTS);
+# endif
# endif
# ifdef CONFIG_KINETIS_UART3
kinetis_pinconfig(PIN_UART3_TX);
kinetis_pinconfig(PIN_UART3_RX);
+# if CONFIG_UART3_IFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART3_RTS);
+# endif
+# if CONFIG_UART3_OFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART3_CTS);
+# endif
# endif
# ifdef CONFIG_KINETIS_UART4
kinetis_pinconfig(PIN_UART4_TX);
kinetis_pinconfig(PIN_UART4_RX);
+# if CONFIG_UART4_IFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART4_RTS);
+# endif
+# if CONFIG_UART4_OFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART4_CTS);
+# endif
# endif
# ifdef CONFIG_KINETIS_UART5
kinetis_pinconfig(PIN_UART5_TX);
kinetis_pinconfig(PIN_UART5_RX);
+# if CONFIG_UART5_IFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART5_RTS);
+# endif
+# if CONFIG_UART5_OFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_UART5_CTS);
+# endif
# endif
/* Configure the console (only) now. Other UARTs will be configured
@@ -300,7 +405,8 @@ void kinetis_lowsetup(void)
# if defined(HAVE_UART_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG)
kinetis_uartconfigure(CONSOLE_BASE, CONSOLE_BAUD, CONSOLE_FREQ, \
- CONSOLE_PARITY, CONSOLE_BITS, CONSOLE_2STOP);
+ CONSOLE_PARITY, CONSOLE_BITS, CONSOLE_2STOP, \
+ CONSOLE_IFLOW, CONSOLE_OFLOW);
# endif
#endif /* HAVE_UART_DEVICE */
@@ -327,17 +433,30 @@ void kinetis_lowsetup(void)
# ifdef CONFIG_KINETIS_LPUART0
kinetis_pinconfig(PIN_LPUART0_TX);
kinetis_pinconfig(PIN_LPUART0_RX);
+# if CONFIG_LPUART0_IFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_LPUART0_RTS);
+# endif
+# if CONFIG_LPUART0_OFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_LOUART0_CTS);
+# endif
# endif
# ifdef CONFIG_KINETIS_LPUART1
kinetis_pinconfig(PIN_LPUART1_TX);
kinetis_pinconfig(PIN_LPUART1_RX);
+# if CONFIG_LPUART1_IFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_LPUART1_RTS);
+# endif
+# if CONFIG_LPUART1_OFLOWCONTROL == 1
+ kinetis_pinconfig(PIN_LOUART1_CTS);
+# endif
# endif
# if defined(HAVE_LPUART_CONSOLE) && !defined(CONFIG_SUPPRESS_LPUART_CONFIG)
kinetis_lpuartconfigure(CONSOLE_BASE, CONSOLE_BAUD, CONSOLE_FREQ, \
- CONSOLE_PARITY, CONSOLE_BITS, CONSOLE_2STOP);
+ CONSOLE_PARITY, CONSOLE_BITS, CONSOLE_2STOP, \
+ CONSOLE_IFLOW, CONSOLE_OFLOW);
# endif
#endif /* HAVE_LPUART_DEVICE */
}
@@ -395,7 +514,8 @@ void kinetis_lpuartreset(uintptr_t uart_base)
#ifdef HAVE_UART_DEVICE
void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud,
uint32_t clock, unsigned int parity,
- unsigned int nbits, unsigned int stop2)
+ unsigned int nbits, unsigned int stop2,
+ bool iflow, bool oflow)
{
uint32_t sbr;
uint32_t brfa;
@@ -542,6 +662,27 @@ void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud,
putreg8(0, uart_base+KINETIS_UART_PFIFO_OFFSET);
#endif
+ /* Hardware flow control */
+
+ regval = getreg8(uart_base+KINETIS_UART_MODEM_OFFSET);
+ regval &= ~(UART_MODEM_TXCTSE | UART_MODEM_RXRTSE);
+
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+ if (iflow)
+ {
+ regval |= UART_MODEM_RXRTSE;
+ }
+#endif
+
+#ifdef CONFIG_SERIAL_OFLOWCONTROL
+ if (oflow)
+ {
+ regval |= UART_MODEM_TXCTSE;
+ }
+#endif
+
+ putreg8(regval, uart_base+KINETIS_UART_MODEM_OFFSET);
+
/* Now we can (re-)enable the transmitter and receiver */
regval = getreg8(uart_base+KINETIS_UART_C2_OFFSET);
@@ -561,7 +702,8 @@ void kinetis_uartconfigure(uintptr_t uart_base, uint32_t baud,
#ifdef HAVE_LPUART_DEVICE
void kinetis_lpuartconfigure(uintptr_t uart_base, uint32_t baud,
uint32_t clock, unsigned int parity,
- unsigned int nbits, unsigned int stop2)
+ unsigned int nbits, unsigned int stop2,
+ bool iflow, bool oflow)
{
uint32_t sbrreg;
uint32_t osrreg;
@@ -711,6 +853,25 @@ void kinetis_lpuartconfigure(uintptr_t uart_base, uint32_t baud,
DEBUGASSERT(nbits == 8);
}
+ /* Hardware flow control */
+
+ regval = getreg32(uart_base+KINETIS_LPUART_MODIR_OFFSET);
+ regval &= ~(UART_MODEM_TXCTSE | UART_MODEM_RXRTSE);
+
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+ if (iflow)
+ {
+ regval |= LPUART_MODIR_RXRTSE;
+ }
+#endif
+ #ifdef CONFIG_SERIAL_OFLOWCONTROL
+ if (oflow)
+ {
+ regval |= LPUART_MODIR_TXCTSE;
+ }
+#endif
+ putreg32(regval, uart_base+KINETIS_LPUART_MODIR_OFFSET);
+
/* Now we can (re-)enable the transmitter and receiver */
regval |= (LPUART_CTRL_RE | LPUART_CTRL_TE);
diff --git a/arch/arm/src/kinetis/kinetis_lpserial.c b/arch/arm/src/kinetis/kinetis_lpserial.c
index 2980f18b8d4..515f1f370e0 100644
--- a/arch/arm/src/kinetis/kinetis_lpserial.c
+++ b/arch/arm/src/kinetis/kinetis_lpserial.c
@@ -53,6 +53,11 @@
#include
#include
+#ifdef CONFIG_SERIAL_TERMIOS
+# include
+#endif
+
+#include
#include
#include "up_arch.h"
@@ -61,6 +66,7 @@
#include "kinetis_config.h"
#include "chip.h"
#include "chip/kinetis_lpuart.h"
+#include "chip/kinetis_pinmux.h"
#include "kinetis.h"
/****************************************************************************
@@ -153,6 +159,18 @@ struct kinetis_dev_s
uint8_t parity; /* 0=none, 1=odd, 2=even */
uint8_t bits; /* Number of bits (8 or 9) */
uint8_t stop2; /* Use 2 stop bits */
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+ bool iflow; /* input flow control (RTS) enabled */
+#endif
+#ifdef CONFIG_SERIAL_OFLOWCONTROL
+ bool oflow; /* output flow control (CTS) enabled */
+#endif
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+ uint32_t rts_gpio; /* UART RTS GPIO pin configuration */
+#endif
+#ifdef CONFIG_SERIAL_OFLOWCONTROL
+ uint32_t cts_gpio; /* UART CTS GPIO pin configuration */
+#endif
};
/****************************************************************************
@@ -168,6 +186,10 @@ static int kinetis_ioctl(struct file *filep, int cmd, unsigned long arg);
static int kinetis_receive(struct uart_dev_s *dev, uint32_t *status);
static void kinetis_rxint(struct uart_dev_s *dev, bool enable);
static bool kinetis_rxavailable(struct uart_dev_s *dev);
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+static bool kinetis_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered,
+ bool upper);
+#endif
static void kinetis_send(struct uart_dev_s *dev, int ch);
static void kinetis_txint(struct uart_dev_s *dev, bool enable);
static bool kinetis_txready(struct uart_dev_s *dev);
@@ -187,7 +209,7 @@ static const struct uart_ops_s g_lpuart_ops =
.rxint = kinetis_rxint,
.rxavailable = kinetis_rxavailable,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
- .rxflowcontrol = NULL,
+ .rxflowcontrol = kinetis_rxflowcontrol,
#endif
.send = kinetis_send,
.txint = kinetis_txint,
@@ -219,6 +241,14 @@ static struct kinetis_dev_s g_lpuart0priv =
.parity = CONFIG_LPUART0_PARITY,
.bits = CONFIG_LPUART0_BITS,
.stop2 = CONFIG_LPUART0_2STOP,
+#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART0_OFLOWCONTROL)
+ .oflow = true,
+ .cts_gpio = PIN_LPUART0_CTS,
+#endif
+#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART0_IFLOWCONTROL)
+ .iflow = true,
+ .rts_gpio = PIN_LPUART0_RTS,
+#endif
};
static uart_dev_t g_lpuart0port =
@@ -251,6 +281,14 @@ static struct kinetis_dev_s g_lpuart1priv =
.parity = CONFIG_LPUART1_PARITY,
.bits = CONFIG_LPUART1_BITS,
.stop2 = CONFIG_LPUART1_2STOP,
+#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_LPUART1_OFLOWCONTROL)
+ .oflow = true,
+ .cts_gpio = PIN_LPUART1_CTS,
+#endif
+#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_LPUART1_IFLOWCONTROL)
+ .iflow = true,
+ .rts_gpio = PIN_LPUART1_RTS,
+#endif
};
static uart_dev_t g_lpuart1port =
@@ -360,11 +398,22 @@ static int kinetis_setup(struct uart_dev_s *dev)
{
#ifndef CONFIG_SUPPRESS_LPUART_CONFIG
struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev->priv;
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+ bool iflow = priv->iflow;
+#else
+ bool iflow = false;
+#endif
+#ifdef CONFIG_SERIAL_OFLOWCONTROL
+ bool oflow = priv->oflow;
+#else
+ bool oflow = false;
+#endif
/* Configure the LPUART as an RS-232 UART */
kinetis_lpuartconfigure(priv->uartbase, priv->baud, priv->clock,
- priv->parity, priv->bits, priv->stop2);
+ priv->parity, priv->bits, priv->stop2,
+ iflow, oflow);
#endif
/* Make sure that all interrupts are disabled */
@@ -564,23 +613,239 @@ static int kinetis_interrupt(int irq, void *context, void *arg)
static int kinetis_ioctl(struct file *filep, int cmd, unsigned long arg)
{
-#if 0 /* Reserved for future growth */
- struct inode *inode;
- struct uart_dev_s *dev;
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || \
+ defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT)
+ struct inode *inode;
+ struct uart_dev_s *dev;
+ uint8_t regval;
+#endif
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT)
struct kinetis_dev_s *priv;
- int ret = OK;
+ bool iflow = false;
+ bool oflow = false;
+#endif
+ int ret = OK;
- DEBUGASSERT(filep, filep->f_inode);
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || \
+ defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT)
+ DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
inode = filep->f_inode;
dev = inode->i_private;
+ DEBUGASSERT(dev != NULL && dev->priv != NULL);
+#endif
- DEBUGASSERT(dev, dev->priv);
- priv = (struct kinetis_dev_s *)dev->priv;
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT)
+ priv = (struct kinetis_dev_s *)dev->priv;
+#endif
switch (cmd)
{
- case xxx: /* Add commands here */
+#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT
+ case TIOCSERGSTRUCT:
+ {
+ struct kinetis_dev_s *user = (struct kinetis_dev_s *)arg;
+ if (!user)
+ {
+ ret = -EINVAL;
+ }
+ else
+ {
+ memcpy(user, dev, sizeof(struct kinetis_dev_s));
+ }
+ }
break;
+#endif
+
+#ifdef CONFIG_KINETIS_UART_SINGLEWIRE
+ case TIOCSSINGLEWIRE:
+ {
+ /* Change to single-wire operation. the RXD pin is disconnected from
+ * the UART and the UART implements a half-duplex serial connection.
+ * The UART uses the TXD pin for both receiving and transmitting
+ */
+
+ regval = kinetis_serialin(priv, KINETIS_LPUART_CTRL_OFFSET);
+
+ if (arg == SER_SINGLEWIRE_ENABLED)
+ {
+ regval |= (LPUART_CTRL_LOOPS | LPUART_CTRL_RSRC);
+ }
+ else
+ {
+ regval &= ~(LPUART_CTRL_LOOPS | LPUART_CTRL_RSRC);
+ }
+
+ kinetis_serialout(priv, KINETIS_LPUART_CTRL_OFFSET, regval);
+ }
+ break;
+#endif
+
+#ifdef CONFIG_SERIAL_TERMIOS
+ case TCGETS:
+ {
+ struct termios *termiosp = (struct termios *)arg;
+
+ if (!termiosp)
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ cfsetispeed(termiosp, priv->baud);
+
+ /* Note: CSIZE only supports 5-8 bits. The driver only support 8/9 bit
+ * modes and therefore is no way to report 9-bit mode, we always claim
+ * 8 bit mode.
+ */
+
+ termiosp->c_cflag =
+ ((priv->parity != 0) ? PARENB : 0) |
+ ((priv->parity == 1) ? PARODD : 0) |
+ ((priv->stop2) ? CSTOPB : 0) |
+# ifdef CONFIG_SERIAL_OFLOWCONTROL
+ ((priv->oflow) ? CCTS_OFLOW : 0) |
+# endif
+# ifdef CONFIG_SERIAL_IFLOWCONTROL
+ ((priv->iflow) ? CRTS_IFLOW : 0) |
+# endif
+ CS8;
+
+ /* TODO: CCTS_IFLOW, CCTS_OFLOW */
+ }
+ break;
+
+ case TCSETS:
+ {
+ struct termios *termiosp = (struct termios *)arg;
+
+ if (!termiosp)
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ /* Perform some sanity checks before accepting any changes */
+
+ if (((termiosp->c_cflag & CSIZE) != CS8)
+# ifdef CONFIG_SERIAL_IFLOWCONTROL
+ || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0))
+# endif
+# ifdef CONFIG_SERIAL_IFLOWCONTROL
+ || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0))
+# endif
+ )
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (termiosp->c_cflag & PARENB)
+ {
+ priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2;
+ }
+ else
+ {
+ priv->parity = 0;
+ }
+
+ priv->stop2 = (termiosp->c_cflag & CSTOPB) != 0;
+# ifdef CONFIG_SERIAL_OFLOWCONTROL
+ priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0;
+ oflow = priv->oflow;
+# endif
+# ifdef CONFIG_SERIAL_IFLOWCONTROL
+ priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0;
+ iflow = priv->iflow;
+# endif
+
+ /* Note that since there is no way to request 9-bit mode
+ * and no way to support 5/6/7-bit modes, we ignore them
+ * all here.
+ */
+
+ /* Note that only cfgetispeed is used because we have knowledge
+ * that only one speed is supported.
+ */
+
+ priv->baud = cfgetispeed(termiosp);
+
+ /* Effect the changes immediately - note that we do not implement
+ * TCSADRAIN / TCSAFLUSH
+ */
+
+ kinetis_uartconfigure(priv->uartbase, priv->baud, priv->clock,
+ priv->parity, priv->bits, priv->stop2,
+ iflow, oflow);
+ }
+ break;
+#endif /* CONFIG_SERIAL_TERMIOS */
+
+#ifdef CONFIG_KINETIS_UART_BREAKS
+ case TIOCSBRK:
+ {
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ /* Send a longer break signal */
+
+ regval = kinetis_serialin(priv, KINETIS_LPUART_STAT_OFFSET);
+ regval &= ~LPUART_STAT_BRK13;
+# ifdef CONFIG_KINETIS_UART_EXTEDED_BREAK
+ regval |= LPUART_STAT_BRK13;
+# endif
+ kinetis_serialout(priv, LPUART_STAT_BRK13, regval);
+
+ /* Send a break signal */
+
+ regval = kinetis_serialin(priv, KINETIS_LPUART_CTRL_OFFSET);
+ regval |= LPUART_CTRL_SBK;
+ kinetis_serialout(priv, KINETIS_LPUART_CTRL_OFFSET, regval);
+
+# ifdef CONFIG_KINETIS_SERIALBRK_BSDCOMPAT
+ /* BSD compatibility: Turn break on, and leave it on */
+
+ kinetis_txint(dev, false);
+# else
+ /* Send a single break character
+ * Toggling SBK sends one break character. Per the manual
+ * Toggling implies clearing the SBK field before the break
+ * character has finished transmitting.
+ */
+
+ regval &= ~LPUART_CTRL_SBK;
+ kinetis_serialout(priv, KINETIS_LPUART_CTRL_OFFSET, regval);
+#endif
+
+ leave_critical_section(flags);
+ }
+ break;
+
+ case TIOCCBRK:
+ {
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ /* Configure TX back to UART
+ * If non BSD compatible: This code has no effect, the SBRK
+ * was already cleared.
+ * but for BSD compatibility: Turn break off
+ */
+
+ regval = kinetis_serialin(priv, KINETIS_LPUART_CTRL_OFFSET);
+ regval &= ~LPUART_CTRL_SBK;
+ kinetis_serialout(priv, KINETIS_LPUART_CTRL_OFFSET, regval);
+
+# ifdef CONFIG_KINETIS_SERIALBRK_BSDCOMPAT
+ /* Enable further tx activity */
+
+ kinetis_txint(dev, true);
+# endif
+ leave_critical_section(flags);
+ }
+ break;
+#endif /* CONFIG_KINETIS_UART_BREAKS */
default:
ret = -ENOTTY;
@@ -588,9 +853,6 @@ static int kinetis_ioctl(struct file *filep, int cmd, unsigned long arg)
}
return ret;
-#else
- return -ENOTTY;
-#endif
}
/****************************************************************************
@@ -696,6 +958,79 @@ static bool kinetis_rxavailable(struct uart_dev_s *dev)
return (kinetis_serialin(priv, KINETIS_LPUART_STAT_OFFSET) & LPUART_STAT_RDRF) != 0;
}
+/****************************************************************************
+ * Name: kinetis_rxflowcontrol
+ *
+ * Description:
+ * Called when Rx buffer is full (or exceeds configured watermark levels
+ * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined).
+ * Return true if UART activated RX flow control to block more incoming
+ * data
+ *
+ * Input parameters:
+ * dev - UART device instance
+ * nbuffered - the number of characters currently buffered
+ * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is
+ * not defined the value will be 0 for an empty buffer or the
+ * defined buffer size for a full buffer)
+ * upper - true indicates the upper watermark was crossed where
+ * false indicates the lower watermark has been crossed
+ *
+ * Returned Value:
+ * true if RX flow control activated.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+static bool kinetis_rxflowcontrol(struct uart_dev_s *dev,
+ unsigned int nbuffered, bool upper)
+{
+#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS)
+ struct kinetis_dev_s *priv = (struct kinetis_dev_s *)dev->priv;
+ uint16_t ie;
+
+ if (priv->iflow)
+ {
+ /* Is the RX buffer full? */
+
+ if (upper)
+ {
+ /* Disable Rx interrupt to prevent more data being from
+ * peripheral. When hardware RTS is enabled, this will
+ * prevent more data from coming in.
+ *
+ * This function is only called when UART recv buffer is full,
+ * that is: "dev->recv.head + 1 == dev->recv.tail".
+ *
+ * Logic in "uart_read" will automatically toggle Rx interrupts
+ * when buffer is read empty and thus we do not have to re-
+ * enable Rx interrupts.
+ */
+
+ ie = priv->ie;
+ ie &= ~LPUART_CTRL_RX_INTS;
+ kinetis_restoreuartint(priv, ie);
+ return true;
+ }
+
+ /* No.. The RX buffer is empty */
+
+ else
+ {
+ /* We might leave Rx interrupt disabled if full recv buffer was
+ * read empty. Enable Rx interrupt to make sure that more input is
+ * received.
+ */
+
+ kinetis_rxint(dev, true);
+ }
+ }
+#endif
+
+ return false;
+}
+#endif
+
/****************************************************************************
* Name: kinetis_send
*
diff --git a/arch/arm/src/kinetis/kinetis_serial.c b/arch/arm/src/kinetis/kinetis_serial.c
index 79f0030b78d..0f2a4b2ee46 100644
--- a/arch/arm/src/kinetis/kinetis_serial.c
+++ b/arch/arm/src/kinetis/kinetis_serial.c
@@ -53,6 +53,11 @@
#include
#include
+#ifdef CONFIG_SERIAL_TERMIOS
+# include
+#endif
+
+#include
#include
#include "up_arch.h"
@@ -61,6 +66,7 @@
#include "kinetis_config.h"
#include "chip.h"
#include "chip/kinetis_uart.h"
+#include "chip/kinetis_pinmux.h"
#include "kinetis.h"
/****************************************************************************
@@ -242,6 +248,18 @@ struct up_dev_s
uint8_t parity; /* 0=none, 1=odd, 2=even */
uint8_t bits; /* Number of bits (8 or 9) */
uint8_t stop2; /* Use 2 stop bits */
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+ bool iflow; /* input flow control (RTS) enabled */
+#endif
+#ifdef CONFIG_SERIAL_OFLOWCONTROL
+ bool oflow; /* output flow control (CTS) enabled */
+#endif
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+ uint32_t rts_gpio; /* UART RTS GPIO pin configuration */
+#endif
+#ifdef CONFIG_SERIAL_OFLOWCONTROL
+ uint32_t cts_gpio; /* UART CTS GPIO pin configuration */
+#endif
};
/****************************************************************************
@@ -260,6 +278,10 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg);
static int up_receive(struct uart_dev_s *dev, uint32_t *status);
static void up_rxint(struct uart_dev_s *dev, bool enable);
static bool up_rxavailable(struct uart_dev_s *dev);
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+static bool up_rxflowcontrol(struct uart_dev_s *dev, unsigned int nbuffered,
+ bool upper);
+#endif
static void up_send(struct uart_dev_s *dev, int ch);
static void up_txint(struct uart_dev_s *dev, bool enable);
static bool up_txready(struct uart_dev_s *dev);
@@ -282,7 +304,7 @@ static const struct uart_ops_s g_uart_ops =
.rxint = up_rxint,
.rxavailable = up_rxavailable,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
- .rxflowcontrol = NULL,
+ .rxflowcontrol = up_rxflowcontrol,
#endif
.send = up_send,
.txint = up_txint,
@@ -337,6 +359,14 @@ static struct up_dev_s g_uart0priv =
.parity = CONFIG_UART0_PARITY,
.bits = CONFIG_UART0_BITS,
.stop2 = CONFIG_UART0_2STOP,
+#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART0_OFLOWCONTROL)
+ .oflow = true,
+ .cts_gpio = PIN_UART0_CTS,
+#endif
+#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART0_IFLOWCONTROL)
+ .iflow = true,
+ .rts_gpio = PIN_UART0_RTS,
+#endif
};
static uart_dev_t g_uart0port =
@@ -372,6 +402,14 @@ static struct up_dev_s g_uart1priv =
.parity = CONFIG_UART1_PARITY,
.bits = CONFIG_UART1_BITS,
.stop2 = CONFIG_UART1_2STOP,
+#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART1_OFLOWCONTROL)
+ .oflow = true,
+ .cts_gpio = PIN_UART1_CTS,
+#endif
+#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART1_IFLOWCONTROL)
+ .iflow = true,
+ .rts_gpio = PIN_UART1_RTS,
+#endif
};
static uart_dev_t g_uart1port =
@@ -407,6 +445,14 @@ static struct up_dev_s g_uart2priv =
.parity = CONFIG_UART2_PARITY,
.bits = CONFIG_UART2_BITS,
.stop2 = CONFIG_UART2_2STOP,
+#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART2_OFLOWCONTROL)
+ .oflow = true,
+ .cts_gpio = PIN_UART2_CTS,
+#endif
+#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART2_IFLOWCONTROL)
+ .iflow = true,
+ .rts_gpio = PIN_UART2_RTS,
+#endif
};
static uart_dev_t g_uart2port =
@@ -442,6 +488,14 @@ static struct up_dev_s g_uart3priv =
.parity = CONFIG_UART3_PARITY,
.bits = CONFIG_UART3_BITS,
.stop2 = CONFIG_UART3_2STOP,
+#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART3_OFLOWCONTROL)
+ .oflow = true,
+ .cts_gpio = PIN_UART3_CTS,
+#endif
+#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART3_IFLOWCONTROL)
+ .iflow = true,
+ .rts_gpio = PIN_UART3_RTS,
+#endif
};
static uart_dev_t g_uart3port =
@@ -477,6 +531,14 @@ static struct up_dev_s g_uart4priv =
.parity = CONFIG_UART4_PARITY,
.bits = CONFIG_UART4_BITS,
.stop2 = CONFIG_UART4_2STOP,
+#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART4_OFLOWCONTROL)
+ .oflow = true,
+ .cts_gpio = PIN_UART4_CTS,
+#endif
+#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART4_IFLOWCONTROL)
+ .iflow = true,
+ .rts_gpio = PIN_UART4_RTS,
+#endif
};
static uart_dev_t g_uart4port =
@@ -512,6 +574,14 @@ static struct up_dev_s g_uart5priv =
.parity = CONFIG_UART5_PARITY,
.bits = CONFIG_UART5_BITS,
.stop2 = CONFIG_UART5_2STOP,
+#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART5_OFLOWCONTROL)
+ .oflow = true,
+ .cts_gpio = PIN_UART5_CTS,
+#endif
+#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART5_IFLOWCONTROL)
+ .iflow = true,
+ .rts_gpio = PIN_UART5_RTS,
+#endif
};
static uart_dev_t g_uart5port =
@@ -621,11 +691,23 @@ static int up_setup(struct uart_dev_s *dev)
{
#ifndef CONFIG_SUPPRESS_UART_CONFIG
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+ bool iflow = priv->iflow;
+#else
+ bool iflow = false;
+#endif
+#ifdef CONFIG_SERIAL_OFLOWCONTROL
+ bool oflow = priv->oflow;
+#else
+ bool oflow = false;
+#endif
+
/* Configure the UART as an RS-232 UART */
kinetis_uartconfigure(priv->uartbase, priv->baud, priv->clock,
- priv->parity, priv->bits, priv->stop2);
+ priv->parity, priv->bits, priv->stop2,
+ iflow, oflow);
#endif
/* Make sure that all interrupts are disabled */
@@ -891,23 +973,239 @@ static int up_interrupts(int irq, void *context, FAR void *arg)
static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
{
-#if 0 /* Reserved for future growth */
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || \
+ defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT)
struct inode *inode;
struct uart_dev_s *dev;
+ uint8_t regval;
+#endif
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT)
struct up_dev_s *priv;
- int ret = OK;
+ bool iflow = false;
+ bool oflow = false;
+#endif
+ int ret = OK;
- DEBUGASSERT(filep, filep->f_inode);
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_SERIAL_TIOCSERGSTRUCT) || \
+ defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT)
+ DEBUGASSERT(filep != NULL && filep->f_inode != NULL);
inode = filep->f_inode;
dev = inode->i_private;
+ DEBUGASSERT(dev != NULL && dev->priv != NULL);
+#endif
- DEBUGASSERT(dev, dev->priv);
- priv = (struct up_dev_s *)dev->priv;
+#if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_KINETIS_SERIALBRK_BSDCOMPAT)
+ priv = (struct up_dev_s *)dev->priv;
+#endif
switch (cmd)
{
- case xxx: /* Add commands here */
+#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT
+ case TIOCSERGSTRUCT:
+ {
+ struct up_dev_s *user = (struct up_dev_s *)arg;
+ if (!user)
+ {
+ ret = -EINVAL;
+ }
+ else
+ {
+ memcpy(user, dev, sizeof(struct up_dev_s));
+ }
+ }
break;
+#endif
+
+#ifdef CONFIG_KINETIS_UART_SINGLEWIRE
+ case TIOCSSINGLEWIRE:
+ {
+ /* Change to single-wire operation. the RXD pin is disconnected from
+ * the UART and the UART implements a half-duplex serial connection.
+ * The UART uses the TXD pin for both receiving and transmitting
+ */
+
+ regval = up_serialin(priv, KINETIS_UART_C1_OFFSET);
+
+ if (arg == SER_SINGLEWIRE_ENABLED)
+ {
+ regval |= (UART_C1_LOOPS | UART_C1_RSRC);
+ }
+ else
+ {
+ regval &= ~(UART_C1_LOOPS | UART_C1_RSRC);
+ }
+
+ up_serialout(priv, KINETIS_UART_C1_OFFSET, regval);
+ }
+ break;
+#endif
+
+#ifdef CONFIG_SERIAL_TERMIOS
+ case TCGETS:
+ {
+ struct termios *termiosp = (struct termios *)arg;
+
+ if (!termiosp)
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ cfsetispeed(termiosp, priv->baud);
+
+ /* Note: CSIZE only supports 5-8 bits. The driver only support 8/9 bit
+ * modes and therefore is no way to report 9-bit mode, we always claim
+ * 8 bit mode.
+ */
+
+ termiosp->c_cflag =
+ ((priv->parity != 0) ? PARENB : 0) |
+ ((priv->parity == 1) ? PARODD : 0) |
+ ((priv->stop2) ? CSTOPB : 0) |
+# ifdef CONFIG_SERIAL_OFLOWCONTROL
+ ((priv->oflow) ? CCTS_OFLOW : 0) |
+# endif
+# ifdef CONFIG_SERIAL_IFLOWCONTROL
+ ((priv->iflow) ? CRTS_IFLOW : 0) |
+# endif
+ CS8;
+
+ /* TODO: CCTS_IFLOW, CCTS_OFLOW */
+ }
+ break;
+
+ case TCSETS:
+ {
+ struct termios *termiosp = (struct termios *)arg;
+
+ if (!termiosp)
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ /* Perform some sanity checks before accepting any changes */
+
+ if (((termiosp->c_cflag & CSIZE) != CS8)
+# ifdef CONFIG_SERIAL_IFLOWCONTROL
+ || ((termiosp->c_cflag & CCTS_OFLOW) && (priv->cts_gpio == 0))
+# endif
+# ifdef CONFIG_SERIAL_IFLOWCONTROL
+ || ((termiosp->c_cflag & CRTS_IFLOW) && (priv->rts_gpio == 0))
+# endif
+ )
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (termiosp->c_cflag & PARENB)
+ {
+ priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2;
+ }
+ else
+ {
+ priv->parity = 0;
+ }
+
+ priv->stop2 = (termiosp->c_cflag & CSTOPB) != 0;
+# ifdef CONFIG_SERIAL_OFLOWCONTROL
+ priv->oflow = (termiosp->c_cflag & CCTS_OFLOW) != 0;
+ oflow = priv->oflow;
+# endif
+# ifdef CONFIG_SERIAL_IFLOWCONTROL
+ priv->iflow = (termiosp->c_cflag & CRTS_IFLOW) != 0;
+ iflow = priv->iflow;
+# endif
+
+ /* Note that since there is no way to request 9-bit mode
+ * and no way to support 5/6/7-bit modes, we ignore them
+ * all here.
+ */
+
+ /* Note that only cfgetispeed is used because we have knowledge
+ * that only one speed is supported.
+ */
+
+ priv->baud = cfgetispeed(termiosp);
+
+ /* Effect the changes immediately - note that we do not implement
+ * TCSADRAIN / TCSAFLUSH
+ */
+
+ kinetis_uartconfigure(priv->uartbase, priv->baud, priv->clock,
+ priv->parity, priv->bits, priv->stop2,
+ iflow, oflow);
+ }
+ break;
+#endif /* CONFIG_SERIAL_TERMIOS */
+
+#ifdef CONFIG_KINETIS_UART_BREAKS
+ case TIOCSBRK:
+ {
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ /* Send a longer break signal */
+
+ regval = up_serialin(priv, KINETIS_UART_S2_OFFSET);
+ regval &= ~UART_S2_BRK13;
+# ifdef CONFIG_KINETIS_UART_EXTEDED_BREAK
+ regval |= UART_S2_BRK13;
+# endif
+ up_serialout(priv, KINETIS_UART_S2_OFFSET, regval);
+
+ /* Send a break signal */
+
+ regval = up_serialin(priv, KINETIS_UART_C2_OFFSET);
+ regval |= UART_C2_SBK;
+ up_serialout(priv, KINETIS_UART_C2_OFFSET, regval);
+
+# ifdef CONFIG_KINETIS_SERIALBRK_BSDCOMPAT
+ /* BSD compatibility: Turn break on, and leave it on */
+
+ up_txint(dev, false);
+# else
+ /* Send a single break character
+ * Toggling SBK sends one break character. Per the manual
+ * Toggling implies clearing the SBK field before the break
+ * character has finished transmitting.
+ */
+
+ regval &= ~(UART_C2_SBK);
+ up_serialout(priv, KINETIS_UART_C2_OFFSET, regval);
+#endif
+
+ leave_critical_section(flags);
+ }
+ break;
+
+ case TIOCCBRK:
+ {
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ /* Configure TX back to UART
+ * If non BSD compatible: This code has no effect, the SBRK
+ * was already cleared.
+ * but for BSD compatibility: Turn break off
+ */
+
+ regval = up_serialin(priv, KINETIS_UART_C2_OFFSET);
+ regval &= ~UART_C2_SBK;
+ up_serialout(priv, KINETIS_UART_C2_OFFSET, regval);
+
+# ifdef CONFIG_KINETIS_SERIALBRK_BSDCOMPAT
+ /* Enable further tx activity */
+
+ up_txint(dev, true);
+# endif
+ leave_critical_section(flags);
+ }
+ break;
+#endif /* CONFIG_KINETIS_UART_BREAKS */
default:
ret = -ENOTTY;
@@ -915,9 +1213,6 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
}
return ret;
-#else
- return -ENOTTY;
-#endif
}
/****************************************************************************
@@ -1030,6 +1325,79 @@ static bool up_rxavailable(struct uart_dev_s *dev)
#endif
}
+/****************************************************************************
+ * Name: up_rxflowcontrol
+ *
+ * Description:
+ * Called when Rx buffer is full (or exceeds configured watermark levels
+ * if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is defined).
+ * Return true if UART activated RX flow control to block more incoming
+ * data
+ *
+ * Input parameters:
+ * dev - UART device instance
+ * nbuffered - the number of characters currently buffered
+ * (if CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS is
+ * not defined the value will be 0 for an empty buffer or the
+ * defined buffer size for a full buffer)
+ * upper - true indicates the upper watermark was crossed where
+ * false indicates the lower watermark has been crossed
+ *
+ * Returned Value:
+ * true if RX flow control activated.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SERIAL_IFLOWCONTROL
+static bool up_rxflowcontrol(struct uart_dev_s *dev,
+ unsigned int nbuffered, bool upper)
+{
+#if defined(CONFIG_SERIAL_IFLOWCONTROL_WATERMARKS)
+ struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
+ uint16_t ie;
+
+ if (priv->iflow)
+ {
+ /* Is the RX buffer full? */
+
+ if (upper)
+ {
+ /* Disable Rx interrupt to prevent more data being from
+ * peripheral. When hardware RTS is enabled, this will
+ * prevent more data from coming in.
+ *
+ * This function is only called when UART recv buffer is full,
+ * that is: "dev->recv.head + 1 == dev->recv.tail".
+ *
+ * Logic in "uart_read" will automatically toggle Rx interrupts
+ * when buffer is read empty and thus we do not have to re-
+ * enable Rx interrupts.
+ */
+
+ ie = priv->ie;
+ ie &= ~UART_C2_RIE;
+ up_restoreuartint(priv, ie);
+ return true;
+ }
+
+ /* No.. The RX buffer is empty */
+
+ else
+ {
+ /* We might leave Rx interrupt disabled if full recv buffer was
+ * read empty. Enable Rx interrupt to make sure that more input is
+ * received.
+ */
+
+ up_rxint(dev, true);
+ }
+ }
+#endif
+
+ return false;
+}
+#endif
+
/****************************************************************************
* Name: up_send
*
diff --git a/arch/arm/src/kinetis/kinetis_tpm.h b/arch/arm/src/kinetis/kinetis_tpm.h
new file mode 100644
index 00000000000..03fe3b13627
--- /dev/null
+++ b/arch/arm/src/kinetis/kinetis_tpm.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+ * arch/arm/src/kinetis/kinetis_tpm.h
+ *
+ * Copyright (C) 2017 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ * David Sidrane
+ *
+ * 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 __ARCH_ARM_SRC_KINETIS_KINETIS_TPM_H
+#define __ARCH_ARM_SRC_KINETIS_KINETIS_TPM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include "chip.h"
+
+/* This file is just a wrapper around tmp header files for the Kinetis family
+ * selected by the logic in chip.h.
+ */
+
+#if defined(KINETIS_K66)
+# include "chip/kinetis_kx6tpm.h"
+#else
+# error "No TMP definitions for this Kinetis part"
+#endif
+
+#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_TPM_H */
diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig
index e36b54673e4..a74bfafc593 100644
--- a/arch/arm/src/stm32/Kconfig
+++ b/arch/arm/src/stm32/Kconfig
@@ -6165,6 +6165,19 @@ if STM32_SERIALDRIVER
comment "Serial Driver Configuration"
+config STM32_SERIAL_RXDMA_BUFFER_SIZE
+ int "Rx DMA buffer size"
+ default 32
+ range 32 4096
+ depends on USART1_RXDMA || USART2_RXDMA || USART3_RXDMA || UART4_RXDMA || UART5_RXDMA || USART6_RXDMA || UART7_RXDMA || UART8_RXDMA
+ ---help---
+ The DMA buffer size when using RX DMA to emulate a FIFO.
+
+ When streaming data, the generic serial layer will be called
+ every time the FIFO receives half or this number of bytes.
+
+ Value given here will be rounded up to next multiple of 4 bytes.
+
config SERIAL_DISABLE_REORDERING
bool "Disable reordering of ttySx devices."
depends on STM32_USART1 || STM32_USART2 || STM32_USART3 || STM32_UART4 || STM32_UART5 || STM32_USART6 || STM32_UART7 || STM32_UART8
diff --git a/arch/arm/src/stm32/stm32_freerun.c b/arch/arm/src/stm32/stm32_freerun.c
index 673b0412d78..f631aa0aa5e 100644
--- a/arch/arm/src/stm32/stm32_freerun.c
+++ b/arch/arm/src/stm32/stm32_freerun.c
@@ -137,6 +137,7 @@ int stm32_freerun_initialize(struct stm32_freerun_s *freerun, int chan,
*/
freerun->chan = chan;
+ freerun->width = STM32_TIM_GETWIDTH(freerun->tch);
freerun->running = false;
#ifdef CONFIG_CLOCK_TIMEKEEPING
@@ -153,7 +154,7 @@ int stm32_freerun_initialize(struct stm32_freerun_s *freerun, int chan,
/* Set timer period */
- STM32_TIM_SETPERIOD(freerun->tch, UINT32_MAX);
+ STM32_TIM_SETPERIOD(freerun->tch, (uint32_t)((1ull << freerun->width) - 1));
/* Start the counter */
@@ -248,7 +249,8 @@ int stm32_freerun_counter(struct stm32_freerun_s *freerun,
* usecs = (ticks * USEC_PER_SEC) / frequency;
*/
- usec = ((((uint64_t)overflow << 32) + (uint64_t)counter) * USEC_PER_SEC) /
+ usec = ((((uint64_t)overflow << freerun->width) +
+ (uint64_t)counter) * USEC_PER_SEC) /
freerun->frequency;
/* And return the value of the timer */
diff --git a/arch/arm/src/stm32/stm32_freerun.h b/arch/arm/src/stm32/stm32_freerun.h
index bc7609666cf..b263367d16c 100644
--- a/arch/arm/src/stm32/stm32_freerun.h
+++ b/arch/arm/src/stm32/stm32_freerun.h
@@ -63,6 +63,7 @@
struct stm32_freerun_s
{
uint8_t chan; /* The timer/counter in use */
+ uint8_t width; /* Width of timer (16- or 32-bits) */
bool running; /* True: the timer is running */
FAR struct stm32_tim_dev_s *tch; /* Handle returned by stm32_tim_init() */
uint32_t frequency;
diff --git a/arch/arm/src/stm32/stm32_serial.c b/arch/arm/src/stm32/stm32_serial.c
index 6b6161f0ce4..77c07ea68e0 100644
--- a/arch/arm/src/stm32/stm32_serial.c
+++ b/arch/arm/src/stm32/stm32_serial.c
@@ -182,8 +182,14 @@
* When streaming data, the generic serial layer will be called
* every time the FIFO receives half this number of bytes.
*/
-
-# define RXDMA_BUFFER_SIZE 32
+# if !defined(CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE)
+# define CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE 32
+# endif
+# define RXDMA_MUTIPLE 4
+# define RXDMA_MUTIPLE_MASK (RXDMA_MUTIPLE -1)
+# define RXDMA_BUFFER_SIZE ((CONFIG_STM32_SERIAL_RXDMA_BUFFER_SIZE \
+ + RXDMA_MUTIPLE_MASK) \
+ & ~RXDMA_MUTIPLE_MASK)
/* DMA priority */
diff --git a/arch/arm/src/stm32/stm32_tim.c b/arch/arm/src/stm32/stm32_tim.c
index 55909928270..d4a4ed25599 100644
--- a/arch/arm/src/stm32/stm32_tim.c
+++ b/arch/arm/src/stm32/stm32_tim.c
@@ -334,22 +334,23 @@ static void stm32_tim_gpioconfig(uint32_t cfg, stm32_tim_channel_t mode);
/* Timer methods */
-static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode);
-static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq);
+static int stm32_tim_setmode(FAR struct stm32_tim_dev_s *dev, stm32_tim_mode_t mode);
+static int stm32_tim_setclock(FAR struct stm32_tim_dev_s *dev, uint32_t freq);
static void stm32_tim_setperiod(FAR struct stm32_tim_dev_s *dev,
uint32_t period);
static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev);
-static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
- stm32_tim_channel_t mode);
-static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
- uint32_t compare);
-static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel);
-static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, xcpt_t handler,
- void *arg, int source);
+static int stm32_tim_getwidth(FAR struct stm32_tim_dev_s *dev);
+static int stm32_tim_setchannel(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
+ stm32_tim_channel_t mode);
+static int stm32_tim_setcompare(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
+ uint32_t compare);
+static int stm32_tim_getcapture(FAR struct stm32_tim_dev_s *dev, uint8_t channel);
+static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, xcpt_t handler,
+ void *arg, int source);
static void stm32_tim_enableint(FAR struct stm32_tim_dev_s *dev, int source);
static void stm32_tim_disableint(FAR struct stm32_tim_dev_s *dev, int source);
static void stm32_tim_ackint(FAR struct stm32_tim_dev_s *dev, int source);
-static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, int source);
+static int stm32_tim_checkint(FAR struct stm32_tim_dev_s *dev, int source);
/************************************************************************************
* Private Data
@@ -361,6 +362,7 @@ static const struct stm32_tim_ops_s stm32_tim_ops =
.setclock = stm32_tim_setclock,
.setperiod = stm32_tim_setperiod,
.getcounter = stm32_tim_getcounter,
+ .getwidth = stm32_tim_getwidth,
.setchannel = stm32_tim_setchannel,
.setcompare = stm32_tim_setcompare,
.getcapture = stm32_tim_getcapture,
@@ -904,6 +906,41 @@ static uint32_t stm32_tim_getcounter(FAR struct stm32_tim_dev_s *dev)
return stm32_getreg32(dev, STM32_BTIM_CNT_OFFSET);
}
+/************************************************************************************
+ * Name: stm32_tim_getwidth
+ ************************************************************************************/
+
+static int stm32_tim_getwidth(FAR struct stm32_tim_dev_s *dev)
+{
+ /* Only TIM2 and TIM5 timers may be 32-bits in width
+ *
+ * Reference Table 2 of en.DM00042534.pdf
+ */
+
+ switch (((struct stm32_tim_priv_s *)dev)->base)
+ {
+ /* TIM2 is 32-bits on all except F10x, L0x, and L1x lines */
+
+#if defined(CONFIG_STM32_TIM2) && !defined(STM32_STM32F10XX) && \
+ !defined(STM32_STM32L15XX)
+ case STM32_TIM2_BASE:
+ return 32;
+#endif
+
+ /* TIM5 is 32-bits on all except F10x lines */
+
+#if defined(CONFIG_STM32_TIM5) && !defined(STM32_STM32F10XX)
+ case STM32_TIM5_BASE:
+ return 32;
+#endif
+
+ /* All others are 16-bit times */
+
+ default:
+ return 16;
+ }
+}
+
/************************************************************************************
* Name: stm32_tim_setchannel
************************************************************************************/
diff --git a/arch/arm/src/stm32/stm32_tim.h b/arch/arm/src/stm32/stm32_tim.h
index 921baebc6c3..5b9422f3ee5 100644
--- a/arch/arm/src/stm32/stm32_tim.h
+++ b/arch/arm/src/stm32/stm32_tim.h
@@ -61,6 +61,7 @@
#define STM32_TIM_SETCLOCK(d,freq) ((d)->ops->setclock(d,freq))
#define STM32_TIM_SETPERIOD(d,period) ((d)->ops->setperiod(d,period))
#define STM32_TIM_GETCOUNTER(d) ((d)->ops->getcounter(d))
+#define STM32_TIM_GETWIDTH(d) ((d)->ops->getwidth(d))
#define STM32_TIM_SETCHANNEL(d,ch,mode) ((d)->ops->setchannel(d,ch,mode))
#define STM32_TIM_SETCOMPARE(d,ch,comp) ((d)->ops->setcompare(d,ch,comp))
#define STM32_TIM_GETCAPTURE(d,ch) ((d)->ops->getcapture(d,ch))
@@ -166,6 +167,7 @@ struct stm32_tim_ops_s
/* General and Advanced Timers Adds */
+ int (*getwidth)(FAR struct stm32_tim_dev_s *dev);
int (*setchannel)(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
stm32_tim_channel_t mode);
int (*setcompare)(FAR struct stm32_tim_dev_s *dev, uint8_t channel,
diff --git a/arch/arm/src/stm32l4/Kconfig b/arch/arm/src/stm32l4/Kconfig
index 28be165f448..76d2dae6136 100644
--- a/arch/arm/src/stm32l4/Kconfig
+++ b/arch/arm/src/stm32l4/Kconfig
@@ -12,57 +12,279 @@ choice
default ARCH_CHIP_STM32L476RG
depends on ARCH_CHIP_STM32L4
+config ARCH_CHIP_STM32L432KB
+ bool "STM32L432KB"
+ select STM32L4_STM32L432XX
+ select STM32L4_FLASH_CONFIG_B
+ select STM32L4_IO_CONFIG_K
+ ---help---
+ STM32 L4 Cortex M4, 128 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L432KC
+ bool "STM32L432KC"
+ select STM32L4_STM32L432XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_K
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L442KC
+ bool "STM32L442KC"
+ select STM32L4_STM32L442XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_K
+ ---help---
+ STM32 L4 Cortex M4, AES, 256 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L433CB
+ bool "STM32L433CB"
+ select STM32L4_STM32L433XX
+ select STM32L4_FLASH_CONFIG_B
+ select STM32L4_IO_CONFIG_C
+ ---help---
+ STM32 L4 Cortex M4, 128 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L433CC
+ bool "STM32L433CC"
+ select STM32L4_STM32L433XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_C
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L433RB
+ bool "STM32L433RB"
+ select STM32L4_STM32L433XX
+ select STM32L4_FLASH_CONFIG_B
+ select STM32L4_IO_CONFIG_R
+ ---help---
+ STM32 L4 Cortex M4, 128 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L433RC
+ bool "STM32L433RC"
+ select STM32L4_STM32L433XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_R
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L433VC
+ bool "STM32L433VC"
+ select STM32L4_STM32L433XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_V
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L443CC
+ bool "STM32L443CC"
+ select STM32L4_STM32L443XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_C
+ ---help---
+ STM32 L4 Cortex M4, AES, 256 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L443RC
+ bool "STM32L443RC"
+ select STM32L4_STM32L443XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_R
+ ---help---
+ STM32 L4 Cortex M4, AES, 256 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L443VC
+ bool "STM32L443VC"
+ select STM32L4_STM32L443XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_V
+ ---help---
+ STM32 L4 Cortex M4, AES, 256 Kb FLASH, 64 Kb SRAM
+
+config ARCH_CHIP_STM32L451CC
+ bool "STM32L451CC"
+ select STM32L4_STM32L451XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_C
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L451CE
+ bool "STM32L451CE"
+ select STM32L4_STM32L451XX
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_C
+ ---help---
+ STM32 L4 Cortex M4, 512 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L451RC
+ bool "STM32L451RC"
+ select STM32L4_STM32L451XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_R
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L451RE
+ bool "STM32L451RE"
+ select STM32L4_STM32L451XX
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_R
+ ---help---
+ STM32 L4 Cortex M4, 512 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L451VC
+ bool "STM32L451VC"
+ select STM32L4_STM32L451XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_V
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L451VE
+ bool "STM32L451VE"
+ select STM32L4_STM32L451XX
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_V
+ ---help---
+ STM32 L4 Cortex M4, 512 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L452CC
+ bool "STM32L452CC"
+ select STM32L4_STM32L452XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_C
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L452CE
+ bool "STM32L452CE"
+ select STM32L4_STM32L452XX
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_C
+ ---help---
+ STM32 L4 Cortex M4, 512 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L452RC
+ bool "STM32L452RC"
+ select STM32L4_STM32L452XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_R
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L452RE
+ bool "STM32L452RE"
+ select STM32L4_STM32L452XX
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_R
+ ---help---
+ STM32 L4 Cortex M4, 512 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L452VC
+ bool "STM32L452VC"
+ select STM32L4_STM32L452XX
+ select STM32L4_FLASH_CONFIG_C
+ select STM32L4_IO_CONFIG_V
+ ---help---
+ STM32 L4 Cortex M4, 256 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L452VE
+ bool "STM32L452VE"
+ select STM32L4_STM32L452XX
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_V
+ ---help---
+ STM32 L4 Cortex M4, 512 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L462CE
+ bool "STM32L462CE"
+ select STM32L4_STM32L462XX
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_C
+ ---help---
+ STM32 L4 Cortex M4, USB FS, AES, 512 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L462RE
+ bool "STM32L462RE"
+ select STM32L4_STM32L462XX
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_R
+ ---help---
+ STM32 L4 Cortex M4, USB FS, AES, 512 Kb FLASH, 128+32 Kb SRAM
+
+config ARCH_CHIP_STM32L462VE
+ bool "STM32L462VE"
+ select STM32L4_STM32L462XX
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_V
+ ---help---
+ STM32 L4 Cortex M4, USB FS, AES, 512 Kb FLASH, 128+32 Kb SRAM
+
config ARCH_CHIP_STM32L476RG
bool "STM32L476RG"
select STM32L4_STM32L476XX
- select STM32L4_FLASH_1024KB
+ select STM32L4_FLASH_CONFIG_G
+ select STM32L4_IO_CONFIG_R
---help---
STM32 L4 Cortex M4, 1024Kb FLASH, 96+32 Kb SRAM
config ARCH_CHIP_STM32L476RE
bool "STM32L476RE"
select STM32L4_STM32L476XX
- select STM32L4_FLASH_512KB
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_R
---help---
STM32 L4 Cortex M4, 512Kb FLASH, 96+32 Kb SRAM
-config ARCH_CHIP_STM32L486
+config ARCH_CHIP_STM32L486 # REVISIT: expand for each chip
bool "STM32L486xx"
select STM32L4_STM32L486XX
- select STM32L4_HAVE_AES
+ select STM32L4_FLASH_CONFIG_G
---help---
STM32 L4 Cortex M4, AES, 1024Kb FLASH, 96+32 Kb SRAM
config ARCH_CHIP_STM32L496ZE
bool "STM32L496ZE"
select STM32L4_STM32L496XX
- select STM32L4_FLASH_512KB
+ select STM32L4_FLASH_CONFIG_E
+ select STM32L4_IO_CONFIG_Z
---help---
STM32 L4 Cortex M4, 512Kb FLASH, 320 Kb SRAM
config ARCH_CHIP_STM32L496ZG
bool "STM32L496ZG"
select STM32L4_STM32L496XX
- select STM32L4_FLASH_1024KB
+ select STM32L4_FLASH_CONFIG_G
+ select STM32L4_IO_CONFIG_Z
---help---
STM32 L4 Cortex M4, 1024Kb FLASH, 320 Kb SRAM
-config ARCH_CHIP_STM32L4A6
+config ARCH_CHIP_STM32L4A6 # REVISIT: expand for each chip
bool "STM32L4A6xx"
- select STM32L4_STM32L496XX # Close enough to L496
- select STM32L4_FLASH_1024KB
- select STM32L4_HAVE_AES
- select STM32L4_HAVE_HASH
+ select STM32L4_STM32L4A6XX
+ select STM32L4_FLASH_CONFIG_G
---help---
STM32 L4 Cortex M4, AES, HASH, 1024Kb FLASH, 320 Kb SRAM
endchoice # STM32 L4 Chip Selection
-# Chip families
+# Chip product lines
+
+config STM32L4_STM32L4X1
+ # Note: This is _not_ for L471xx as in RM0392
+ bool
+ default n
+ select STM32L4_STM32L4X3
+
+config STM32L4_STM32L4X2
+ bool
+ default n
+ select STM32L4_STM32L4X3
config STM32L4_STM32L4X3
bool
default n
+ select ARCH_HAVE_FPU
select STM32L4_HAVE_USART1
select STM32L4_HAVE_USART2
select STM32L4_HAVE_USART3 if !(STM32L4_L432XX || STM32L4_L442XX)
@@ -75,67 +297,260 @@ config STM32L4_STM32L4X3
config STM32L4_STM32L4X5
bool
default n
- select STM32L4_HAVE_USART1
- select STM32L4_HAVE_USART2
- select STM32L4_HAVE_USART3
- select STM32L4_HAVE_LPTIM1
- select STM32L4_HAVE_LPTIM2
- select STM32L4_HAVE_COMP
- select STM32L4_HAVE_SAI1
- select STM32L4_HAVE_SAI2
-
-config STM32L4_STM32L4X6
- bool
- default n
+ select ARCH_HAVE_FPU
select STM32L4_HAVE_USART1
select STM32L4_HAVE_USART2
select STM32L4_HAVE_USART3
select STM32L4_HAVE_UART4
select STM32L4_HAVE_UART5
+ select STM32L4_HAVE_ADC2
+ select STM32L4_HAVE_ADC3
+ select STM32L4_HAVE_DAC2
+ select STM32L4_HAVE_FSMC
+ select STM32L4_HAVE_TIM3
+ select STM32L4_HAVE_TIM4
+ select STM32L4_HAVE_TIM5
+ select STM32L4_HAVE_TIM7
+ select STM32L4_HAVE_TIM8
+ select STM32L4_HAVE_TIM17
select STM32L4_HAVE_LPTIM1
select STM32L4_HAVE_LPTIM2
select STM32L4_HAVE_COMP
select STM32L4_HAVE_SAI1
select STM32L4_HAVE_SAI2
+ select STM32L4_HAVE_SDMMC1
+ select STM32L4_HAVE_OTGFS
+ select STM32L4_HAVE_DFSDM1
+
+config STM32L4_STM32L4X6
+ bool
+ default n
+ select ARCH_HAVE_FPU
+ select STM32L4_HAVE_USART1
+ select STM32L4_HAVE_USART2
+ select STM32L4_HAVE_USART3
+ select STM32L4_HAVE_UART4
+ select STM32L4_HAVE_UART5
+ select STM32L4_HAVE_ADC2
+ select STM32L4_HAVE_ADC3
+ select STM32L4_HAVE_DAC2
+ select STM32L4_HAVE_FSMC
+ select STM32L4_HAVE_TIM3
+ select STM32L4_HAVE_TIM4
+ select STM32L4_HAVE_TIM5
+ select STM32L4_HAVE_TIM7
+ select STM32L4_HAVE_TIM8
+ select STM32L4_HAVE_TIM17
+ select STM32L4_HAVE_LPTIM1
+ select STM32L4_HAVE_LPTIM2
+ select STM32L4_HAVE_COMP
+ select STM32L4_HAVE_SAI1
+ select STM32L4_HAVE_SAI2
+ select STM32L4_HAVE_SDMMC1
+ select STM32L4_HAVE_OTGFS
+ select STM32L4_HAVE_LCD
+
+# Chip subfamilies:
+
+config STM32L4_STM32L431XX
+ bool
+ default n
+ select STM32L4_STM32L4X1
+ select STM32L4_HAVE_TIM7
+ select STM32L4_HAVE_SDMMC1 if (STM32L4_IO_CONFIG_V || STM32L4_IO_CONFIG_R)
+
+config STM32L4_STM32L432XX
+ bool
+ default n
+ select STM32L4_STM32L4X2
+ select STM32L4_HAVE_TIM7
+
+config STM32L4_STM32L433XX
+ bool
+ default n
+ select STM32L4_STM32L4X3
+ select STM32L4_HAVE_TIM7
+
+config STM32L4_STM32L442XX
+ bool
+ default n
+ select STM32L4_STM32L4X2
+ select STM32L4_HAVE_TIM7
+ select STM32L4_HAVE_AES
+
+config STM32L4_STM32L443XX
+ bool
+ default n
+ select STM32L4_STM32L4X3
+ select STM32L4_HAVE_TIM7
+ select STM32L4_HAVE_SDMMC1
+ select STM32L4_HAVE_AES
+
+config STM32L4_STM32L451XX
+ bool
+ default n
+ select STM32L4_STM32L4X1
+ select STM32L4_HAVE_UART4
+ select STM32L4_HAVE_TIM3
+ select STM32L4_HAVE_I2C4
+ select STM32L4_HAVE_SDMMC1 if !STM32L4_IO_CONFIG_C
+ select STM32L4_HAVE_DFSDM1
+
+config STM32L4_STM32L452XX
+ bool
+ default n
+ select STM32L4_STM32L4X2
+ select STM32L4_HAVE_UART4
+ select STM32L4_HAVE_TIM3
+ select STM32L4_HAVE_I2C4
+ select STM32L4_HAVE_SDMMC1
+ select STM32L4_HAVE_DFSDM1
+
+config STM32L4_STM32L462XX
+ bool
+ default n
+ select STM32L4_STM32L4X2
+ select STM32L4_HAVE_UART4
+ select STM32L4_HAVE_TIM3
+ select STM32L4_HAVE_I2C4
+ select STM32L4_HAVE_SDMMC1
+ select STM32L4_HAVE_DFSDM1
+ select STM32L4_HAVE_AES
+
+config STM32L4_STM32L471XX
+ bool
+ default n
+ # TODO
config STM32L4_STM32L476XX
bool
default n
select STM32L4_STM32L4X6
- select ARCH_HAVE_FPU
config STM32L4_STM32L486XX
bool
default n
select STM32L4_STM32L4X6
- select ARCH_HAVE_FPU
- select STM32L4_FLASH_1024KB
+ select STM32L4_HAVE_AES
config STM32L4_STM32L496XX
bool
default n
select STM32L4_STM32L4X6
- select ARCH_HAVE_FPU
select STM32L4_HAVE_I2C4
select STM32L4_HAVE_CAN2
select STM32L4_HAVE_DCMI
select STM32L4_HAVE_DMA2D
+ select STM32L4_HAVE_DFSDM1
+
+config STM32L4_STM32L4A6XX
+ bool
+ default n
+ select STM32L4_STM32L496XX
+ select STM32L4_HAVE_AES
+ select STM32L4_HAVE_HASH
choice
- prompt "Embedded FLASH size"
- default STM32L4_FLASH_1024KB
+ prompt "Override Flash Size Designator"
+ depends on ARCH_CHIP_STM32L4
+ default STM32L4_FLASH_OVERRIDE_DEFAULT
+ ---help---
+ STM32L4 series parts numbering (sans the package type) ends with a letter
+ that designates the FLASH size.
-config STM32L4_FLASH_256KB
- bool "256 KB"
+ Designator Size in KiB
+ B 128
+ C 256
+ E 512
+ G 1024
+
+ This configuration option defaults to using the configuration based on that designator
+ or the default smaller size if there is no last character designator is present in the
+ STM32 Chip Selection.
+
+ Examples:
+ If the STM32L476VE is chosen, the Flash configuration would be 'E', if a variant of
+ the part with a 1024 KiB Flash is released in the future one could simply select
+ the 'G' designator here.
+
+ If an STM32L4xxx Series parts is chosen the default Flash configuration will be set
+ herein and can be changed.
+
+config STM32L4_FLASH_OVERRIDE_DEFAULT
+ bool "Default"
+
+config STM32L4_FLASH_OVERRIDE_B
+ bool "B 128 KB"
+
+config STM32L4_FLASH_OVERRIDE_C
+ bool "C 256 KB"
+
+config STM32L4_FLASH_OVERRIDE_E
+ bool "E 512 KB"
+
+config STM32L4_FLASH_OVERRIDE_G
+ bool "G 1024 KB"
+
+endchoice # "Override Flash Size Designator"
+
+# Flash configurations
+
+config STM32L4_FLASH_CONFIG_B
+ bool
+ default n
+ depends on STM32L4_STM32L4X1 || STM32L4_STM32L4X3
+
+config STM32L4_FLASH_CONFIG_C
+ bool
+ default n
depends on !STM32L4_STM32L496XX
-config STM32L4_FLASH_512KB
- bool "512 KB"
+config STM32L4_FLASH_CONFIG_E
+ bool
+ default n
-config STM32L4_FLASH_1024KB
- bool "1024 KB"
+config STM32L4_FLASH_CONFIG_G
+ bool
+ default n
+ depends on STM32L4_STM32L4X5 || STM32L4_STM32L4X6
-endchoice # Embedded FLASH size
+# Pin/package configurations
+
+config STM32L4_IO_CONFIG_K
+ bool
+ default n
+
+config STM32L4_IO_CONFIG_C
+ bool
+ default n
+
+config STM32L4_IO_CONFIG_R
+ bool
+ default n
+
+config STM32L4_IO_CONFIG_J
+ bool
+ default n
+
+config STM32L4_IO_CONFIG_M
+ bool
+ default n
+
+config STM32L4_IO_CONFIG_V
+ bool
+ default n
+
+config STM32L4_IO_CONFIG_Q
+ bool
+ default n
+
+config STM32L4_IO_CONFIG_Z
+ bool
+ default n
+
+config STM32L4_IO_CONFIG_A
+ bool
+ default n
comment "STM32L4 SRAM2 Options"
@@ -172,6 +587,14 @@ menu "STM32L4 Peripheral Support"
# These "hidden" settings determine is a peripheral option is available for the
# selection MCU
+config STM32L4_HAVE_ADC2
+ bool
+ default n
+
+config STM32L4_HAVE_ADC3
+ bool
+ default n
+
config STM32L4_HAVE_AES
bool
default n
@@ -184,14 +607,26 @@ config STM32L4_HAVE_COMP
bool
default n
+config STM32L4_HAVE_DAC2
+ bool
+ default n
+
config STM32L4_HAVE_DCMI
bool
default n
+config STM32L4_HAVE_DFSDM1
+ bool
+ default n
+
config STM32L4_HAVE_DMA2D
bool
default n
+config STM32L4_HAVE_FSMC
+ bool
+ default n
+
config STM32L4_HAVE_HASH
bool
default n
@@ -200,6 +635,10 @@ config STM32L4_HAVE_I2C4
bool
default n
+config STM32L4_HAVE_LCD
+ bool
+ default n
+
config STM32L4_HAVE_LTDC
bool
default n
@@ -212,6 +651,10 @@ config STM32L4_HAVE_LPTIM2
bool
default n
+config STM32L4_HAVE_OTGFS
+ bool
+ default n
+
config STM32L4_HAVE_SAI1
bool
default n
@@ -220,6 +663,34 @@ config STM32L4_HAVE_SAI2
bool
default n
+config STM32L4_HAVE_SDMMC1
+ bool
+ default n
+
+config STM32L4_HAVE_TIM3
+ bool
+ default n
+
+config STM32L4_HAVE_TIM4
+ bool
+ default n
+
+config STM32L4_HAVE_TIM5
+ bool
+ default n
+
+config STM32L4_HAVE_TIM7
+ bool
+ default n
+
+config STM32L4_HAVE_TIM8
+ bool
+ default n
+
+config STM32L4_HAVE_TIM17
+ bool
+ default n
+
# These "hidden" settings are the OR of individual peripheral selections
# indicating that the general capability is required.
@@ -289,6 +760,7 @@ config STM32L4_OTGFS
bool "OTG FS"
default n
select USBHOST_HAVE_ASYNCH if USBHOST
+ depends on STM32L4_HAVE_OTGFS
config STM32L4_ADC1
bool "ADC1"
@@ -299,11 +771,13 @@ config STM32L4_ADC2
bool "ADC2"
default n
select STM32L4_ADC
+ depends on STM32L4_HAVE_ADC2
config STM32L4_ADC3
bool "ADC3"
default n
select STM32L4_ADC
+ depends on STM32L4_HAVE_ADC3
config STM32L4_AES
bool "AES"
@@ -330,43 +804,12 @@ config STM32L4_RNG
default n
select ARCH_HAVE_RNG
-config STM32L4_SAI1_A
- bool "SAI1 Block A"
- default n
- select AUDIO
- select I2S
- select SCHED_WORKQUEUE
- select STM32L4_SAI
-
-config STM32L4_SAI1_B
- bool "SAI1 Block B"
- default n
- select AUDIO
- select I2S
- select SCHED_WORKQUEUE
- select STM32L4_SAI
-
-config STM32L4_SAI2_A
- bool "SAI2 Block A"
- default n
- select AUDIO
- select I2S
- select SCHED_WORKQUEUE
- select STM32L4_SAI
-
-config STM32L4_SAI2_B
- bool "SAI2 Block B"
- default n
- select AUDIO
- select I2S
- select SCHED_WORKQUEUE
- select STM32L4_SAI
-
comment "AHB3 Peripherals"
-config STM32L4_FMC
- bool "FMC"
+config STM32L4_FSMC
+ bool "FSMC"
default n
+ depends on STM32L4_HAVE_FSMC
config STM32L4_QSPI
bool "QuadSPI"
@@ -526,14 +969,17 @@ config STM32L4_TIM2
config STM32L4_TIM3
bool "TIM3"
default n
+ depends on STM32L4_HAVE_TIM3
config STM32L4_TIM4
bool "TIM4"
default n
+ depends on STM32L4_HAVE_TIM4
config STM32L4_TIM5
bool "TIM5"
default n
+ depends on STM32L4_HAVE_TIM5
config STM32L4_TIM6
bool "TIM6"
@@ -542,14 +988,17 @@ config STM32L4_TIM6
config STM32L4_TIM7
bool "TIM7"
default n
+ depends on STM32L4_HAVE_TIM7
config STM32L4_LCD
bool "LCD"
default n
+ depends on STM32L4_HAVE_LCD
config STM32L4_SPI2
bool "SPI2"
default n
+ depends on !(STM32L4_L432XX || STM32L4_L442XX)
select SPI
select STM32L4_SPI
@@ -607,6 +1056,7 @@ config STM32L4_I2C1
config STM32L4_I2C2
bool "I2C2"
default n
+ depends on !(STM32L4_L432XX || STM32L4_L442XX)
select STM32L4_I2C
config STM32L4_I2C3
@@ -642,6 +1092,7 @@ config STM32L4_DAC2
bool "DAC2"
default n
select STM32L4_DAC
+ depends on STM32L4_HAVE_DAC2
config STM32L4_OPAMP
bool "OPAMP"
@@ -684,6 +1135,7 @@ config STM32L4_SDMMC1
bool "SDMMC1"
default n
select ARCH_HAVE_SDIO
+ depends on STM32L4_HAVE_SDMMC1
config STM32L4_TIM1
bool "TIM1"
@@ -698,6 +1150,7 @@ config STM32L4_SPI1
config STM32L4_TIM8
bool "TIM8"
default n
+ depends on STM32L4_HAVE_TIM8
config STM32L4_USART1
bool "USART1"
@@ -717,6 +1170,7 @@ config STM32L4_TIM16
config STM32L4_TIM17
bool "TIM17"
default n
+ depends on STM32L4_HAVE_TIM17
config STM32L4_COMP
bool "COMP"
@@ -728,14 +1182,51 @@ config STM32L4_SAI1
default n
depends on STM32L4_HAVE_SAI1
+config STM32L4_SAI1_A
+ bool "SAI1 Block A"
+ default n
+ select AUDIO
+ select I2S
+ select SCHED_WORKQUEUE
+ select STM32L4_SAI
+ depends on STM32L4_SAI1
+
+config STM32L4_SAI1_B
+ bool "SAI1 Block B"
+ default n
+ select AUDIO
+ select I2S
+ select SCHED_WORKQUEUE
+ select STM32L4_SAI
+ depends on STM32L4_SAI1
+
config STM32L4_SAI2
bool "SAI2"
default n
depends on STM32L4_HAVE_SAI2
-config STM32L4_DFSDM
- bool "DFSDM"
+config STM32L4_SAI2_A
+ bool "SAI2 Block A"
default n
+ select AUDIO
+ select I2S
+ select SCHED_WORKQUEUE
+ select STM32L4_SAI
+ depends on STM32L4_SAI2
+
+config STM32L4_SAI2_B
+ bool "SAI2 Block B"
+ default n
+ select AUDIO
+ select I2S
+ select SCHED_WORKQUEUE
+ select STM32L4_SAI
+ depends on STM32L4_SAI2
+
+config STM32L4_DFSDM1
+ bool "DFSDM1"
+ default n
+ depends on STM32L4_HAVE_DFSDM1
comment "Other Peripherals"
@@ -809,6 +1300,7 @@ config STM32L4_SAI1PLL
config STM32L4_SAI2PLL
bool "SAI2PLL"
default n
+ depends on STM32L4_HAVE_SAI2
---help---
The STM32L476 has a separate PLL for the SAI2 block.
Set this true and provide configuration parameters in
diff --git a/arch/arm/src/stm32l4/Make.defs b/arch/arm/src/stm32l4/Make.defs
index 49ee9725394..417d7c170d0 100644
--- a/arch/arm/src/stm32l4/Make.defs
+++ b/arch/arm/src/stm32l4/Make.defs
@@ -212,3 +212,7 @@ ifeq ($(CONFIG_STM32L4_CAN),y)
CHIP_CSRCS += stm32l4_can.c
endif
+ifeq ($(CONFIG_STM32L4_FIREWALL),y)
+CHIP_CSRCS += stm32l4_firewall.c
+endif
+
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h b/arch/arm/src/stm32l4/chip/stm32l4_gpio.h
similarity index 98%
rename from arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h
rename to arch/arm/src/stm32l4/chip/stm32l4_gpio.h
index f4f32e7f926..08e0e9e5197 100644
--- a/arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h
+++ b/arch/arm/src/stm32l4/chip/stm32l4_gpio.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/stm32l4/chip/stm32l4x6xx_gpio.h
+ * arch/arm/src/stm32l4/chip/stm32l4_gpio.h
*
* Copyright (C) 2016, Sebastien Lorquet. All rights reserved.
* Author: Sebastien Lorquet
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_GPIO_H
-#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_GPIO_H
+#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_GPIO_H
+#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_GPIO_H
/************************************************************************************
* Included Files
@@ -371,5 +371,5 @@
#define GPIO_AFRH15_SHIFT (28)
#define GPIO_AFRH15_MASK (15 << GPIO_AFRH15_SHIFT)
-#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_GPIO_H */
+#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_GPIO_H */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h b/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h
index 33a9b5bd566..cbd89cc429f 100644
--- a/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h
+++ b/arch/arm/src/stm32l4/chip/stm32l4_memorymap.h
@@ -40,7 +40,7 @@
* Pre-processor Definitions
************************************************************************************/
-/* STM32F40XXX Address Blocks *******************************************************/
+/* STM32L4XXX Address Blocks ********************************************************/
#define STM32L4_CODE_BASE 0x00000000 /* 0x00000000-0x1fffffff: 512Mb code block */
#define STM32L4_SRAM_BASE 0x20000000 /* 0x20000000-0x3fffffff: 512Mb sram block (96k or 256k) */
@@ -50,7 +50,7 @@
# define STM32L4_FSMC_BANK2 0x70000000 /* 0x70000000-0x7fffffff: 256Mb NAND FLASH */
#define STM32L4_FSMC_BASE34 0x80000000 /* 0x80000000-0x8fffffff: 512Mb FSMC bank3 / QSPI block */
# define STM32L4_FSMC_BANK3 0x80000000 /* 0x80000000-0x8fffffff: 256Mb NAND FLASH */
-# define STM32L4_QSPI_BANK 0x90000000 /* 0x90000000-0x9fffffff: 256Mb QUADSPI*/
+# define STM32L4_QSPI_BANK 0x90000000 /* 0x90000000-0x9fffffff: 256Mb QUADSPI */
#define STM32L4_FSMC_BASE 0xa0000000 /* 0xa0000000-0xbfffffff: FSMC register block */
#define STM32L4_QSPI_BASE 0xa0001000 /* 0xa0000000-0xbfffffff: QSPI register block */
/* 0xc0000000-0xdfffffff: 512Mb (not used) */
@@ -68,10 +68,13 @@
/* 0x08100000-0x0fffffff: Reserved */
#define STM32L4_SRAM2_BASE 0x10000000 /* 0x10000000-0x1000ffff: 32Kb or 64Kb SRAM2 */
/* 0x10010000-0x1ffeffff: Reserved */
-#define STM32L4_SYSMEM_BASE 0x1fff0000 /* 0x1fff0000-0x1fff7a0f: System memory */
- /* 0x1fff7a10-0x1fff7fff: Reserved */
-#define STM32L4_OPTION_BASE 0x1fffc000 /* 0x1fffc000-0x1fffc007: Option bytes */
- /* 0x1fffc008-0x1fffffff: Reserved */
+#define STM32L4_SYSMEM_BASE 0x1fff0000 /* 0x1fff0000-0x1fff6fff: System memory */
+#define STM32L4_OTP_BASE 0x1fff7000 /* 0x1fff7000-0x1fff73ff: OTP memory */
+ /* 0x1fff7400-0x1fff77ff: Reserved */
+#define STM32L4_OPTION_BASE 0x1fff7800 /* 0x1fff7800-0x1fff780f: Option bytes */
+ /* 0x1fff7810-0x1ffff7ff: Reserved */
+#define STM32L4_OPTION2_BASE 0x1ffff800 /* 0x1ffff800-0x1ffff80f: Option bytes 2 */
+ /* 0x1ffff810-0x1fffffff: Reserved */
/* System Memory Addresses **********************************************************/
@@ -84,9 +87,13 @@
#define STM32L4_SYSMEM_PACKAGE 0x1fff7500 /* This bitfield indicates the package
* type.
* 0: LQFP64
+ * 1: WLCSP64
* 2: LQFP100
* 3: UFBGA132
* 4: LQFP144, WLCSP81 or WLCSP72
+ * 10: WLCSP49
+ * 11: UFBGA64
+ * 12: UFBGA100
* 16: UFBGA169
* 17: WLCSP100
*/
@@ -124,8 +131,14 @@
#define STM32L4_OPAMP_BASE 0x40007800
#define STM32L4_DAC_BASE 0x40007400
#define STM32L4_PWR_BASE 0x40007000
-#define STM32L4_CAN2_BASE 0x40006800
+#if defined(CONFIG_STM32L4_STM32L4X2)
+# define STM32L4_USB_SRAM_BASE 0x40006c00
+# define STM32L4_USB_FS_BASE 0x40006800
+#else
+# define STM32L4_CAN2_BASE 0x40006800
+#endif
#define STM32L4_CAN1_BASE 0x40006400
+#define STM32L4_CRS_BASE 0x40006000
#define STM32L4_I2C3_BASE 0x40005c00
#define STM32L4_I2C2_BASE 0x40005800
#define STM32L4_I2C1_BASE 0x40005400
diff --git a/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h b/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h
index 28257e17386..85140db0343 100644
--- a/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h
+++ b/arch/arm/src/stm32l4/chip/stm32l4_pinmap.h
@@ -43,9 +43,10 @@
#include
#include "chip.h"
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
+#if defined(CONFIG_STM32L4_STM32L4X6)
# include "chip/stm32l4x6xx_pinmap.h"
+#elif defined(CONFIG_STM32L4_STM32L4X3)
+# include "chip/stm32l4x3xx_pinmap.h"
#else
# error "Unsupported STM32 L4 pin map"
#endif
diff --git a/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h b/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h
index 2cbffbc7f1e..c68c992296e 100644
--- a/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h
+++ b/arch/arm/src/stm32l4/chip/stm32l4_syscfg.h
@@ -1,8 +1,8 @@
-/****************************************************************************************************
+/************************************************************************************
* arch/arm/src/stm32l4/chip/stm32l4_syscfg.h
*
- * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt
+ * Copyright (C) 2015 Sebastien Lorquet. All rights reserved.
+ * Author: Sebastien Lorquet
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,162 +31,25 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- ****************************************************************************************************/
+ ************************************************************************************/
#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SYSCFG_H
#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SYSCFG_H
-/****************************************************************************************************
+/************************************************************************************
* Included Files
- ****************************************************************************************************/
+ ************************************************************************************/
#include
#include "chip.h"
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
+#if defined(CONFIG_STM32L4_STM32L4X6)
+# include "chip/stm32l4x6xx_syscfg.h"
+#elif defined(CONFIG_STM32L4_STM32L4X3)
+# include "chip/stm32l4x3xx_syscfg.h"
+#else
+# error "Unsupported STM32 L4 chip"
+#endif
-/****************************************************************************************************
- * Pre-processor Definitions
- ****************************************************************************************************/
-
-/* Register Offsets *********************************************************************************/
-
-#define STM32L4_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */
-#define STM32L4_SYSCFG_CFGR1_OFFSET 0x0004 /* SYSCFG configuration register 1 */
-#define STM32L4_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */
-#define STM32L4_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */
-#define STM32L4_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */
-#define STM32L4_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */
-#define STM32L4_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */
-#define STM32L4_SYSCFG_SCSR_OFFSET 0x0018 /* SYSCFG SRAM2 control and status register */
-#define STM32L4_SYSCFG_CFGR2_OFFSET 0x001c /* SYSCFG configuration register 2 */
-#define STM32L4_SYSCFG_SWPR_OFFSET 0x0020 /* SYSCFG SRAM2 write protection register */
-#define STM32L4_SYSCFG_SKR_OFFSET 0x0024 /* SYSCFG SRAM2 key register */
-#define STM32L4_SYSCFG_SWPR2_OFFSET 0x0028 /* SYSCFG SRAM2 write protection register 2 */
-
-/* Register Addresses *******************************************************************************/
-
-#define STM32L4_SYSCFG_MEMRMP (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_MEMRMP_OFFSET)
-#define STM32L4_SYSCFG_CFGR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR1_OFFSET)
-#define STM32L4_SYSCFG_EXTICR(p) (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR_OFFSET(p))
-#define STM32L4_SYSCFG_EXTICR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR1_OFFSET)
-#define STM32L4_SYSCFG_EXTICR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR2_OFFSET)
-#define STM32L4_SYSCFG_EXTICR3 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR3_OFFSET)
-#define STM32L4_SYSCFG_EXTICR4 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR4_OFFSET)
-#define STM32L4_SYSCFG_SCSR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SCSR_OFFSET)
-#define STM32L4_SYSCFG_CFGR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR2_OFFSET)
-#define STM32L4_SYSCFG_SWPR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SWPR_OFFSET)
-#define STM32L4_SYSCFG_SKR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SKR_OFFSET)
-
-/* Register Bitfield Definitions ********************************************************************/
-
-/* SYSCFG memory remap register */
-
-#define SYSCFG_MEMRMP_SHIFT (0) /* Bits 2:0 MEM_MODE: Memory mapping selection */
-#define SYSCFG_MEMRMP_MASK (7 << SYSCFG_MEMRMP_SHIFT)
-# define SYSCFG_MEMRMP_FLASH (0 << SYSCFG_MEMRMP_SHIFT) /* 000: Main Flash memory mapped at 0x0000 0000 */
-# define SYSCFG_MEMRMP_SYSTEM (1 << SYSCFG_MEMRMP_SHIFT) /* 001: System Flash memory mapped at 0x0000 0000 */
-# define SYSCFG_MEMRMP_FMC (2 << SYSCFG_MEMRMP_SHIFT) /* 010: FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x0000 0000 */
-# define SYSCFG_MEMRMP_SRAM (3 << SYSCFG_MEMRMP_SHIFT) /* 011: SRAM1 (112kB) mapped at 0x0000 0000 */
-# define SYSCFG_MEMRMP_QSPI (6 << SYSCFG_MEMRMP_SHIFT) /* 110: QUADSPI mapped at 0x0000 0000 */
-#define SYSCFG_FBMODE (1 << 8) /* Bit 8: Flash Bank mode selection */
-
-/* SYSCFG configuration register 1 */
-
-#define SYSCFG_CFGR1_FWDIS (1 << 0) /* Bit 0: Firewall disable */
-#define SYSCFG_CFGR1_BOOSTEN (1 << 8) /* Bit 8: I/O analog switch voltage booster enable (use when vdd is low) */
-#define SYSCFG_CFGR1_I2C_PB6_FMP (1 << 16) /* Bit 16: Fast-mode Plus (Fm+) driving capability activation on PB6 */
-#define SYSCFG_CFGR1_I2C_PB7_FMP (1 << 17) /* Bit 17: Fast-mode Plus (Fm+) driving capability activation on PB7 */
-#define SYSCFG_CFGR1_I2C_PB8_FMP (1 << 18) /* Bit 18: Fast-mode Plus (Fm+) driving capability activation on PB8 */
-#define SYSCFG_CFGR1_I2C_PB9_FMP (1 << 19) /* Bit 19: Fast-mode Plus (Fm+) driving capability activation on PB9 */
-#define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 Fast-mode Plus (Fm+) driving capability activation */
-#define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C2 Fast-mode Plus (Fm+) driving capability activation */
-#define SYSCFG_CFGR1_I2C3_FMP (1 << 22) /* Bit 22: I2C3 Fast-mode Plus (Fm+) driving capability activation */
-#define SYSCFG_CFGR1_I2C4_FMP (1 << 23) /* Bit 23: I2C4 Fast-mode Plus (Fm+) driving capability activation */
-#define SYSCFG_CFGR1_FPU_IE0 (1 << 26) /* Bit 26: FPU Invalid operation interrupt enable */
-#define SYSCFG_CFGR1_FPU_IE1 (1 << 27) /* Bit 27: FPU Divide-by-zero interrupt enable */
-#define SYSCFG_CFGR1_FPU_IE2 (1 << 28) /* Bit 28: FPU Underflow interrupt enable */
-#define SYSCFG_CFGR1_FPU_IE3 (1 << 29) /* Bit 29: FPU Overflow interrupt enable */
-#define SYSCFG_CFGR1_FPU_IE4 (1 << 30) /* Bit 30: FPU Input denormal interrupt enable */
-#define SYSCFG_CFGR1_FPU_IE5 (1 << 31) /* Bit 31: FPU Inexact interrupt enable */
-
-/* SYSCFG external interrupt configuration register 1-4 */
-
-#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */
-#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */
-#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */
-#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */
-#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */
-#define SYSCFG_EXTICR_PORTF (5) /* 0101: PF[C] pin */
-#define SYSCFG_EXTICR_PORTG (6) /* 0110: PG[x] pin */
-#define SYSCFG_EXTICR_PORTH (7) /* 0111: PH[x] pin (only on STM32L496xx/4A6xx) */
-#define SYSCFG_EXTICR_PORTI (8) /* 1000: PI[x] pin (only on STM32L496xx/4A6xx) */
-
-#define SYSCFG_EXTICR_PORT_MASK (15)
-#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2)
-#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g)))
-
-#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-2: EXTI 0 configuration */
-#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT)
-#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-6: EXTI 1 configuration */
-#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT)
-#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-10: EXTI 2 configuration */
-#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT)
-#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-14: EXTI 3 configuration */
-#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT)
-
-#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-2: EXTI 4 configuration */
-#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT)
-#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-6: EXTI 5 configuration */
-#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT)
-#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-10: EXTI 6 configuration */
-#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT)
-#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-14: EXTI 7 configuration */
-#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT)
-
-#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-2: EXTI 8 configuration */
-#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT)
-#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-6: EXTI 9 configuration */
-#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT)
-#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-10: EXTI 10 configuration */
-#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT)
-#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-14: EXTI 11 configuration */
-#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT)
-
-#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-2: EXTI 12 configuration */
-#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT)
-#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-6: EXTI 13 configuration */
-#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT)
-#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-10: EXTI 14 configuration */
-#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT)
-#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-14: EXTI 15 configuration */
-#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT)
-
-/* SYSCFG SRAM2 control and status register */
-
-#define SYSCFG_SCSR_SRAM2ER (1 << 0) /* Bit 0: SRAM2 Erase */
-#define SYSCFG_SCSR_SRAM2BSY (1 << 1) /* Bit 1: SRAM2 busy in erase operation */
-
-/* SYSCFG configuration register 2 */
-
-#define SYSCFG_CFGR2_CLL (1 << 0) /* Bit 0: Cortex-M4 LOCKUP (Hardfault) output enable (TIMx break enable, see refman) */
-#define SYSCFG_CFGR2_SPL (1 << 1) /* Bit 1: SRAM2 parity lock enable (same) */
-#define SYSCFG_CFGR2_PVDL (1 << 2) /* Bit 2: PVD lock enable (same) */
-#define SYSCFG_CFGR2_ECCL (1 << 3) /* Bit 3: ECC lock enable (same) */
-#define SYSCFG_CFGR2_SPF (1 << 8) /* Bit 8: SRAM2 parity error flag */
-
-/* SYSCFG SRAM2 write protection register */
-/* There is one bit per SRAM2 page (0 to 31) */
-
-/* SYSCFG SRAM2 key register */
-
-#define SYSCFG_SKR_SHIFT 0
-#define SYSCFG_SKR_MASK (0xFF << SYSCFG_SKR_SHIFT)
-
-/* SYSCFG SRAM2 write protection register 2 (only on STM32L496xx/4A6xx) */
-/* There is one bit per SRAM2 page (32 to 63) */
-
-#endif /* CONFIG_STM32L4_STM32L476XX || CONFIG_STM32L4_STM32L486XX || CONFIG_STM32L4_STM32L496XX */
#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_SYSCFG_H */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h b/arch/arm/src/stm32l4/chip/stm32l4_uart.h
similarity index 97%
rename from arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h
rename to arch/arm/src/stm32l4/chip/stm32l4_uart.h
index 7e1855061d5..c7605ab8ad8 100644
--- a/arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h
+++ b/arch/arm/src/stm32l4/chip/stm32l4_uart.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/stm32l4/chip/stm32l4x6xx_uart.h
+ * arch/arm/src/stm32l4/chip/stm32l4_uart.h
*
* Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_UART_H
-#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_UART_H
+#ifndef __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_UART_H
+#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4_UART_H
/************************************************************************************
* Included Files
@@ -57,7 +57,7 @@
#define STM32L4_USART_GTPR_OFFSET 0x0010 /* Guard time and prescaler register */
#define STM32L4_USART_RTOR_OFFSET 0x0014 /* Receiver timeout register */
#define STM32L4_USART_RQR_OFFSET 0x0018 /* Request register */
-#define STM32L4_USART_ISR_OFFSET 0x001c /* Interrupot and status register */
+#define STM32L4_USART_ISR_OFFSET 0x001c /* Interrupt and status register */
#define STM32L4_USART_ICR_OFFSET 0x0020 /* Interrupt flag clear register */
#define STM32L4_USART_RDR_OFFSET 0x0024 /* Receive Data register */
#define STM32L4_USART_TDR_OFFSET 0x0028 /* Transmit Data register */
@@ -139,7 +139,7 @@
/* Control register 1 */
#define USART_CR1_UE (1 << 0) /* Bit 0: USART Enable */
-#define USART_CR1_UESM (1 << 1) /* Bit 1: USART Enable in Stop mode*/
+#define USART_CR1_UESM (1 << 1) /* Bit 1: USART Enable in Stop mode */
#define USART_CR1_RE (1 << 2) /* Bit 2: Receiver Enable */
#define USART_CR1_TE (1 << 3) /* Bit 3: Transmitter Enable */
#define USART_CR1_IDLEIE (1 << 4) /* Bit 4: IDLE Interrupt Enable */
@@ -150,7 +150,7 @@
#define USART_CR1_PS (1 << 9) /* Bit 9: Parity Selection */
#define USART_CR1_PCE (1 << 10) /* Bit 10: Parity Control Enable */
#define USART_CR1_WAKE (1 << 11) /* Bit 11: Wakeup method */
-#define USART_CR1_M0 (1 << 12) /* Bit 12: word length */
+#define USART_CR1_M0 (1 << 12) /* Bit 12: Word length */
#define USART_CR1_MME (1 << 13) /* Bit 13: Mute mode enable */
#define USART_CR1_CMIE (1 << 14) /* Bit 14: Character match interrupt enable */
#define USART_CR1_OVER8 (1 << 15) /* Bit 15: Oversampling mode */
@@ -163,7 +163,7 @@
#define USART_CR1_RTOIE (1 << 26) /* Bit 26: Receiver timeout interrupt enable */
#define USART_CR1_EOBIE (1 << 27) /* Bit 27: End of block interrupt enable */
-#define USART_CR1_M1 (1 << 28) /* Bit 12: word length */
+#define USART_CR1_M1 (1 << 28) /* Bit 28: Word length */
#define USART_CR1_ALLINTS (USART_CR1_IDLEIE|USART_CR1_RXNEIE| \
USART_CR1_TCIE|USART_CR1_TXEIE|USART_CR1_PEIE|USART_CR1_CMIE| \
@@ -171,7 +171,7 @@
/* Control register 2 */
-#define USART_CR2_ADDM7 (1 << 4) /* Bit 4: */
+#define USART_CR2_ADDM7 (1 << 4) /* Bit 4: 7-bit/4-bit Address Detection */
#define USART_CR2_LBDL (1 << 5) /* Bit 5: LIN Break Detection Length */
#define USART_CR2_LBDIE (1 << 6) /* Bit 6: LIN Break Detection Interrupt Enable */
#define USART_CR2_LBCL (1 << 8) /* Bit 8: Last Bit Clock pulse */
@@ -314,5 +314,5 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_STC_STM32L4_CHIP_STM32L4X6XX_UART_H */
+#endif /* __ARCH_ARM_STC_STM32L4_CHIP_STM32L4_UART_H */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x3xx_dma.h b/arch/arm/src/stm32l4/chip/stm32l4x3xx_dma.h
new file mode 100644
index 00000000000..166562c9c5b
--- /dev/null
+++ b/arch/arm/src/stm32l4/chip/stm32l4x3xx_dma.h
@@ -0,0 +1,461 @@
+/************************************************************************************
+ * arch/arm/src/stm32l4/chip/stm32l4x3xx_dma.h
+ *
+ * Copyright (C) 2009, 2011-2013 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 __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_DMA_H
+#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_DMA_H
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+/* 14 Channels Total: 7 DMA1 Channels(1-7) and 7 DMA2 channels (1-7) */
+
+#define DMA1 0
+#define DMA2 1
+#define DMA3 2
+#define DMA4 3
+#define DMA5 4
+#define DMA6 5
+#define DMA7 6
+
+/* Register Offsets *****************************************************************/
+
+#define STM32L4_DMA_ISR_OFFSET 0x0000 /* DMA interrupt status register */
+#define STM32L4_DMA_IFCR_OFFSET 0x0004 /* DMA interrupt flag clear register */
+
+#define STM32L4_DMACHAN_OFFSET(n) (0x0014*(n))
+#define STM32L4_DMACHAN1_OFFSET 0x0000
+#define STM32L4_DMACHAN2_OFFSET 0x0014
+#define STM32L4_DMACHAN3_OFFSET 0x0028
+#define STM32L4_DMACHAN4_OFFSET 0x003c
+#define STM32L4_DMACHAN5_OFFSET 0x0050
+#define STM32L4_DMACHAN6_OFFSET 0x0064
+#define STM32L4_DMACHAN7_OFFSET 0x0078
+
+#define STM32L4_DMACHAN_CCR_OFFSET 0x0008 /* DMA channel configuration register */
+#define STM32L4_DMACHAN_CNDTR_OFFSET 0x000c /* DMA channel number of data register */
+#define STM32L4_DMACHAN_CPAR_OFFSET 0x0010 /* DMA channel peripheral address register */
+#define STM32L4_DMACHAN_CMAR_OFFSET 0x0014 /* DMA channel memory address register */
+
+#define STM32L4_DMA_CCR_OFFSET(n) (STM32L4_DMACHAN_CCR_OFFSET+STM32L4_DMACHAN_OFFSET(n))
+#define STM32L4_DMA_CNDTR_OFFSET(n) (STM32L4_DMACHAN_CNDTR_OFFSET+STM32L4_DMACHAN_OFFSET(n))
+#define STM32L4_DMA_CPAR_OFFSET(n) (STM32L4_DMACHAN_CPAR_OFFSET+STM32L4_DMACHAN_OFFSET(n))
+#define STM32L4_DMA_CMAR_OFFSET(n) (STM32L4_DMACHAN_CMAR_OFFSET+STM32L4_DMACHAN_OFFSET(n))
+
+#define STM32L4_DMA_CCR1_OFFSET 0x0008 /* DMA channel 1 configuration register */
+#define STM32L4_DMA_CCR2_OFFSET 0x001c /* DMA channel 2 configuration register */
+#define STM32L4_DMA_CCR3_OFFSET 0x0030 /* DMA channel 3 configuration register */
+#define STM32L4_DMA_CCR4_OFFSET 0x0044 /* DMA channel 4 configuration register */
+#define STM32L4_DMA_CCR5_OFFSET 0x0058 /* DMA channel 5 configuration register */
+#define STM32L4_DMA_CCR6_OFFSET 0x006c /* DMA channel 6 configuration register */
+#define STM32L4_DMA_CCR7_OFFSET 0x0080 /* DMA channel 7 configuration register */
+
+#define STM32L4_DMA_CNDTR1_OFFSET 0x000c /* DMA channel 1 number of data register */
+#define STM32L4_DMA_CNDTR2_OFFSET 0x0020 /* DMA channel 2 number of data register */
+#define STM32L4_DMA_CNDTR3_OFFSET 0x0034 /* DMA channel 3 number of data register */
+#define STM32L4_DMA_CNDTR4_OFFSET 0x0048 /* DMA channel 4 number of data register */
+#define STM32L4_DMA_CNDTR5_OFFSET 0x005c /* DMA channel 5 number of data register */
+#define STM32L4_DMA_CNDTR6_OFFSET 0x0070 /* DMA channel 6 number of data register */
+#define STM32L4_DMA_CNDTR7_OFFSET 0x0084 /* DMA channel 7 number of data register */
+
+#define STM32L4_DMA_CPAR1_OFFSET 0x0010 /* DMA channel 1 peripheral address register */
+#define STM32L4_DMA_CPAR2_OFFSET 0x0024 /* DMA channel 2 peripheral address register */
+#define STM32L4_DMA_CPAR3_OFFSET 0x0038 /* DMA channel 3 peripheral address register */
+#define STM32L4_DMA_CPAR4_OFFSET 0x004c /* DMA channel 4 peripheral address register */
+#define STM32L4_DMA_CPAR5_OFFSET 0x0060 /* DMA channel 5 peripheral address register */
+#define STM32L4_DMA_CPAR6_OFFSET 0x0074 /* DMA channel 6 peripheral address register */
+#define STM32L4_DMA_CPAR7_OFFSET 0x0088 /* DMA channel 7 peripheral address register */
+
+#define STM32L4_DMA_CMAR1_OFFSET 0x0014 /* DMA channel 1 memory address register */
+#define STM32L4_DMA_CMAR2_OFFSET 0x0028 /* DMA channel 2 memory address register */
+#define STM32L4_DMA_CMAR3_OFFSET 0x003c /* DMA channel 3 memory address register */
+#define STM32L4_DMA_CMAR4_OFFSET 0x0050 /* DMA channel 4 memory address register */
+#define STM32L4_DMA_CMAR5_OFFSET 0x0064 /* DMA channel 5 memory address register */
+#define STM32L4_DMA_CMAR6_OFFSET 0x0078 /* DMA channel 6 memory address register */
+#define STM32L4_DMA_CMAR7_OFFSET 0x008c /* DMA channel 7 memory address register */
+
+#define STM32L4_DMA_CSELR_OFFSET 0x00a8 /* DMA channel selection register */
+
+/* Register Addresses ***************************************************************/
+
+#define STM32L4_DMA1_ISRC (STM32L4_DMA1_BASE+STM32L4_DMA_ISR_OFFSET)
+#define STM32L4_DMA1_IFCR (STM32L4_DMA1_BASE+STM32L4_DMA_IFCR_OFFSET)
+
+#define STM32L4_DMA1_CCR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CCR_OFFSET(n))
+#define STM32L4_DMA1_CCR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR1_OFFSET)
+#define STM32L4_DMA1_CCR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR2_OFFSET)
+#define STM32L4_DMA1_CCR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR3_OFFSET)
+#define STM32L4_DMA1_CCR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR4_OFFSET)
+#define STM32L4_DMA1_CCR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR5_OFFSET)
+#define STM32L4_DMA1_CCR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR6_OFFSET)
+#define STM32L4_DMA1_CCR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CCR7_OFFSET)
+
+#define STM32L4_DMA1_CNDTR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR_OFFSET(n))
+#define STM32L4_DMA1_CNDTR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR1_OFFSET)
+#define STM32L4_DMA1_CNDTR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR2_OFFSET)
+#define STM32L4_DMA1_CNDTR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR3_OFFSET)
+#define STM32L4_DMA1_CNDTR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR4_OFFSET)
+#define STM32L4_DMA1_CNDTR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR5_OFFSET)
+#define STM32L4_DMA1_CNDTR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR6_OFFSET)
+#define STM32L4_DMA1_CNDTR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CNDTR7_OFFSET)
+
+#define STM32L4_DMA1_CPAR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR_OFFSET(n))
+#define STM32L4_DMA1_CPAR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR1_OFFSET)
+#define STM32L4_DMA1_CPAR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR2_OFFSET)
+#define STM32L4_DMA1_CPAR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR3_OFFSET)
+#define STM32L4_DMA1_CPAR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR4_OFFSET)
+#define STM32L4_DMA1_CPAR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR5_OFFSET)
+#define STM32L4_DMA1_CPAR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR6_OFFSET)
+#define STM32L4_DMA1_CPAR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CPAR7_OFFSET)
+
+#define STM32L4_DMA1_CMAR(n) (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR_OFFSET(n))
+#define STM32L4_DMA1_CMAR1 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR1_OFFSET)
+#define STM32L4_DMA1_CMAR2 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR2_OFFSET)
+#define STM32L4_DMA1_CMAR3 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR3_OFFSET)
+#define STM32L4_DMA1_CMAR4 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR4_OFFSET)
+#define STM32L4_DMA1_CMAR5 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR5_OFFSET)
+#define STM32L4_DMA1_CMAR6 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR6_OFFSET)
+#define STM32L4_DMA1_CMAR7 (STM32L4_DMA1_BASE+STM32L4_DMA_CMAR7_OFFSET)
+
+#define STM32L4_DMA2_ISRC (STM32L4_DMA2_BASE+STM32L4_DMA_ISR_OFFSET)
+#define STM32L4_DMA2_IFCR (STM32L4_DMA2_BASE+STM32L4_DMA_IFCR_OFFSET)
+
+#define STM32L4_DMA2_CCR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CCR_OFFSET(n))
+#define STM32L4_DMA2_CCR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR1_OFFSET)
+#define STM32L4_DMA2_CCR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR2_OFFSET)
+#define STM32L4_DMA2_CCR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR3_OFFSET)
+#define STM32L4_DMA2_CCR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR4_OFFSET)
+#define STM32L4_DMA2_CCR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR5_OFFSET)
+#define STM32L4_DMA2_CCR6 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR6_OFFSET)
+#define STM32L4_DMA2_CCR7 (STM32L4_DMA2_BASE+STM32L4_DMA_CCR7_OFFSET)
+
+#define STM32L4_DMA2_CNDTR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR_OFFSET(n))
+#define STM32L4_DMA2_CNDTR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR1_OFFSET)
+#define STM32L4_DMA2_CNDTR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR2_OFFSET)
+#define STM32L4_DMA2_CNDTR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR3_OFFSET)
+#define STM32L4_DMA2_CNDTR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR4_OFFSET)
+#define STM32L4_DMA2_CNDTR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR5_OFFSET)
+#define STM32L4_DMA2_CNDTR6 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR6_OFFSET)
+#define STM32L4_DMA2_CNDTR7 (STM32L4_DMA2_BASE+STM32L4_DMA_CNDTR7_OFFSET)
+
+#define STM32L4_DMA2_CPAR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR_OFFSET(n))
+#define STM32L4_DMA2_CPAR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR1_OFFSET)
+#define STM32L4_DMA2_CPAR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR2_OFFSET)
+#define STM32L4_DMA2_CPAR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR3_OFFSET)
+#define STM32L4_DMA2_CPAR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR4_OFFSET)
+#define STM32L4_DMA2_CPAR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR5_OFFSET)
+#define STM32L4_DMA2_CPAR6 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR6_OFFSET)
+#define STM32L4_DMA2_CPAR7 (STM32L4_DMA2_BASE+STM32L4_DMA_CPAR7_OFFSET)
+
+#define STM32L4_DMA2_CMAR(n) (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR_OFFSET(n))
+#define STM32L4_DMA2_CMAR1 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR1_OFFSET)
+#define STM32L4_DMA2_CMAR2 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR2_OFFSET)
+#define STM32L4_DMA2_CMAR3 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR3_OFFSET)
+#define STM32L4_DMA2_CMAR4 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR4_OFFSET)
+#define STM32L4_DMA2_CMAR5 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR5_OFFSET)
+#define STM32L4_DMA2_CMAR6 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR6_OFFSET)
+#define STM32L4_DMA2_CMAR7 (STM32L4_DMA2_BASE+STM32L4_DMA_CMAR7_OFFSET)
+
+/* Register Bitfield Definitions ****************************************************/
+
+#define DMA_CHAN_SHIFT(n) ((n) << 2)
+#define DMA_CHAN_MASK 0x0f
+#define DMA_CHAN_GIF_BIT (1 << 0) /* Bit 0: Channel Global interrupt flag */
+#define DMA_CHAN_TCIF_BIT (1 << 1) /* Bit 1: Channel Transfer Complete flag */
+#define DMA_CHAN_HTIF_BIT (1 << 2) /* Bit 2: Channel Half Transfer flag */
+#define DMA_CHAN_TEIF_BIT (1 << 3) /* Bit 3: Channel Transfer Error flag */
+
+/* DMA interrupt status register */
+
+#define DMA_ISR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n)
+#define DMA_ISR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_ISR_CHAN_SHIFT(n))
+#define DMA_ISR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt status */
+#define DMA_ISR_CHAN1_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN1_SHIFT)
+#define DMA_ISR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt status */
+#define DMA_ISR_CHAN2_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN2_SHIFT)
+#define DMA_ISR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt status */
+#define DMA_ISR_CHAN3_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN3_SHIFT)
+#define DMA_ISR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt status */
+#define DMA_ISR_CHAN4_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN4_SHIFT)
+#define DMA_ISR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt status */
+#define DMA_ISR_CHAN5_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN5_SHIFT)
+#define DMA_ISR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt status */
+#define DMA_ISR_CHAN6_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN6_SHIFT)
+#define DMA_ISR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt status */
+#define DMA_ISR_CHAN7_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN7_SHIFT)
+
+#define DMA_ISR_GIF(n) (DMA_CHAN_GIF_BIT << DMA_ISR_CHAN_SHIFT(n))
+#define DMA_ISR_TCIF(n) (DMA_CHAN_TCIF_BIT << DMA_ISR_CHAN_SHIFT(n))
+#define DMA_ISR_HTIF(n) (DMA_CHAN_HTIF_BIT << DMA_ISR_CHAN_SHIFT(n))
+#define DMA_ISR_TEIF(n) (DMA_CHAN_TEIF_BIT << DMA_ISR_CHAN_SHIFT(n))
+
+/* DMA interrupt flag clear register */
+
+#define DMA_IFCR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n)
+#define DMA_IFCR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_IFCR_CHAN_SHIFT(n))
+#define DMA_IFCR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt flag clear */
+#define DMA_IFCR_CHAN1_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN1_SHIFT)
+#define DMA_IFCR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt flag clear */
+#define DMA_IFCR_CHAN2_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN2_SHIFT)
+#define DMA_IFCR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt flag clear */
+#define DMA_IFCR_CHAN3_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN3_SHIFT)
+#define DMA_IFCR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt flag clear */
+#define DMA_IFCR_CHAN4_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN4_SHIFT)
+#define DMA_IFCR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt flag clear */
+#define DMA_IFCR_CHAN5_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN5_SHIFT)
+#define DMA_IFCR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt flag clear */
+#define DMA_IFCR_CHAN6_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN6_SHIFT)
+#define DMA_IFCR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt flag clear */
+#define DMA_IFCR_CHAN7_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN7_SHIFT)
+#define DMA_IFCR_ALLCHANNELS (0x0fffffff)
+
+#define DMA_IFCR_CGIF(n) (DMA_CHAN_GIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
+#define DMA_IFCR_CTCIF(n) (DMA_CHAN_TCIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
+#define DMA_IFCR_CHTIF(n) (DMA_CHAN_HTIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
+#define DMA_IFCR_CTEIF(n) (DMA_CHAN_TEIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
+
+/* DMA channel configuration register */
+
+#define DMA_CCR_EN (1 << 0) /* Bit 0: Channel enable */
+#define DMA_CCR_TCIE (1 << 1) /* Bit 1: Transfer complete interrupt enable */
+#define DMA_CCR_HTIE (1 << 2) /* Bit 2: Half Transfer interrupt enable */
+#define DMA_CCR_TEIE (1 << 3) /* Bit 3: Transfer error interrupt enable */
+#define DMA_CCR_DIR (1 << 4) /* Bit 4: Data transfer direction */
+#define DMA_CCR_CIRC (1 << 5) /* Bit 5: Circular mode */
+#define DMA_CCR_PINC (1 << 6) /* Bit 6: Peripheral increment mode */
+#define DMA_CCR_MINC (1 << 7) /* Bit 7: Memory increment mode */
+#define DMA_CCR_PSIZE_SHIFT (8) /* Bits 8-9: Peripheral size */
+#define DMA_CCR_PSIZE_MASK (3 << DMA_CCR_PSIZE_SHIFT)
+# define DMA_CCR_PSIZE_8BITS (0 << DMA_CCR_PSIZE_SHIFT) /* 00: 8-bits */
+# define DMA_CCR_PSIZE_16BITS (1 << DMA_CCR_PSIZE_SHIFT) /* 01: 16-bits */
+# define DMA_CCR_PSIZE_32BITS (2 << DMA_CCR_PSIZE_SHIFT) /* 10: 32-bits */
+#define DMA_CCR_MSIZE_SHIFT (10) /* Bits 10-11: Memory size */
+#define DMA_CCR_MSIZE_MASK (3 << DMA_CCR_MSIZE_SHIFT)
+# define DMA_CCR_MSIZE_8BITS (0 << DMA_CCR_MSIZE_SHIFT) /* 00: 8-bits */
+# define DMA_CCR_MSIZE_16BITS (1 << DMA_CCR_MSIZE_SHIFT) /* 01: 16-bits */
+# define DMA_CCR_MSIZE_32BITS (2 << DMA_CCR_MSIZE_SHIFT) /* 10: 32-bits */
+#define DMA_CCR_PL_SHIFT (12) /* Bits 12-13: Channel Priority level */
+#define DMA_CCR_PL_MASK (3 << DMA_CCR_PL_SHIFT)
+# define DMA_CCR_PRILO (0 << DMA_CCR_PL_SHIFT) /* 00: Low */
+# define DMA_CCR_PRIMED (1 << DMA_CCR_PL_SHIFT) /* 01: Medium */
+# define DMA_CCR_PRIHI (2 << DMA_CCR_PL_SHIFT) /* 10: High */
+# define DMA_CCR_PRIVERYHI (3 << DMA_CCR_PL_SHIFT) /* 11: Very high */
+#define DMA_CCR_MEM2MEM (1 << 14) /* Bit 14: Memory to memory mode */
+
+#define DMA_CCR_ALLINTS (DMA_CCR_TEIE|DMA_CCR_HTIE|DMA_CCR_TCIE)
+
+/* DMA channel number of data register */
+
+#define DMA_CNDTR_NDT_SHIFT (0) /* Bits 15-0: Number of data to Transfer */
+#define DMA_CNDTR_NDT_MASK (0xffff << DMA_CNDTR_NDT_SHIFT)
+
+/* DMA Channel mapping. Each DMA channel has a mapping to one of several
+ * possible sources/sinks of data. The requests from peripherals assigned to a
+ * channel are multiplexed together before entering the DMA block. This means
+ * that only one request on a given channel can be enabled at once.
+ *
+ * Alternative DMA channel selections are provided with a numeric suffix like _1,
+ * _2, etc. Drivers, however, will use the pin selection without the numeric suffix.
+ * Additional definitions are required in the board.h file.
+ */
+
+#define STM32L4_DMA1_CHAN1 (0)
+#define STM32L4_DMA1_CHAN2 (1)
+#define STM32L4_DMA1_CHAN3 (2)
+#define STM32L4_DMA1_CHAN4 (3)
+#define STM32L4_DMA1_CHAN5 (4)
+#define STM32L4_DMA1_CHAN6 (5)
+#define STM32L4_DMA1_CHAN7 (6)
+
+#define STM32L4_DMA2_CHAN1 (7)
+#define STM32L4_DMA2_CHAN2 (8)
+#define STM32L4_DMA2_CHAN3 (9)
+#define STM32L4_DMA2_CHAN4 (10)
+#define STM32L4_DMA2_CHAN5 (11)
+#define STM32L4_DMA2_CHAN6 (12)
+#define STM32L4_DMA2_CHAN7 (13)
+
+/* DMA Channel settings include a channel and an alternative function.
+ * Channel is in bits 0..7
+ * Request number is in bits 8..15
+ */
+
+#define DMACHAN_SETTING(chan, req) ((((req) & 0xff) << 8) | ((chan) & 0xff))
+#define DMACHAN_SETTING_CHANNEL_MASK 0x00FF
+#define DMACHAN_SETTING_CHANNEL_SHIFT (0)
+#define DMACHAN_SETTING_FUNCTION_MASK 0xFF00
+#define DMACHAN_SETTING_FUNCTION_SHIFT (8)
+
+/* ADC */
+
+#define DMACHAN_ADC1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 0)
+#define DMACHAN_ADC1_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 0)
+
+/* AES */
+
+#define DMACHAN_AES_IN_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 6)
+#define DMACHAN_AES_IN_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 6)
+#define DMACHAN_AES_OUT_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 6)
+#define DMACHAN_AES_OUT_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 6)
+
+/* DAC */
+
+#define DMACHAN_DAC1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 6)
+#define DMACHAN_DAC1_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 5)
+#define DMACHAN_DAC1_3 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 3)
+
+/* DCMI */
+
+#define DMACHAN_DCMI_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 4)
+#define DMACHAN_DCMI_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 0)
+
+/* DFSDM */
+
+#define DMACHAN_DFSDM1_FLT0 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 0)
+#define DMACHAN_DFSDM1_FLT1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 0)
+
+/* I2C */
+
+#define DMACHAN_I2C1_RX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 3)
+#define DMACHAN_I2C1_RX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 5)
+#define DMACHAN_I2C1_TX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 3)
+#define DMACHAN_I2C1_TX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 5)
+
+#define DMACHAN_I2C2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 3)
+#define DMACHAN_I2C2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 3)
+
+#define DMACHAN_I2C3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 2)
+#define DMACHAN_I2C3_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 3)
+
+#define DMACHAN_I2C4_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 0)
+#define DMACHAN_I2C4_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 0)
+
+/* QUADSPI */
+
+#define DMACHAN_QUADSPI_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 5)
+#define DMACHAN_QUADSPI_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 3)
+
+/* SAI */
+
+#define DMACHAN_SAI1_A_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 1)
+#define DMACHAN_SAI1_A_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 1)
+#define DMACHAN_SAI1_B_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 1)
+#define DMACHAN_SAI1_B_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 1)
+
+#define DMACHAN_SAI2_A_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 1)
+#define DMACHAN_SAI2_A_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 1)
+#define DMACHAN_SAI2_B_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 1)
+#define DMACHAN_SAI2_B_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 1)
+
+/* SDMMC */
+
+#define DMACHAN_SDMMC_1 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 7)
+#define DMACHAN_SDMMC_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 7)
+
+/* SPI */
+
+#define DMACHAN_SPI1_RX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 1)
+#define DMACHAN_SPI1_RX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 4)
+#define DMACHAN_SPI1_TX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 1)
+#define DMACHAN_SPI1_TX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 4)
+
+#define DMACHAN_SPI2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 1)
+#define DMACHAN_SPI2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 1)
+
+#define DMACHAN_SPI3_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 3)
+#define DMACHAN_SPI3_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 3)
+
+/* SWPMI */
+
+#define DMACHAN_SWPMI_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN1, 4)
+#define DMACHAN_SWPMI_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN2, 4)
+
+/* TIM */
+
+#define DMACHAN_TIM1_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 7)
+#define DMACHAN_TIM1_CH2 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 7)
+#define DMACHAN_TIM1_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 7)
+#define DMACHAN_TIM1_CH4 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 7)
+#define DMACHAN_TIM1_COM DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 7)
+#define DMACHAN_TIM1_TRIG DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 7)
+#define DMACHAN_TIM1_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 7)
+
+#define DMACHAN_TIM2_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 4)
+#define DMACHAN_TIM2_CH2 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 4)
+#define DMACHAN_TIM2_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN1, 4)
+#define DMACHAN_TIM2_CH4 DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 4)
+#define DMACHAN_TIM2_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 4)
+
+#define DMACHAN_TIM3_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 5)
+#define DMACHAN_TIM3_CH3 DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 5)
+#define DMACHAN_TIM3_CH4 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 5)
+#define DMACHAN_TIM3_TRIG DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 5)
+#define DMACHAN_TIM3_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 5)
+
+#define DMACHAN_TIM6_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 6)
+#define DMACHAN_TIM6_UP_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN4, 3)
+
+#define DMACHAN_TIM7_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 5)
+#define DMACHAN_TIM7_UP_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 3)
+
+#define DMACHAN_TIM15_CH1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7)
+#define DMACHAN_TIM15_COM DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7)
+#define DMACHAN_TIM15_TRIG DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7)
+#define DMACHAN_TIM15_UP DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 7)
+
+#define DMACHAN_TIM16_CH1_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 4)
+#define DMACHAN_TIM16_CH1_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 4)
+#define DMACHAN_TIM16_UP_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 4)
+#define DMACHAN_TIM16_UP_2 DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 4)
+
+/* UART */
+
+#define DMACHAN_USART1_RX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN5, 2)
+#define DMACHAN_USART1_RX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 2)
+#define DMACHAN_USART1_TX_1 DMACHAN_SETTING(STM32L4_DMA1_CHAN4, 2)
+#define DMACHAN_USART1_TX_2 DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 2)
+
+#define DMACHAN_USART2_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN6, 2)
+#define DMACHAN_USART2_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN7, 2)
+
+#define DMACHAN_USART3_RX DMACHAN_SETTING(STM32L4_DMA1_CHAN3, 1)
+#define DMACHAN_USART3_TX DMACHAN_SETTING(STM32L4_DMA1_CHAN2, 2)
+
+#define DMACHAN_UART4_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN5, 2)
+#define DMACHAN_UART4_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN3, 2)
+
+#define DMACHAN_LPUART_RX DMACHAN_SETTING(STM32L4_DMA2_CHAN7, 4)
+#define DMACHAN_LPUART_TX DMACHAN_SETTING(STM32L4_DMA2_CHAN6, 4)
+
+#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_DMA_H */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x3xx_firewall.h b/arch/arm/src/stm32l4/chip/stm32l4x3xx_firewall.h
new file mode 100644
index 00000000000..4e78b60102c
--- /dev/null
+++ b/arch/arm/src/stm32l4/chip/stm32l4x3xx_firewall.h
@@ -0,0 +1,103 @@
+/************************************************************************************
+ * arch/arm/src/stm32l4/chip/stm32l4x3xx_firewall.h
+ *
+ * Copyright (C) 2016 Sebastien Lorquet. All rights reserved.
+ * Author: Sebastien Lorquet
+ *
+ * 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 __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_FIREWALL_H
+#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_FIREWALL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+#include
+
+#include "chip.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Register Offsets *****************************************************************/
+
+#define STM32L4_FIREWALL_CSSA_OFFSET 0x0000
+#define STM32L4_FIREWALL_CSL_OFFSET 0x0004
+#define STM32L4_FIREWALL_NVDSSA_OFFSET 0x0008
+#define STM32L4_FIREWALL_NVDSL_OFFSET 0x000C
+#define STM32L4_FIREWALL_VDSSA_OFFSET 0x0010
+#define STM32L4_FIREWALL_VDSL_OFFSET 0x0014
+#define STM32L4_FIREWALL_CR_OFFSET 0x0020
+
+/* Register Addresses ***************************************************************/
+
+#define STM32L4_FIREWALL_CSSA (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_CSSA_OFFSET)
+#define STM32L4_FIREWALL_CSL (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_CSL_OFFSET)
+#define STM32L4_FIREWALL_NVDSSA (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_NVDSSA_OFFSET)
+#define STM32L4_FIREWALL_NVDSL (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_NVDSL_OFFSET)
+#define STM32L4_FIREWALL_VDSSA (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_VDSSA_OFFSET)
+#define STM32L4_FIREWALL_VDSL (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_VDSL_OFFSET)
+#define STM32L4_FIREWALL_CR (STM32L4_FIREWALL_BASE+STM32L4_FIREWALL_CR_OFFSET)
+
+/* Register Bitfield Definitions ****************************************************/
+
+/* Code Segment Start Address */
+#define FIREWALL_CSSADD_SHIFT 8
+#define FIREWALL_CSSADD_MASK (0xFFFF << FIREWALL_CSSADD_SHIFT)
+
+/* Code Segment Length */
+#define FIREWALL_CSSLENG_SHIFT 8
+#define FIREWALL_CSSLENG_MASK (0x3FFF << FIREWALL_CSSLENG_SHIFT)
+
+/* Non-volatile Data Segment Start Address */
+#define FIREWALL_NVDSADD_SHIFT 8
+#define FIREWALL_NVDSADD_MASK (0xFFFF << FIREWALL_NVDSADD_SHIFT)
+
+/* Non-volatile Data Segment Length */
+#define FIREWALL_NVDSLENG_SHIFT 8
+#define FIREWALL_NVDSLENG_MASK (0x3FFF << FIREWALL_NVDSLENG_SHIFT)
+
+/* Volatile Data Segment Start Address */
+#define FIREWALL_VDSADD_SHIFT 6
+#define FIREWALL_VDSADD_MASK (0x07FF << FIREWALL_VDSADD_SHIFT)
+
+/* Volatile Data Segment Length */
+#define FIREWALL_VDSLENG_SHIFT 6
+#define FIREWALL_VDSLENG_MASK (0x07FF << FIREWALL_VDSLENG_SHIFT)
+
+/* Configuration Register */
+#define FIREWALL_CR_FPA (1 << 0) /* Bit 0: Firewall prearm */
+#define FIREWALL_CR_VDS (1 << 1) /* Bit 1: Volatile data shared */
+#define FIREWALL_CR_VDE (1 << 2) /* Bit 2: Volatile data execution */
+
+#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_FIREWALL_H */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x3xx_pinmap.h b/arch/arm/src/stm32l4/chip/stm32l4x3xx_pinmap.h
new file mode 100644
index 00000000000..5820f2a009f
--- /dev/null
+++ b/arch/arm/src/stm32l4/chip/stm32l4x3xx_pinmap.h
@@ -0,0 +1,559 @@
+/************************************************************************************
+ * arch/arm/src/stm32l4/chip/stm32l4x3xx_pinmap.h
+ *
+ * Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
+ * Authors: Sebastien Lorquet
+ * Juha Niskanen
+ *
+ * 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 __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_PINMAP_H
+#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_PINMAP_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include "stm32l4_gpio.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Alternate Pin Functions. All members of the STM32L4xxx family share the same
+ * pin multiplexing (although they may differ in the pins physically available).
+ *
+ * Alternative pin selections are provided with a numeric suffix like _1, _2, etc.
+ * Drivers, however, will use the pin selection without the numeric suffix.
+ * Additional definitions are required in the board.h file. For example, if
+ * CAN1_RX connects vis PA11 on some board, then the following definitions should
+ * appear inthe board.h header file for that board:
+ *
+ * #define GPIO_CAN1_RX GPIO_CAN1_RX_1
+ *
+ * The driver will then automatically configre PA11 as the CAN1 RX pin.
+ */
+
+/* WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!! WARNING!!!
+ * Additional effort is required to select specific GPIO options such as frequency,
+ * open-drain/push-pull, and pull-up/down! Just the basics are defined for most
+ * pins in this file.
+ */
+
+/* ADC */
+
+#define GPIO_ADC1_IN1 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN0)
+#define GPIO_ADC1_IN2 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN1)
+#define GPIO_ADC1_IN3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN2)
+#define GPIO_ADC1_IN4 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN3)
+#define GPIO_ADC1_IN5 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_ADC1_IN6 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_ADC1_IN7 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_ADC1_IN8 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_ADC1_IN9 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4)
+#define GPIO_ADC1_IN10 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN5)
+#define GPIO_ADC1_IN11 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_ADC1_IN12 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_ADC1_IN13 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4)
+#define GPIO_ADC1_IN14 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5)
+#define GPIO_ADC1_IN15 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN0)
+#define GPIO_ADC1_IN16 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1)
+
+/* CAN */
+
+#define GPIO_CAN1_RX_1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN11)
+#define GPIO_CAN1_RX_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN5)
+#define GPIO_CAN1_RX_3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN8)
+#define GPIO_CAN1_RX_4 (GPIO_ALT|GPIO_AF10 |GPIO_PORTB|GPIO_PIN12)
+#define GPIO_CAN1_RX_5 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN0)
+#define GPIO_CAN1_TX_1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN12)
+#define GPIO_CAN1_TX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN6)
+#define GPIO_CAN1_TX_3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN9)
+#define GPIO_CAN1_TX_4 (GPIO_ALT|GPIO_AF10 |GPIO_PORTB|GPIO_PIN13)
+#define GPIO_CAN1_TX_5 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN1)
+
+/* Clocks outputs */
+
+#define GPIO_MCO (GPIO_ALT|GPIO_AF0 |GPIO_PORTA|GPIO_PIN8)
+
+/* Comparators */
+
+#define GPIO_COMP1_INM_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_COMP1_INM_2 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_COMP1_INM_3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN4)
+#define GPIO_COMP1_INP_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_COMP1_INP_2 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN2)
+#define GPIO_COMP1_INP_3 (GPIO_ANALOG|GPIO_PORTC|GPIO_PIN5)
+#define GPIO_COMP1_OUT_1 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_COMP1_OUT_2 (GPIO_ALT|GPIO_AF6|GPIO_PORTA|GPIO_PIN11)
+#define GPIO_COMP1_OUT_3 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_COMP1_OUT_4 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN0)
+#define GPIO_COMP1_OUT_5 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN10)
+
+#define GPIO_COMP2_INM_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_COMP2_INM_2 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN3)
+#define GPIO_COMP2_INM_3 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN7)
+#define GPIO_COMP2_INP_1 (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_COMP2_INP_2 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN4)
+#define GPIO_COMP2_INP_3 (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN6)
+#define GPIO_COMP2_OUT_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_COMP2_OUT_2 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_COMP2_OUT_3 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN5)
+#define GPIO_COMP2_OUT_4 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN11)
+
+/* DAC */
+
+#define GPIO_DAC1_OUT (GPIO_ANALOG|GPIO_PORTA|GPIO_PIN4)
+
+/* Digital Filter for Sigma-Delta Modulators (DFSDM) */
+
+#define GPIO_DFSDM_DATIN0_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN1)
+#define GPIO_DFSDM_DATIN0_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN3)
+#define GPIO_DFSDM_DATIN1_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN12)
+#define GPIO_DFSDM_DATIN1_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN6)
+#define GPIO_DFSDM_DATIN2_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN14)
+#define GPIO_DFSDM_DATIN2_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN7)
+#define GPIO_DFSDM_DATIN3_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN7)
+#define GPIO_DFSDM_DATIN3_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN4)
+
+#define GPIO_DFSDM_CKIN0_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN2)
+#define GPIO_DFSDM_CKIN0_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN4)
+#define GPIO_DFSDM_CKIN1_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN13)
+#define GPIO_DFSDM_CKIN1_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTD|GPIO_PIN7)
+#define GPIO_DFSDM_CKIN2_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN15)
+#define GPIO_DFSDM_CKIN2_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN8)
+#define GPIO_DFSDM_CKIN3_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN6)
+#define GPIO_DFSDM_CKIN3_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN5)
+
+#define GPIO_DFSDM_CKOUT_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTA|GPIO_PIN5)
+#define GPIO_DFSDM_CKOUT_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN2)
+#define GPIO_DFSDM_CKOUT_3 (GPIO_ALT|GPIO_AF6 |GPIO_PORTE|GPIO_PIN9)
+
+/* I2C */
+
+#define GPIO_I2C1_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN7)
+#define GPIO_I2C1_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN9)
+#define GPIO_I2C1_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN6)
+#define GPIO_I2C1_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN8)
+#define GPIO_I2C1_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTA|GPIO_PIN1)
+#define GPIO_I2C1_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTA|GPIO_PIN14)
+#define GPIO_I2C1_SMBA_3 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN5)
+
+#define GPIO_I2C2_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN11)
+#define GPIO_I2C2_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN14)
+#define GPIO_I2C2_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN10)
+#define GPIO_I2C2_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN13)
+#define GPIO_I2C2_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN12)
+
+#define GPIO_I2C3_SDA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN4)
+#define GPIO_I2C3_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN1)
+#define GPIO_I2C3_SCL_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTA|GPIO_PIN7)
+#define GPIO_I2C3_SCL_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTC|GPIO_PIN0)
+#define GPIO_I2C3_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_PORTB|GPIO_PIN2)
+
+#define GPIO_I2C4_SDA_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN7)
+#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN11)
+#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN1)
+#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF4 |GPIO_PORTD|GPIO_PIN13)
+#define GPIO_I2C4_SCL_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN6)
+#define GPIO_I2C4_SCL_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN10)
+#define GPIO_I2C4_SCL_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTC|GPIO_PIN0)
+#define GPIO_I2C4_SCL_4 (GPIO_ALT|GPIO_AF4 |GPIO_PORTD|GPIO_PIN12)
+#define GPIO_I2C4_SMBA_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN14)
+#define GPIO_I2C4_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_PORTD|GPIO_PIN11)
+
+/* JTAG */
+
+#define GPIO_JTCK_SWCLK (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN14)
+#define GPIO_JTDI (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN15)
+#define GPIO_JTDO (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN3)
+#define GPIO_JTMS_SWDAT (GPIO_ALT|GPIO_AF0|GPIO_PORTA|GPIO_PIN13)
+#define GPIO_JTRST (GPIO_ALT|GPIO_AF0|GPIO_PORTB|GPIO_PIN4)
+
+/* QUADSPI */
+
+#define GPIO_QSPI_NCS_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN11)
+#define GPIO_QSPI_NCS_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN11)
+#define GPIO_QSPI_CLK_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN10)
+#define GPIO_QSPI_CLK_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN10)
+#define GPIO_QSPI_BK1_IO0_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_QSPI_BK1_IO0_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN12)
+#define GPIO_QSPI_BK1_IO1_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTB|GPIO_PIN0)
+#define GPIO_QSPI_BK1_IO1_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN13)
+#define GPIO_QSPI_BK1_IO2_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_QSPI_BK1_IO2_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN14)
+#define GPIO_QSPI_BK1_IO3_1 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_QSPI_BK1_IO3_2 (GPIO_ALT|GPIO_AF10|GPIO_PORTE|GPIO_PIN15)
+
+/* RTC */
+
+#define GPIO_RTC_OUT (GPIO_ALT|GPIO_AF0 |GPIO_PORTB|GPIO_PIN2)
+#define GPIO_RTC_REFIN (GPIO_ALT|GPIO_AF0 |GPIO_PORTB|GPIO_PIN15)
+
+/* SAI */
+
+#define GPIO_SAI1_EXTCLK (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN0)
+
+#define GPIO_SAI1_FS_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN9)
+#define GPIO_SAI1_FS_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN4)
+#define GPIO_SAI1_SCK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN10)
+#define GPIO_SAI1_SCK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN5)
+#define GPIO_SAI1_SD_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTC|GPIO_PIN3)
+#define GPIO_SAI1_SD_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTD|GPIO_PIN6)
+#define GPIO_SAI1_SD_A_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN6)
+#define GPIO_SAI1_MCLK_A_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN8)
+#define GPIO_SAI1_MCLK_A_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN2)
+
+#define GPIO_SAI1_FS_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTA|GPIO_PIN4)
+#define GPIO_SAI1_FS_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN6)
+#define GPIO_SAI1_FS_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN9)
+#define GPIO_SAI1_SCK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN3)
+#define GPIO_SAI1_SCK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN8)
+#define GPIO_SAI1_SD_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN5)
+#define GPIO_SAI1_SD_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN3)
+#define GPIO_SAI1_SD_B_3 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN7)
+#define GPIO_SAI1_MCLK_B_1 (GPIO_ALT|GPIO_AF13|GPIO_PORTB|GPIO_PIN4)
+#define GPIO_SAI1_MCLK_B_2 (GPIO_ALT|GPIO_AF13|GPIO_PORTE|GPIO_PIN10)
+
+/* SDIO */
+
+#define GPIO_SDMMC1_CK (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN12)
+#define GPIO_SDMMC1_CMD (GPIO_ALT|GPIO_AF12|GPIO_PORTD|GPIO_PIN2)
+#define GPIO_SDMMC1_D0 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN8)
+#define GPIO_SDMMC1_D1 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN9)
+#define GPIO_SDMMC1_D2 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN10)
+#define GPIO_SDMMC1_D3 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN11)
+#define GPIO_SDMMC1_D4 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN8)
+#define GPIO_SDMMC1_D5 (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN9)
+#define GPIO_SDMMC1_D6 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN6)
+#define GPIO_SDMMC1_D7 (GPIO_ALT|GPIO_AF12|GPIO_PORTC|GPIO_PIN7)
+
+/* Single Wire Protocol Interface */
+
+#define GPIO_SWPMI1_IO (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN12)
+#define GPIO_SWPMI1_TX (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN13)
+#define GPIO_SWPMI1_RX (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN14)
+#define GPIO_SWPMI1_SUSPEND (GPIO_ALT|GPIO_AF12|GPIO_PORTB|GPIO_PIN15)
+
+/* SPI */
+
+#define GPIO_SPI1_NSS_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN4)
+#define GPIO_SPI1_NSS_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN15)
+#define GPIO_SPI1_NSS_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN0)
+#define GPIO_SPI1_NSS_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN12)
+#define GPIO_SPI1_SCK_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN1)
+#define GPIO_SPI1_SCK_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN5)
+#define GPIO_SPI1_SCK_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN3)
+#define GPIO_SPI1_SCK_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN13)
+#define GPIO_SPI1_MOSI_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN7)
+#define GPIO_SPI1_MOSI_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN12)
+#define GPIO_SPI1_MOSI_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN5)
+#define GPIO_SPI1_MOSI_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN15)
+#define GPIO_SPI1_MISO_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN6)
+#define GPIO_SPI1_MISO_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTA|GPIO_PIN11)
+#define GPIO_SPI1_MISO_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN4)
+#define GPIO_SPI1_MISO_4 (GPIO_ALT|GPIO_AF5 |GPIO_PORTE|GPIO_PIN14)
+
+#define GPIO_SPI2_NSS_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN9)
+#define GPIO_SPI2_NSS_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN12)
+#define GPIO_SPI2_NSS_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN0)
+#define GPIO_SPI2_SCK_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN10)
+#define GPIO_SPI2_SCK_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN13)
+#define GPIO_SPI2_SCK_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN1)
+#define GPIO_SPI2_MOSI_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN15)
+#define GPIO_SPI2_MOSI_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTC|GPIO_PIN3)
+#define GPIO_SPI2_MOSI_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN4)
+#define GPIO_SPI2_MISO_1 (GPIO_ALT|GPIO_AF5 |GPIO_PORTB|GPIO_PIN14)
+#define GPIO_SPI2_MISO_2 (GPIO_ALT|GPIO_AF5 |GPIO_PORTC|GPIO_PIN2)
+#define GPIO_SPI2_MISO_3 (GPIO_ALT|GPIO_AF5 |GPIO_PORTD|GPIO_PIN3)
+
+#define GPIO_SPI3_NSS_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTA|GPIO_PIN4)
+#define GPIO_SPI3_NSS_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTA|GPIO_PIN15)
+#define GPIO_SPI3_SCK_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN3)
+#define GPIO_SPI3_SCK_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN10)
+#define GPIO_SPI3_MOSI_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN5)
+#define GPIO_SPI3_MOSI_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN12)
+#define GPIO_SPI3_MISO_1 (GPIO_ALT|GPIO_AF6 |GPIO_PORTB|GPIO_PIN4)
+#define GPIO_SPI3_MISO_2 (GPIO_ALT|GPIO_AF6 |GPIO_PORTC|GPIO_PIN11)
+
+/* Timers */
+
+#define GPIO_TIM1_CH1IN_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN8)
+#define GPIO_TIM1_CH1IN_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN9)
+#define GPIO_TIM1_CH1OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN8)
+#define GPIO_TIM1_CH1OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN9)
+#define GPIO_TIM1_CH2IN_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN9)
+#define GPIO_TIM1_CH2IN_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN11)
+#define GPIO_TIM1_CH2OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN9)
+#define GPIO_TIM1_CH2OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN11)
+#define GPIO_TIM1_CH3IN_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN10)
+#define GPIO_TIM1_CH3IN_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN13)
+#define GPIO_TIM1_CH3OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN10)
+#define GPIO_TIM1_CH3OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN13)
+#define GPIO_TIM1_CH4IN_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN11)
+#define GPIO_TIM1_CH4IN_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN14)
+#define GPIO_TIM1_CH4OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN11)
+#define GPIO_TIM1_CH4OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN14)
+#define GPIO_TIM1_CH1N_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_TIM1_CH1N_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13)
+#define GPIO_TIM1_CH1N_3 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN8)
+#define GPIO_TIM1_CH2N_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0)
+#define GPIO_TIM1_CH2N_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14)
+#define GPIO_TIM1_CH2N_3 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN10)
+#define GPIO_TIM1_CH3N_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_TIM1_CH3N_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15)
+#define GPIO_TIM1_CH3N_3 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN12)
+#define GPIO_TIM1_BKIN_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN6)
+#define GPIO_TIM1_BKIN_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN12)
+#define GPIO_TIM1_BKIN_3 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN15)
+#define GPIO_TIM1_BKIN_COMP1 (GPIO_ALT|GPIO_AF3 |GPIO_PORTE|GPIO_PIN15)
+#define GPIO_TIM1_BKIN_COMP2_1 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_TIM1_BKIN_COMP2_2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTB|GPIO_PIN12)
+#define GPIO_TIM1_BKIN2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN11)
+#define GPIO_TIM1_BKIN2_COMP1 (GPIO_ALT|GPIO_AF12|GPIO_PORTA|GPIO_PIN11)
+#define GPIO_TIM1_BKIN2_COMP2 (GPIO_ALT|GPIO_AF3 |GPIO_PORTE|GPIO_PIN14)
+#define GPIO_TIM1_ETR_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN12)
+#define GPIO_TIM1_ETR_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTE|GPIO_PIN7)
+
+#define GPIO_TIM2_CH1IN_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_TIM2_CH1IN_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN5)
+#define GPIO_TIM2_CH1IN_3 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN15)
+#define GPIO_TIM2_CH1OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_TIM2_CH1OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN5)
+#define GPIO_TIM2_CH1OUT_3 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN15)
+#define GPIO_TIM2_CH2IN_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_TIM2_CH2IN_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN3)
+#define GPIO_TIM2_CH2OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_TIM2_CH2OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN3)
+#define GPIO_TIM2_CH3IN_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_TIM2_CH3IN_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN10)
+#define GPIO_TIM2_CH3OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_TIM2_CH3OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN10)
+#define GPIO_TIM2_CH4IN_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_TIM2_CH4IN_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN11)
+#define GPIO_TIM2_CH4OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_TIM2_CH4OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN11)
+#define GPIO_TIM2_BKIN (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN14)
+#define GPIO_TIM2_ETR_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN0)
+#define GPIO_TIM2_ETR_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN5)
+#define GPIO_TIM2_ETR_3 (GPIO_ALT|GPIO_AF2 |GPIO_PORTA|GPIO_PIN15)
+
+#define GPIO_TIM3_CH1IN_1 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_TIM3_CH1IN_2 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN4)
+#define GPIO_TIM3_CH1IN_3 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN6)
+#define GPIO_TIM3_CH1IN_4 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN3)
+#define GPIO_TIM3_CH1OUT_1 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_TIM3_CH1OUT_2 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN4)
+#define GPIO_TIM3_CH1OUT_3 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN6)
+#define GPIO_TIM3_CH1OUT_4 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN3)
+#define GPIO_TIM3_CH2IN_1 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_TIM3_CH2IN_2 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN5)
+#define GPIO_TIM3_CH2IN_3 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN7)
+#define GPIO_TIM3_CH2IN_4 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN4)
+#define GPIO_TIM3_CH2OUT_1 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN7)
+#define GPIO_TIM3_CH2OUT_2 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN5)
+#define GPIO_TIM3_CH2OUT_3 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN7)
+#define GPIO_TIM3_CH2OUT_4 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN4)
+#define GPIO_TIM3_CH3IN_1 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN0)
+#define GPIO_TIM3_CH3IN_2 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN8)
+#define GPIO_TIM3_CH3IN_3 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN5)
+#define GPIO_TIM3_CH3OUT_1 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN0)
+#define GPIO_TIM3_CH3OUT_2 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN8)
+#define GPIO_TIM3_CH3OUT_3 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN5)
+#define GPIO_TIM3_CH4IN_1 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_TIM3_CH4IN_2 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTC|GPIO_PIN9)
+#define GPIO_TIM3_CH4IN_3 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN6)
+#define GPIO_TIM3_CH4OUT_1 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_TIM3_CH4OUT_2 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTC|GPIO_PIN9)
+#define GPIO_TIM3_CH4OUT_3 (GPIO_ALT|GPIO_AF2 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN6)
+#define GPIO_TIM3_ETR_1 (GPIO_ALT|GPIO_AF2 |GPIO_PORTD|GPIO_PIN2)
+#define GPIO_TIM3_ETR_2 (GPIO_ALT|GPIO_AF2 |GPIO_PORTE|GPIO_PIN2)
+
+#define GPIO_TIM15_CH1IN_1 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_TIM15_CH1IN_2 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN14)
+#define GPIO_TIM15_CH1OUT_1 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN2)
+#define GPIO_TIM15_CH1OUT_2 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14)
+#define GPIO_TIM15_CH2IN_1 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_TIM15_CH2IN_2 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN15)
+#define GPIO_TIM15_CH2OUT_1 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN3)
+#define GPIO_TIM15_CH2OUT_2 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15)
+#define GPIO_TIM15_CH1N_1 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN1)
+#define GPIO_TIM15_CH1N_2 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN13)
+#define GPIO_TIM15_BKIN_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN9)
+#define GPIO_TIM15_BKIN_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN12)
+
+#define GPIO_TIM16_CH1IN_1 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_TIM16_CH1IN_2 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN8)
+#define GPIO_TIM16_CH1IN_3 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTE|GPIO_PIN0)
+#define GPIO_TIM16_CH1OUT_1 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN6)
+#define GPIO_TIM16_CH1OUT_2 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN8)
+#define GPIO_TIM16_CH1OUT_3 (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTE|GPIO_PIN0)
+#define GPIO_TIM16_CH1N (GPIO_ALT|GPIO_AF14|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN6)
+#define GPIO_TIM16_BKIN (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN5)
+
+#define GPIO_LPTIM1_IN1_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN5)
+#define GPIO_LPTIM1_IN1_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN0)
+#define GPIO_LPTIM1_IN2_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN7)
+#define GPIO_LPTIM1_IN2_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN2)
+#define GPIO_LPTIM1_OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN2)
+#define GPIO_LPTIM1_OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN1)
+#define GPIO_LPTIM1_ETR_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN6)
+#define GPIO_LPTIM1_ETR_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTC|GPIO_PIN3)
+
+#define GPIO_LPTIM2_IN1_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTB|GPIO_PIN1)
+#define GPIO_LPTIM2_IN1_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN0)
+#define GPIO_LPTIM2_IN1_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN12)
+#define GPIO_LPTIM2_OUT_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN4)
+#define GPIO_LPTIM2_OUT_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN8)
+#define GPIO_LPTIM2_OUT_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN13)
+#define GPIO_LPTIM2_ETR_1 (GPIO_ALT|GPIO_AF14|GPIO_PORTA|GPIO_PIN5)
+#define GPIO_LPTIM2_ETR_2 (GPIO_ALT|GPIO_AF14|GPIO_PORTC|GPIO_PIN3)
+#define GPIO_LPTIM2_ETR_3 (GPIO_ALT|GPIO_AF14|GPIO_PORTD|GPIO_PIN11)
+
+/* Touch Screen Controller */
+
+#define GPIO_TSC_SYNC (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN2)
+
+#define GPIO_TSC_G1_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN12)
+#define GPIO_TSC_G1_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN13)
+#define GPIO_TSC_G1_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN14)
+#define GPIO_TSC_G1_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN15)
+
+#define GPIO_TSC_G2_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN4)
+#define GPIO_TSC_G2_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN5)
+#define GPIO_TSC_G2_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN6)
+#define GPIO_TSC_G2_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTB|GPIO_PIN7)
+
+#define GPIO_TSC_G3_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTA|GPIO_PIN15)
+#define GPIO_TSC_G3_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN10)
+#define GPIO_TSC_G3_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN11)
+#define GPIO_TSC_G3_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN12)
+
+#define GPIO_TSC_G4_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN6)
+#define GPIO_TSC_G4_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN7)
+#define GPIO_TSC_G4_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN8)
+#define GPIO_TSC_G4_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTC|GPIO_PIN9)
+
+#define GPIO_TSC_G5_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN10)
+#define GPIO_TSC_G5_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN11)
+#define GPIO_TSC_G5_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN12)
+#define GPIO_TSC_G5_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN13)
+
+#define GPIO_TSC_G6_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN10)
+#define GPIO_TSC_G6_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN11)
+#define GPIO_TSC_G6_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN12)
+#define GPIO_TSC_G6_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTD|GPIO_PIN13)
+
+#define GPIO_TSC_G7_IO1 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN2)
+#define GPIO_TSC_G7_IO2 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN3)
+#define GPIO_TSC_G7_IO3 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN4)
+#define GPIO_TSC_G7_IO4 (GPIO_ALT|GPIO_AF9 |GPIO_PORTE|GPIO_PIN5)
+
+/* IR interface (with timers 16 and 17) */
+
+#define GPIO_IR_OUT_1 (GPIO_ALT|GPIO_AF1 |GPIO_PORTA|GPIO_PIN13)
+#define GPIO_IR_OUT_2 (GPIO_ALT|GPIO_AF1 |GPIO_PORTB|GPIO_PIN9)
+
+/* Trace */
+
+#define GPIO_TRACECK (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN2)
+#define GPIO_TRACED0 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN3)
+#define GPIO_TRACED1 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN4)
+#define GPIO_TRACED2 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN5)
+#define GPIO_TRACED3 (GPIO_ALT|GPIO_AF0 |GPIO_PORTE|GPIO_PIN6)
+
+/* UARTs/USARTs */
+
+#define GPIO_USART1_TX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN9)
+#define GPIO_USART1_TX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN6)
+#define GPIO_USART1_RX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN10)
+#define GPIO_USART1_RX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN7)
+#define GPIO_USART1_CK_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN8)
+#define GPIO_USART1_CK_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN5)
+#define GPIO_USART1_CTS_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN11)
+#define GPIO_USART1_CTS_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN4)
+#define GPIO_USART1_RTS_DE_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN12)
+#define GPIO_USART1_RTS_DE_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN3)
+
+#define GPIO_USART2_TX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN2)
+#define GPIO_USART2_TX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN5)
+#define GPIO_USART2_RX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN3)
+#define GPIO_USART2_RX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN6)
+#define GPIO_USART2_CK_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN4)
+#define GPIO_USART2_CK_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN7)
+#define GPIO_USART2_CTS_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN0)
+#define GPIO_USART2_CTS_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN3)
+#define GPIO_USART2_RTS_DE_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN1)
+#define GPIO_USART2_RTS_DE_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN4)
+
+#define GPIO_USART3_TX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN10)
+#define GPIO_USART3_TX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN4)
+#define GPIO_USART3_TX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN10)
+#define GPIO_USART3_TX_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN8)
+#define GPIO_USART3_RX_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN11)
+#define GPIO_USART3_RX_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN5)
+#define GPIO_USART3_RX_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN11)
+#define GPIO_USART3_RX_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN9)
+#define GPIO_USART3_CK_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN0)
+#define GPIO_USART3_CK_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN12)
+#define GPIO_USART3_CK_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTC|GPIO_PIN12)
+#define GPIO_USART3_CK_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN10)
+#define GPIO_USART3_CTS_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTA|GPIO_PIN6)
+#define GPIO_USART3_CTS_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN13)
+#define GPIO_USART3_CTS_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN11)
+#define GPIO_USART3_RTS_DE_1 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN1)
+#define GPIO_USART3_RTS_DE_2 (GPIO_ALT|GPIO_AF7 |GPIO_PORTB|GPIO_PIN14)
+#define GPIO_USART3_RTS_DE_3 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN2)
+#define GPIO_USART3_RTS_DE_4 (GPIO_ALT|GPIO_AF7 |GPIO_PORTD|GPIO_PIN12)
+
+#define GPIO_UART4_TX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN0)
+#define GPIO_UART4_TX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN10)
+#define GPIO_UART4_RX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN1)
+#define GPIO_UART4_RX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN11)
+#define GPIO_UART4_CTS (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN7)
+#define GPIO_UART4_RTS_DE (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN15)
+
+#define GPIO_UART5_TX (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN12)
+#define GPIO_UART5_RX (GPIO_ALT|GPIO_AF8 |GPIO_PORTD|GPIO_PIN2)
+#define GPIO_UART5_CTS (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN5)
+#define GPIO_UART5_RTS_DE (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN4)
+
+#define GPIO_LPUART1_TX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN11)
+#define GPIO_LPUART1_TX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN1)
+#define GPIO_LPUART1_RX_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN10)
+#define GPIO_LPUART1_RX_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTC|GPIO_PIN0)
+#define GPIO_LPUART1_CTS_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTA|GPIO_PIN6)
+#define GPIO_LPUART1_CTS_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN13)
+#define GPIO_LPUART1_RTS_DE_1 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN1)
+#define GPIO_LPUART1_RTS_DE_2 (GPIO_ALT|GPIO_AF8 |GPIO_PORTB|GPIO_PIN12)
+
+#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_PINMAP_H */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x3xx_rcc.h b/arch/arm/src/stm32l4/chip/stm32l4x3xx_rcc.h
new file mode 100644
index 00000000000..7aa7edfd6c6
--- /dev/null
+++ b/arch/arm/src/stm32l4/chip/stm32l4x3xx_rcc.h
@@ -0,0 +1,789 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32l4/chip/stm32l4x3xx_rcc.h
+ *
+ * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2016 Sebastien Lorquet. All rights reserved.
+ * Author: Gregory Nutt
+ * Author: Sebastien Lorquet
+ * Author: Juha Niskanen
+ *
+ * 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 __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_RCC_H
+#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_RCC_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include
+
+#if defined(CONFIG_STM32L4_STM32L4X3)
+
+/****************************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************************/
+
+/* Register Offsets *********************************************************************************/
+
+#define STM32L4_RCC_CR_OFFSET 0x0000 /* Clock control register */
+#define STM32L4_RCC_ICSCR_OFFSET 0x0004 /* Internal clock sources calibration register */
+#define STM32L4_RCC_CFGR_OFFSET 0x0008 /* Clock configuration register */
+#define STM32L4_RCC_PLLCFG_OFFSET 0x000c /* PLL configuration register */
+#define STM32L4_RCC_PLLSAI1CFG_OFFSET 0x0010 /* PLLSAI1 configuration register */
+#define STM32L4_RCC_PLLSAI2CFG_OFFSET 0x0014 /* PLLSAI2 configuration register */
+#define STM32L4_RCC_CIER_OFFSET 0x0018 /* Clock interrupt enable register */
+#define STM32L4_RCC_CIFR_OFFSET 0x001c /* Clock interrupt flag register */
+#define STM32L4_RCC_CICR_OFFSET 0x0020 /* Clock interrupt clear register */
+#define STM32L4_RCC_AHB1RSTR_OFFSET 0x0028 /* AHB1 peripheral reset register */
+#define STM32L4_RCC_AHB2RSTR_OFFSET 0x002c /* AHB2 peripheral reset register */
+#define STM32L4_RCC_AHB3RSTR_OFFSET 0x0030 /* AHB3 peripheral reset register */
+#define STM32L4_RCC_APB1RSTR1_OFFSET 0x0038 /* APB1 Peripheral reset register 1 */
+#define STM32L4_RCC_APB1RSTR2_OFFSET 0x003c /* APB1 Peripheral reset register 2 */
+#define STM32L4_RCC_APB2RSTR_OFFSET 0x0040 /* APB2 Peripheral reset register */
+#define STM32L4_RCC_AHB1ENR_OFFSET 0x0048 /* AHB1 Peripheral Clock enable register */
+#define STM32L4_RCC_AHB2ENR_OFFSET 0x004c /* AHB2 Peripheral Clock enable register */
+#define STM32L4_RCC_AHB3ENR_OFFSET 0x0050 /* AHB3 Peripheral Clock enable register */
+#define STM32L4_RCC_APB1ENR1_OFFSET 0x0058 /* APB1 Peripheral Clock enable register 1 */
+#define STM32L4_RCC_APB1ENR2_OFFSET 0x005c /* APB1 Peripheral Clock enable register 2 */
+#define STM32L4_RCC_APB2ENR_OFFSET 0x0060 /* APB2 Peripheral Clock enable register */
+#define STM32L4_RCC_AHB1SMENR_OFFSET 0x0068 /* RCC AHB1 low power mode peripheral clock enable register */
+#define STM32L4_RCC_AHB2SMENR_OFFSET 0x006c /* RCC AHB2 low power mode peripheral clock enable register */
+#define STM32L4_RCC_AHB3SMENR_OFFSET 0x0070 /* RCC AHB3 low power mode peripheral clock enable register */
+#define STM32L4_RCC_APB1SMENR1_OFFSET 0x0078 /* RCC APB1 low power mode peripheral clock enable register 1 */
+#define STM32L4_RCC_APB1SMENR2_OFFSET 0x007c /* RCC APB1 low power mode peripheral clock enable register 2 */
+#define STM32L4_RCC_APB2SMENR_OFFSET 0x0080 /* RCC APB2 low power mode peripheral clock enable register */
+#define STM32L4_RCC_CCIPR_OFFSET 0x0088 /* Peripherals independent clock configuration register 1 */
+#define STM32L4_RCC_BDCR_OFFSET 0x0090 /* Backup domain control register */
+#define STM32L4_RCC_CSR_OFFSET 0x0094 /* Control/status register */
+#define STM32L4_RCC_CRRCR_OFFSET 0x0098 /* Clock recovery RC register */
+
+/* Register Addresses *******************************************************************************/
+
+#define STM32L4_RCC_CR (STM32L4_RCC_BASE+STM32L4_RCC_CR_OFFSET)
+#define STM32L4_RCC_ICSCR (STM32L4_RCC_BASE+STM32L4_RCC_ICSCR_OFFSET)
+#define STM32L4_RCC_CFGR (STM32L4_RCC_BASE+STM32L4_RCC_CFGR_OFFSET)
+#define STM32L4_RCC_PLLCFG (STM32L4_RCC_BASE+STM32L4_RCC_PLLCFG_OFFSET)
+#define STM32L4_RCC_PLLSAI1CFG (STM32L4_RCC_BASE+STM32L4_RCC_PLLSAI1CFG_OFFSET)
+#define STM32L4_RCC_PLLSAI2CFG (STM32L4_RCC_BASE+STM32L4_RCC_PLLSAI2CFG_OFFSET)
+#define STM32L4_RCC_CIER (STM32L4_RCC_BASE+STM32L4_RCC_CIER_OFFSET)
+#define STM32L4_RCC_CIFR (STM32L4_RCC_BASE+STM32L4_RCC_CIFR_OFFSET)
+#define STM32L4_RCC_CICR (STM32L4_RCC_BASE+STM32L4_RCC_CICR_OFFSET)
+#define STM32L4_RCC_AHB1RSTR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1RSTR_OFFSET)
+#define STM32L4_RCC_AHB2RSTR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2RSTR_OFFSET)
+#define STM32L4_RCC_AHB3RSTR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3RSTR_OFFSET)
+#define STM32L4_RCC_APB1RSTR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1RSTR1_OFFSET)
+#define STM32L4_RCC_APB1RSTR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1RSTR2_OFFSET)
+#define STM32L4_RCC_APB2RSTR (STM32L4_RCC_BASE+STM32L4_RCC_APB2RSTR_OFFSET)
+#define STM32L4_RCC_AHB1ENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1ENR_OFFSET)
+#define STM32L4_RCC_AHB2ENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2ENR_OFFSET)
+#define STM32L4_RCC_AHB3ENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3ENR_OFFSET)
+#define STM32L4_RCC_APB1ENR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1ENR1_OFFSET)
+#define STM32L4_RCC_APB1ENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1ENR2_OFFSET)
+#define STM32L4_RCC_APB2ENR (STM32L4_RCC_BASE+STM32L4_RCC_APB2ENR_OFFSET)
+#define STM32L4_RCC_AHB1SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB1SMENR_OFFSET)
+#define STM32L4_RCC_AHB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB2SMENR)
+#define STM32L4_RCC_AHB3SMENR (STM32L4_RCC_BASE+STM32L4_RCC_AHB3SMENR_OFFSET)
+#define STM32L4_RCC_APB1SMENR1 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR1_OFFSET)
+#define STM32L4_RCC_APB1SMENR2 (STM32L4_RCC_BASE+STM32L4_RCC_APB1SMENR2_OFFSET)
+#define STM32L4_RCC_APB2SMENR (STM32L4_RCC_BASE+STM32L4_RCC_APB2SMENR_OFFSET)
+#define STM32L4_RCC_CCIPR (STM32L4_RCC_BASE+STM32L4_RCC_CCIPR_OFFSET)
+#define STM32L4_RCC_BDCR (STM32L4_RCC_BASE+STM32L4_RCC_BDCR_OFFSET)
+#define STM32L4_RCC_CSR (STM32L4_RCC_BASE+STM32L4_RCC_CSR_OFFSET)
+#define STM32L4_RCC_CRRCR (STM32L4_RCC_BASE+STM32L4_RCC_CRRCR_OFFSET)
+
+/* Register Bitfield Definitions ********************************************************************/
+
+/* Clock control register */
+
+#define RCC_CR_MSION (1 << 0) /* Bit 0: Internal Multi Speed clock enable */
+#define RCC_CR_MSIRDY (1 << 1) /* Bit 1: Internal Multi Speed clock ready flag */
+#define RCC_CR_MSIPLLEN (1 << 2) /* Bit 2: MSI clock PLL enable */
+#define RCC_CR_MSIRGSEL (1 << 3) /* Bit 2: MSI clock range selection */
+#define RCC_CR_MSIRANGE_SHIFT (4) /* Bits 7-4: MSI clock range */
+#define RCC_CR_MSIRANGE_MASK (0x0f << RCC_CR_MSIRANGE_SHIFT)
+# define RCC_CR_MSIRANGE_100K (0 << RCC_CR_MSIRANGE_SHIFT) /* 0000: around 100 kHz */
+# define RCC_CR_MSIRANGE_200K (1 << RCC_CR_MSIRANGE_SHIFT) /* 0001: around 200 kHz */
+# define RCC_CR_MSIRANGE_400K (2 << RCC_CR_MSIRANGE_SHIFT) /* 0010: around 400 kHz */
+# define RCC_CR_MSIRANGE_800K (3 << RCC_CR_MSIRANGE_SHIFT) /* 0011: around 800 kHz */
+# define RCC_CR_MSIRANGE_1M (4 << RCC_CR_MSIRANGE_SHIFT) /* 0100: around 1 MHz */
+# define RCC_CR_MSIRANGE_2M (5 << RCC_CR_MSIRANGE_SHIFT) /* 0101: around 2 MHz */
+# define RCC_CR_MSIRANGE_4M (6 << RCC_CR_MSIRANGE_SHIFT) /* 0110: around 4 MHz */
+# define RCC_CR_MSIRANGE_8M (7 << RCC_CR_MSIRANGE_SHIFT) /* 0111: around 8 MHz */
+# define RCC_CR_MSIRANGE_16M (8 << RCC_CR_MSIRANGE_SHIFT) /* 1000: around 16 MHz */
+# define RCC_CR_MSIRANGE_24M (9 << RCC_CR_MSIRANGE_SHIFT) /* 1001: around 24 MHz */
+# define RCC_CR_MSIRANGE_32M (10 << RCC_CR_MSIRANGE_SHIFT) /* 1010: around 32 MHz */
+# define RCC_CR_MSIRANGE_48M (11 << RCC_CR_MSIRANGE_SHIFT) /* 1011: around 48 MHz */
+
+#define RCC_CR_HSION (1 << 8) /* Bit 8: Internal High Speed clock enable */
+#define RCC_CR_HSIKERON (1 << 9) /* Bit 9: HSI16 always enable for peripheral kernels */
+#define RCC_CR_HSIRDY (1 << 10) /* Bit 10: Internal High Speed clock ready flag */
+#define RCC_CR_HSIASFS (1 << 11) /* Bit 11: HSI automatic start from stop */
+
+#define RCC_CR_HSEON (1 << 16) /* Bit 16: External High Speed clock enable */
+#define RCC_CR_HSERDY (1 << 17) /* Bit 17: External High Speed clock ready flag */
+#define RCC_CR_HSEBYP (1 << 18) /* Bit 18: External High Speed clock Bypass */
+#define RCC_CR_CSSON (1 << 19) /* Bit 19: Clock Security System enable */
+#define RCC_CR_PLLON (1 << 24) /* Bit 24: PLL enable */
+#define RCC_CR_PLLRDY (1 << 25) /* Bit 25: PLL clock ready flag */
+#define RCC_CR_PLLSAI1ON (1 << 26) /* Bit 26: PLLSAI1 enable */
+#define RCC_CR_PLLSAI1RDY (1 << 27) /* Bit 27: PLLSAI1 clock ready flag */
+#define RCC_CR_PLLSAI2ON (1 << 28) /* Bit 28: PLLSAI2 enable */
+#define RCC_CR_PLLSAI2RDY (1 << 29) /* Bit 29: PLLSAI2 clock ready flag */
+
+/* Internal Clock Sources Calibration */
+
+#define RCC_CR_HSITRIM_SHIFT (24) /* Bits 28-24: Internal High Speed clock trimming */
+#define RCC_CR_HSITRIM_MASK (0x1f << RCC_CR_HSITRIM_SHIFT)
+#define RCC_CR_HSICAL_SHIFT (16) /* Bits 23-16: Internal High Speed clock Calibration */
+#define RCC_CR_HSICAL_MASK (0xff << RCC_CR_HSICAL_SHIFT)
+#define RCC_CR_MSITRIM_SHIFT (8) /* Bits 15-8: Internal Multi Speed clock trimming */
+#define RCC_CR_MSITRIM_MASK (0xff << RCC_CR_MSITRIM_SHIFT)
+#define RCC_CR_MSICAL_SHIFT (0) /* Bits 7-0: Internal Multi Speed clock Calibration */
+#define RCC_CR_MSICAL_MASK (0xff << RCC_CR_MSICAL_SHIFT)
+
+/* Clock configuration register */
+
+#define RCC_CFGR_SW_SHIFT (0) /* Bits 0-1: System clock Switch */
+#define RCC_CFGR_SW_MASK (3 << RCC_CFGR_SW_SHIFT)
+# define RCC_CFGR_SW_MSI (0 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */
+# define RCC_CFGR_SW_HSI (1 << RCC_CFGR_SW_SHIFT) /* 00: HSI selected as system clock */
+# define RCC_CFGR_SW_HSE (2 << RCC_CFGR_SW_SHIFT) /* 01: HSE selected as system clock */
+# define RCC_CFGR_SW_PLL (3 << RCC_CFGR_SW_SHIFT) /* 10: PLL selected as system clock */
+
+#define RCC_CFGR_SWS_SHIFT (2) /* Bits 2-3: System Clock Switch Status */
+#define RCC_CFGR_SWS_MASK (3 << RCC_CFGR_SWS_SHIFT)
+# define RCC_CFGR_SWS_MSI (0 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */
+# define RCC_CFGR_SWS_HSI (1 << RCC_CFGR_SWS_SHIFT) /* 00: HSI oscillator used as system clock */
+# define RCC_CFGR_SWS_HSE (2 << RCC_CFGR_SWS_SHIFT) /* 01: HSE oscillator used as system clock */
+# define RCC_CFGR_SWS_PLL (3 << RCC_CFGR_SWS_SHIFT) /* 10: PLL used as system clock */
+
+#define RCC_CFGR_HPRE_SHIFT (4) /* Bits 4-7: AHB prescaler */
+#define RCC_CFGR_HPRE_MASK (0x0f << RCC_CFGR_HPRE_SHIFT)
+# define RCC_CFGR_HPRE_SYSCLK (0 << RCC_CFGR_HPRE_SHIFT) /* 0xxx: SYSCLK not divided */
+# define RCC_CFGR_HPRE_SYSCLKd2 (8 << RCC_CFGR_HPRE_SHIFT) /* 1000: SYSCLK divided by 2 */
+# define RCC_CFGR_HPRE_SYSCLKd4 (9 << RCC_CFGR_HPRE_SHIFT) /* 1001: SYSCLK divided by 4 */
+# define RCC_CFGR_HPRE_SYSCLKd8 (10 << RCC_CFGR_HPRE_SHIFT) /* 1010: SYSCLK divided by 8 */
+# define RCC_CFGR_HPRE_SYSCLKd16 (11 << RCC_CFGR_HPRE_SHIFT) /* 1011: SYSCLK divided by 16 */
+# define RCC_CFGR_HPRE_SYSCLKd64 (12 << RCC_CFGR_HPRE_SHIFT) /* 1100: SYSCLK divided by 64 */
+# define RCC_CFGR_HPRE_SYSCLKd128 (13 << RCC_CFGR_HPRE_SHIFT) /* 1101: SYSCLK divided by 128 */
+# define RCC_CFGR_HPRE_SYSCLKd256 (14 << RCC_CFGR_HPRE_SHIFT) /* 1110: SYSCLK divided by 256 */
+# define RCC_CFGR_HPRE_SYSCLKd512 (15 << RCC_CFGR_HPRE_SHIFT) /* 1111: SYSCLK divided by 512 */
+
+#define RCC_CFGR_PPRE1_SHIFT (8) /* Bits 8-10: APB Low speed prescaler (APB1) */
+#define RCC_CFGR_PPRE1_MASK (7 << RCC_CFGR_PPRE1_SHIFT)
+# define RCC_CFGR_PPRE1_HCLK (0 << RCC_CFGR_PPRE1_SHIFT) /* 0xx: HCLK not divided */
+# define RCC_CFGR_PPRE1_HCLKd2 (4 << RCC_CFGR_PPRE1_SHIFT) /* 100: HCLK divided by 2 */
+# define RCC_CFGR_PPRE1_HCLKd4 (5 << RCC_CFGR_PPRE1_SHIFT) /* 101: HCLK divided by 4 */
+# define RCC_CFGR_PPRE1_HCLKd8 (6 << RCC_CFGR_PPRE1_SHIFT) /* 110: HCLK divided by 8 */
+# define RCC_CFGR_PPRE1_HCLKd16 (7 << RCC_CFGR_PPRE1_SHIFT) /* 111: HCLK divided by 16 */
+
+#define RCC_CFGR_PPRE2_SHIFT (11) /* Bits 11-13: APB High speed prescaler (APB2) */
+#define RCC_CFGR_PPRE2_MASK (7 << RCC_CFGR_PPRE2_SHIFT)
+# define RCC_CFGR_PPRE2_HCLK (0 << RCC_CFGR_PPRE2_SHIFT) /* 0xx: HCLK not divided */
+# define RCC_CFGR_PPRE2_HCLKd2 (4 << RCC_CFGR_PPRE2_SHIFT) /* 100: HCLK divided by 2 */
+# define RCC_CFGR_PPRE2_HCLKd4 (5 << RCC_CFGR_PPRE2_SHIFT) /* 101: HCLK divided by 4 */
+# define RCC_CFGR_PPRE2_HCLKd8 (6 << RCC_CFGR_PPRE2_SHIFT) /* 110: HCLK divided by 8 */
+# define RCC_CFGR_PPRE2_HCLKd16 (7 << RCC_CFGR_PPRE2_SHIFT) /* 111: HCLK divided by 16 */
+
+#define RCC_CFGR_STOPWUCK (1 << 15) /* Bit 15: Wakeup from Stop and CSS backup clock selection */
+# define RCC_CFGR_STOPWUCK_MSI (0 << 15) /* 0: MSI */
+# define RCC_CFGR_STOPWUCK_HSI (1 << 15) /* 0: HSI */
+
+#define RCC_CFGR_MCO_SHIFT (24) /* Bits 24-26: Microcontroller Clock Output */
+#define RCC_CFGR_MCO_MASK (7 << RCC_CFGR_MCO_SHIFT)
+# define RCC_CFGR_MCO_NONE (0 << RCC_CFGR_MCO_SHIFT) /* 000: Disabled */
+# define RCC_CFGR_MCO_SYSCLK (1 << RCC_CFGR_MCO_SHIFT) /* 001: SYSCLK system clock selected */
+# define RCC_CFGR_MCO_MSI (2 << RCC_CFGR_MCO_SHIFT) /* 010: MSI clock selected */
+# define RCC_CFGR_MCO_HSI (3 << RCC_CFGR_MCO_SHIFT) /* 011: HSI clock selected */
+# define RCC_CFGR_MCO_HSE (4 << RCC_CFGR_MCO_SHIFT) /* 100: HSE clock selected */
+# define RCC_CFGR_MCO_PLL (5 << RCC_CFGR_MCO_SHIFT) /* 101: Main PLL selected */
+# define RCC_CFGR_MCO_LSI (6 << RCC_CFGR_MCO_SHIFT) /* 110: LSI clock selected */
+# define RCC_CFGR_MCO_LSE (7 << RCC_CFGR_MCO_SHIFT) /* 111: LSE clock selected */
+
+#define RCC_CFGR_MCOPRE_SHIFT (28) /* Bits 28-30: MCO prescaler */
+#define RCC_CFGR_MCOPRE_MASK (7 << RCC_CFGR_MCOPRE_SHIFT)
+# define RCC_CFGR_MCOPRE_NONE (0 << RCC_CFGR_MCOPRE_SHIFT) /* 000: no division */
+# define RCC_CFGR_MCOPRE_DIV2 (1 << RCC_CFGR_MCOPRE_SHIFT) /* 001: division by 2 */
+# define RCC_CFGR_MCOPRE_DIV4 (2 << RCC_CFGR_MCOPRE_SHIFT) /* 010: division by 4 */
+# define RCC_CFGR_MCOPRE_DIV8 (3 << RCC_CFGR_MCOPRE_SHIFT) /* 011: division by 8 */
+# define RCC_CFGR_MCOPRE_DIV16 (4 << RCC_CFGR_MCOPRE_SHIFT) /* 100: division by 16 */
+
+/* PLL configuration register */
+
+#define RCC_PLLCFG_PLLSRC_SHIFT (0) /* Bit 0-1: Main PLL(PLL) and audio PLLs (PLLSAIx)
+ * entry clock source */
+#define RCC_PLLCFG_PLLSRC_MASK (3 << RCC_PLLCFG_PLLSRC_SHIFT)
+# define RCC_PLLCFG_PLLSRC_NONE (0 << RCC_PLLCFG_PLLSRC_SHIFT) /* 000: No clock sent to PLLs */
+# define RCC_PLLCFG_PLLSRC_MSI (1 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: MSI selected as PLL source */
+# define RCC_PLLCFG_PLLSRC_HSI (2 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: HSI selected as PLL source */
+# define RCC_PLLCFG_PLLSRC_HSE (3 << RCC_PLLCFG_PLLSRC_SHIFT) /* 001: HSE selected as PLL source */
+
+#define RCC_PLLCFG_PLLM_SHIFT (4) /* Bits 4-6: Main PLL (PLL) input clock divider */
+#define RCC_PLLCFG_PLLM_MASK (0x07 << RCC_PLLCFG_PLLM_SHIFT)
+# define RCC_PLLCFG_PLLM(n) ((n-1) << RCC_PLLCFG_PLLM_SHIFT) /* m = 1..8 */
+
+#define RCC_PLLCFG_PLLN_SHIFT (8) /* Bits 6-14: Main PLL (PLL) VCO multiplier */
+#define RCC_PLLCFG_PLLN_MASK (0x7f << RCC_PLLCFG_PLLN_SHIFT)
+# define RCC_PLLCFG_PLLN(n) ((n) << RCC_PLLCFG_PLLN_SHIFT) /* n = 8..86 */
+
+#define RCC_PLLCFG_PLLPEN (1 << 16) /* Bit 16: Main PLL PLLSAI3CLK output enable */
+
+#define RCC_PLLCFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI3CLK */
+# define RCC_PLLCFG_PLLP_7 0 /* 0: PLLP = 7 */
+# define RCC_PLLCFG_PLLP_17 RCC_PLLCFG_PLLP /* 1: PLLP = 17 */
+
+#define RCC_PLLCFG_PLLQEN (1 << 20) /* Bit 20: Main PLL PLL48M1CLK output enable */
+
+#define RCC_PLLCFG_PLLQ_SHIFT (21)
+#define RCC_PLLCFG_PLLQ_MASK (3 << RCC_PLLCFG_PLLQ_SHIFT)
+# define RCC_PLLCFG_PLLQ(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLQ_SHIFT) /* n=2,4,6,8 */
+# define RCC_PLLCFG_PLLQ_2 (0 << RCC_PLLCFG_PLLQ_SHIFT) /* 00: PLLQ = 2 */
+# define RCC_PLLCFG_PLLQ_4 (1 << RCC_PLLCFG_PLLQ_SHIFT) /* 01: PLLQ = 4 */
+# define RCC_PLLCFG_PLLQ_6 (2 << RCC_PLLCFG_PLLQ_SHIFT) /* 10: PLLQ = 6 */
+# define RCC_PLLCFG_PLLQ_8 (3 << RCC_PLLCFG_PLLQ_SHIFT) /* 11: PLLQ = 8 */
+
+#define RCC_PLLCFG_PLLREN (1 << 24) /* Bit 24: Main PLL PLLCLK output enable */
+
+#define RCC_PLLCFG_PLLR_SHIFT (25)
+#define RCC_PLLCFG_PLLR_MASK (3 << RCC_PLLCFG_PLLR_SHIFT)
+# define RCC_PLLCFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLCFG_PLLR_SHIFT) /* n=2,4,6,8 */
+# define RCC_PLLCFG_PLLR_2 (0 << RCC_PLLCFG_PLLR_SHIFT) /* 00: PLLR = 2 */
+# define RCC_PLLCFG_PLLR_4 (1 << RCC_PLLCFG_PLLR_SHIFT) /* 01: PLLR = 4 */
+# define RCC_PLLCFG_PLLR_6 (2 << RCC_PLLCFG_PLLR_SHIFT) /* 10: PLLR = 6 */
+# define RCC_PLLCFG_PLLR_8 (3 << RCC_PLLCFG_PLLR_SHIFT) /* 11: PLLR = 8 */
+
+#define RCC_PLLCFG_RESET (0x00001000) /* PLLCFG reset value */
+
+/* PLLSAI1 Configuration register */
+
+#define RCC_PLLSAI1CFG_PLLN_SHIFT (8) /* Bits 6-14: SAI1 PLL (PLLSAI1) VCO multiplier */
+#define RCC_PLLSAI1CFG_PLLN_MASK (0x7f << RCC_PLLSAI1CFG_PLLN_SHIFT)
+# define RCC_PLLSAI1CFG_PLLN(n) ((n) << RCC_PLLSAI1CFG_PLLN_SHIFT) /* n = 8..86 */
+
+#define RCC_PLLSAI1CFG_PLLPEN (1 << 16) /* Bit 16: SAI1 PLL PLLSAI1CLK output enable */
+
+#define RCC_PLLSAI1CFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI1CLK */
+# define RCC_PLLSAI1CFG_PLLP_7 0 /* 0: PLLP = 7 */
+# define RCC_PLLSAI1CFG_PLLP_17 RCC_PLLSAI1CFG_PLLP /* 1: PLLP = 17 */
+
+#define RCC_PLLSAI1CFG_PLLQEN (1 << 20) /* Bit 20: Main PLL PLL48M2CLK output enable */
+
+#define RCC_PLLSAI1CFG_PLLQ_SHIFT (21)
+#define RCC_PLLSAI1CFG_PLLQ_MASK (3 << RCC_PLLSAI1CFG_PLLQ_SHIFT)
+# define RCC_PLLSAI1CFG_PLLQ(n) ((((n)>>1)-1)<< RCC_PLLSAI1CFG_PLLQ_SHIFT) /* n=2,4,6,8 */
+# define RCC_PLLSAI1CFG_PLLQ_2 (0 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 00: PLLQ = 2 */
+# define RCC_PLLSAI1CFG_PLLQ_4 (1 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 01: PLLQ = 4 */
+# define RCC_PLLSAI1CFG_PLLQ_6 (2 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 10: PLLQ = 6 */
+# define RCC_PLLSAI1CFG_PLLQ_8 (3 << RCC_PLLSAI1CFG_PLLQ_SHIFT) /* 11: PLLQ = 8 */
+
+#define RCC_PLLSAI1CFG_PLLREN (1 << 24) /* Bit 24: SAI1 PLL PLLADC1CLK output enable */
+
+#define RCC_PLLSAI1CFG_PLLR_SHIFT (25)
+#define RCC_PLLSAI1CFG_PLLR_MASK (3 << RCC_PLLSAI1CFG_PLLR_SHIFT)
+# define RCC_PLLSAI1CFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLSAI1CFG_PLLR_SHIFT) /* n=2,4,6,8 */
+# define RCC_PLLSAI1CFG_PLLR_2 (0 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 00: PLLR = 2 */
+# define RCC_PLLSAI1CFG_PLLR_4 (1 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 01: PLLR = 4 */
+# define RCC_PLLSAI1CFG_PLLR_6 (2 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 10: PLLR = 6 */
+# define RCC_PLLSAI1CFG_PLLR_8 (3 << RCC_PLLSAI1CFG_PLLR_SHIFT) /* 11: PLLR = 8 */
+
+/* PLLSAI2 Configuration register */
+
+#define RCC_PLLSAI2CFG_PLLN_SHIFT (8) /* Bits 6-14: SAI2 PLL (PLLSAI2) VCO multiplier */
+#define RCC_PLLSAI2CFG_PLLN_MASK (0x7f << RCC_PLLSAI2CFG_PLLN_SHIFT)
+# define RCC_PLLSAI2CFG_PLLN(n) ((n) << RCC_PLLSAI2CFG_PLLN_SHIFT) /* n = 8..86 */
+
+#define RCC_PLLSAI2CFG_PLLPEN (1 << 16) /* Bit 16: SAI1 PLL PLLSAI2CLK output enable */
+
+#define RCC_PLLSAI2CFG_PLLP (1 << 17) /* Bit 17: Main PLL div factor for PLLSAI2CLK */
+# define RCC_PLLSAI2CFG_PLLP_7 0 /* 0: PLLP = 7 */
+# define RCC_PLLSAI2CFG_PLLP_17 RCC_PLLSAI2CFG_PLLP /* 1: PLLP = 17 */
+
+#define RCC_PLLSAI2CFG_PLLREN (1 << 24) /* Bit 24: SAI2 PLL PLLADC2CLK output enable */
+
+#define RCC_PLLSAI2CFG_PLLR_SHIFT (25)
+#define RCC_PLLSAI2CFG_PLLR_MASK (3 << RCC_PLLSAI2CFG_PLLR_SHIFT)
+# define RCC_PLLSAI2CFG_PLLR(n) ((((n)>>1)-1)<< RCC_PLLSAI2CFG_PLLR_SHIFT) /* n=2,4,6,8 */
+# define RCC_PLLSAI2CFG_PLLR_2 (0 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 00: PLLR = 2 */
+# define RCC_PLLSAI2CFG_PLLR_4 (1 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 01: PLLR = 4 */
+# define RCC_PLLSAI2CFG_PLLR_6 (2 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 10: PLLR = 6 */
+# define RCC_PLLSAI2CFG_PLLR_8 (3 << RCC_PLLSAI2CFG_PLLR_SHIFT) /* 11: PLLR = 8 */
+
+/* Clock interrupt enable register */
+
+#define RCC_CIR_LSIRDYIE (1 << 0) /* Bit 0: LSI Ready Interrupt Enable */
+#define RCC_CIR_LSERDYIE (1 << 1) /* Bit 1: LSE Ready Interrupt Enable */
+#define RCC_CIR_MSIRDYIE (1 << 2) /* Bit 2: MSI Ready Interrupt Enable */
+#define RCC_CIR_HSIRDYIE (1 << 3) /* Bit 3: HSI Ready Interrupt Enable */
+#define RCC_CIR_HSERDYIE (1 << 4) /* Bit 4: HSE Ready Interrupt Enable */
+#define RCC_CIR_PLLRDYIE (1 << 5) /* Bit 5: PLL Ready Interrupt Enable */
+#define RCC_CIR_PLLSAI1RDYIE (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt enable */
+#define RCC_CIR_PLLSAI2RDYIE (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt enable */
+#define RCC_CIR_LSECSSIE (1 << 9) /* Bit 9: LSE Clock Security System Interrupt Enable */
+#define RCC_CIR_HSI48RDYIE (1 << 10) /* Bit 10: HSI48 Ready Interrupt Enable */
+
+/* Clock interrupt flag register */
+
+#define RCC_CIR_LSIRDYIF (1 << 0) /* Bit 0: LSI Ready Interrupt Flag */
+#define RCC_CIR_LSERDYIF (1 << 1) /* Bit 1: LSE Ready Interrupt Flag */
+#define RCC_CIR_MSIRDYIF (1 << 2) /* Bit 2: MSI Ready Interrupt Flag */
+#define RCC_CIR_HSIRDYIF (1 << 3) /* Bit 3: HSI Ready Interrupt Flag */
+#define RCC_CIR_HSERDYIF (1 << 4) /* Bit 4: HSE Ready Interrupt Flag */
+#define RCC_CIR_PLLRDYIF (1 << 5) /* Bit 5: PLL Ready Interrupt Flag */
+#define RCC_CIR_PLLSAI1RDYIF (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt Flag */
+#define RCC_CIR_PLLSAI2RDYIF (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt Flag */
+#define RCC_CIR_CSSF (1 << 8) /* Bit 8: Clock Security System Interrupt Flag */
+#define RCC_CIR_LSECSSIF (1 << 9) /* Bit 9: LSE Clock Security System Interrupt Flag */
+#define RCC_CIR_HSI48RDYIF (1 << 10) /* Bit 10: HSI48 Ready Interrupt Flag */
+
+/* Clock interrupt clear register */
+
+#define RCC_CIR_LSIRDYIC (1 << 0) /* Bit 0: LSI Ready Interrupt Clear */
+#define RCC_CIR_LSERDYIC (1 << 1) /* Bit 1: LSE Ready Interrupt Clear */
+#define RCC_CIR_MSIRDYIC (1 << 2) /* Bit 2: MSI Ready Interrupt Clear */
+#define RCC_CIR_HSIRDYIC (1 << 3) /* Bit 3: HSI Ready Interrupt Clear */
+#define RCC_CIR_HSERDYIC (1 << 4) /* Bit 4: HSE Ready Interrupt Clear */
+#define RCC_CIR_PLLRDYIC (1 << 5) /* Bit 5: PLL Ready Interrupt Clear */
+#define RCC_CIR_PLLSAI1RDYIC (1 << 6) /* Bit 6: PLLSAI1 Ready Interrupt Clear */
+#define RCC_CIR_PLLSAI2RDYIC (1 << 7) /* Bit 7: PLLSAI2 Ready Interrupt Clear */
+#define RCC_CIR_CSSC (1 << 8) /* Bit 8: Clock Security System Interrupt Clear */
+#define RCC_CIR_LSECSSIC (1 << 9) /* Bit 9: LSE Clock Security System Interrupt Clear */
+#define RCC_CIR_HSI48RDYIC (1 << 10) /* Bit 10: HSI48 Oscillator Ready Interrupt Clear */
+
+/* AHB1 peripheral reset register */
+
+#define RCC_AHB1RSTR_DMA1RST (1 << 0) /* Bit 0: DMA1 reset */
+#define RCC_AHB1RSTR_DMA2RST (1 << 1) /* Bit 1: DMA2 reset */
+#define RCC_AHB1RSTR_FLASHRST (1 << 8) /* Bit 8: Flash memory interface reset */
+#define RCC_AHB1RSTR_CRCRST (1 << 12) /* Bit 12: CRC reset */
+#define RCC_AHB1RSTR_TSCRST (1 << 16) /* Bit 16: Touch Sensing Controller reset */
+#define RCC_AHB1RSTR_DMA2DRST (1 << 17) /* Bit 17: DMA2D reset */
+
+/* AHB2 peripheral reset register */
+
+#define RCC_AHB1ENR_GPIOEN(port) (1 << (port))
+#define RCC_AHB2RSTR_GPIOARST (1 << 0) /* Bit 0: IO port A reset */
+#define RCC_AHB2RSTR_GPIOBRST (1 << 1) /* Bit 1: IO port B reset */
+#define RCC_AHB2RSTR_GPIOCRST (1 << 2) /* Bit 2: IO port C reset */
+#define RCC_AHB2RSTR_GPIODRST (1 << 3) /* Bit 3: IO port D reset */
+#define RCC_AHB2RSTR_GPIOERST (1 << 4) /* Bit 4: IO port E reset */
+#define RCC_AHB2RSTR_GPIOHRST (1 << 7) /* Bit 7: IO port H reset */
+#define RCC_AHB2RSTR_ADCRST (1 << 13) /* Bit 13: ADC interface reset (common to all ADCs) */
+#define RCC_AHB2RSTR_DCMIRST (1 << 14) /* Bit 14: DCMI interface reset */
+#define RCC_AHB2RSTR_AESRST (1 << 16) /* Bit 16: AES Cryptographic module reset */
+#define RCC_AHB2RSTR_HASHRST (1 << 17) /* Bit 17: HASH module reset */
+#define RCC_AHB2RSTR_RNGRST (1 << 18) /* Bit 18: Random number generator module reset */
+
+/* AHB3 peripheral reset register */
+
+#define RCC_AHB3RSTR_FSMCRST (1 << 0) /* Bit 0: Flexible static memory controller module reset */
+#define RCC_AHB3RSTR_QSPIRST (1 << 8) /* Bit 8: Quad SPI module reset */
+
+/* APB1 Peripheral reset register 1 */
+
+#define RCC_APB1RSTR1_TIM2RST (1 << 0) /* Bit 0: TIM2 reset */
+#define RCC_APB1RSTR1_TIM3RST (1 << 1) /* Bit 1: TIM3 reset */
+#define RCC_APB1RSTR1_TIM4RST (1 << 2) /* Bit 2: TIM4 reset */
+#define RCC_APB1RSTR1_TIM5RST (1 << 3) /* Bit 3: TIM5 reset */
+#define RCC_APB1RSTR1_TIM6RST (1 << 4) /* Bit 4: TIM6 reset */
+#define RCC_APB1RSTR1_TIM7RST (1 << 5) /* Bit 5: TIM7 reset */
+#define RCC_APB1RSTR1_LCDRST (1 << 9) /* Bit 9: LCD controller reset */
+#define RCC_APB1RSTR1_SPI2RST (1 << 14) /* Bit 14: SPI2 reset */
+#define RCC_APB1RSTR1_SPI3RST (1 << 15) /* Bit 15: SPI3 reset */
+#define RCC_APB1RSTR1_USART2RST (1 << 17) /* Bit 17: USART2 reset */
+#define RCC_APB1RSTR1_USART3RST (1 << 18) /* Bit 18: USART3 reset */
+#define RCC_APB1RSTR1_UART4RST (1 << 19) /* Bit 19: USART4 reset */
+#define RCC_APB1RSTR1_UART5RST (1 << 20) /* Bit 20: USART5 reset */
+#define RCC_APB1RSTR1_I2C1RST (1 << 21) /* Bit 21: I2C1 reset */
+#define RCC_APB1RSTR1_I2C2RST (1 << 22) /* Bit 22: I2C2 reset */
+#define RCC_APB1RSTR1_I2C3RST (1 << 23) /* Bit 23: I2C3 reset */
+#define RCC_APB1RSTR1_CRSRST (1 << 24) /* Bit 24: CRS reset */
+#define RCC_APB1RSTR1_CAN1RST (1 << 25) /* Bit 25: CAN1 reset */
+#define RCC_APB1RSTR1_USBFSRST (1 << 26) /* Bit 26: USB FS reset */
+#define RCC_APB1RSTR1_PWRRST (1 << 28) /* Bit 28: Power interface reset */
+#define RCC_APB1RSTR1_DAC1RST (1 << 29) /* Bit 29: DAC1 reset */
+#define RCC_APB1RSTR1_OPAMPRST (1 << 30) /* Bit 30: OPAMP reset */
+#define RCC_APB1RSTR1_LPTIM1RST (1 << 31) /* Bit 31: Low-power Timer 1 reset */
+
+/* APB1 Peripheral reset register 2 */
+
+#define RCC_APB1RSTR2_LPUART1RST (1 << 0) /* Bit 0: Low-power UART 1 reset */
+#define RCC_APB1RSTR2_I2C4RST (1 << 1) /* Bit 1: I2C4 reset */
+#define RCC_APB1RSTR2_SWPMI1RST (1 << 2) /* Bit 2: Single Wire Protocol reset */
+#define RCC_APB1RSTR2_LPTIM2RST (1 << 5) /* Bit 5: Low-power Timer 2 reset */
+
+/* APB2 Peripheral reset register */
+
+#define RCC_APB2RSTR_SYSCFGRST (1 << 0) /* Bit 0: System configuration controller reset */
+#define RCC_APB2RSTR_SDMMCRST (1 << 10) /* Bit 10: SDMMC reset */
+#define RCC_APB2RSTR_TIM1RST (1 << 11) /* Bit 11: TIM1 reset */
+#define RCC_APB2RSTR_SPI1RST (1 << 12) /* Bit 12: SPI1 reset */
+#define RCC_APB2RSTR_TIM8RST (1 << 13) /* Bit 13: TIM8 reset */
+#define RCC_APB2RSTR_USART1RST (1 << 14) /* Bit 14: USART1 reset */
+#define RCC_APB2RSTR_TIM15RST (1 << 16) /* Bit 16: TIM15 reset */
+#define RCC_APB2RSTR_TIM16RST (1 << 17) /* Bit 17: TIM16 reset */
+#define RCC_APB2RSTR_TIM17RST (1 << 18) /* Bit 18: TIM17 reset */
+#define RCC_APB2RSTR_SAI1RST (1 << 21) /* Bit 21: SAI1 reset */
+#define RCC_APB2RSTR_SAI2RST (1 << 22) /* Bit 22: SAI2 reset */
+#define RCC_APB2RSTR_DFSDMRST (1 << 24) /* Bit 24: DFSDM reset */
+
+/* AHB1 Peripheral Clock enable register */
+
+#define RCC_AHB1ENR_DMA1EN (1 << 0) /* Bit 0: DMA1 enable */
+#define RCC_AHB1ENR_DMA2EN (1 << 1) /* Bit 1: DMA2 enable */
+#define RCC_AHB1ENR_FLASHEN (1 << 8) /* Bit 8: Flash memory interface enable */
+#define RCC_AHB1ENR_CRCEN (1 << 12) /* Bit 12: CRC enable */
+#define RCC_AHB1ENR_TSCEN (1 << 16) /* Bit 16: Touch Sensing Controller enable */
+#define RCC_AHB1ENR_DMA2DEN (1 << 17) /* Bit 17: DMA2D enable */
+
+/* AHB2 Peripheral Clock enable register */
+
+#define RCC_AHB2ENR_GPIOAEN (1 << 0) /* Bit 0: IO port A enable */
+#define RCC_AHB2ENR_GPIOBEN (1 << 1) /* Bit 1: IO port B enable */
+#define RCC_AHB2ENR_GPIOCEN (1 << 2) /* Bit 2: IO port C enable */
+#define RCC_AHB2ENR_GPIODEN (1 << 3) /* Bit 3: IO port D enable */
+#define RCC_AHB2ENR_GPIOEEN (1 << 4) /* Bit 4: IO port E enable */
+#define RCC_AHB2ENR_GPIOHEN (1 << 7) /* Bit 7: IO port H enable */
+#define RCC_AHB2ENR_ADCEN (1 << 13) /* Bit 13: ADC interface enable (common to all ADCs) */
+#define RCC_AHB2ENR_DCMIEN (1 << 14) /* Bit 14: DCMI interface enable */
+#define RCC_AHB2ENR_AESEN (1 << 16) /* Bit 16: AES Cryptographic module enable */
+#define RCC_AHB2ENR_HASHEN (1 << 17) /* Bit 17: HASH module enable */
+#define RCC_AHB2ENR_RNGEN (1 << 18) /* Bit 18: Random number generator module enable */
+
+/* AHB3 Peripheral Clock enable register */
+
+#define RCC_AHB3ENR_FSMCEN (1 << 0) /* Bit 0: Flexible static memory controller module enable */
+#define RCC_AHB3ENR_QSPIEN (1 << 8) /* Bit 8: Quad SPI module enable */
+
+/* APB1 Peripheral Clock enable register 1 */
+
+#define RCC_APB1ENR1_TIM2EN (1 << 0) /* Bit 0: TIM2 enable */
+#define RCC_APB1ENR1_TIM3EN (1 << 1) /* Bit 1: TIM3 enable */
+#define RCC_APB1ENR1_TIM4EN (1 << 2) /* Bit 2: TIM4 enable */
+#define RCC_APB1ENR1_TIM5EN (1 << 3) /* Bit 3: TIM5 enable */
+#define RCC_APB1ENR1_TIM6EN (1 << 4) /* Bit 4: TIM6 enable */
+#define RCC_APB1ENR1_TIM7EN (1 << 5) /* Bit 5: TIM7 enable */
+#define RCC_APB1ENR1_LCDEN (1 << 9) /* Bit 9: LCD controller enable */
+#define RCC_APB1ENR1_RTCAPBEN (1 << 10) /* Bit 10: RTC APB clock enable */
+#define RCC_APB1ENR1_WWDGEN (1 << 11) /* Bit 11: Windowed Watchdog enable */
+#define RCC_APB1ENR1_SPI2EN (1 << 14) /* Bit 14: SPI2 enable */
+#define RCC_APB1ENR1_SPI3EN (1 << 15) /* Bit 15: SPI3 enable */
+#define RCC_APB1ENR1_USART2EN (1 << 17) /* Bit 17: USART2 enable */
+#define RCC_APB1ENR1_USART3EN (1 << 18) /* Bit 18: USART3 enable */
+#define RCC_APB1ENR1_UART4EN (1 << 19) /* Bit 19: USART4 enable */
+#define RCC_APB1ENR1_UART5EN (1 << 20) /* Bit 20: USART5 enable */
+#define RCC_APB1ENR1_I2C1EN (1 << 21) /* Bit 21: I2C1 enable */
+#define RCC_APB1ENR1_I2C2EN (1 << 22) /* Bit 22: I2C2 enable */
+#define RCC_APB1ENR1_I2C3EN (1 << 23) /* Bit 23: I2C3 enable */
+#define RCC_APB1ENR1_CRSEN (1 << 24) /* Bit 24: CRSEN enable */
+#define RCC_APB1ENR1_CAN1EN (1 << 25) /* Bit 25: CAN1 enable */
+#define RCC_APB1ENR1_USBFSEN (1 << 26) /* Bit 26: USB FS enable */
+#define RCC_APB1ENR1_PWREN (1 << 28) /* Bit 28: Power interface enable */
+#define RCC_APB1ENR1_DAC1EN (1 << 29) /* Bit 29: DAC1 enable */
+#define RCC_APB1ENR1_OPAMPEN (1 << 30) /* Bit 30: OPAMP enable */
+#define RCC_APB1ENR1_LPTIM1EN (1 << 31) /* Bit 31: Low-power Timer 1 enable */
+
+/* APB1 Peripheral Clock enable register 2 */
+
+#define RCC_APB1ENR2_LPUART1EN (1 << 0) /* Bit 0: Low-power UART 1 enable */
+#define RCC_APB1ENR2_I2C4EN (1 << 1) /* Bit 1: I2C4 enable */
+#define RCC_APB1ENR2_SWPMI1EN (1 << 2) /* Bit 2: Single Wire Protocol enable */
+#define RCC_APB1ENR2_LPTIM2EN (1 << 5) /* Bit 5: Low-power Timer 2 enable */
+
+/* APB2 Peripheral Clock enable register */
+
+#define RCC_APB2ENR_SYSCFGEN (1 << 0) /* Bit 0: System configuration controller enable */
+#define RCC_APB2ENR_FWEN (1 << 7) /* Bit 7: Firewall enable */
+#define RCC_APB2ENR_SDMMCEN (1 << 10) /* Bit 10: SDMMC enable */
+#define RCC_APB2ENR_TIM1EN (1 << 11) /* Bit 11: TIM1 enable */
+#define RCC_APB2ENR_SPI1EN (1 << 12) /* Bit 12: SPI1 enable */
+#define RCC_APB2ENR_TIM8EN (1 << 13) /* Bit 13: TIM8 enable */
+#define RCC_APB2ENR_USART1EN (1 << 14) /* Bit 14: USART1 enable */
+#define RCC_APB2ENR_TIM15EN (1 << 16) /* Bit 16: TIM15 enable */
+#define RCC_APB2ENR_TIM16EN (1 << 17) /* Bit 17: TIM16 enable */
+#define RCC_APB2ENR_TIM17EN (1 << 18) /* Bit 18: TIM17 enable */
+#define RCC_APB2ENR_SAI1EN (1 << 21) /* Bit 21: SAI1 enable */
+#define RCC_APB2ENR_SAI2EN (1 << 22) /* Bit 22: SAI2 enable */
+#define RCC_APB2ENR_DFSDMEN (1 << 24) /* Bit 24: DFSDM enable */
+
+/* RCC AHB1 low power mode peripheral clock enable register */
+
+#define RCC_AHB1SMENR_DMA1LPSMEN (1 << 0) /* Bit 0: DMA1 enable during Sleep mode */
+#define RCC_AHB1SMENR_DMA2LPSMEN (1 << 1) /* Bit 1: DMA2 enable during Sleep mode */
+#define RCC_AHB1SMENR_FLASHLPSMEN (1 << 8) /* Bit 8: Flash memory interface enable during Sleep mode */
+#define RCC_AHB1SMENR_SRAM1SMEN (1 << 9) /* Bit 9: SRAM1 enable during Sleep mode */
+#define RCC_AHB1SMENR_CRCLPSMEN (1 << 12) /* Bit 12: CRC enable during Sleep mode */
+#define RCC_AHB1SMENR_TSCLPSMEN (1 << 16) /* Bit 16: Touch Sensing Controller enable during Sleep mode */
+#define RCC_AHB1SMENR_DMA2DSMEN (1 << 17) /* Bit 17: DMA2D enable during Sleep mode */
+
+/* RCC AHB2 low power mode peripheral clock enable register */
+
+#define RCC_AHB2SMENR_GPIOASMEN (1 << 0) /* Bit 0: IO port A enable during Sleep mode */
+#define RCC_AHB2SMENR_GPIOBSMEN (1 << 1) /* Bit 1: IO port B enable during Sleep mode */
+#define RCC_AHB2SMENR_GPIOCSMEN (1 << 2) /* Bit 2: IO port C enable during Sleep mode */
+#define RCC_AHB2SMENR_GPIODSMEN (1 << 3) /* Bit 3: IO port D enable during Sleep mode */
+#define RCC_AHB2SMENR_GPIOESMEN (1 << 4) /* Bit 4: IO port E enable during Sleep mode */
+#define RCC_AHB2SMENR_GPIOHSMEN (1 << 7) /* Bit 7: IO port H enable during Sleep mode */
+#define RCC_AHB2SMENR_SRAM2SMEN (1 << 9) /* Bit 9: SRAM2 enable during Sleep mode */
+#define RCC_AHB2SMENR_ADCSMEN (1 << 13) /* Bit 13: ADC interface enable during Sleep mode (common to all ADCs) */
+#define RCC_AHB2SMENR_DCMISMEN (1 << 14) /* Bit 14: DCMI interface enable during Sleep mode */
+#define RCC_AHB2SMENR_AESSMEN (1 << 16) /* Bit 16: AES Cryptographic module enable during Sleep mode */
+#define RCC_AHB2SMENR_HASHSMEN (1 << 17) /* Bit 17: HASH module enable during Sleep mode */
+#define RCC_AHB2SMENR_RNGSMEN (1 << 18) /* Bit 18: Random number generator module enable during Sleep mode */
+
+/* RCC AHB3 low power mode peripheral clock enable register */
+
+#define RCC_AHB3SMENR_FSMCSMEN (1 << 0) /* Bit 0: Flexible static memory controller module enable during Sleep mode */
+#define RCC_AHB3SMENR_QSPISMEN (1 << 8) /* Bit 8: Quad SPI module enable during Sleep mode */
+
+/* RCC APB1 low power mode peripheral clock enable register 1 */
+
+#define RCC_APB1SMENR1_TIM2SMEN (1 << 0) /* Bit 0: TIM2 enable during Sleep mode */
+#define RCC_APB1SMENR1_TIM3SMEN (1 << 1) /* Bit 1: TIM3 enable during Sleep mode */
+#define RCC_APB1SMENR1_TIM4SMEN (1 << 2) /* Bit 2: TIM4 enable during Sleep mode */
+#define RCC_APB1SMENR1_TIM5SMEN (1 << 3) /* Bit 3: TIM5 enable during Sleep mode */
+#define RCC_APB1SMENR1_TIM6SMEN (1 << 4) /* Bit 4: TIM6 enable during Sleep mode */
+#define RCC_APB1SMENR1_TIM7SMEN (1 << 5) /* Bit 5: TIM7 enable during Sleep mode */
+#define RCC_APB1SMENR1_LCDSMEN (1 << 9) /* Bit 9: LCD controller enable during Sleep mode */
+#define RCC_APB1SMENR1_RTCAPBSMEN (1 << 10) /* Bit 10: RTC APB clock enable during Sleep mode */
+#define RCC_APB1SMENR1_WWDGSMEN (1 << 11) /* Bit 11: Windowed Watchdog enable during Sleep mode */
+#define RCC_APB1SMENR1_SPI2SMEN (1 << 14) /* Bit 14: SPI2 enable during Sleep mode */
+#define RCC_APB1SMENR1_SPI3SMEN (1 << 15) /* Bit 15: SPI3 enable during Sleep mode */
+#define RCC_APB1SMENR1_USART2SMEN (1 << 17) /* Bit 17: USART2 enable during Sleep mode */
+#define RCC_APB1SMENR1_USART3SMEN (1 << 18) /* Bit 18: USART3 enable during Sleep mode */
+#define RCC_APB1SMENR1_UART4SMEN (1 << 19) /* Bit 19: USART4 enable during Sleep mode */
+#define RCC_APB1SMENR1_UART5SMEN (1 << 20) /* Bit 20: USART5 enable during Sleep mode */
+#define RCC_APB1SMENR1_I2C1SMEN (1 << 21) /* Bit 21: I2C1 enable during Sleep mode */
+#define RCC_APB1SMENR1_I2C2SMEN (1 << 22) /* Bit 22: I2C2 enable during Sleep mode */
+#define RCC_APB1SMENR1_I2C3SMEN (1 << 23) /* Bit 23: I2C3 enable during Sleep mode */
+#define RCC_APB1SMENR1_CRSSMEN (1 << 24) /* Bit 24: CRS enable during Sleep mode */
+#define RCC_APB1SMENR1_CAN1SMEN (1 << 25) /* Bit 25: CAN1 enable during Sleep mode */
+#define RCC_APB1SMENR1_USBFSSMEN (1 << 26) /* Bit 26: USB FS enable during Sleep mode */
+#define RCC_APB1SMENR1_PWRSMEN (1 << 28) /* Bit 28: Power interface enable during Sleep mode */
+#define RCC_APB1SMENR1_DAC1SMEN (1 << 29) /* Bit 29: DAC1 enable during Sleep mode */
+#define RCC_APB1SMENR1_OPAMPSMEN (1 << 30) /* Bit 30: OPAMP enable during Sleep mode */
+#define RCC_APB1SMENR1_LPTIM1SMEN (1 << 31) /* Bit 31: Low-power Timer 1 enable during Sleep mode */
+
+/* RCC APB1 low power modeperipheral clock enable register 2 */
+
+#define RCC_APB1SMENR2_LPUART1SMEN (1 << 0) /* Bit 0: Low-power UART 1 enable during Sleep mode */
+#define RCC_APB1SMENR2_I2C4SMEN (1 << 1) /* Bit 1: I2C4 enable during Sleep mode */
+#define RCC_APB1SMENR2_SWPMI1SMEN (1 << 2) /* Bit 2: Single Wire Protocol enable during Sleep mode */
+#define RCC_APB1SMENR2_LPTIM2SMEN (1 << 5) /* Bit 5: Low-power Timer 2 enable during Sleep mode */
+
+/* RCC APB2 low power mode peripheral clock enable register */
+
+#define RCC_APB2SMENR_SYSCFGSMEN (1 << 0) /* Bit 0: System configuration controller enable during Sleep mode */
+#define RCC_APB2SMENR_SDMMCSMEN (1 << 10) /* Bit 10: SDMMC enable during Sleep mode */
+#define RCC_APB2SMENR_TIM1SMEN (1 << 11) /* Bit 11: TIM1 enable during Sleep mode */
+#define RCC_APB2SMENR_SPI1SMEN (1 << 12) /* Bit 12: SPI1 enable during Sleep mode */
+#define RCC_APB2SMENR_TIM8SMEN (1 << 13) /* Bit 13: TIM8 enable during Sleep mode */
+#define RCC_APB2SMENR_USART1SMEN (1 << 14) /* Bit 14: USART1 enable during Sleep mode */
+#define RCC_APB2SMENR_TIM15SMEN (1 << 16) /* Bit 16: TIM15 enable during Sleep mode */
+#define RCC_APB2SMENR_TIM16SMEN (1 << 17) /* Bit 17: TIM16 enable during Sleep mode */
+#define RCC_APB2SMENR_TIM17SMEN (1 << 18) /* Bit 18: TIM17 enable during Sleep mode */
+#define RCC_APB2SMENR_SAI1SMEN (1 << 21) /* Bit 21: SAI1 enable during Sleep mode */
+#define RCC_APB2SMENR_SAI2SMEN (1 << 22) /* Bit 22: SAI2 enable during Sleep mode */
+#define RCC_APB2SMENR_DFSDMSMEN (1 << 24) /* Bit 24: DFSDM enable during Sleep mode */
+
+/* Peripheral Independent Clock Configuration register */
+
+#define RCC_CCIPR_USART1SEL_SHIFT (0)
+#define RCC_CCIPR_USART1SEL_MASK (3 << RCC_CCIPR_USART1SEL_SHIFT)
+# define RCC_CCIPR_USART1SEL_PCLK (0 << RCC_CCIPR_USART1SEL_SHIFT)
+# define RCC_CCIPR_USART1SEL_SYSCLK (1 << RCC_CCIPR_USART1SEL_SHIFT)
+# define RCC_CCIPR_USART1SEL_HSI (2 << RCC_CCIPR_USART1SEL_SHIFT)
+# define RCC_CCIPR_USART1SEL_LSE (3 << RCC_CCIPR_USART1SEL_SHIFT)
+
+#define RCC_CCIPR_USART2SEL_SHIFT (2)
+#define RCC_CCIPR_USART2SEL_MASK (3 << RCC_CCIPR_USART2SEL_SHIFT)
+# define RCC_CCIPR_USART2SEL_PCLK (0 << RCC_CCIPR_USART2SEL_SHIFT)
+# define RCC_CCIPR_USART2SEL_SYSCLK (1 << RCC_CCIPR_USART2SEL_SHIFT)
+# define RCC_CCIPR_USART2SEL_HSI (2 << RCC_CCIPR_USART2SEL_SHIFT)
+# define RCC_CCIPR_USART2SEL_LSE (3 << RCC_CCIPR_USART2SEL_SHIFT)
+
+#define RCC_CCIPR_USART3SEL_SHIFT (4)
+#define RCC_CCIPR_USART3SEL_MASK (3 << RCC_CCIPR_USART3SEL_SHIFT)
+# define RCC_CCIPR_USART3SEL_PCLK (0 << RCC_CCIPR_USART3SEL_SHIFT)
+# define RCC_CCIPR_USART3SEL_SYSCLK (1 << RCC_CCIPR_USART3SEL_SHIFT)
+# define RCC_CCIPR_USART3SEL_HSI (2 << RCC_CCIPR_USART3SEL_SHIFT)
+# define RCC_CCIPR_USART3SEL_LSE (3 << RCC_CCIPR_USART3SEL_SHIFT)
+
+#define RCC_CCIPR_UART4SEL_SHIFT (6)
+#define RCC_CCIPR_UART4SEL_MASK (3 << RCC_CCIPR_UART4SEL_SHIFT)
+# define RCC_CCIPR_UART4SEL_PCLK (0 << RCC_CCIPR_UART4SEL_SHIFT)
+# define RCC_CCIPR_UART4SEL_SYSCLK (1 << RCC_CCIPR_UART4SEL_SHIFT)
+# define RCC_CCIPR_UART4SEL_HSI (2 << RCC_CCIPR_UART4SEL_SHIFT)
+# define RCC_CCIPR_UART4SEL_LSE (3 << RCC_CCIPR_UART4SEL_SHIFT)
+
+#define RCC_CCIPR_UART5SEL_SHIFT (8)
+#define RCC_CCIPR_UART5SEL_MASK (3 << RCC_CCIPR_UART5SEL_SHIFT)
+# define RCC_CCIPR_UART5SEL_PCLK (0 << RCC_CCIPR_UART5SEL_SHIFT)
+# define RCC_CCIPR_UART5SEL_SYSCLK (1 << RCC_CCIPR_UART5SEL_SHIFT)
+# define RCC_CCIPR_UART5SEL_HSI (2 << RCC_CCIPR_UART5SEL_SHIFT)
+# define RCC_CCIPR_UART5SEL_LSE (3 << RCC_CCIPR_UART5SEL_SHIFT)
+
+#define RCC_CCIPR_LPUART1SEL_SHIFT (10)
+#define RCC_CCIPR_LPUART1SEL_MASK (3 << RCC_CCIPR_LPUART1SEL_SHIFT)
+# define RCC_CCIPR_LPUART1SEL_PCLK (0 << RCC_CCIPR_LPUART1SEL_SHIFT)
+# define RCC_CCIPR_LPUART1SEL_SYSCLK (1 << RCC_CCIPR_LPUART1SEL_SHIFT)
+# define RCC_CCIPR_LPUART1SEL_HSI (2 << RCC_CCIPR_LPUART1SEL_SHIFT)
+# define RCC_CCIPR_LPUART1SEL_LSE (3 << RCC_CCIPR_LPUART1SEL_SHIFT)
+
+#define RCC_CCIPR_I2C1SEL_SHIFT (12)
+#define RCC_CCIPR_I2C1SEL_MASK (3 << RCC_CCIPR_I2C1SEL_SHIFT)
+# define RCC_CCIPR_I2C1SEL_PCLK (0 << RCC_CCIPR_I2C1SEL_SHIFT)
+# define RCC_CCIPR_I2C1SEL_SYSCLK (1 << RCC_CCIPR_I2C1SEL_SHIFT)
+# define RCC_CCIPR_I2C1SEL_HSI (2 << RCC_CCIPR_I2C1SEL_SHIFT)
+
+#define RCC_CCIPR_I2C2SEL_SHIFT (14)
+#define RCC_CCIPR_I2C2SEL_MASK (3 << RCC_CCIPR_I2C2SEL_SHIFT)
+# define RCC_CCIPR_I2C2SEL_PCLK (0 << RCC_CCIPR_I2C2SEL_SHIFT)
+# define RCC_CCIPR_I2C2SEL_SYSCLK (1 << RCC_CCIPR_I2C2SEL_SHIFT)
+# define RCC_CCIPR_I2C2SEL_HSI (2 << RCC_CCIPR_I2C2SEL_SHIFT)
+
+#define RCC_CCIPR_I2C3SEL_SHIFT (16)
+#define RCC_CCIPR_I2C3SEL_MASK (3 << RCC_CCIPR_I2C3SEL_SHIFT)
+# define RCC_CCIPR_I2C3SEL_PCLK (0 << RCC_CCIPR_I2C3SEL_SHIFT)
+# define RCC_CCIPR_I2C3SEL_SYSCLK (1 << RCC_CCIPR_I2C3SEL_SHIFT)
+# define RCC_CCIPR_I2C3SEL_HSI (2 << RCC_CCIPR_I2C3SEL_SHIFT)
+
+#define RCC_CCIPR_LPTIM1SEL_SHIFT (18)
+#define RCC_CCIPR_LPTIM1SEL_MASK (3 << RCC_CCIPR_LPTIM1SEL_SHIFT)
+# define RCC_CCIPR_LPTIM1SEL_PCLK (0 << RCC_CCIPR_LPTIM1SEL_SHIFT)
+# define RCC_CCIPR_LPTIM1SEL_LSI (1 << RCC_CCIPR_LPTIM1SEL_SHIFT)
+# define RCC_CCIPR_LPTIM1SEL_HSI (2 << RCC_CCIPR_LPTIM1SEL_SHIFT)
+# define RCC_CCIPR_LPTIM1SEL_LSE (3 << RCC_CCIPR_LPTIM1SEL_SHIFT)
+
+#define RCC_CCIPR_LPTIM2SEL_SHIFT (20)
+#define RCC_CCIPR_LPTIM2SEL_MASK (3 << RCC_CCIPR_LPTIM2SEL_SHIFT)
+# define RCC_CCIPR_LPTIM2SEL_PCLK (0 << RCC_CCIPR_LPTIM2SEL_SHIFT)
+# define RCC_CCIPR_LPTIM2SEL_LSI (1 << RCC_CCIPR_LPTIM2SEL_SHIFT)
+# define RCC_CCIPR_LPTIM2SEL_HSI (2 << RCC_CCIPR_LPTIM2SEL_SHIFT)
+# define RCC_CCIPR_LPTIM2SEL_LSE (3 << RCC_CCIPR_LPTIM2SEL_SHIFT)
+
+#define RCC_CCIPR_SAI1SEL_SHIFT (22)
+#define RCC_CCIPR_SAI1SEL_MASK (3 << RCC_CCIPR_SAI1SEL_SHIFT)
+# define RCC_CCIPR_SAI1SEL_PLLSAI1 (0 << RCC_CCIPR_SAI1SEL_SHIFT)
+# define RCC_CCIPR_SAI1SEL_PLLSAI2 (1 << RCC_CCIPR_SAI1SEL_SHIFT)
+# define RCC_CCIPR_SAI1SEL_PLLMAIN (2 << RCC_CCIPR_SAI1SEL_SHIFT)
+# define RCC_CCIPR_SAI1SEL_EXTCLK (3 << RCC_CCIPR_SAI1SEL_SHIFT)
+
+#define RCC_CCIPR_SAI2SEL_SHIFT (24)
+#define RCC_CCIPR_SAI2SEL_MASK (3 << RCC_CCIPR_SAI2SEL_SHIFT)
+# define RCC_CCIPR_SAI2SEL_PLLSAI1 (0 << RCC_CCIPR_SAI2SEL_SHIFT)
+# define RCC_CCIPR_SAI2SEL_PLLSAI2 (1 << RCC_CCIPR_SAI2SEL_SHIFT)
+# define RCC_CCIPR_SAI2SEL_PLLMAIN (2 << RCC_CCIPR_SAI2SEL_SHIFT)
+# define RCC_CCIPR_SAI2SEL_EXTCLK (3 << RCC_CCIPR_SAI2SEL_SHIFT)
+
+#define RCC_CCIPR_CLK48SEL_SHIFT (26)
+#define RCC_CCIPR_CLK48SEL_MASK (3 << RCC_CCIPR_CLK48SEL_SHIFT)
+# define RCC_CCIPR_CLK48SEL_NONE (0 << RCC_CCIPR_CLK48SEL_SHIFT)
+# define RCC_CCIPR_CLK48SEL_PLLSAI1 (1 << RCC_CCIPR_CLK48SEL_SHIFT)
+# define RCC_CCIPR_CLK48SEL_PLLMAIN (2 << RCC_CCIPR_CLK48SEL_SHIFT)
+# define RCC_CCIPR_CLK48SEL_MSI (3 << RCC_CCIPR_CLK48SEL_SHIFT)
+
+#define RCC_CCIPR_ADCSEL_SHIFT (28)
+#define RCC_CCIPR_ADCSEL_MASK (3 << RCC_CCIPR_ADCSEL_SHIFT)
+# define RCC_CCIPR_ADCSEL_NONE (0 << RCC_CCIPR_ADCSEL_SHIFT)
+# define RCC_CCIPR_ADCSEL_PLLSAI1 (1 << RCC_CCIPR_ADCSEL_SHIFT)
+# define RCC_CCIPR_ADCSEL_PLLSAI2 (2 << RCC_CCIPR_ADCSEL_SHIFT)
+# define RCC_CCIPR_ADCSEL_SYSCLK (3 << RCC_CCIPR_ADCSEL_SHIFT)
+
+#define RCC_CCIPR_SWPMI1SEL (1 << 30)
+# define RCC_CCIPR_SWPMI1SEL_PCLK 0
+# define RCC_CCIPR_SWPMI1SEL_HSI RCC_CCIPR_SWPMI1SEL
+
+#define RCC_CCIPR_DFSDMSEL (1 << 31)
+# define RCC_CCIPR_DFSDMSEL_PCLK 0
+# define RCC_CCIPR_DFSDMSEL_SYSCLK RCC_CCIPR_DFSDMSEL
+
+/* Backup domain control register */
+
+#define RCC_BDCR_LSEON (1 << 0) /* Bit 0: External Low Speed oscillator enable */
+#define RCC_BDCR_LSERDY (1 << 1) /* Bit 1: External Low Speed oscillator Ready */
+#define RCC_BDCR_LSEBYP (1 << 2) /* Bit 2: External Low Speed oscillator Bypass */
+
+#define RCC_BDCR_LSEDRV_SHIFT (3) /* Bits 3-4: LSE oscillator drive capability */
+#define RCC_BDCR_LSEDRV_MASK (3 << RCC_BDCR_LSEDRV_SHIFT)
+# define RCC_BDCR_LSEDRV_LOWER (0 << RCC_BDCR_LSEDRV_SHIFT) /* 00: Lower driving capability */
+# define RCC_BDCR_LSEDRV_MIDLOW (1 << RCC_BDCR_LSEDRV_SHIFT) /* 01: Medium Low driving capability */
+# define RCC_BDCR_LSEDRV_MIDHI (2 << RCC_BDCR_LSEDRV_SHIFT) /* 10: Medium High driving capability*/
+# define RCC_BDCR_LSEDRV_HIGER (3 << RCC_BDCR_LSEDRV_SHIFT) /* 11: Higher driving capability */
+
+#define RCC_BDCR_LSECSSON (1 << 5) /* Bit 5: CSS on LSE enable */
+#define RCC_BDCR_LSECSSD (1 << 6) /* Bit 6: CSS on LSE failure Detection */
+
+#define RCC_BDCR_RTCSEL_SHIFT (8) /* Bits 9:8: RTC clock source selection */
+#define RCC_BDCR_RTCSEL_MASK (3 << RCC_BDCR_RTCSEL_SHIFT)
+# define RCC_BDCR_RTCSEL_NOCLK (0 << RCC_BDCR_RTCSEL_SHIFT) /* 00: No clock */
+# define RCC_BDCR_RTCSEL_LSE (1 << RCC_BDCR_RTCSEL_SHIFT) /* 01: LSE oscillator clock used as RTC clock */
+# define RCC_BDCR_RTCSEL_LSI (2 << RCC_BDCR_RTCSEL_SHIFT) /* 10: LSI oscillator clock used as RTC clock */
+# define RCC_BDCR_RTCSEL_HSE (3 << RCC_BDCR_RTCSEL_SHIFT) /* 11: HSE oscillator clock divided by 32 used as RTC clock */
+
+#define RCC_BDCR_RTCEN (1 << 15) /* Bit 15: RTC clock enable */
+#define RCC_BDCR_BDRST (1 << 16) /* Bit 16: Backup domain software reset */
+#define RCC_BDCR_LSCOEN (1 << 24) /* Bit 24: Low speed clock output enable */
+#define RCC_BDCR_LSCOSEL (1 << 25) /* Bit 25: Low speed clock output selection */
+# define RCC_BCDR_LSCOSEL_LSI 0 /* LSI selected */
+# define RCC_BDCR_LSCOSEL_LSE RCC_BDCR_LSCOSEL /* LSE selected */
+
+/* Control/status register */
+
+#define RCC_CSR_LSION (1 << 0) /* Bit 0: Internal Low Speed oscillator enable */
+#define RCC_CSR_LSIRDY (1 << 1) /* Bit 1: Internal Low Speed oscillator Ready */
+
+#define RCC_CSR_MSISRANGE_SHIFT 8
+# define RCC_CSR_MSISRANGE_MASK (0x0F << RCC_CSR_MSISRANGE_SHIFT) /* MSI range after Standby mode */
+# define RCC_CSR_MSISRANGE_1M (4 << RCC_CSR_MSISRANGE_SHIFT) /* 0100: around 1 MHz */
+# define RCC_CSR_MSISRANGE_2M (5 << RCC_CSR_MSISRANGE_SHIFT) /* 0101: around 2 MHz */
+# define RCC_CSR_MSISRANGE_4M (6 << RCC_CSR_MSISRANGE_SHIFT) /* 0110: around 4 MHz */
+# define RCC_CSR_MSISRANGE_8M (7 << RCC_CSR_MSISRANGE_SHIFT) /* 0111: around 8 MHz */
+
+#define RCC_CSR_RMVF (1 << 23) /* Bit 23: Remove reset flag */
+#define RCC_CSR_FWRSTF (1 << 24) /* Bit 24: Firewall reset flag */
+#define RCC_CSR_OBLRSTF (1 << 25) /* Bit 25: Option byte loader reset flag */
+#define RCC_CSR_PINRSTF (1 << 26) /* Bit 26: PIN reset flag */
+#define RCC_CSR_BORRSTF (1 << 27) /* Bit 27: BOR reset flag */
+#define RCC_CSR_SFTRSTF (1 << 28) /* Bit 28: Software Reset flag */
+#define RCC_CSR_IWDGRSTF (1 << 29) /* Bit 29: Independent Watchdog reset flag */
+#define RCC_CSR_WWDGRSTF (1 << 30) /* Bit 30: Window watchdog reset flag */
+#define RCC_CSR_LPWRRSTF (1 << 31) /* Bit 31: Low-Power reset flag */
+
+/* Clock recovery RC register */
+
+#define RCC_CRRCR_HSI48CAL_SHIFT 7
+# define RCC_CRRCR_HSI48CAL_MASK (0x01ff << RCC_CRRCR_HSI48CAL_SHIFT) /* HSI48 clock calibration */
+
+#define RCC_CRRCR_HSI48ON (1 << 0) /* Bit 0: HSI48 clock enable */
+#define RCC_CRRCR_HSI48RDY (1 << 1) /* Bit 1: HSI48 clock ready flag */
+
+#endif /* CONFIG_STM32L4_STM32L4X3 */
+#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_RCC_H */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x3xx_syscfg.h b/arch/arm/src/stm32l4/chip/stm32l4x3xx_syscfg.h
new file mode 100644
index 00000000000..446ce1811a1
--- /dev/null
+++ b/arch/arm/src/stm32l4/chip/stm32l4x3xx_syscfg.h
@@ -0,0 +1,182 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32l4/chip/stm32l4x3xx_syscfg.h
+ *
+ * Copyright (C) 2014-2015 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 __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_SYSCFG_H
+#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_SYSCFG_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include
+#include "chip.h"
+
+#if defined(CONFIG_STM32L4_STM32L4X3)
+
+/****************************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************************/
+
+/* Register Offsets *********************************************************************************/
+
+#define STM32L4_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */
+#define STM32L4_SYSCFG_CFGR1_OFFSET 0x0004 /* SYSCFG configuration register 1 */
+#define STM32L4_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */
+#define STM32L4_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */
+#define STM32L4_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */
+#define STM32L4_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */
+#define STM32L4_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */
+#define STM32L4_SYSCFG_SCSR_OFFSET 0x0018 /* SYSCFG SRAM2 control and status register */
+#define STM32L4_SYSCFG_CFGR2_OFFSET 0x001c /* SYSCFG configuration register 2 */
+#define STM32L4_SYSCFG_SWPR_OFFSET 0x0020 /* SYSCFG SRAM2 write protection register */
+#define STM32L4_SYSCFG_SKR_OFFSET 0x0024 /* SYSCFG SRAM2 key register */
+
+/* Register Addresses *******************************************************************************/
+
+#define STM32L4_SYSCFG_MEMRMP (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_MEMRMP_OFFSET)
+#define STM32L4_SYSCFG_CFGR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR1_OFFSET)
+#define STM32L4_SYSCFG_EXTICR(p) (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR_OFFSET(p))
+#define STM32L4_SYSCFG_EXTICR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR1_OFFSET)
+#define STM32L4_SYSCFG_EXTICR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR2_OFFSET)
+#define STM32L4_SYSCFG_EXTICR3 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR3_OFFSET)
+#define STM32L4_SYSCFG_EXTICR4 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR4_OFFSET)
+#define STM32L4_SYSCFG_SCSR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SCSR_OFFSET)
+#define STM32L4_SYSCFG_CFGR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR2_OFFSET)
+#define STM32L4_SYSCFG_SWPR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SWPR_OFFSET)
+#define STM32L4_SYSCFG_SKR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SKR_OFFSET)
+
+/* Register Bitfield Definitions ********************************************************************/
+
+/* SYSCFG memory remap register */
+
+#define SYSCFG_MEMRMP_SHIFT (0) /* Bits 2:0 MEM_MODE: Memory mapping selection */
+#define SYSCFG_MEMRMP_MASK (7 << SYSCFG_MEMRMP_SHIFT)
+# define SYSCFG_MEMRMP_FLASH (0 << SYSCFG_MEMRMP_SHIFT) /* 000: Main Flash memory mapped at 0x0000 0000 */
+# define SYSCFG_MEMRMP_SYSTEM (1 << SYSCFG_MEMRMP_SHIFT) /* 001: System Flash memory mapped at 0x0000 0000 */
+# define SYSCFG_MEMRMP_SRAM (3 << SYSCFG_MEMRMP_SHIFT) /* 011: SRAM1 (112kB) mapped at 0x0000 0000 */
+# define SYSCFG_MEMRMP_QSPI (6 << SYSCFG_MEMRMP_SHIFT) /* 110: QUADSPI mapped at 0x0000 0000 */
+
+/* SYSCFG configuration register 1 */
+
+#define SYSCFG_CFGR1_FWDIS (1 << 0) /* Bit 0: Firewall disable */
+#define SYSCFG_CFGR1_BOOSTEN (1 << 8) /* Bit 8: I/O analog switch voltage booster enable (use when vdd is low) */
+#define SYSCFG_CFGR1_I2C_PB6_FMP (1 << 16) /* Bit 16: Fast-mode Plus (Fm+) driving capability activation on PB6 */
+#define SYSCFG_CFGR1_I2C_PB7_FMP (1 << 17) /* Bit 17: Fast-mode Plus (Fm+) driving capability activation on PB7 */
+#define SYSCFG_CFGR1_I2C_PB8_FMP (1 << 18) /* Bit 18: Fast-mode Plus (Fm+) driving capability activation on PB8 */
+#define SYSCFG_CFGR1_I2C_PB9_FMP (1 << 19) /* Bit 19: Fast-mode Plus (Fm+) driving capability activation on PB9 */
+#define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 Fast-mode Plus (Fm+) driving capability activation */
+#define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C2 Fast-mode Plus (Fm+) driving capability activation */
+#define SYSCFG_CFGR1_I2C3_FMP (1 << 22) /* Bit 22: I2C3 Fast-mode Plus (Fm+) driving capability activation */
+#define SYSCFG_CFGR1_I2C4_FMP (1 << 23) /* Bit 23: I2C4 Fast-mode Plus (Fm+) driving capability activation */
+#define SYSCFG_CFGR1_FPU_IE0 (1 << 26) /* Bit 26: FPU Invalid operation interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE1 (1 << 27) /* Bit 27: FPU Divide-by-zero interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE2 (1 << 28) /* Bit 28: FPU Underflow interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE3 (1 << 29) /* Bit 29: FPU Overflow interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE4 (1 << 30) /* Bit 30: FPU Input denormal interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE5 (1 << 31) /* Bit 31: FPU Inexact interrupt enable */
+
+/* SYSCFG external interrupt configuration register 1-4 */
+
+#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */
+#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */
+#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */
+#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */
+#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */
+/* No PORTF or PORTG on these chips */
+#define SYSCFG_EXTICR_PORTH (7) /* 0111: PH[x] pin */
+
+#define SYSCFG_EXTICR_PORT_MASK (7)
+#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2)
+#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g)))
+
+#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-2: EXTI 0 configuration */
+#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT)
+#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-6: EXTI 1 configuration */
+#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT)
+#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-10: EXTI 2 configuration */
+#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT)
+#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-14: EXTI 3 configuration */
+#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT)
+
+#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-2: EXTI 4 configuration */
+#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT)
+#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-6: EXTI 5 configuration */
+#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT)
+#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-10: EXTI 6 configuration */
+#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT)
+#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-14: EXTI 7 configuration */
+#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT)
+
+#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-2: EXTI 8 configuration */
+#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT)
+#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-6: EXTI 9 configuration */
+#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT)
+#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-10: EXTI 10 configuration */
+#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT)
+#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-14: EXTI 11 configuration */
+#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT)
+
+#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-2: EXTI 12 configuration */
+#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT)
+#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-6: EXTI 13 configuration */
+#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT)
+#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-10: EXTI 14 configuration */
+#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT)
+#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-14: EXTI 15 configuration */
+#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT)
+
+/* SYSCFG SRAM2 control and status register */
+
+#define SYSCFG_SCSR_SRAM2ER (1 << 0) /* Bit 0: SRAM2 Erase */
+#define SYSCFG_SCSR_SRAM2BSY (1 << 1) /* Bit 1: SRAM2 busy in erase operation */
+
+/* SYSCFG configuration register 2 */
+
+#define SYSCFG_CFGR2_CLL (1 << 0) /* Bit 0: Cortex-M4 LOCKUP (Hardfault) output enable (TIMx break enable, see refman) */
+#define SYSCFG_CFGR2_SPL (1 << 1) /* Bit 1: SRAM2 parity lock enable (same) */
+#define SYSCFG_CFGR2_PVDL (1 << 2) /* Bit 2: PVD lock enable (same) */
+#define SYSCFG_CFGR2_ECCL (1 << 3) /* Bit 3: ECC lock enable (same) */
+#define SYSCFG_CFGR2_SPF (1 << 8) /* Bit 8: SRAM2 parity error flag */
+
+/* SYSCFG SRAM2 write protection register */
+/* There is one bit per SRAM2 page (0 to 31) */
+
+/* SYSCFG SRAM2 key register */
+
+#define SYSCFG_SKR_SHIFT 0
+#define SYSCFG_SKR_MASK (0xFF << SYSCFG_SKR_SHIFT)
+
+#endif /* CONFIG_STM32L4_STM32L4X3 */
+#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X3XX_SYSCFG_H */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h
index e1531de5d03..55826d73f76 100644
--- a/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h
+++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_firewall.h
@@ -89,11 +89,19 @@
/* Volatile Data Segment Start Address */
#define FIREWALL_VDSADD_SHIFT 6
+#if defined(CONFIG_STM32L4_STM32L496XX)
+#define FIREWALL_VDSADD_MASK (0x0FFF << FIREWALL_VDSADD_SHIFT)
+#else
#define FIREWALL_VDSADD_MASK (0x07FF << FIREWALL_VDSADD_SHIFT)
+#endif
/* Volatile Data Segment Length */
#define FIREWALL_VDSLENG_SHIFT 6
+#if defined(CONFIG_STM32L4_STM32L496XX)
+#define FIREWALL_VDSLENG_MASK (0x0FFF << FIREWALL_VDSLENG_SHIFT)
+#else
#define FIREWALL_VDSLENG_MASK (0x07FF << FIREWALL_VDSLENG_SHIFT)
+#endif
/* Configuration Register */
#define FIREWALL_CR_FPA (1 << 0) /* Bit 0: Firewall prearm */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h
index d180033ad28..6d55cfea9ad 100644
--- a/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h
+++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_rcc.h
@@ -44,8 +44,7 @@
#include
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
+#if defined(CONFIG_STM32L4_STM32L4X6)
/****************************************************************************************************
* Pre-processor Definitions
@@ -807,5 +806,5 @@
# define RCC_CCIPR2_I2C4SEL_SYSCLK (1 << RCC_CCIPR2_I2C4SEL_SHIFT)
# define RCC_CCIPR2_I2C4SEL_HSI (2 << RCC_CCIPR2_I2C4SEL_SHIFT)
-#endif /* CONFIG_STM32L4_STM32L476XX || CONFIG_STM32L4_STM32L486XX || CONFIG_STM32L4_STM32L496XX */
+#endif /* CONFIG_STM32L4_STM32L4X6 */
#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_RCC_H */
diff --git a/arch/arm/src/stm32l4/chip/stm32l4x6xx_syscfg.h b/arch/arm/src/stm32l4/chip/stm32l4x6xx_syscfg.h
new file mode 100644
index 00000000000..e7446cfb29c
--- /dev/null
+++ b/arch/arm/src/stm32l4/chip/stm32l4x6xx_syscfg.h
@@ -0,0 +1,191 @@
+/****************************************************************************************************
+ * arch/arm/src/stm32l4/chip/stm32l4x6xx_syscfg.h
+ *
+ * Copyright (C) 2014-2015 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 __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_SYSCFG_H
+#define __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_SYSCFG_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include
+#include "chip.h"
+
+#if defined(CONFIG_STM32L4_STM32L4X6)
+
+/****************************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************************/
+
+/* Register Offsets *********************************************************************************/
+
+#define STM32L4_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */
+#define STM32L4_SYSCFG_CFGR1_OFFSET 0x0004 /* SYSCFG configuration register 1 */
+#define STM32L4_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */
+#define STM32L4_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */
+#define STM32L4_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */
+#define STM32L4_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */
+#define STM32L4_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */
+#define STM32L4_SYSCFG_SCSR_OFFSET 0x0018 /* SYSCFG SRAM2 control and status register */
+#define STM32L4_SYSCFG_CFGR2_OFFSET 0x001c /* SYSCFG configuration register 2 */
+#define STM32L4_SYSCFG_SWPR_OFFSET 0x0020 /* SYSCFG SRAM2 write protection register */
+#define STM32L4_SYSCFG_SKR_OFFSET 0x0024 /* SYSCFG SRAM2 key register */
+#define STM32L4_SYSCFG_SWPR2_OFFSET 0x0028 /* SYSCFG SRAM2 write protection register 2 */
+
+/* Register Addresses *******************************************************************************/
+
+#define STM32L4_SYSCFG_MEMRMP (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_MEMRMP_OFFSET)
+#define STM32L4_SYSCFG_CFGR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR1_OFFSET)
+#define STM32L4_SYSCFG_EXTICR(p) (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR_OFFSET(p))
+#define STM32L4_SYSCFG_EXTICR1 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR1_OFFSET)
+#define STM32L4_SYSCFG_EXTICR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR2_OFFSET)
+#define STM32L4_SYSCFG_EXTICR3 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR3_OFFSET)
+#define STM32L4_SYSCFG_EXTICR4 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_EXTICR4_OFFSET)
+#define STM32L4_SYSCFG_SCSR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SCSR_OFFSET)
+#define STM32L4_SYSCFG_CFGR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_CFGR2_OFFSET)
+#define STM32L4_SYSCFG_SWPR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SWPR_OFFSET)
+#define STM32L4_SYSCFG_SKR (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SKR_OFFSET)
+#define STM32L4_SYSCFG_SWPR2 (STM32L4_SYSCFG_BASE+STM32L4_SYSCFG_SWPR2_OFFSET)
+
+/* Register Bitfield Definitions ********************************************************************/
+
+/* SYSCFG memory remap register */
+
+#define SYSCFG_MEMRMP_SHIFT (0) /* Bits 2:0 MEM_MODE: Memory mapping selection */
+#define SYSCFG_MEMRMP_MASK (7 << SYSCFG_MEMRMP_SHIFT)
+# define SYSCFG_MEMRMP_FLASH (0 << SYSCFG_MEMRMP_SHIFT) /* 000: Main Flash memory mapped at 0x0000 0000 */
+# define SYSCFG_MEMRMP_SYSTEM (1 << SYSCFG_MEMRMP_SHIFT) /* 001: System Flash memory mapped at 0x0000 0000 */
+# define SYSCFG_MEMRMP_FMC (2 << SYSCFG_MEMRMP_SHIFT) /* 010: FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x0000 0000 */
+# define SYSCFG_MEMRMP_SRAM (3 << SYSCFG_MEMRMP_SHIFT) /* 011: SRAM1 (112kB) mapped at 0x0000 0000 */
+# define SYSCFG_MEMRMP_QSPI (6 << SYSCFG_MEMRMP_SHIFT) /* 110: QUADSPI mapped at 0x0000 0000 */
+#define SYSCFG_FBMODE (1 << 8) /* Bit 8: Flash Bank mode selection */
+
+/* SYSCFG configuration register 1 */
+
+#define SYSCFG_CFGR1_FWDIS (1 << 0) /* Bit 0: Firewall disable */
+#define SYSCFG_CFGR1_BOOSTEN (1 << 8) /* Bit 8: I/O analog switch voltage booster enable (use when vdd is low) */
+#define SYSCFG_CFGR1_I2C_PB6_FMP (1 << 16) /* Bit 16: Fast-mode Plus (Fm+) driving capability activation on PB6 */
+#define SYSCFG_CFGR1_I2C_PB7_FMP (1 << 17) /* Bit 17: Fast-mode Plus (Fm+) driving capability activation on PB7 */
+#define SYSCFG_CFGR1_I2C_PB8_FMP (1 << 18) /* Bit 18: Fast-mode Plus (Fm+) driving capability activation on PB8 */
+#define SYSCFG_CFGR1_I2C_PB9_FMP (1 << 19) /* Bit 19: Fast-mode Plus (Fm+) driving capability activation on PB9 */
+#define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 Fast-mode Plus (Fm+) driving capability activation */
+#define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C2 Fast-mode Plus (Fm+) driving capability activation */
+#define SYSCFG_CFGR1_I2C3_FMP (1 << 22) /* Bit 22: I2C3 Fast-mode Plus (Fm+) driving capability activation */
+#define SYSCFG_CFGR1_I2C4_FMP (1 << 23) /* Bit 23: I2C4 Fast-mode Plus (Fm+) driving capability activation */
+#define SYSCFG_CFGR1_FPU_IE0 (1 << 26) /* Bit 26: FPU Invalid operation interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE1 (1 << 27) /* Bit 27: FPU Divide-by-zero interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE2 (1 << 28) /* Bit 28: FPU Underflow interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE3 (1 << 29) /* Bit 29: FPU Overflow interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE4 (1 << 30) /* Bit 30: FPU Input denormal interrupt enable */
+#define SYSCFG_CFGR1_FPU_IE5 (1 << 31) /* Bit 31: FPU Inexact interrupt enable */
+
+/* SYSCFG external interrupt configuration register 1-4 */
+
+#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */
+#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */
+#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */
+#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */
+#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */
+#define SYSCFG_EXTICR_PORTF (5) /* 0101: PF[C] pin */
+#define SYSCFG_EXTICR_PORTG (6) /* 0110: PG[x] pin */
+#define SYSCFG_EXTICR_PORTH (7) /* 0111: PH[x] pin (only on STM32L496xx/4A6xx) */
+#define SYSCFG_EXTICR_PORTI (8) /* 1000: PI[x] pin (only on STM32L496xx/4A6xx) */
+
+#define SYSCFG_EXTICR_PORT_MASK (15)
+#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2)
+#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g)))
+
+#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-2: EXTI 0 configuration */
+#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT)
+#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-6: EXTI 1 configuration */
+#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT)
+#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-10: EXTI 2 configuration */
+#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT)
+#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-14: EXTI 3 configuration */
+#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT)
+
+#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-2: EXTI 4 configuration */
+#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT)
+#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-6: EXTI 5 configuration */
+#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT)
+#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-10: EXTI 6 configuration */
+#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT)
+#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-14: EXTI 7 configuration */
+#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT)
+
+#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-2: EXTI 8 configuration */
+#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT)
+#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-6: EXTI 9 configuration */
+#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT)
+#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-10: EXTI 10 configuration */
+#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT)
+#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-14: EXTI 11 configuration */
+#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT)
+
+#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-2: EXTI 12 configuration */
+#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT)
+#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-6: EXTI 13 configuration */
+#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT)
+#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-10: EXTI 14 configuration */
+#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT)
+#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-14: EXTI 15 configuration */
+#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT)
+
+/* SYSCFG SRAM2 control and status register */
+
+#define SYSCFG_SCSR_SRAM2ER (1 << 0) /* Bit 0: SRAM2 Erase */
+#define SYSCFG_SCSR_SRAM2BSY (1 << 1) /* Bit 1: SRAM2 busy in erase operation */
+
+/* SYSCFG configuration register 2 */
+
+#define SYSCFG_CFGR2_CLL (1 << 0) /* Bit 0: Cortex-M4 LOCKUP (Hardfault) output enable (TIMx break enable, see refman) */
+#define SYSCFG_CFGR2_SPL (1 << 1) /* Bit 1: SRAM2 parity lock enable (same) */
+#define SYSCFG_CFGR2_PVDL (1 << 2) /* Bit 2: PVD lock enable (same) */
+#define SYSCFG_CFGR2_ECCL (1 << 3) /* Bit 3: ECC lock enable (same) */
+#define SYSCFG_CFGR2_SPF (1 << 8) /* Bit 8: SRAM2 parity error flag */
+
+/* SYSCFG SRAM2 write protection register */
+/* There is one bit per SRAM2 page (0 to 31) */
+
+/* SYSCFG SRAM2 key register */
+
+#define SYSCFG_SKR_SHIFT 0
+#define SYSCFG_SKR_MASK (0xFF << SYSCFG_SKR_SHIFT)
+
+/* SYSCFG SRAM2 write protection register 2 (only on STM32L496xx/4A6xx) */
+/* There is one bit per SRAM2 page (32 to 63) */
+
+#endif /* CONFIG_STM32L4_STM32L4X6 */
+#endif /* __ARCH_ARM_SRC_STM32L4_CHIP_STM32L4X6XX_SYSCFG_H */
diff --git a/arch/arm/src/stm32l4/stm32l4_dma.c b/arch/arm/src/stm32l4/stm32l4_dma.c
index d2fd26546eb..fbde7e04e6a 100644
--- a/arch/arm/src/stm32l4/stm32l4_dma.c
+++ b/arch/arm/src/stm32l4/stm32l4_dma.c
@@ -41,34 +41,15 @@
#include "chip.h"
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
/* This file is only a thin shell that includes the correct DMA implementation
* for the selected STM32 family. The correct file cannot be selected by
* the make system because it needs the intelligence that only exists in
* chip.h that can associate an STM32 part number with an STM32 family.
+ *
+ * TODO: do we need separate implementation for STM32L4X3?
*/
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
+#if defined(CONFIG_STM32L4_STM32L4X6) || defined(CONFIG_STM32L4_STM32L4X3)
#include "stm32l4x6xx_dma.c"
#else
# error "Unsupported STM32L4 chip"
diff --git a/arch/arm/src/stm32l4/stm32l4_dma.h b/arch/arm/src/stm32l4/stm32l4_dma.h
index 89196cb3811..c12013782d6 100644
--- a/arch/arm/src/stm32l4/stm32l4_dma.h
+++ b/arch/arm/src/stm32l4/stm32l4_dma.h
@@ -49,9 +49,10 @@
/* Include the correct DMA register definitions for this STM32 family */
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
+#if defined(CONFIG_STM32L4_STM32L4X6)
# include "chip/stm32l4x6xx_dma.h"
+#elif defined(CONFIG_STM32L4_STM32L4X3)
+# include "chip/stm32l4x3xx_dma.h"
#else
# error "Unsupported STM32L4 chip"
#endif
diff --git a/arch/arm/src/stm32l4/stm32l4_firewall.c b/arch/arm/src/stm32l4/stm32l4_firewall.c
index 46cc3ff62de..27f948e43f7 100644
--- a/arch/arm/src/stm32l4/stm32l4_firewall.c
+++ b/arch/arm/src/stm32l4/stm32l4_firewall.c
@@ -38,6 +38,10 @@
****************************************************************************/
#include
+#include
+
+#include "up_arch.h"
+#include "chip/stm32l4_syscfg.h"
#include "stm32l4_firewall.h"
diff --git a/arch/arm/src/stm32l4/stm32l4_firewall.h b/arch/arm/src/stm32l4/stm32l4_firewall.h
index ec667fe5a7c..7b4a4dd0c45 100644
--- a/arch/arm/src/stm32l4/stm32l4_firewall.h
+++ b/arch/arm/src/stm32l4/stm32l4_firewall.h
@@ -47,9 +47,10 @@
/* Include the correct firewall register definitions for this STM32L4 family */
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
+#if defined(CONFIG_STM32L4_STM32L4X6)
# include "chip/stm32l4x6xx_firewall.h"
+#elif defined(CONFIG_STM32L4_STM32L4X3)
+# include "chip/stm32l4x3xx_firewall.h"
#else
# error "Unsupported STM32L4 chip"
#endif
@@ -60,11 +61,11 @@
struct stm32l4_firewall_t
{
- uintptr_t *codestart;
+ uintptr_t codestart;
size_t codelen;
- uintptr_t *nvdatastart;
+ uintptr_t nvdatastart;
size_t nvdatalen;
- uintptr_t *datastart;
+ uintptr_t datastart;
size_t datalen;
uint8_t datashared:1;
uint8_t dataexec :1;
diff --git a/arch/arm/src/stm32l4/stm32l4_flash.h b/arch/arm/src/stm32l4/stm32l4_flash.h
index 96bd6135d90..c29a8d35a55 100644
--- a/arch/arm/src/stm32l4/stm32l4_flash.h
+++ b/arch/arm/src/stm32l4/stm32l4_flash.h
@@ -41,42 +41,72 @@
* Pre-processor Definitions
************************************************************************************/
+/* Flash size is known from the chip selection:
+ *
+ * When CONFIG_STM32L4_FLASH_OVERRIDE_DEFAULT is set the
+ * CONFIG_STM32L4_FLASH_CONFIG_x selects the default FLASH size based on the chip
+ * part number. This value can be overridden with CONFIG_STM32L4_FLASH_OVERRIDE_x
+ *
+ * Parts STM32L4xxE have 512Kb of FLASH
+ * Parts STM32L4xxG have 1024Kb of FLASH
+ *
+ * N.B. Only Single bank mode is supported
+ */
+
#define _K(x) ((x)*1024)
-#if !defined(CONFIG_STM32L4_FLASH_CONFIG_DEFAULT) && \
+#if !defined(CONFIG_STM32L4_FLASH_OVERRIDE_DEFAULT) && \
+ !defined(CONFIG_STM32L4_FLASH_OVERRIDE_B) && \
+ !defined(CONFIG_STM32L4_FLASH_OVERRIDE_C) && \
+ !defined(CONFIG_STM32L4_FLASH_OVERRIDE_E) && \
+ !defined(CONFIG_STM32L4_FLASH_OVERRIDE_G) && \
+ !defined(CONFIG_STM32L4_FLASH_CONFIG_B) && \
!defined(CONFIG_STM32L4_FLASH_CONFIG_C) && \
!defined(CONFIG_STM32L4_FLASH_CONFIG_E) && \
!defined(CONFIG_STM32L4_FLASH_CONFIG_G)
-# define CONFIG_STM32L4_FLASH_CONFIG_DEFAULT
+# define CONFIG_STM32L4_FLASH_OVERRIDE_E
+# warning "Flash size not defined defaulting to 512KiB (E)"
#endif
-#if defined(CONFIG_STM32L4_FLASH_CONFIG_DEFAULT)
-# define STM32L4_FLASH_NPAGES 512
-# define STM32L4_FLASH_PAGESIZE 2048
-#endif /* CONFIG_STM32L4_FLASH_CONFIG_DEFAULT */
+/* Override of the Flash has been chosen */
-/* Override of the Flash Has been Chosen */
-
-#if !defined(CONFIG_STM32L4_FLASH_CONFIG_DEFAULT)
-
-/* Define the Valid Configuration the F1 and F3 */
-
-# if defined(CONFIG_STM32L4_FLASH_CONFIG_C) /* 256 kB */
-# define STM32L4_FLASH_NPAGES 128
-# define STM32L4_FLASH_PAGESIZE 2048
-# elif defined(CONFIG_STM32L4_FLASH_CONFIG_E) /* 512 kB */
-# define STM32L4_FLASH_NPAGES 256
-# define STM32L4_FLASH_PAGESIZE 2048
-# elif defined(CONFIG_STM32L4_FLASH_CONFIG_G) /* 1 MB */
-# define STM32L4_FLASH_NPAGES 512
-# define STM32L4_FLASH_PAGESIZE 2048
-# else
+#if !defined(CONFIG_STM32L4_FLASH_OVERRIDE_DEFAULT)
+# undef CONFIG_STM32L4_FLASH_CONFIG_B
+# undef CONFIG_STM32L4_FLASH_CONFIG_C
+# undef CONFIG_STM32L4_FLASH_CONFIG_E
+# undef CONFIG_STM32L4_FLASH_CONFIG_G
+# if defined(CONFIG_STM32L4_FLASH_OVERRIDE_B)
+# define CONFIG_STM32L4_FLASH_CONFIG_B
+# elif defined(CONFIG_STM32L4_FLASH_OVERRIDE_C)
+# define CONFIG_STM32L4_FLASH_CONFIG_C
+# elif defined(CONFIG_STM32L4_FLASH_OVERRIDE_E)
+# define CONFIG_STM32L4_FLASH_CONFIG_E
+# elif defined(CONFIG_STM32L4_FLASH_OVERRIDE_G)
+# define CONFIG_STM32L4_FLASH_CONFIG_G
# endif
#endif
+/* Define the valid configuration */
+
+#if defined(CONFIG_STM32L4_FLASH_CONFIG_B) /* 128 kB */
+# define STM32L4_FLASH_NPAGES 64
+# define STM32L4_FLASH_PAGESIZE 2048
+#elif defined(CONFIG_STM32L4_FLASH_CONFIG_C) /* 256 kB */
+# define STM32L4_FLASH_NPAGES 128
+# define STM32L4_FLASH_PAGESIZE 2048
+#elif defined(CONFIG_STM32L4_FLASH_CONFIG_E) /* 512 kB */
+# define STM32L4_FLASH_NPAGES 256
+# define STM32L4_FLASH_PAGESIZE 2048
+#elif defined(CONFIG_STM32L4_FLASH_CONFIG_G) /* 1 MB */
+# define STM32L4_FLASH_NPAGES 512
+# define STM32L4_FLASH_PAGESIZE 2048
+#else
+# error "unknown flash configuration!"
+#endif
+
#ifdef STM32L4_FLASH_PAGESIZE
# define STM32L4_FLASH_SIZE (STM32L4_FLASH_NPAGES * STM32L4_FLASH_PAGESIZE)
-#endif /* def STM32L4_FLASH_PAGESIZE */
+#endif
/* Register Offsets *****************************************************************/
@@ -128,7 +158,7 @@
# define FLASH_ACR_LATENCY_3 (3 << FLASH_ACR_LATENCY_SHIFT) /* 011: Three wait states <=64 <=26 */
# define FLASH_ACR_LATENCY_4 (4 << FLASH_ACR_LATENCY_SHIFT) /* 100: Four wait states <=80 <=26 */
-#define FLASH_ACR_PRFTEN (1 << 8) /* Bit 8: Pprefetch enable */
+#define FLASH_ACR_PRFTEN (1 << 8) /* Bit 8: Prefetch enable */
#define FLASH_ACR_ICEN (1 << 9) /* Bit 9: Instruction cache enable */
#define FLASH_ACR_DCEN (1 << 10) /* Bit 10: Data cache enable */
#define FLASH_ACR_ICRST (1 << 11) /* Bit 11: Instruction cache reset */
diff --git a/arch/arm/src/stm32l4/stm32l4_gpio.h b/arch/arm/src/stm32l4/stm32l4_gpio.h
index 57076a83ed5..e0fac1e2734 100644
--- a/arch/arm/src/stm32l4/stm32l4_gpio.h
+++ b/arch/arm/src/stm32l4/stm32l4_gpio.h
@@ -54,9 +54,8 @@
#include "chip.h"
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
-# include "chip/stm32l4x6xx_gpio.h"
+#if defined(CONFIG_STM32L4_STM32L4X6) || defined(CONFIG_STM32L4_STM32L4X3)
+# include "chip/stm32l4_gpio.h"
#else
# error "Unsupported STM32L4 chip"
#endif
diff --git a/arch/arm/src/stm32l4/stm32l4_rcc.c b/arch/arm/src/stm32l4/stm32l4_rcc.c
index 6d7a240d89b..ffe1c4d2dc7 100644
--- a/arch/arm/src/stm32l4/stm32l4_rcc.c
+++ b/arch/arm/src/stm32l4/stm32l4_rcc.c
@@ -78,9 +78,10 @@
/* Include chip-specific clocking initialization logic */
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
+#if defined(CONFIG_STM32L4_STM32L4X6)
# include "stm32l4x6xx_rcc.c"
+#elif defined(CONFIG_STM32L4_STM32L4X3)
+# include "stm32l4x3xx_rcc.c"
#else
# error "Unsupported STM32L4 chip"
#endif
diff --git a/arch/arm/src/stm32l4/stm32l4_rcc.h b/arch/arm/src/stm32l4/stm32l4_rcc.h
index 6c77771ec67..8e3f84adc8e 100644
--- a/arch/arm/src/stm32l4/stm32l4_rcc.h
+++ b/arch/arm/src/stm32l4/stm32l4_rcc.h
@@ -45,9 +45,10 @@
#include "up_arch.h"
#include "chip.h"
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
+#if defined(CONFIG_STM32L4_STM32L4X6)
# include "chip/stm32l4x6xx_rcc.h"
+#elif defined(CONFIG_STM32L4_STM32L4X3)
+# include "chip/stm32l4x3xx_rcc.h"
#else
# error "Unsupported STM32L4 chip"
#endif
diff --git a/arch/arm/src/stm32l4/stm32l4_serial.c b/arch/arm/src/stm32l4/stm32l4_serial.c
index 187a8f8f9bb..955fb548e1f 100644
--- a/arch/arm/src/stm32l4/stm32l4_serial.c
+++ b/arch/arm/src/stm32l4/stm32l4_serial.c
@@ -61,6 +61,7 @@
#include
#include "chip.h"
+#include "stm32l4_gpio.h"
#include "stm32l4_uart.h"
#include "stm32l4_dma.h"
#include "stm32l4_rcc.h"
diff --git a/arch/arm/src/stm32l4/stm32l4_uart.h b/arch/arm/src/stm32l4/stm32l4_uart.h
index d6922269fb9..286ba8eeb85 100644
--- a/arch/arm/src/stm32l4/stm32l4_uart.h
+++ b/arch/arm/src/stm32l4/stm32l4_uart.h
@@ -44,9 +44,8 @@
#include "chip.h"
-#if defined(CONFIG_STM32L4_STM32L476XX) || defined(CONFIG_STM32L4_STM32L486XX) || \
- defined(CONFIG_STM32L4_STM32L496XX)
-# include "chip/stm32l4x6xx_uart.h"
+#if defined(CONFIG_STM32L4_STM32L4X6) || defined(CONFIG_STM32L4_STM32L4X3)
+# include "chip/stm32l4_uart.h"
#else
# error "Unsupported STM32L4 chip"
#endif
diff --git a/arch/arm/src/stm32l4/stm32l4x3xx_rcc.c b/arch/arm/src/stm32l4/stm32l4x3xx_rcc.c
new file mode 100644
index 00000000000..855481df090
--- /dev/null
+++ b/arch/arm/src/stm32l4/stm32l4x3xx_rcc.c
@@ -0,0 +1,864 @@
+/****************************************************************************
+ * arch/arm/src/stm32l4/stm32l4x3xx_rcc.c
+ *
+ * Copyright (C) 2011-2012, 2014-2015 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2016 Sebastien Lorquet. All rights reserved.
+ * Authors: Gregory Nutt
+ * Sebastien Lorquet
+ * Juha Niskanen
+ *
+ * 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 "stm32l4_pwr.h"
+#include "stm32l4_flash.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Allow up to 100 milliseconds for the high speed clock to become ready.
+ * that is a very long delay, but if the clock does not become ready we are
+ * hosed anyway. Normally this is very fast, but I have seen at least one
+ * board that required this long, long timeout for the HSE to be ready.
+ */
+
+#define HSERDY_TIMEOUT (100 * CONFIG_BOARD_LOOPSPERMSEC)
+
+/* Same for HSI and MSI */
+
+#define HSIRDY_TIMEOUT HSERDY_TIMEOUT
+#define MSIRDY_TIMEOUT HSERDY_TIMEOUT
+
+/* HSE divisor to yield ~1MHz RTC clock */
+
+#define HSE_DIVISOR (STM32L4_HSE_FREQUENCY + 500000) / 1000000
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rcc_reset
+ *
+ * Description:
+ * Reset the RCC clock configuration to the default reset state
+ *
+ ****************************************************************************/
+
+static inline void rcc_reset(void)
+{
+ uint32_t regval;
+
+ /* Enable the Internal High Speed clock (HSI) */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval |= RCC_CR_HSION;
+ putreg32(regval, STM32L4_RCC_CR);
+
+ /* Reset CFGR register */
+
+ putreg32(0x00000000, STM32L4_RCC_CFGR);
+
+ /* Reset HSION, HSEON, CSSON and PLLON bits */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON);
+ putreg32(regval, STM32L4_RCC_CR);
+
+ /* Reset PLLCFGR register to reset default */
+
+ putreg32(RCC_PLLCFG_RESET, STM32L4_RCC_PLLCFG);
+
+ /* Reset HSEBYP bit */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval &= ~RCC_CR_HSEBYP;
+ putreg32(regval, STM32L4_RCC_CR);
+
+ /* Disable all interrupts */
+
+ putreg32(0x00000000, STM32L4_RCC_CIER);
+}
+
+/****************************************************************************
+ * Name: rcc_enableahb1
+ *
+ * Description:
+ * Enable selected AHB1 peripherals
+ *
+ ****************************************************************************/
+
+static inline void rcc_enableahb1(void)
+{
+ uint32_t regval;
+
+ /* Set the appropriate bits in the AHB1ENR register to enabled the
+ * selected AHB1 peripherals.
+ */
+
+ regval = getreg32(STM32L4_RCC_AHB1ENR);
+
+#ifdef CONFIG_STM32L4_DMA1
+ /* DMA 1 clock enable */
+
+ regval |= RCC_AHB1ENR_DMA1EN;
+#endif
+
+#ifdef CONFIG_STM32L4_DMA2
+ /* DMA 2 clock enable */
+
+ regval |= RCC_AHB1ENR_DMA2EN;
+#endif
+
+#ifdef CONFIG_STM32L4_CRC
+ /* CRC clock enable */
+
+ regval |= RCC_AHB1ENR_CRCEN;
+#endif
+
+#ifdef CONFIG_STM32L4_TSC
+ /* TSC clock enable */
+
+ regval |= RCC_AHB1ENR_TSCEN;
+#endif
+
+ putreg32(regval, STM32L4_RCC_AHB1ENR); /* Enable peripherals */
+}
+
+/****************************************************************************
+ * Name: rcc_enableahb2
+ *
+ * Description:
+ * Enable selected AHB2 peripherals
+ *
+ ****************************************************************************/
+
+static inline void rcc_enableahb2(void)
+{
+ uint32_t regval;
+
+ /* Set the appropriate bits in the AHB2ENR register to enable the
+ * selected AHB2 peripherals.
+ */
+
+ regval = getreg32(STM32L4_RCC_AHB2ENR);
+
+ /* Enable GPIOA, GPIOB, .... GPIOH */
+
+#if STM32L4_NPORTS > 0
+ regval |= (RCC_AHB2ENR_GPIOAEN
+#if STM32L4_NPORTS > 1
+ | RCC_AHB2ENR_GPIOBEN
+#endif
+#if STM32L4_NPORTS > 2
+ | RCC_AHB2ENR_GPIOCEN
+#endif
+#if STM32L4_NPORTS > 3
+ | RCC_AHB2ENR_GPIODEN
+#endif
+#if STM32L4_NPORTS > 4
+ | RCC_AHB2ENR_GPIOEEN
+#endif
+/* These chips have no GPIOF, GPIOG or GPIOI */
+#if STM32L4_NPORTS > 7
+ | RCC_AHB2ENR_GPIOHEN
+#endif
+ );
+#endif
+
+#if defined(CONFIG_STM32L4_ADC1) || defined(CONFIG_STM32L4_ADC2) || defined(CONFIG_STM32L4_ADC3)
+ /* ADC clock enable */
+
+ regval |= RCC_AHB2ENR_ADCEN;
+#endif
+
+#ifdef CONFIG_STM32L4_AES
+ /* Cryptographic modules clock enable */
+
+ regval |= RCC_AHB2ENR_AESEN;
+#endif
+
+#ifdef CONFIG_STM32L4_RNG
+ /* Random number generator clock enable */
+
+ regval |= RCC_AHB2ENR_RNGEN;
+#endif
+
+ putreg32(regval, STM32L4_RCC_AHB2ENR); /* Enable peripherals */
+}
+
+/****************************************************************************
+ * Name: rcc_enableahb3
+ *
+ * Description:
+ * Enable selected AHB3 peripherals
+ *
+ ****************************************************************************/
+
+static inline void rcc_enableahb3(void)
+{
+ uint32_t regval;
+
+ /* Set the appropriate bits in the AHB3ENR register to enabled the
+ * selected AHB3 peripherals.
+ */
+
+ regval = getreg32(STM32L4_RCC_AHB3ENR);
+
+#ifdef CONFIG_STM32L4_QSPI
+ /* QuadSPI module clock enable */
+
+ regval |= RCC_AHB3ENR_QSPIEN;
+#endif
+
+ putreg32(regval, STM32L4_RCC_AHB3ENR); /* Enable peripherals */
+}
+
+/****************************************************************************
+ * Name: rcc_enableapb1
+ *
+ * Description:
+ * Enable selected APB1 peripherals
+ *
+ ****************************************************************************/
+
+static inline void rcc_enableapb1(void)
+{
+ uint32_t regval;
+
+ /* Set the appropriate bits in the APB1ENR register to enabled the
+ * selected APB1 peripherals.
+ */
+
+ regval = getreg32(STM32L4_RCC_APB1ENR1);
+
+#ifdef CONFIG_STM32L4_TIM2
+ /* TIM2 clock enable */
+
+ regval |= RCC_APB1ENR1_TIM2EN;
+#endif
+
+#ifdef CONFIG_STM32L4_TIM3
+ /* TIM3 clock enable */
+
+ regval |= RCC_APB1ENR1_TIM3EN;
+#endif
+
+#ifdef CONFIG_STM32L4_TIM6
+ /* TIM6 clock enable */
+
+ regval |= RCC_APB1ENR1_TIM6EN;
+#endif
+
+#ifdef CONFIG_STM32L4_TIM7
+ /* TIM7 clock enable */
+
+ regval |= RCC_APB1ENR1_TIM7EN;
+#endif
+
+#ifdef CONFIG_STM32L4_LCD
+ /* LCD clock enable */
+
+ regval |= RCC_APB1ENR1_LCDEN;
+#endif
+
+#ifdef CONFIG_STM32L4_SPI2
+ /* SPI2 clock enable */
+
+ regval |= RCC_APB1ENR1_SPI2EN;
+#endif
+
+#ifdef CONFIG_STM32L4_SPI3
+ /* SPI3 clock enable */
+
+ regval |= RCC_APB1ENR1_SPI3EN;
+#endif
+
+#ifdef CONFIG_STM32L4_USART2
+ /* USART 2 clock enable */
+
+ regval |= RCC_APB1ENR1_USART2EN;
+#endif
+
+#ifdef CONFIG_STM32L4_USART3
+ /* USART3 clock enable */
+
+ regval |= RCC_APB1ENR1_USART3EN;
+#endif
+
+#ifdef CONFIG_STM32L4_UART4
+ /* UART4 clock enable */
+
+ regval |= RCC_APB1ENR1_UART4EN;
+#endif
+
+#ifdef CONFIG_STM32L4_I2C1
+ /* I2C1 clock enable */
+
+ regval |= RCC_APB1ENR1_I2C1EN;
+#endif
+
+#ifdef CONFIG_STM32L4_I2C2
+ /* I2C2 clock enable */
+
+ regval |= RCC_APB1ENR1_I2C2EN;
+#endif
+
+#ifdef CONFIG_STM32L4_I2C3
+ /* I2C3 clock enable */
+
+ regval |= RCC_APB1ENR1_I2C3EN;
+#endif
+
+#ifdef CONFIG_STM32L4_CAN1
+ /* CAN 1 clock enable */
+
+ regval |= RCC_APB1ENR1_CAN1EN;
+#endif
+
+#ifdef CONFIG_STM32L4_USBFS
+ /* USB FS clock enable */
+
+ regval |= RCC_APB1ENR1_USBFSEN;
+#endif
+
+ /* Power interface clock enable. The PWR block is always enabled so that
+ * we can set the internal voltage regulator as required.
+ */
+
+ regval |= RCC_APB1ENR1_PWREN;
+
+#if defined (CONFIG_STM32L4_DAC1) || defined(CONFIG_STM32L4_DAC2)
+ /* DAC interface clock enable */
+
+ regval |= RCC_APB1ENR1_DACEN;
+#endif
+
+#ifdef CONFIG_STM32L4_OPAMP
+ /* OPAMP clock enable */
+
+ regval |= RCC_APB1ENR1_OPAMPEN;
+#endif
+
+#ifdef CONFIG_STM32L4_LPTIM1
+ /* Low power timer 1 clock enable */
+
+ regval |= RCC_APB1ENR1_LPTIM1EN;
+#endif
+
+ putreg32(regval, STM32L4_RCC_APB1ENR1); /* Enable peripherals */
+
+ /* Second APB1 register */
+
+ regval = getreg32(STM32L4_RCC_APB1ENR2);
+
+#ifdef CONFIG_STM32L4_LPUART1
+ /* Low power uart clock enable */
+
+ regval |= RCC_APB1ENR2_LPUART1EN;
+#endif
+
+#ifdef CONFIG_STM32L4_I2C4
+ /* I2C4 clock enable */
+
+ regval |= RCC_APB1ENR2_I2C4EN;
+#endif
+
+#ifdef CONFIG_STM32L4_SWPMI
+ /* Single-wire protocol master clock enable */
+
+ regval |= RCC_APB1ENR2_SWPMI1EN;
+#endif
+
+#ifdef CONFIG_STM32L4_LPTIM2
+ /* Low power timer 2 clock enable */
+
+ regval |= RCC_APB1ENR2_LPTIM2EN;
+#endif
+
+ putreg32(regval, STM32L4_RCC_APB1ENR2); /* Enable peripherals */
+}
+
+/****************************************************************************
+ * Name: rcc_enableapb2
+ *
+ * Description:
+ * Enable selected APB2 peripherals
+ *
+ ****************************************************************************/
+
+static inline void rcc_enableapb2(void)
+{
+ uint32_t regval;
+
+ /* Set the appropriate bits in the APB2ENR register to enabled the
+ * selected APB2 peripherals.
+ */
+
+ regval = getreg32(STM32L4_RCC_APB2ENR);
+
+#ifdef CONFIG_STM32L4_SYSCFG
+ /* System configuration controller clock enable */
+
+ regval |= RCC_APB2ENR_SYSCFGEN;
+#endif
+
+#ifdef CONFIG_STM32L4_FIREWALL
+ /* Firewall clock enable */
+
+ regval |= RCC_APB2ENR_FWEN;
+#endif
+
+#ifdef CONFIG_STM32L4_SDMMC
+ /* SDMMC clock enable */
+
+ regval |= RCC_APB2ENR_SDMMCEN;
+#endif
+
+#ifdef CONFIG_STM32L4_TIM1
+ /* TIM1 clock enable */
+
+ regval |= RCC_APB2ENR_TIM1EN;
+#endif
+
+#ifdef CONFIG_STM32L4_SPI1
+ /* SPI1 clock enable */
+
+ regval |= RCC_APB2ENR_SPI1EN;
+#endif
+
+#ifdef CONFIG_STM32L4_USART1
+ /* USART1 clock enable */
+
+ regval |= RCC_APB2ENR_USART1EN;
+#endif
+
+#ifdef CONFIG_STM32L4_TIM15
+ /* TIM15 clock enable */
+
+ regval |= RCC_APB2ENR_TIM15EN;
+#endif
+
+#ifdef CONFIG_STM32L4_TIM16
+ /* TIM16 clock enable */
+
+ regval |= RCC_APB2ENR_TIM16EN;
+#endif
+
+#ifdef CONFIG_STM32L4_SAI1
+ /* SAI1 clock enable */
+
+ regval |= RCC_APB2ENR_SAI1EN;
+#endif
+
+#ifdef CONFIG_STM32L4_DFSDM1
+ /* DFSDM clock enable */
+
+ regval |= RCC_APB2ENR_DFSDMEN;
+#endif
+
+ putreg32(regval, STM32L4_RCC_APB2ENR); /* Enable peripherals */
+}
+
+/****************************************************************************
+ * Name: stm32l4_stdclockconfig
+ *
+ * Description:
+ * Called to change to new clock based on settings in board.h
+ *
+ * NOTE: This logic would need to be extended if you need to select low-
+ * power clocking modes!
+ ****************************************************************************/
+
+#ifndef CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG
+static void stm32l4_stdclockconfig(void)
+{
+ uint32_t regval;
+ volatile int32_t timeout;
+
+#ifdef STM32L4_BOARD_USEHSI
+ /* Enable Internal High-Speed Clock (HSI) */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval |= RCC_CR_HSION; /* Enable HSI */
+ putreg32(regval, STM32L4_RCC_CR);
+
+ /* Wait until the HSI is ready (or until a timeout elapsed) */
+
+ for (timeout = HSIRDY_TIMEOUT; timeout > 0; timeout--)
+ {
+ /* Check if the HSIRDY flag is the set in the CR */
+
+ if ((getreg32(STM32L4_RCC_CR) & RCC_CR_HSIRDY) != 0)
+ {
+ /* If so, then break-out with timeout > 0 */
+
+ break;
+ }
+ }
+
+#elif defined(STM32L4_BOARD_USEMSI)
+ /* Enable Internal Multi-Speed Clock (MSI) */
+
+ /* Wait until the MSI is either off or ready (or until a timeout elapsed) */
+
+ for (timeout = MSIRDY_TIMEOUT; timeout > 0; timeout--)
+ {
+ if ((regval = getreg32(STM32L4_RCC_CR)), (regval & RCC_CR_MSIRDY) || ~(regval & RCC_CR_MSION))
+ {
+ /* If so, then break-out with timeout > 0 */
+
+ break;
+ }
+ }
+
+ /* setting MSIRANGE */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval |= (STM32L4_BOARD_MSIRANGE | RCC_CR_MSION); /* Enable MSI and frequency */
+ putreg32(regval, STM32L4_RCC_CR);
+
+ /* Wait until the MSI is ready (or until a timeout elapsed) */
+
+ for (timeout = MSIRDY_TIMEOUT; timeout > 0; timeout--)
+ {
+ /* Check if the MSIRDY flag is the set in the CR */
+
+ if ((getreg32(STM32L4_RCC_CR) & RCC_CR_MSIRDY) != 0)
+ {
+ /* If so, then break-out with timeout > 0 */
+
+ break;
+ }
+ }
+
+#elif defined(STM32L4_BOARD_USEHSE)
+ /* Enable External High-Speed Clock (HSE) */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval |= RCC_CR_HSEON; /* Enable HSE */
+ putreg32(regval, STM32L4_RCC_CR);
+
+ /* Wait until the HSE is ready (or until a timeout elapsed) */
+
+ for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--)
+ {
+ /* Check if the HSERDY flag is the set in the CR */
+
+ if ((getreg32(STM32L4_RCC_CR) & RCC_CR_HSERDY) != 0)
+ {
+ /* If so, then break-out with timeout > 0 */
+
+ break;
+ }
+ }
+#else
+
+# error stm32l4_stdclockconfig(), must have one of STM32L4_BOARD_USEHSI, STM32L4_BOARD_USEMSI, STM32L4_BOARD_USEHSE defined
+
+#endif
+
+ /* Check for a timeout. If this timeout occurs, then we are hosed. We
+ * have no real back-up plan, although the following logic makes it look
+ * as though we do.
+ */
+
+ if (timeout > 0)
+ {
+#warning todo: regulator voltage according to clock freq
+#if 0
+ /* Ensure Power control is enabled before modifying it. */
+
+ regval = getreg32(STM32L4_RCC_APB1ENR);
+ regval |= RCC_APB1ENR_PWREN;
+ putreg32(regval, STM32L4_RCC_APB1ENR);
+
+ /* Select regulator voltage output Scale 1 mode to support system
+ * frequencies up to 168 MHz.
+ */
+
+ regval = getreg32(STM32L4_PWR_CR);
+ regval &= ~PWR_CR_VOS_MASK;
+ regval |= PWR_CR_VOS_SCALE_1;
+ putreg32(regval, STM32L4_PWR_CR);
+#endif
+
+ /* Set the HCLK source/divider */
+
+ regval = getreg32(STM32L4_RCC_CFGR);
+ regval &= ~RCC_CFGR_HPRE_MASK;
+ regval |= STM32L4_RCC_CFGR_HPRE;
+ putreg32(regval, STM32L4_RCC_CFGR);
+
+ /* Set the PCLK2 divider */
+
+ regval = getreg32(STM32L4_RCC_CFGR);
+ regval &= ~RCC_CFGR_PPRE2_MASK;
+ regval |= STM32L4_RCC_CFGR_PPRE2;
+ putreg32(regval, STM32L4_RCC_CFGR);
+
+ /* Set the PCLK1 divider */
+
+ regval = getreg32(STM32L4_RCC_CFGR);
+ regval &= ~RCC_CFGR_PPRE1_MASK;
+ regval |= STM32L4_RCC_CFGR_PPRE1;
+ putreg32(regval, STM32L4_RCC_CFGR);
+
+#ifdef CONFIG_RTC_HSECLOCK
+ /* Set the RTC clock divisor */
+
+ regval = getreg32(STM32L4_RCC_CFGR);
+ regval &= ~RCC_CFGR_RTCPRE_MASK;
+ regval |= RCC_CFGR_RTCPRE(HSE_DIVISOR);
+ putreg32(regval, STM32L4_RCC_CFGR);
+#endif
+
+ /* Set the PLL source and main divider */
+
+ regval = getreg32(STM32L4_RCC_PLLCFG);
+
+ /* Configure Main PLL */
+
+ /* Set the PLL dividers and multipliers to configure the main PLL */
+
+ regval = (STM32L4_PLLCFG_PLLM | STM32L4_PLLCFG_PLLN | STM32L4_PLLCFG_PLLP
+ | STM32L4_PLLCFG_PLLQ | STM32L4_PLLCFG_PLLR);
+
+#ifdef STM32L4_PLLCFG_PLLP_ENABLED
+ regval |= RCC_PLLCFG_PLLPEN;
+#endif
+#ifdef STM32L4_PLLCFG_PLLQ_ENABLED
+ regval |= RCC_PLLCFG_PLLQEN;
+#endif
+#ifdef STM32L4_PLLCFG_PLLR_ENABLED
+ regval |= RCC_PLLCFG_PLLREN;
+#endif
+
+ /* XXX The choice of clock source to PLL (all three) is independent
+ * of the sys clock source choice, review the STM32L4_BOARD_USEHSI
+ * name; probably split it into two, one for PLL source and one
+ * for sys clock source.
+ */
+
+#ifdef STM32L4_BOARD_USEHSI
+ regval |= RCC_PLLCFG_PLLSRC_HSI;
+#elif defined(STM32L4_BOARD_USEMSI)
+ regval |= RCC_PLLCFG_PLLSRC_MSI;
+#else /* if STM32L4_BOARD_USEHSE */
+ regval |= RCC_PLLCFG_PLLSRC_HSE;
+#endif
+
+ putreg32(regval, STM32L4_RCC_PLLCFG);
+
+ /* Enable the main PLL */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval |= RCC_CR_PLLON;
+ putreg32(regval, STM32L4_RCC_CR);
+
+ /* Wait until the PLL is ready */
+
+ while ((getreg32(STM32L4_RCC_CR) & RCC_CR_PLLRDY) == 0)
+ {
+ }
+
+#ifdef CONFIG_STM32L4_SAI1PLL
+ /* Configure SAI1 PLL */
+
+ regval = getreg32(STM32L4_RCC_PLLSAI1CFG);
+
+ /* Set the PLL dividers and multipliers to configure the SAI1 PLL */
+
+ regval = (STM32L4_PLLSAI1CFG_PLLN | STM32L4_PLLSAI1CFG_PLLP
+ | STM32L4_PLLSAI1CFG_PLLQ | STM32L4_PLLSAI1CFG_PLLR);
+
+#ifdef STM32L4_PLLSAI1CFG_PLLP_ENABLED
+ regval |= RCC_PLLSAI1CFG_PLLPEN;
+#endif
+#ifdef STM32L4_PLLSAI1CFG_PLLQ_ENABLED
+ regval |= RCC_PLLSAI1CFG_PLLQEN;
+#endif
+#ifdef STM32L4_PLLSAI1CFG_PLLR_ENABLED
+ regval |= RCC_PLLSAI1CFG_PLLREN;
+#endif
+
+ putreg32(regval, STM32L4_RCC_PLLSAI1CFG);
+
+ /* Enable the SAI1 PLL */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval |= RCC_CR_PLLSAI1ON;
+ putreg32(regval, STM32L4_RCC_CR);
+
+ /* Wait until the PLL is ready */
+
+ while ((getreg32(STM32L4_RCC_CR) & RCC_CR_PLLSAI1RDY) == 0)
+ {
+ }
+#endif
+
+#ifdef CONFIG_STM32L4_SAI2PLL
+ /* Configure SAI2 PLL */
+
+ regval = getreg32(STM32L4_RCC_PLLSAI2CFG);
+
+ /* Set the PLL dividers and multipliers to configure the SAI2 PLL */
+
+ regval = (STM32L4_PLLSAI2CFG_PLLN | STM32L4_PLLSAI2CFG_PLLP |
+ STM32L4_PLLSAI2CFG_PLLR);
+
+#ifdef STM32L4_PLLSAI2CFG_PLLP_ENABLED
+ regval |= RCC_PLLSAI2CFG_PLLPEN;
+#endif
+#ifdef STM32L4_PLLSAI2CFG_PLLR_ENABLED
+ regval |= RCC_PLLSAI2CFG_PLLREN;
+#endif
+
+ putreg32(regval, STM32L4_RCC_PLLSAI2CFG);
+
+ /* Enable the SAI2 PLL */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval |= RCC_CR_PLLSAI2ON;
+ putreg32(regval, STM32L4_RCC_CR);
+
+ /* Wait until the PLL is ready */
+
+ while ((getreg32(STM32L4_RCC_CR) & RCC_CR_PLLSAI2RDY) == 0)
+ {
+ }
+#endif
+
+ /* Enable FLASH prefetch, instruction cache, data cache, and 4 wait states */
+
+#ifdef CONFIG_STM32L4_FLASH_PREFETCH
+ regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN);
+#else
+ regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN);
+#endif
+ putreg32(regval, STM32L4_FLASH_ACR);
+
+ /* Select the main PLL as system clock source */
+
+ regval = getreg32(STM32L4_RCC_CFGR);
+ regval &= ~RCC_CFGR_SW_MASK;
+ regval |= RCC_CFGR_SW_PLL;
+ putreg32(regval, STM32L4_RCC_CFGR);
+
+ /* Wait until the PLL source is used as the system clock source */
+
+ while ((getreg32(STM32L4_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL)
+ {
+ }
+
+#if defined(CONFIG_STM32L4_IWDG) || defined(CONFIG_RTC_LSICLOCK)
+ /* Low speed internal clock source LSI */
+
+ stm32l4_rcc_enablelsi();
+#endif
+
+#if defined(STM32L4_USE_LSE)
+ /* Low speed external clock source LSE
+ *
+ * TODO: There is another case where the LSE needs to
+ * be enabled: if the MCO1 pin selects LSE as source.
+ * XXX and other cases, like automatic trimming of MSI for USB use
+ */
+
+ /* ensure Power control is enabled since it is indirectly required
+ * to alter the LSE parameters.
+ */
+ stm32l4_pwr_enableclk(true);
+
+ /* XXX other LSE settings must be made before turning on the oscillator
+ * and we need to ensure it is first off before doing so.
+ */
+
+ /* Turn on the LSE oscillator
+ * XXX this will almost surely get moved since we also want to use
+ * this for automatically trimming MSI, etc.
+ */
+
+ stm32l4_rcc_enablelse();
+
+# if defined(STM32L4_BOARD_USEMSI)
+ /* Now that LSE is up, auto trim the MSI */
+
+ regval = getreg32(STM32L4_RCC_CR);
+ regval |= RCC_CR_MSIPLLEN;
+ putreg32(regval, STM32L4_RCC_CR);
+# endif
+#endif
+
+#if defined(STM32L4_USE_CLK48)
+ /* XXX sanity if sdmmc1 or usb or rng, then we need to set the clk48 source
+ * and then we can also do away with STM32L4_USE_CLK48, and give better
+ * warning messages
+ *
+ * XXX sanity if our STM32L4_CLK48_SEL is YYY then we need to have already
+ * enabled ZZZ
+ */
+
+ regval = getreg32(STM32L4_RCC_CCIPR);
+ regval &= RCC_CCIPR_CLK48SEL_MASK;
+ regval |= STM32L4_CLK48_SEL;
+ putreg32(regval, STM32L4_RCC_CCIPR);
+#endif
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: rcc_enableperipherals
+ ****************************************************************************/
+
+static inline void rcc_enableperipherals(void)
+{
+ rcc_enableahb1();
+ rcc_enableahb2();
+ rcc_enableahb3();
+ rcc_enableapb1();
+ rcc_enableapb2();
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
diff --git a/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c
index 08344fa0ba6..3b174177402 100644
--- a/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c
+++ b/arch/arm/src/stm32l4/stm32l4x6xx_rcc.c
@@ -277,7 +277,7 @@ static inline void rcc_enableahb3(void)
#ifdef CONFIG_STM32L4_FSMC
/* Flexible static memory controller module clock enable */
- regval |= RCC_AHB3ENR_FMCEN;
+ regval |= RCC_AHB3ENR_FSMCEN;
#endif
@@ -563,7 +563,7 @@ static inline void rcc_enableapb2(void)
regval |= RCC_APB2ENR_SAI2EN;
#endif
-#ifdef CONFIG_STM32L4_DFSDM
+#ifdef CONFIG_STM32L4_DFSDM1
/* DFSDM clock enable */
regval |= RCC_APB2ENR_DFSDMEN;
@@ -814,7 +814,6 @@ static void stm32l4_stdclockconfig(void)
regval = getreg32(STM32L4_RCC_PLLSAI2CFG);
- /* Enable the SAI2 PLL */
/* Set the PLL dividers and multipliers to configure the SAI2 PLL */
regval = (STM32L4_PLLSAI2CFG_PLLN | STM32L4_PLLSAI2CFG_PLLP |
@@ -829,7 +828,7 @@ static void stm32l4_stdclockconfig(void)
putreg32(regval, STM32L4_RCC_PLLSAI2CFG);
- /* Enable the SAI1 PLL */
+ /* Enable the SAI2 PLL */
regval = getreg32(STM32L4_RCC_CR);
regval |= RCC_CR_PLLSAI2ON;
@@ -842,7 +841,7 @@ static void stm32l4_stdclockconfig(void)
}
#endif
- /* Enable FLASH prefetch, instruction cache, data cache, and 5 wait states */
+ /* Enable FLASH prefetch, instruction cache, data cache, and 4 wait states */
#ifdef CONFIG_STM32L4_FLASH_PREFETCH
regval = (FLASH_ACR_LATENCY_4 | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN);
diff --git a/configs/Kconfig b/configs/Kconfig
index 6daffc80e0a..d61c7ef8793 100644
--- a/configs/Kconfig
+++ b/configs/Kconfig
@@ -810,6 +810,15 @@ config ARCH_BOARD_NUCLEO_F411RE
This is a minimal configuration that supports low-level test of the
Nucleo F411RE in the NuttX source tree.
+config ARCH_BOARD_NUCLEO_L452RE
+ bool "STM32L452 Nucleo L452RE"
+ depends on ARCH_CHIP_STM32L452RE
+ select ARCH_HAVE_LEDS
+ select ARCH_HAVE_BUTTONS
+ select ARCH_HAVE_IRQBUTTONS
+ ---help---
+ STMicro Nucleo L452RE board based on the STMicro STM32L452RET6 MCU.
+
config ARCH_BOARD_NUCLEO_L476RG
bool "STM32L476 Nucleo L476RG"
depends on ARCH_CHIP_STM32L476RG
@@ -1557,6 +1566,7 @@ config ARCH_BOARD
default "nucleo-f303re" if ARCH_BOARD_NUCLEO_F303RE
default "nucleo-f334r8" if ARCH_BOARD_NUCLEO_F334R8
default "nucleo-f4x1re" if ARCH_BOARD_NUCLEO_F401RE || ARCH_BOARD_NUCLEO_F411RE
+ default "nucleo-l452re" if ARCH_BOARD_NUCLEO_L452RE
default "nucleo-l476rg" if ARCH_BOARD_NUCLEO_L476RG
default "nucleo-l496zg" if ARCH_BOARD_NUCLEO_L496ZG
default "qemu-i486" if ARCH_BOARD_QEMU_I486
@@ -1876,6 +1886,9 @@ endif
if ARCH_BOARD_NUCLEO_F401RE || ARCH_BOARD_NUCLEO_F411RE
source "configs/nucleo-f4x1re/Kconfig"
endif
+if ARCH_BOARD_NUCLEO_L452RE
+source "configs/nucleo-l452re/Kconfig"
+endif
if ARCH_BOARD_NUCLEO_L476RG
source "configs/nucleo-l476rg/Kconfig"
endif
diff --git a/configs/clicker2-stm32/Kconfig b/configs/clicker2-stm32/Kconfig
index 1ca0fbc9eef..9344f015da4 100644
--- a/configs/clicker2-stm32/Kconfig
+++ b/configs/clicker2-stm32/Kconfig
@@ -19,4 +19,20 @@ config CLICKER2_STM32_MB2_SPI
---help---
Enable SPI support on mikroBUS1 (STM32 SPI2)
+config CLICKER2_STM32_MB1_BEE
+ bool "mikroBUS1 MRF24J40 BEE"
+ default y
+ depends on IEEE802154_MRF24J40
+ select CLICKER2_STM32_MB1_SPI
+ ---help---
+ Enable support for MRF24J40 BEE on mikroBUS1
+
+config CLICKER2_STM32_MB2_BEE
+ bool "mikroBUS2 MRF24J40 BEE"
+ default n
+ depends on IEEE802154_MRF24J40
+ select CLICKER2_STM32_MB2_SPI
+ ---help---
+ Enable support for MRF24J40 BEE on mikroBUS2
+
endif # ARCH_BOARD_CLICKER2_STM32
diff --git a/configs/clicker2-stm32/README.txt b/configs/clicker2-stm32/README.txt
index bcc2cc93f63..d2892192e84 100644
--- a/configs/clicker2-stm32/README.txt
+++ b/configs/clicker2-stm32/README.txt
@@ -304,6 +304,48 @@ Configurations
If you do this a lot, you will probably want to invest a little time
to develop a tool to automate these steps.
+ mrf24j40-radio
+
+ This is a version of nsh that was used for testing the MRF24J40 be as a
+ character device. The most important configuration differences are
+ summarized below:
+
+ 1. Support for the BEE click and SPI are in enabled in the mikroBUS1 slot:
+
+ CONFIG_CLICKER2_STM32_MB1_BEE=y
+ CONFIG_CLICKER2_STM32_MB1_SPI=y
+
+ 2. SPI support and STM32 SPI3, in particular, are enabled:
+
+ CONFIG_SPI=y
+ CONFIG_SPI_EXCHANGE=y
+
+ CONFIG_STM32_SPI=y
+ CONFIG_STM32_SPI3=y
+
+ 4. Support for the IEEE802.15.4 "upper half" character driver is enabled:
+
+ CONFIG_WIRELESS=y
+ CONFIG_WIRELESS_IEEE802154=y
+ CONFIG_IEEE802154_DEV=y
+
+ 5. Support for the lower half MRF24J40 character driver is enabled
+
+ CONFIG_DRIVERS_WIRELESS=y
+ CONFIG_DRIVERS_IEEE802154=y
+ CONFIG_IEEE802154_MRF24J40=y
+
+ 6. Support for the test program at apps/ieee802154 is enabled:
+
+ CONFIG_IEEE802154_COMMON=y
+ CONFIG_IEEE802154_COORD=y
+ CONFIG_IEEE802154_I8SAK=y
+
+ 7. Initialization hooks are provided to enable the MRF24J40 and to
+ register the radio character driver.
+
+ CONFIG_NSH_ARCHINIT=y
+
nsh:
Configures the NuttShell (nsh) located at examples/nsh. This
diff --git a/configs/clicker2-stm32/mrf24j40-radio/Make.defs b/configs/clicker2-stm32/mrf24j40-radio/Make.defs
new file mode 100644
index 00000000000..4aa245f38b7
--- /dev/null
+++ b/configs/clicker2-stm32/mrf24j40-radio/Make.defs
@@ -0,0 +1,122 @@
+############################################################################
+# configs/clicker2-stm32/mrf24j40-radio/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 ${TOPDIR}/.config
+include ${TOPDIR}/tools/Config.mk
+include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
+
+LDSCRIPT = flash.ld
+
+ifeq ($(WINTOOL),y)
+ # Windows-native toolchains
+ DIRLINK = $(TOPDIR)/tools/copydir.sh
+ DIRUNLINK = $(TOPDIR)/tools/unlink.sh
+ MKDEP = $(TOPDIR)/tools/mkwindeps.sh
+ ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
+ ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
+ ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
+else
+ # Linux/Cygwin-native toolchain
+ MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
+ ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
+ ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
+ ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
+endif
+
+CC = $(CROSSDEV)gcc
+CXX = $(CROSSDEV)g++
+CPP = $(CROSSDEV)gcc -E
+LD = $(CROSSDEV)ld
+AR = $(CROSSDEV)ar rcs
+NM = $(CROSSDEV)nm
+OBJCOPY = $(CROSSDEV)objcopy
+OBJDUMP = $(CROSSDEV)objdump
+
+ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
+ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
+
+ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
+ ARCHOPTIMIZATION = -g
+endif
+
+ifneq ($(CONFIG_DEBUG_NOOPT),y)
+ ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer
+endif
+
+ARCHCFLAGS = -fno-builtin
+ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti
+ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
+ARCHWARNINGSXX = -Wall -Wshadow -Wundef
+ARCHDEFINES =
+ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
+
+CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
+CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
+CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
+AFLAGS = $(CFLAGS) -D__ASSEMBLY__
+
+NXFLATLDFLAGS1 = -r -d -warn-common
+NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-gotoff.ld -no-check-sections
+LDNXFLATFLAGS = -e main -s 2048
+
+# Loadable module definitions
+
+CMODULEFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
+
+LDMODULEFLAGS = -r -e module_initialize
+ifeq ($(WINTOOL),y)
+ LDMODULEFLAGS += -T "${shell cygpath -w $(TOPDIR)/libc/modlib/gnu-elf.ld}"
+else
+ LDMODULEFLAGS += -T $(TOPDIR)/libc/modlib/gnu-elf.ld
+endif
+
+ASMEXT = .S
+OBJEXT = .o
+LIBEXT = .a
+EXEEXT =
+
+ifneq ($(CROSSDEV),arm-nuttx-elf-)
+ LDFLAGS += -nostartfiles -nodefaultlibs
+endif
+ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
+ LDFLAGS += -g
+endif
+
+HOSTCC = gcc
+HOSTINCLUDES = -I.
+HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe
+HOSTLDFLAGS =
diff --git a/configs/clicker2-stm32/mrf24j40-radio/defconfig b/configs/clicker2-stm32/mrf24j40-radio/defconfig
new file mode 100644
index 00000000000..33284b022cd
--- /dev/null
+++ b/configs/clicker2-stm32/mrf24j40-radio/defconfig
@@ -0,0 +1,1355 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Nuttx/ Configuration
+#
+
+#
+# Build Setup
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_DEFAULT_SMALL is not set
+CONFIG_HOST_LINUX=y
+# CONFIG_HOST_OSX is not set
+# CONFIG_HOST_WINDOWS is not set
+# CONFIG_HOST_OTHER is not set
+
+#
+# Build Configuration
+#
+# CONFIG_APPS_DIR="../apps"
+CONFIG_BUILD_FLAT=y
+# CONFIG_BUILD_2PASS is not set
+
+#
+# Binary Output Formats
+#
+# CONFIG_RRLOAD_BINARY is not set
+CONFIG_INTELHEX_BINARY=y
+# CONFIG_MOTOROLA_SREC is not set
+CONFIG_RAW_BINARY=y
+# CONFIG_UBOOT_UIMAGE is not set
+
+#
+# Customize Header Files
+#
+# CONFIG_ARCH_STDINT_H is not set
+# CONFIG_ARCH_STDBOOL_H is not set
+# CONFIG_ARCH_MATH_H is not set
+# CONFIG_ARCH_FLOAT_H is not set
+# CONFIG_ARCH_STDARG_H is not set
+# CONFIG_ARCH_DEBUG_H is not set
+
+#
+# Debug Options
+#
+CONFIG_DEBUG_ALERT=y
+# CONFIG_DEBUG_FEATURES is not set
+CONFIG_ARCH_HAVE_STACKCHECK=y
+# CONFIG_STACK_COLORATION is not set
+CONFIG_ARCH_HAVE_HEAPCHECK=y
+# CONFIG_HEAP_COLORATION is not set
+# CONFIG_DEBUG_SYMBOLS is not set
+CONFIG_ARCH_HAVE_CUSTOMOPT=y
+# CONFIG_DEBUG_NOOPT is not set
+# CONFIG_DEBUG_CUSTOMOPT is not set
+CONFIG_DEBUG_FULLOPT=y
+
+#
+# System Type
+#
+CONFIG_ARCH_ARM=y
+# CONFIG_ARCH_AVR is not set
+# CONFIG_ARCH_HC is not set
+# CONFIG_ARCH_MIPS is not set
+# CONFIG_ARCH_MISOC is not set
+# CONFIG_ARCH_RENESAS is not set
+# CONFIG_ARCH_RISCV is not set
+# CONFIG_ARCH_SIM is not set
+# CONFIG_ARCH_X86 is not set
+# CONFIG_ARCH_XTENSA is not set
+# CONFIG_ARCH_Z16 is not set
+# CONFIG_ARCH_Z80 is not set
+CONFIG_ARCH="arm"
+
+#
+# ARM Options
+#
+# CONFIG_ARCH_CHIP_A1X is not set
+# CONFIG_ARCH_CHIP_C5471 is not set
+# CONFIG_ARCH_CHIP_DM320 is not set
+# CONFIG_ARCH_CHIP_EFM32 is not set
+# CONFIG_ARCH_CHIP_IMX1 is not set
+# CONFIG_ARCH_CHIP_IMX6 is not set
+# CONFIG_ARCH_CHIP_KINETIS is not set
+# CONFIG_ARCH_CHIP_KL is not set
+# CONFIG_ARCH_CHIP_LM is not set
+# CONFIG_ARCH_CHIP_TIVA is not set
+# CONFIG_ARCH_CHIP_LPC11XX is not set
+# CONFIG_ARCH_CHIP_LPC17XX is not set
+# CONFIG_ARCH_CHIP_LPC214X is not set
+# CONFIG_ARCH_CHIP_LPC2378 is not set
+# CONFIG_ARCH_CHIP_LPC31XX is not set
+# CONFIG_ARCH_CHIP_LPC43XX is not set
+# CONFIG_ARCH_CHIP_MOXART is not set
+# CONFIG_ARCH_CHIP_NUC1XX is not set
+# CONFIG_ARCH_CHIP_SAMA5 is not set
+# CONFIG_ARCH_CHIP_SAMD is not set
+# CONFIG_ARCH_CHIP_SAML is not set
+# CONFIG_ARCH_CHIP_SAM34 is not set
+# CONFIG_ARCH_CHIP_SAMV7 is not set
+CONFIG_ARCH_CHIP_STM32=y
+# CONFIG_ARCH_CHIP_STM32F7 is not set
+# CONFIG_ARCH_CHIP_STM32L4 is not set
+# CONFIG_ARCH_CHIP_STR71X is not set
+# CONFIG_ARCH_CHIP_TMS570 is not set
+# CONFIG_ARCH_CHIP_XMC4 is not set
+# CONFIG_ARCH_ARM7TDMI is not set
+# CONFIG_ARCH_ARM926EJS is not set
+# CONFIG_ARCH_ARM920T is not set
+# CONFIG_ARCH_CORTEXM0 is not set
+# CONFIG_ARCH_CORTEXM23 is not set
+# CONFIG_ARCH_CORTEXM3 is not set
+# CONFIG_ARCH_CORTEXM33 is not set
+CONFIG_ARCH_CORTEXM4=y
+# CONFIG_ARCH_CORTEXM7 is not set
+# CONFIG_ARCH_CORTEXA5 is not set
+# CONFIG_ARCH_CORTEXA8 is not set
+# CONFIG_ARCH_CORTEXA9 is not set
+# CONFIG_ARCH_CORTEXR4 is not set
+# CONFIG_ARCH_CORTEXR4F is not set
+# CONFIG_ARCH_CORTEXR5 is not set
+# CONFIG_ARCH_CORTEX5F is not set
+# CONFIG_ARCH_CORTEXR7 is not set
+# CONFIG_ARCH_CORTEXR7F is not set
+CONFIG_ARCH_FAMILY="armv7-m"
+CONFIG_ARCH_CHIP="stm32"
+# CONFIG_ARM_TOOLCHAIN_IAR is not set
+CONFIG_ARM_TOOLCHAIN_GNU=y
+# CONFIG_ARMV7M_USEBASEPRI is not set
+CONFIG_ARCH_HAVE_CMNVECTOR=y
+# CONFIG_ARMV7M_CMNVECTOR is not set
+# CONFIG_ARMV7M_LAZYFPU is not set
+CONFIG_ARCH_HAVE_FPU=y
+# CONFIG_ARCH_HAVE_DPFPU is not set
+CONFIG_ARCH_FPU=y
+# CONFIG_ARCH_HAVE_TRUSTZONE is not set
+CONFIG_ARM_HAVE_MPU_UNIFIED=y
+# CONFIG_ARM_MPU is not set
+
+#
+# ARMV7M Configuration Options
+#
+# CONFIG_ARMV7M_HAVE_ICACHE is not set
+# CONFIG_ARMV7M_HAVE_DCACHE is not set
+# CONFIG_ARMV7M_HAVE_ITCM is not set
+# CONFIG_ARMV7M_HAVE_DTCM is not set
+# CONFIG_ARMV7M_TOOLCHAIN_IARL is not set
+# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
+# CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set
+# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set
+CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y
+CONFIG_ARMV7M_HAVE_STACKCHECK=y
+# CONFIG_ARMV7M_STACKCHECK is not set
+# CONFIG_ARMV7M_ITMSYSLOG is not set
+# CONFIG_SERIAL_TERMIOS is not set
+
+#
+# STM32 Configuration Options
+#
+# CONFIG_ARCH_CHIP_STM32L151C6 is not set
+# CONFIG_ARCH_CHIP_STM32L151C8 is not set
+# CONFIG_ARCH_CHIP_STM32L151CB is not set
+# CONFIG_ARCH_CHIP_STM32L151R6 is not set
+# CONFIG_ARCH_CHIP_STM32L151R8 is not set
+# CONFIG_ARCH_CHIP_STM32L151RB is not set
+# CONFIG_ARCH_CHIP_STM32L151V6 is not set
+# CONFIG_ARCH_CHIP_STM32L151V8 is not set
+# CONFIG_ARCH_CHIP_STM32L151VB is not set
+# CONFIG_ARCH_CHIP_STM32L152C6 is not set
+# CONFIG_ARCH_CHIP_STM32L152C8 is not set
+# CONFIG_ARCH_CHIP_STM32L152CB is not set
+# CONFIG_ARCH_CHIP_STM32L152R6 is not set
+# CONFIG_ARCH_CHIP_STM32L152R8 is not set
+# CONFIG_ARCH_CHIP_STM32L152RB is not set
+# CONFIG_ARCH_CHIP_STM32L152V6 is not set
+# CONFIG_ARCH_CHIP_STM32L152V8 is not set
+# CONFIG_ARCH_CHIP_STM32L152VB is not set
+# CONFIG_ARCH_CHIP_STM32L162ZD is not set
+# CONFIG_ARCH_CHIP_STM32L162VE is not set
+# CONFIG_ARCH_CHIP_STM32F100C8 is not set
+# CONFIG_ARCH_CHIP_STM32F100CB is not set
+# CONFIG_ARCH_CHIP_STM32F100R8 is not set
+# CONFIG_ARCH_CHIP_STM32F100RB is not set
+# CONFIG_ARCH_CHIP_STM32F100RC is not set
+# CONFIG_ARCH_CHIP_STM32F100RD is not set
+# CONFIG_ARCH_CHIP_STM32F100RE is not set
+# CONFIG_ARCH_CHIP_STM32F100V8 is not set
+# CONFIG_ARCH_CHIP_STM32F100VB is not set
+# CONFIG_ARCH_CHIP_STM32F100VC is not set
+# CONFIG_ARCH_CHIP_STM32F100VD is not set
+# CONFIG_ARCH_CHIP_STM32F100VE is not set
+# CONFIG_ARCH_CHIP_STM32F102CB is not set
+# CONFIG_ARCH_CHIP_STM32F103T8 is not set
+# CONFIG_ARCH_CHIP_STM32F103TB is not set
+# CONFIG_ARCH_CHIP_STM32F103C4 is not set
+# CONFIG_ARCH_CHIP_STM32F103C8 is not set
+# CONFIG_ARCH_CHIP_STM32F103CB is not set
+# CONFIG_ARCH_CHIP_STM32F103R8 is not set
+# CONFIG_ARCH_CHIP_STM32F103RB is not set
+# CONFIG_ARCH_CHIP_STM32F103RC is not set
+# CONFIG_ARCH_CHIP_STM32F103RD is not set
+# CONFIG_ARCH_CHIP_STM32F103RE is not set
+# CONFIG_ARCH_CHIP_STM32F103RG is not set
+# CONFIG_ARCH_CHIP_STM32F103V8 is not set
+# CONFIG_ARCH_CHIP_STM32F103VB is not set
+# CONFIG_ARCH_CHIP_STM32F103VC is not set
+# CONFIG_ARCH_CHIP_STM32F103VE is not set
+# CONFIG_ARCH_CHIP_STM32F103ZE is not set
+# CONFIG_ARCH_CHIP_STM32F105VB is not set
+# CONFIG_ARCH_CHIP_STM32F105RB is not set
+# CONFIG_ARCH_CHIP_STM32F107VC is not set
+# CONFIG_ARCH_CHIP_STM32F205RG is not set
+# CONFIG_ARCH_CHIP_STM32F207IG is not set
+# CONFIG_ARCH_CHIP_STM32F207ZE is not set
+# CONFIG_ARCH_CHIP_STM32F302K6 is not set
+# CONFIG_ARCH_CHIP_STM32F302K8 is not set
+# CONFIG_ARCH_CHIP_STM32F302CB is not set
+# CONFIG_ARCH_CHIP_STM32F302CC is not set
+# CONFIG_ARCH_CHIP_STM32F302RB is not set
+# CONFIG_ARCH_CHIP_STM32F302RC is not set
+# CONFIG_ARCH_CHIP_STM32F302VB is not set
+# CONFIG_ARCH_CHIP_STM32F302VC is not set
+# CONFIG_ARCH_CHIP_STM32F303K6 is not set
+# CONFIG_ARCH_CHIP_STM32F303K8 is not set
+# CONFIG_ARCH_CHIP_STM32F303C6 is not set
+# CONFIG_ARCH_CHIP_STM32F303C8 is not set
+# CONFIG_ARCH_CHIP_STM32F303CB is not set
+# CONFIG_ARCH_CHIP_STM32F303CC is not set
+# CONFIG_ARCH_CHIP_STM32F303RB is not set
+# CONFIG_ARCH_CHIP_STM32F303RC is not set
+# CONFIG_ARCH_CHIP_STM32F303RD is not set
+# CONFIG_ARCH_CHIP_STM32F303RE is not set
+# CONFIG_ARCH_CHIP_STM32F303VB is not set
+# CONFIG_ARCH_CHIP_STM32F303VC is not set
+# CONFIG_ARCH_CHIP_STM32F334K4 is not set
+# CONFIG_ARCH_CHIP_STM32F334K6 is not set
+# CONFIG_ARCH_CHIP_STM32F334K8 is not set
+# CONFIG_ARCH_CHIP_STM32F334C4 is not set
+# CONFIG_ARCH_CHIP_STM32F334C6 is not set
+# CONFIG_ARCH_CHIP_STM32F334C8 is not set
+# CONFIG_ARCH_CHIP_STM32F334R4 is not set
+# CONFIG_ARCH_CHIP_STM32F334R6 is not set
+# CONFIG_ARCH_CHIP_STM32F334R8 is not set
+# CONFIG_ARCH_CHIP_STM32F372C8 is not set
+# CONFIG_ARCH_CHIP_STM32F372R8 is not set
+# CONFIG_ARCH_CHIP_STM32F372V8 is not set
+# CONFIG_ARCH_CHIP_STM32F372CB is not set
+# CONFIG_ARCH_CHIP_STM32F372RB is not set
+# CONFIG_ARCH_CHIP_STM32F372VB is not set
+# CONFIG_ARCH_CHIP_STM32F372CC is not set
+# CONFIG_ARCH_CHIP_STM32F372RC is not set
+# CONFIG_ARCH_CHIP_STM32F372VC is not set
+# CONFIG_ARCH_CHIP_STM32F373C8 is not set
+# CONFIG_ARCH_CHIP_STM32F373R8 is not set
+# CONFIG_ARCH_CHIP_STM32F373V8 is not set
+# CONFIG_ARCH_CHIP_STM32F373CB is not set
+# CONFIG_ARCH_CHIP_STM32F373RB is not set
+# CONFIG_ARCH_CHIP_STM32F373VB is not set
+# CONFIG_ARCH_CHIP_STM32F373CC is not set
+# CONFIG_ARCH_CHIP_STM32F373RC is not set
+# CONFIG_ARCH_CHIP_STM32F373VC is not set
+# CONFIG_ARCH_CHIP_STM32F401RE is not set
+# CONFIG_ARCH_CHIP_STM32F411RE is not set
+# CONFIG_ARCH_CHIP_STM32F411VE is not set
+# CONFIG_ARCH_CHIP_STM32F405RG is not set
+# CONFIG_ARCH_CHIP_STM32F405VG is not set
+# CONFIG_ARCH_CHIP_STM32F405ZG is not set
+# CONFIG_ARCH_CHIP_STM32F407VE is not set
+CONFIG_ARCH_CHIP_STM32F407VG=y
+# CONFIG_ARCH_CHIP_STM32F407ZE is not set
+# CONFIG_ARCH_CHIP_STM32F407ZG is not set
+# CONFIG_ARCH_CHIP_STM32F407IE is not set
+# CONFIG_ARCH_CHIP_STM32F407IG is not set
+# CONFIG_ARCH_CHIP_STM32F427V is not set
+# CONFIG_ARCH_CHIP_STM32F427Z is not set
+# CONFIG_ARCH_CHIP_STM32F427I is not set
+# CONFIG_ARCH_CHIP_STM32F429V is not set
+# CONFIG_ARCH_CHIP_STM32F429Z is not set
+# CONFIG_ARCH_CHIP_STM32F429I is not set
+# CONFIG_ARCH_CHIP_STM32F429B is not set
+# CONFIG_ARCH_CHIP_STM32F429N is not set
+# CONFIG_ARCH_CHIP_STM32F446M is not set
+# CONFIG_ARCH_CHIP_STM32F446R is not set
+# CONFIG_ARCH_CHIP_STM32F446V is not set
+# CONFIG_ARCH_CHIP_STM32F446Z is not set
+# CONFIG_ARCH_CHIP_STM32F469A is not set
+# CONFIG_ARCH_CHIP_STM32F469I is not set
+# CONFIG_ARCH_CHIP_STM32F469B is not set
+# CONFIG_ARCH_CHIP_STM32F469N is not set
+CONFIG_STM32_FLASH_CONFIG_DEFAULT=y
+# CONFIG_STM32_FLASH_CONFIG_4 is not set
+# CONFIG_STM32_FLASH_CONFIG_6 is not set
+# CONFIG_STM32_FLASH_CONFIG_8 is not set
+# CONFIG_STM32_FLASH_CONFIG_B is not set
+# CONFIG_STM32_FLASH_CONFIG_C is not set
+# CONFIG_STM32_FLASH_CONFIG_D is not set
+# CONFIG_STM32_FLASH_CONFIG_E is not set
+# CONFIG_STM32_FLASH_CONFIG_F is not set
+# CONFIG_STM32_FLASH_CONFIG_G is not set
+# CONFIG_STM32_FLASH_CONFIG_I is not set
+# CONFIG_STM32_STM32L15XX is not set
+# CONFIG_STM32_ENERGYLITE is not set
+# CONFIG_STM32_STM32F10XX is not set
+# CONFIG_STM32_VALUELINE is not set
+# CONFIG_STM32_CONNECTIVITYLINE is not set
+# CONFIG_STM32_PERFORMANCELINE is not set
+# CONFIG_STM32_USBACCESSLINE is not set
+# CONFIG_STM32_HIGHDENSITY is not set
+# CONFIG_STM32_MEDIUMDENSITY is not set
+# CONFIG_STM32_LOWDENSITY is not set
+# CONFIG_STM32_STM32F20XX is not set
+# CONFIG_STM32_STM32F205 is not set
+# CONFIG_STM32_STM32F207 is not set
+# CONFIG_STM32_STM32F30XX is not set
+# CONFIG_STM32_STM32F302 is not set
+# CONFIG_STM32_STM32F303 is not set
+# CONFIG_STM32_STM32F33XX is not set
+# CONFIG_STM32_STM32F37XX is not set
+CONFIG_STM32_STM32F40XX=y
+# CONFIG_STM32_STM32F401 is not set
+# CONFIG_STM32_STM32F411 is not set
+# CONFIG_STM32_STM32F405 is not set
+CONFIG_STM32_STM32F407=y
+# CONFIG_STM32_STM32F427 is not set
+# CONFIG_STM32_STM32F429 is not set
+# CONFIG_STM32_STM32F446 is not set
+# CONFIG_STM32_STM32F469 is not set
+# CONFIG_STM32_DFU is not set
+
+#
+# STM32 Peripheral Support
+#
+CONFIG_STM32_HAVE_CCM=y
+# CONFIG_STM32_HAVE_USBDEV is not set
+CONFIG_STM32_HAVE_OTGFS=y
+CONFIG_STM32_HAVE_FSMC=y
+# CONFIG_STM32_HAVE_HRTIM1 is not set
+# CONFIG_STM32_HAVE_LTDC is not set
+CONFIG_STM32_HAVE_USART3=y
+CONFIG_STM32_HAVE_UART4=y
+CONFIG_STM32_HAVE_UART5=y
+CONFIG_STM32_HAVE_USART6=y
+# CONFIG_STM32_HAVE_UART7 is not set
+# CONFIG_STM32_HAVE_UART8 is not set
+CONFIG_STM32_HAVE_TIM1=y
+CONFIG_STM32_HAVE_TIM2=y
+CONFIG_STM32_HAVE_TIM3=y
+CONFIG_STM32_HAVE_TIM4=y
+CONFIG_STM32_HAVE_TIM5=y
+CONFIG_STM32_HAVE_TIM6=y
+CONFIG_STM32_HAVE_TIM7=y
+CONFIG_STM32_HAVE_TIM8=y
+CONFIG_STM32_HAVE_TIM9=y
+CONFIG_STM32_HAVE_TIM10=y
+CONFIG_STM32_HAVE_TIM11=y
+CONFIG_STM32_HAVE_TIM12=y
+CONFIG_STM32_HAVE_TIM13=y
+CONFIG_STM32_HAVE_TIM14=y
+# CONFIG_STM32_HAVE_TIM15 is not set
+# CONFIG_STM32_HAVE_TIM16 is not set
+# CONFIG_STM32_HAVE_TIM17 is not set
+CONFIG_STM32_HAVE_ADC2=y
+CONFIG_STM32_HAVE_ADC3=y
+# CONFIG_STM32_HAVE_ADC4 is not set
+# CONFIG_STM32_HAVE_ADC1_DMA is not set
+# CONFIG_STM32_HAVE_ADC2_DMA is not set
+# CONFIG_STM32_HAVE_ADC3_DMA is not set
+# CONFIG_STM32_HAVE_ADC4_DMA is not set
+# CONFIG_STM32_HAVE_SDADC1 is not set
+# CONFIG_STM32_HAVE_SDADC2 is not set
+# CONFIG_STM32_HAVE_SDADC3 is not set
+# CONFIG_STM32_HAVE_SDADC1_DMA is not set
+# CONFIG_STM32_HAVE_SDADC2_DMA is not set
+# CONFIG_STM32_HAVE_SDADC3_DMA is not set
+CONFIG_STM32_HAVE_CAN1=y
+CONFIG_STM32_HAVE_CAN2=y
+# CONFIG_STM32_HAVE_COMP1 is not set
+# CONFIG_STM32_HAVE_COMP2 is not set
+# CONFIG_STM32_HAVE_COMP3 is not set
+# CONFIG_STM32_HAVE_COMP4 is not set
+# CONFIG_STM32_HAVE_COMP5 is not set
+# CONFIG_STM32_HAVE_COMP6 is not set
+# CONFIG_STM32_HAVE_COMP7 is not set
+CONFIG_STM32_HAVE_DAC1=y
+CONFIG_STM32_HAVE_DAC2=y
+CONFIG_STM32_HAVE_RNG=y
+CONFIG_STM32_HAVE_ETHMAC=y
+CONFIG_STM32_HAVE_I2C2=y
+CONFIG_STM32_HAVE_I2C3=y
+CONFIG_STM32_HAVE_SPI2=y
+CONFIG_STM32_HAVE_SPI3=y
+# CONFIG_STM32_HAVE_SPI4 is not set
+# CONFIG_STM32_HAVE_SPI5 is not set
+# CONFIG_STM32_HAVE_SPI6 is not set
+# CONFIG_STM32_HAVE_SAIPLL is not set
+# CONFIG_STM32_HAVE_I2SPLL is not set
+# CONFIG_STM32_HAVE_OPAMP1 is not set
+# CONFIG_STM32_HAVE_OPAMP2 is not set
+# CONFIG_STM32_HAVE_OPAMP3 is not set
+# CONFIG_STM32_HAVE_OPAMP4 is not set
+# CONFIG_STM32_ADC1 is not set
+# CONFIG_STM32_ADC2 is not set
+# CONFIG_STM32_ADC3 is not set
+# CONFIG_STM32_BKPSRAM is not set
+# CONFIG_STM32_CAN1 is not set
+# CONFIG_STM32_CAN2 is not set
+# CONFIG_STM32_CCMDATARAM is not set
+# CONFIG_STM32_CRC is not set
+# CONFIG_STM32_CRYP is not set
+# CONFIG_STM32_DMA1 is not set
+# CONFIG_STM32_DMA2 is not set
+# CONFIG_STM32_DAC1 is not set
+# CONFIG_STM32_DAC2 is not set
+# CONFIG_STM32_DCMI is not set
+# CONFIG_STM32_ETHMAC is not set
+# CONFIG_STM32_FSMC is not set
+# CONFIG_STM32_HASH is not set
+# CONFIG_STM32_I2C1 is not set
+# CONFIG_STM32_I2C2 is not set
+# CONFIG_STM32_I2C3 is not set
+# CONFIG_STM32_OPAMP is not set
+# CONFIG_STM32_OTGFS is not set
+# CONFIG_STM32_OTGHS is not set
+CONFIG_STM32_PWR=y
+# CONFIG_STM32_RNG is not set
+# CONFIG_STM32_SDIO is not set
+# CONFIG_STM32_SPI1 is not set
+# CONFIG_STM32_SPI2 is not set
+CONFIG_STM32_SPI3=y
+CONFIG_STM32_SYSCFG=y
+# CONFIG_STM32_TIM1 is not set
+# CONFIG_STM32_TIM2 is not set
+# CONFIG_STM32_TIM3 is not set
+# CONFIG_STM32_TIM4 is not set
+# CONFIG_STM32_TIM5 is not set
+# CONFIG_STM32_TIM6 is not set
+# CONFIG_STM32_TIM7 is not set
+# CONFIG_STM32_TIM8 is not set
+# CONFIG_STM32_TIM9 is not set
+# CONFIG_STM32_TIM10 is not set
+# CONFIG_STM32_TIM11 is not set
+# CONFIG_STM32_TIM12 is not set
+# CONFIG_STM32_TIM13 is not set
+# CONFIG_STM32_TIM14 is not set
+# CONFIG_STM32_USART1 is not set
+# CONFIG_STM32_USART2 is not set
+CONFIG_STM32_USART3=y
+# CONFIG_STM32_UART4 is not set
+# CONFIG_STM32_UART5 is not set
+# CONFIG_STM32_USART6 is not set
+# CONFIG_STM32_IWDG is not set
+# CONFIG_STM32_WWDG is not set
+CONFIG_STM32_SPI=y
+# CONFIG_STM32_NOEXT_VECTORS is not set
+
+#
+# Alternate Pin Mapping
+#
+# CONFIG_STM32_FLASH_PREFETCH is not set
+# CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW is not set
+# CONFIG_STM32_JTAG_DISABLE is not set
+# CONFIG_STM32_JTAG_FULL_ENABLE is not set
+# CONFIG_STM32_JTAG_NOJNTRST_ENABLE is not set
+CONFIG_STM32_JTAG_SW_ENABLE=y
+CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
+# CONFIG_STM32_FORCEPOWER is not set
+# CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is not set
+CONFIG_STM32_CCMEXCLUDE=y
+
+#
+# Timer Configuration
+#
+# CONFIG_STM32_ONESHOT is not set
+# CONFIG_STM32_FREERUN is not set
+# CONFIG_STM32_TIM1_CAP is not set
+# CONFIG_STM32_TIM2_CAP is not set
+# CONFIG_STM32_TIM3_CAP is not set
+# CONFIG_STM32_TIM4_CAP is not set
+# CONFIG_STM32_TIM5_CAP is not set
+# CONFIG_STM32_TIM8_CAP is not set
+# CONFIG_STM32_TIM9_CAP is not set
+# CONFIG_STM32_TIM10_CAP is not set
+# CONFIG_STM32_TIM11_CAP is not set
+# CONFIG_STM32_TIM12_CAP is not set
+# CONFIG_STM32_TIM13_CAP is not set
+# CONFIG_STM32_TIM14_CAP is not set
+CONFIG_STM32_USART=y
+CONFIG_STM32_SERIALDRIVER=y
+
+#
+# U[S]ART Configuration
+#
+
+#
+# U[S]ART Device Configuration
+#
+CONFIG_STM32_USART3_SERIALDRIVER=y
+# CONFIG_STM32_USART3_1WIREDRIVER is not set
+# CONFIG_USART3_RS485 is not set
+
+#
+# Serial Driver Configuration
+#
+# CONFIG_SERIAL_DISABLE_REORDERING is not set
+# CONFIG_STM32_FLOWCONTROL_BROKEN is not set
+# CONFIG_STM32_USART_BREAKS is not set
+# CONFIG_STM32_USART_SINGLEWIRE is not set
+
+#
+# SPI Configuration
+#
+# CONFIG_STM32_SPI_INTERRUPTS is not set
+# CONFIG_STM32_SPI_DMA is not set
+# CONFIG_STM32_HAVE_RTC_COUNTER is not set
+# CONFIG_STM32_HAVE_RTC_SUBSECONDS is not set
+
+#
+# USB FS Host Configuration
+#
+
+#
+# USB HS Host Configuration
+#
+
+#
+# USB Host Debug Configuration
+#
+
+#
+# USB Device Configuration
+#
+
+#
+# Architecture Options
+#
+# CONFIG_ARCH_NOINTC is not set
+# CONFIG_ARCH_VECNOTIRQ is not set
+# CONFIG_ARCH_DMA is not set
+CONFIG_ARCH_HAVE_IRQPRIO=y
+# CONFIG_ARCH_L2CACHE is not set
+# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set
+# CONFIG_ARCH_HAVE_ADDRENV is not set
+# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set
+# CONFIG_ARCH_HAVE_MULTICPU is not set
+CONFIG_ARCH_HAVE_VFORK=y
+# CONFIG_ARCH_HAVE_MMU is not set
+CONFIG_ARCH_HAVE_MPU=y
+# CONFIG_ARCH_NAND_HWECC is not set
+# CONFIG_ARCH_HAVE_EXTCLK is not set
+# CONFIG_ARCH_HAVE_POWEROFF is not set
+CONFIG_ARCH_HAVE_RESET=y
+# CONFIG_ARCH_USE_MPU is not set
+# CONFIG_ARCH_IRQPRIO is not set
+CONFIG_ARCH_STACKDUMP=y
+# CONFIG_ENDIAN_BIG is not set
+# CONFIG_ARCH_IDLE_CUSTOM is not set
+# CONFIG_ARCH_HAVE_RAMFUNCS is not set
+CONFIG_ARCH_HAVE_RAMVECTORS=y
+# CONFIG_ARCH_RAMVECTORS is not set
+# CONFIG_ARCH_MINIMAL_VECTORTABLE is not set
+
+#
+# Board Settings
+#
+CONFIG_BOARD_LOOPSPERMSEC=16717
+# CONFIG_ARCH_CALIBRATION is not set
+
+#
+# Interrupt options
+#
+CONFIG_ARCH_HAVE_INTERRUPTSTACK=y
+CONFIG_ARCH_INTERRUPTSTACK=0
+CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y
+# CONFIG_ARCH_HIPRI_INTERRUPT is not set
+
+#
+# Boot options
+#
+# CONFIG_BOOT_RUNFROMEXTSRAM is not set
+CONFIG_BOOT_RUNFROMFLASH=y
+# CONFIG_BOOT_RUNFROMISRAM is not set
+# CONFIG_BOOT_RUNFROMSDRAM is not set
+# CONFIG_BOOT_COPYTORAM is not set
+
+#
+# Boot Memory Configuration
+#
+CONFIG_RAM_START=0x20000000
+CONFIG_RAM_SIZE=131072
+# CONFIG_ARCH_HAVE_SDRAM is not set
+
+#
+# Board Selection
+#
+CONFIG_ARCH_BOARD_CLICKER2_STM32=y
+# CONFIG_ARCH_BOARD_STM32F4_DISCOVERY is not set
+# CONFIG_ARCH_BOARD_MIKROE_STM32F4 is not set
+# CONFIG_ARCH_BOARD_CUSTOM is not set
+CONFIG_ARCH_BOARD="clicker2-stm32"
+
+#
+# Common Board Options
+#
+CONFIG_ARCH_HAVE_LEDS=y
+CONFIG_ARCH_LEDS=y
+CONFIG_ARCH_HAVE_BUTTONS=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_HAVE_IRQBUTTONS=y
+CONFIG_ARCH_IRQBUTTONS=y
+
+#
+# Board-Specific Options
+#
+CONFIG_CLICKER2_STM32_MB1_SPI=y
+# CONFIG_CLICKER2_STM32_MB2_SPI is not set
+CONFIG_CLICKER2_STM32_MB1_BEE=y
+# CONFIG_CLICKER2_STM32_MB2_BEE is not set
+# CONFIG_BOARD_CRASHDUMP is not set
+CONFIG_LIB_BOARDCTL=y
+# CONFIG_BOARDCTL_RESET is not set
+# CONFIG_BOARDCTL_UNIQUEID is not set
+# CONFIG_BOARDCTL_TSCTEST is not set
+# CONFIG_BOARDCTL_GRAPHICS is not set
+# CONFIG_BOARDCTL_IOCTL is not set
+
+#
+# RTOS Features
+#
+CONFIG_DISABLE_OS_API=y
+# CONFIG_DISABLE_POSIX_TIMERS is not set
+# CONFIG_DISABLE_PTHREAD is not set
+# CONFIG_DISABLE_SIGNALS is not set
+# CONFIG_DISABLE_MQUEUE is not set
+# CONFIG_DISABLE_ENVIRON is not set
+
+#
+# Clocks and Timers
+#
+CONFIG_ARCH_HAVE_TICKLESS=y
+# CONFIG_SCHED_TICKLESS is not set
+CONFIG_USEC_PER_TICK=10000
+# CONFIG_SYSTEM_TIME64 is not set
+# CONFIG_CLOCK_MONOTONIC is not set
+CONFIG_ARCH_HAVE_TIMEKEEPING=y
+# CONFIG_JULIAN_TIME is not set
+CONFIG_START_YEAR=2013
+CONFIG_START_MONTH=1
+CONFIG_START_DAY=1
+CONFIG_MAX_WDOGPARMS=2
+CONFIG_PREALLOC_WDOGS=8
+CONFIG_WDOG_INTRESERVE=1
+CONFIG_PREALLOC_TIMERS=4
+
+#
+# Tasks and Scheduling
+#
+# CONFIG_SPINLOCK is not set
+# CONFIG_INIT_NONE is not set
+CONFIG_INIT_ENTRYPOINT=y
+# CONFIG_INIT_FILEPATH is not set
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_RR_INTERVAL=200
+# CONFIG_SCHED_SPORADIC is not set
+CONFIG_TASK_NAME_SIZE=32
+CONFIG_MAX_TASKS=16
+# CONFIG_SCHED_HAVE_PARENT is not set
+CONFIG_SCHED_WAITPID=y
+
+#
+# Pthread Options
+#
+# CONFIG_PTHREAD_MUTEX_TYPES is not set
+CONFIG_PTHREAD_MUTEX_ROBUST=y
+# CONFIG_PTHREAD_MUTEX_UNSAFE is not set
+# CONFIG_PTHREAD_MUTEX_BOTH is not set
+CONFIG_NPTHREAD_KEYS=4
+# CONFIG_PTHREAD_CLEANUP is not set
+# CONFIG_CANCELLATION_POINTS is not set
+
+#
+# Performance Monitoring
+#
+# CONFIG_SCHED_CPULOAD is not set
+# CONFIG_SCHED_INSTRUMENTATION is not set
+
+#
+# Files and I/O
+#
+CONFIG_DEV_CONSOLE=y
+# CONFIG_FDCLONE_DISABLE is not set
+# CONFIG_FDCLONE_STDIO is not set
+CONFIG_SDCLONE_DISABLE=y
+CONFIG_NFILE_DESCRIPTORS=8
+CONFIG_NFILE_STREAMS=8
+CONFIG_NAME_MAX=32
+# CONFIG_PRIORITY_INHERITANCE is not set
+
+#
+# RTOS hooks
+#
+CONFIG_BOARD_INITIALIZE=y
+# CONFIG_BOARD_INITTHREAD is not set
+# CONFIG_SCHED_STARTHOOK is not set
+# CONFIG_SCHED_ATEXIT is not set
+# CONFIG_SCHED_ONEXIT is not set
+# CONFIG_SIG_EVTHREAD is not set
+
+#
+# Signal Numbers
+#
+CONFIG_SIG_SIGUSR1=1
+CONFIG_SIG_SIGUSR2=2
+CONFIG_SIG_SIGALARM=3
+CONFIG_SIG_SIGCONDTIMEDOUT=16
+CONFIG_SIG_SIGWORK=17
+
+#
+# POSIX Message Queue Options
+#
+CONFIG_PREALLOC_MQ_MSGS=4
+CONFIG_MQ_MAXMSGSIZE=32
+# CONFIG_MODULE is not set
+
+#
+# Work queue support
+#
+CONFIG_SCHED_WORKQUEUE=y
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_HPWORKPRIORITY=192
+CONFIG_SCHED_HPWORKPERIOD=50000
+CONFIG_SCHED_HPWORKSTACKSIZE=2048
+# CONFIG_SCHED_LPWORK is not set
+
+#
+# Stack and heap information
+#
+CONFIG_IDLETHREAD_STACKSIZE=1024
+CONFIG_USERMAIN_STACKSIZE=2048
+CONFIG_PTHREAD_STACK_MIN=256
+CONFIG_PTHREAD_STACK_DEFAULT=2048
+# CONFIG_LIB_SYSCALL is not set
+
+#
+# Device Drivers
+#
+CONFIG_DISABLE_POLL=y
+CONFIG_DEV_NULL=y
+# CONFIG_DEV_ZERO is not set
+# CONFIG_DEV_URANDOM is not set
+# CONFIG_DEV_LOOP is not set
+
+#
+# Buffering
+#
+# CONFIG_DRVR_WRITEBUFFER is not set
+# CONFIG_DRVR_READAHEAD is not set
+# CONFIG_RAMDISK is not set
+# CONFIG_CAN is not set
+# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set
+# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set
+# CONFIG_PWM is not set
+CONFIG_ARCH_HAVE_I2CRESET=y
+# CONFIG_I2C is not set
+# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set
+# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set
+CONFIG_ARCH_HAVE_SPI_BITORDER=y
+CONFIG_SPI=y
+# CONFIG_SPI_SLAVE is not set
+CONFIG_SPI_EXCHANGE=y
+# CONFIG_SPI_CMDDATA is not set
+# CONFIG_SPI_CALLBACK is not set
+# CONFIG_SPI_HWFEATURES is not set
+# CONFIG_SPI_BITORDER is not set
+# CONFIG_SPI_CS_DELAY_CONTROL is not set
+# CONFIG_SPI_DRIVER is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_I2S is not set
+
+#
+# Timer Driver Support
+#
+# CONFIG_TIMER is not set
+# CONFIG_ONESHOT is not set
+# CONFIG_RTC is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_ANALOG is not set
+# CONFIG_AUDIO_DEVICES is not set
+# CONFIG_VIDEO_DEVICES is not set
+# CONFIG_BCH is not set
+# CONFIG_INPUT is not set
+
+#
+# IO Expander/GPIO Support
+#
+# CONFIG_IOEXPANDER is not set
+# CONFIG_DEV_GPIO is not set
+
+#
+# LCD Driver Support
+#
+# CONFIG_LCD is not set
+# CONFIG_SLCD is not set
+
+#
+# LED Support
+#
+# CONFIG_USERLED is not set
+# CONFIG_RGBLED is not set
+# CONFIG_PCA9635PW is not set
+# CONFIG_NCP5623C is not set
+# CONFIG_MMCSD is not set
+# CONFIG_MODEM is not set
+# CONFIG_MTD is not set
+# CONFIG_EEPROM is not set
+# CONFIG_PIPES is not set
+# CONFIG_PM is not set
+# CONFIG_POWER is not set
+# CONFIG_SENSORS is not set
+CONFIG_SERIAL=y
+# CONFIG_DEV_LOWCONSOLE is not set
+# CONFIG_SERIAL_REMOVABLE is not set
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_16550_UART is not set
+# CONFIG_UART_SERIALDRIVER is not set
+# CONFIG_UART0_SERIALDRIVER is not set
+# CONFIG_UART1_SERIALDRIVER is not set
+# CONFIG_UART2_SERIALDRIVER is not set
+# CONFIG_UART3_SERIALDRIVER is not set
+# CONFIG_UART4_SERIALDRIVER is not set
+# CONFIG_UART5_SERIALDRIVER is not set
+# CONFIG_UART6_SERIALDRIVER is not set
+# CONFIG_UART7_SERIALDRIVER is not set
+# CONFIG_UART8_SERIALDRIVER is not set
+# CONFIG_SCI0_SERIALDRIVER is not set
+# CONFIG_SCI1_SERIALDRIVER is not set
+# CONFIG_USART0_SERIALDRIVER is not set
+# CONFIG_USART1_SERIALDRIVER is not set
+# CONFIG_USART2_SERIALDRIVER is not set
+CONFIG_USART3_SERIALDRIVER=y
+# CONFIG_USART4_SERIALDRIVER is not set
+# CONFIG_USART5_SERIALDRIVER is not set
+# CONFIG_USART6_SERIALDRIVER is not set
+# CONFIG_USART7_SERIALDRIVER is not set
+# CONFIG_USART8_SERIALDRIVER is not set
+# CONFIG_OTHER_UART_SERIALDRIVER is not set
+CONFIG_MCU_SERIAL=y
+CONFIG_STANDARD_SERIAL=y
+# CONFIG_SERIAL_IFLOWCONTROL is not set
+# CONFIG_SERIAL_OFLOWCONTROL is not set
+# CONFIG_SERIAL_DMA is not set
+CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y
+CONFIG_USART3_SERIAL_CONSOLE=y
+# CONFIG_OTHER_SERIAL_CONSOLE is not set
+# CONFIG_NO_SERIAL_CONSOLE is not set
+
+#
+# USART3 Configuration
+#
+CONFIG_USART3_RXBUFSIZE=256
+CONFIG_USART3_TXBUFSIZE=256
+CONFIG_USART3_BAUD=115200
+CONFIG_USART3_BITS=8
+CONFIG_USART3_PARITY=0
+CONFIG_USART3_2STOP=0
+# CONFIG_USART3_IFLOWCONTROL is not set
+# CONFIG_USART3_OFLOWCONTROL is not set
+# CONFIG_USART3_DMA is not set
+# CONFIG_PSEUDOTERM is not set
+# CONFIG_USBDEV is not set
+# CONFIG_USBHOST is not set
+# CONFIG_USBMISC is not set
+# CONFIG_HAVE_USBTRACE is not set
+CONFIG_DRIVERS_WIRELESS=y
+# CONFIG_WL_CC1101 is not set
+# CONFIG_WL_CC3000 is not set
+CONFIG_DRIVERS_IEEE802154=y
+CONFIG_IEEE802154_MRF24J40=y
+# CONFIG_IEEE802154_AT86RF233 is not set
+# CONFIG_DRIVERS_IEEE80211 is not set
+# CONFIG_WL_NRF24L01 is not set
+# CONFIG_DRIVERS_CONTACTLESS is not set
+
+#
+# System Logging
+#
+# CONFIG_ARCH_SYSLOG is not set
+# CONFIG_RAMLOG is not set
+# CONFIG_SYSLOG_INTBUFFER is not set
+# CONFIG_SYSLOG_TIMESTAMP is not set
+CONFIG_SYSLOG_SERIAL_CONSOLE=y
+# CONFIG_SYSLOG_CHAR is not set
+CONFIG_SYSLOG_CONSOLE=y
+# CONFIG_SYSLOG_NONE is not set
+# CONFIG_SYSLOG_FILE is not set
+# CONFIG_SYSLOG_CHARDEV is not set
+
+#
+# Networking Support
+#
+# CONFIG_ARCH_HAVE_NET is not set
+# CONFIG_ARCH_HAVE_PHY is not set
+# CONFIG_NET is not set
+
+#
+# Crypto API
+#
+# CONFIG_CRYPTO is not set
+
+#
+# File Systems
+#
+
+#
+# File system configuration
+#
+# CONFIG_DISABLE_MOUNTPOINT is not set
+# CONFIG_FS_AUTOMOUNTER is not set
+# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
+# CONFIG_PSEUDOFS_SOFTLINKS is not set
+CONFIG_FS_READABLE=y
+CONFIG_FS_WRITABLE=y
+# CONFIG_FS_NAMED_SEMAPHORES is not set
+CONFIG_FS_MQUEUE_MPATH="/var/mqueue"
+# CONFIG_FS_RAMMAP is not set
+# CONFIG_FS_FAT is not set
+# CONFIG_FS_NXFFS is not set
+# CONFIG_FS_ROMFS is not set
+# CONFIG_FS_TMPFS is not set
+# CONFIG_FS_SMARTFS is not set
+# CONFIG_FS_BINFS is not set
+CONFIG_FS_PROCFS=y
+# CONFIG_FS_PROCFS_REGISTER is not set
+
+#
+# Exclude individual procfs entries
+#
+# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set
+# CONFIG_FS_UNIONFS is not set
+
+#
+# Graphics Support
+#
+# CONFIG_NX is not set
+
+#
+# Memory Management
+#
+# CONFIG_MM_SMALL is not set
+CONFIG_MM_REGIONS=1
+# CONFIG_ARCH_HAVE_HEAP2 is not set
+# CONFIG_GRAN is not set
+
+#
+# Audio Support
+#
+# CONFIG_AUDIO is not set
+
+#
+# Wireless Support
+#
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_IEEE802154=y
+CONFIG_IEEE802154_MAC=y
+# CONFIG_IEEE802154_MAC_DEV is not set
+CONFIG_IEEE802154_DEV=y
+
+#
+# Binary Loader
+#
+# CONFIG_BINFMT_DISABLE is not set
+# CONFIG_BINFMT_EXEPATH is not set
+# CONFIG_NXFLAT is not set
+# CONFIG_ELF is not set
+CONFIG_BUILTIN=y
+# CONFIG_PIC is not set
+# CONFIG_SYMTAB_ORDEREDBYNAME is not set
+
+#
+# Library Routines
+#
+
+#
+# Standard C Library Options
+#
+
+#
+# Standard C I/O
+#
+# CONFIG_STDIO_DISABLE_BUFFERING is not set
+CONFIG_STDIO_BUFFER_SIZE=64
+CONFIG_STDIO_LINEBUFFER=y
+CONFIG_NUNGET_CHARS=2
+# CONFIG_NOPRINTF_FIELDWIDTH is not set
+# CONFIG_LIBC_FLOATINGPOINT is not set
+CONFIG_LIBC_LONG_LONG=y
+# CONFIG_LIBC_SCANSET is not set
+# CONFIG_EOL_IS_CR is not set
+# CONFIG_EOL_IS_LF is not set
+# CONFIG_EOL_IS_BOTH_CRLF is not set
+CONFIG_EOL_IS_EITHER_CRLF=y
+# CONFIG_MEMCPY_VIK is not set
+# CONFIG_LIBM is not set
+
+#
+# Architecture-Specific Support
+#
+CONFIG_ARCH_LOWPUTC=y
+# CONFIG_ARCH_ROMGETC is not set
+# CONFIG_LIBC_ARCH_MEMCPY is not set
+# CONFIG_LIBC_ARCH_MEMCMP is not set
+# CONFIG_LIBC_ARCH_MEMMOVE is not set
+# CONFIG_LIBC_ARCH_MEMSET is not set
+# CONFIG_LIBC_ARCH_STRCHR is not set
+# CONFIG_LIBC_ARCH_STRCMP is not set
+# CONFIG_LIBC_ARCH_STRCPY is not set
+# CONFIG_LIBC_ARCH_STRNCPY is not set
+# CONFIG_LIBC_ARCH_STRLEN is not set
+# CONFIG_LIBC_ARCH_STRNLEN is not set
+# CONFIG_LIBC_ARCH_ELF is not set
+# CONFIG_ARMV7M_MEMCPY is not set
+
+#
+# stdlib Options
+#
+CONFIG_LIB_RAND_ORDER=1
+CONFIG_LIB_HOMEDIR="/"
+CONFIG_LIBC_TMPDIR="/tmp"
+CONFIG_LIBC_MAX_TMPFILE=32
+
+#
+# Program Execution Options
+#
+# CONFIG_LIBC_EXECFUNCS is not set
+CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024
+CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
+
+#
+# errno Decode Support
+#
+# CONFIG_LIBC_STRERROR is not set
+# CONFIG_LIBC_PERROR_STDOUT is not set
+
+#
+# memcpy/memset Options
+#
+# CONFIG_MEMSET_OPTSPEED is not set
+# CONFIG_LIBC_DLLFCN is not set
+# CONFIG_LIBC_MODLIB is not set
+# CONFIG_LIBC_WCHAR is not set
+# CONFIG_LIBC_LOCALE is not set
+
+#
+# Time/Time Zone Support
+#
+# CONFIG_LIBC_LOCALTIME is not set
+# CONFIG_TIME_EXTENDED is not set
+CONFIG_ARCH_HAVE_TLS=y
+
+#
+# Thread Local Storage (TLS)
+#
+# CONFIG_TLS is not set
+
+#
+# Network-Related Options
+#
+# CONFIG_LIBC_IPv4_ADDRCONV is not set
+# CONFIG_LIBC_IPv6_ADDRCONV is not set
+# CONFIG_LIBC_NETDB is not set
+
+#
+# NETDB Support
+#
+# CONFIG_NETDB_HOSTFILE is not set
+# CONFIG_LIBC_IOCTL_VARIADIC is not set
+CONFIG_LIB_SENDFILE_BUFSIZE=512
+
+#
+# Non-standard Library Support
+#
+# CONFIG_LIB_CRC64_FAST is not set
+# CONFIG_LIB_KBDCODEC is not set
+# CONFIG_LIB_SLCDCODEC is not set
+# CONFIG_LIB_HEX2BIN is not set
+
+#
+# Basic CXX Support
+#
+# CONFIG_C99_BOOL8 is not set
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+# CONFIG_CXX_NEWLONG is not set
+
+#
+# LLVM C++ Library (libcxx)
+#
+# CONFIG_LIBCXX is not set
+
+#
+# uClibc++ Standard C++ Library
+#
+# CONFIG_UCLIBCXX is not set
+
+#
+# Application Configuration
+#
+
+#
+# Built-In Applications
+#
+CONFIG_BUILTIN_PROXY_STACKSIZE=1024
+
+#
+# CAN Utilities
+#
+
+#
+# Examples
+#
+# CONFIG_EXAMPLES_BUTTONS is not set
+# CONFIG_EXAMPLES_CCTYPE is not set
+# CONFIG_EXAMPLES_CHAT is not set
+# CONFIG_EXAMPLES_CONFIGDATA is not set
+# CONFIG_EXAMPLES_CXXTEST is not set
+# CONFIG_EXAMPLES_DHCPD is not set
+# CONFIG_EXAMPLES_ELF is not set
+# CONFIG_EXAMPLES_FSTEST is not set
+# CONFIG_EXAMPLES_FTPC is not set
+# CONFIG_EXAMPLES_FTPD is not set
+# CONFIG_EXAMPLES_HELLO is not set
+# CONFIG_EXAMPLES_HELLOXX is not set
+# CONFIG_EXAMPLES_HIDKBD is not set
+# CONFIG_EXAMPLES_IGMP is not set
+# CONFIG_EXAMPLES_JSON is not set
+# CONFIG_EXAMPLES_KEYPADTEST is not set
+# CONFIG_EXAMPLES_MEDIA is not set
+# CONFIG_EXAMPLES_MM is not set
+# CONFIG_EXAMPLES_MODBUS is not set
+# CONFIG_EXAMPLES_MOUNT is not set
+# CONFIG_EXAMPLES_NRF24L01TERM is not set
+CONFIG_EXAMPLES_NSH=y
+CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
+# CONFIG_EXAMPLES_NULL is not set
+# CONFIG_EXAMPLES_NX is not set
+# CONFIG_EXAMPLES_NXFFS is not set
+# CONFIG_EXAMPLES_NXHELLO is not set
+# CONFIG_EXAMPLES_NXIMAGE is not set
+# CONFIG_EXAMPLES_NXLINES is not set
+# CONFIG_EXAMPLES_NXTERM is not set
+# CONFIG_EXAMPLES_NXTEXT is not set
+# CONFIG_EXAMPLES_OSTEST is not set
+# CONFIG_EXAMPLES_PCA9635 is not set
+# CONFIG_EXAMPLES_POSIXSPAWN is not set
+# CONFIG_EXAMPLES_PPPD is not set
+# CONFIG_EXAMPLES_RFID_READUID is not set
+# CONFIG_EXAMPLES_RGBLED is not set
+# CONFIG_EXAMPLES_SENDMAIL is not set
+# CONFIG_EXAMPLES_SERIALBLASTER is not set
+# CONFIG_EXAMPLES_SERIALRX is not set
+# CONFIG_EXAMPLES_SERLOOP is not set
+# CONFIG_EXAMPLES_SLCD is not set
+# CONFIG_EXAMPLES_SMART is not set
+# CONFIG_EXAMPLES_SMART_TEST is not set
+# CONFIG_EXAMPLES_SMP is not set
+# CONFIG_EXAMPLES_STAT is not set
+# CONFIG_EXAMPLES_TCPECHO is not set
+# CONFIG_EXAMPLES_TELNETD is not set
+# CONFIG_EXAMPLES_TIFF is not set
+# CONFIG_EXAMPLES_TOUCHSCREEN is not set
+# CONFIG_EXAMPLES_USBSERIAL is not set
+# CONFIG_EXAMPLES_WATCHDOG is not set
+# CONFIG_EXAMPLES_WEBSERVER is not set
+# CONFIG_EXAMPLES_XBC_TEST is not set
+
+#
+# File System Utilities
+#
+# CONFIG_FSUTILS_INIFILE is not set
+# CONFIG_FSUTILS_PASSWD is not set
+
+#
+# GPS Utilities
+#
+# CONFIG_GPSUTILS_MINMEA_LIB is not set
+
+#
+# Graphics Support
+#
+# CONFIG_TIFF is not set
+# CONFIG_GRAPHICS_TRAVELER is not set
+
+#
+# Interpreters
+#
+# CONFIG_INTERPRETERS_BAS is not set
+# CONFIG_INTERPRETERS_FICL is not set
+# CONFIG_INTERPRETERS_MICROPYTHON is not set
+# CONFIG_INTERPRETERS_MINIBASIC is not set
+# CONFIG_INTERPRETERS_PCODE is not set
+
+#
+# FreeModBus
+#
+# CONFIG_MODBUS is not set
+
+#
+# Network Utilities
+#
+# CONFIG_NETUTILS_CODECS is not set
+# CONFIG_NETUTILS_ESP8266 is not set
+# CONFIG_NETUTILS_FTPC is not set
+# CONFIG_NETUTILS_JSON is not set
+# CONFIG_NETUTILS_SMTP is not set
+
+#
+# NSH Library
+#
+CONFIG_NSH_LIBRARY=y
+# CONFIG_NSH_MOTD is not set
+
+#
+# Command Line Configuration
+#
+CONFIG_NSH_READLINE=y
+# CONFIG_NSH_CLE is not set
+CONFIG_NSH_LINELEN=64
+# CONFIG_NSH_DISABLE_SEMICOLON is not set
+CONFIG_NSH_CMDPARMS=y
+CONFIG_NSH_MAXARGUMENTS=6
+CONFIG_NSH_ARGCAT=y
+CONFIG_NSH_NESTDEPTH=3
+# CONFIG_NSH_DISABLEBG is not set
+CONFIG_NSH_BUILTIN_APPS=y
+
+#
+# Disable Individual commands
+#
+# CONFIG_NSH_DISABLE_ADDROUTE is not set
+# CONFIG_NSH_DISABLE_BASENAME is not set
+# CONFIG_NSH_DISABLE_CAT is not set
+# CONFIG_NSH_DISABLE_CD is not set
+# CONFIG_NSH_DISABLE_CP is not set
+# CONFIG_NSH_DISABLE_CMP is not set
+CONFIG_NSH_DISABLE_DATE=y
+# CONFIG_NSH_DISABLE_DD is not set
+# CONFIG_NSH_DISABLE_DF is not set
+# CONFIG_NSH_DISABLE_DELROUTE is not set
+# CONFIG_NSH_DISABLE_DIRNAME is not set
+# CONFIG_NSH_DISABLE_ECHO is not set
+# CONFIG_NSH_DISABLE_EXEC is not set
+# CONFIG_NSH_DISABLE_EXIT is not set
+# CONFIG_NSH_DISABLE_FREE is not set
+CONFIG_NSH_DISABLE_GET=y
+# CONFIG_NSH_DISABLE_HELP is not set
+# CONFIG_NSH_DISABLE_HEXDUMP is not set
+# CONFIG_NSH_DISABLE_IFCONFIG is not set
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+# CONFIG_NSH_DISABLE_KILL is not set
+# CONFIG_NSH_DISABLE_LOSETUP is not set
+CONFIG_NSH_DISABLE_LOSMART=y
+# CONFIG_NSH_DISABLE_LS is not set
+# CONFIG_NSH_DISABLE_MB is not set
+# CONFIG_NSH_DISABLE_MKDIR is not set
+# CONFIG_NSH_DISABLE_MKRD is not set
+# CONFIG_NSH_DISABLE_MH is not set
+# CONFIG_NSH_DISABLE_MOUNT is not set
+# CONFIG_NSH_DISABLE_MV is not set
+# CONFIG_NSH_DISABLE_MW is not set
+CONFIG_NSH_DISABLE_PRINTF=y
+# CONFIG_NSH_DISABLE_PS is not set
+CONFIG_NSH_DISABLE_PUT=y
+# CONFIG_NSH_DISABLE_PWD is not set
+# CONFIG_NSH_DISABLE_RM is not set
+# CONFIG_NSH_DISABLE_RMDIR is not set
+# CONFIG_NSH_DISABLE_SET is not set
+# CONFIG_NSH_DISABLE_SH is not set
+# CONFIG_NSH_DISABLE_SLEEP is not set
+# CONFIG_NSH_DISABLE_TIME is not set
+# CONFIG_NSH_DISABLE_TEST is not set
+# CONFIG_NSH_DISABLE_UMOUNT is not set
+# CONFIG_NSH_DISABLE_UNAME is not set
+# CONFIG_NSH_DISABLE_UNSET is not set
+# CONFIG_NSH_DISABLE_USLEEP is not set
+CONFIG_NSH_DISABLE_WGET=y
+# CONFIG_NSH_DISABLE_XD is not set
+CONFIG_NSH_MMCSDMINOR=0
+
+#
+# Configure Command Options
+#
+# CONFIG_NSH_CMDOPT_DF_H is not set
+# CONFIG_NSH_CMDOPT_DD_STATS is not set
+CONFIG_NSH_CODECS_BUFSIZE=128
+CONFIG_NSH_CMDOPT_HEXDUMP=y
+CONFIG_NSH_PROC_MOUNTPOINT="/proc"
+CONFIG_NSH_FILEIOSIZE=512
+
+#
+# Scripting Support
+#
+# CONFIG_NSH_DISABLESCRIPT is not set
+# CONFIG_NSH_DISABLE_ITEF is not set
+# CONFIG_NSH_DISABLE_LOOPS is not set
+
+#
+# Console Configuration
+#
+CONFIG_NSH_CONSOLE=y
+# CONFIG_NSH_ALTCONDEV is not set
+CONFIG_NSH_ARCHINIT=y
+# CONFIG_NSH_LOGIN is not set
+# CONFIG_NSH_CONSOLE_LOGIN is not set
+
+#
+# NxWidgets/NxWM
+#
+
+#
+# Platform-specific Support
+#
+# CONFIG_PLATFORM_CONFIGDATA is not set
+
+#
+# System Libraries and NSH Add-Ons
+#
+# CONFIG_SYSTEM_CLE is not set
+# CONFIG_SYSTEM_CUTERM is not set
+# CONFIG_SYSTEM_FREE is not set
+# CONFIG_SYSTEM_HEX2BIN is not set
+# CONFIG_SYSTEM_HEXED is not set
+# CONFIG_SYSTEM_INSTALL is not set
+# CONFIG_SYSTEM_RAMTEST is not set
+CONFIG_READLINE_HAVE_EXTMATCH=y
+CONFIG_SYSTEM_READLINE=y
+CONFIG_READLINE_ECHO=y
+# CONFIG_READLINE_TABCOMPLETION is not set
+# CONFIG_READLINE_CMD_HISTORY is not set
+# CONFIG_SYSTEM_SUDOKU is not set
+# CONFIG_SYSTEM_SYSTEM is not set
+# CONFIG_SYSTEM_TEE is not set
+# CONFIG_SYSTEM_UBLOXMODEM is not set
+# CONFIG_SYSTEM_VI is not set
+# CONFIG_SYSTEM_ZMODEM is not set
+
+#
+# Wireless Libraries and NSH Add-Ons
+#
+
+#
+# IEEE 802.15.4 applications
+#
+CONFIG_IEEE802154_COMMON=y
+CONFIG_IEEE802154_COORD=y
+CONFIG_IEEE802154_I8SAK=y
diff --git a/configs/clicker2-stm32/src/Makefile b/configs/clicker2-stm32/src/Makefile
index bafc45bff17..3980c3ac7df 100644
--- a/configs/clicker2-stm32/src/Makefile
+++ b/configs/clicker2-stm32/src/Makefile
@@ -56,6 +56,10 @@ ifeq ($(CONFIG_LIB_BOARDCTL),y)
CSRCS += stm32_appinit.c
endif
+ifeq ($(CONFIG_IEEE802154_MRF24J40),y)
+CSRCS += stm32_mrf24j40.c
+endif
+
ifeq ($(CONFIG_ADC),y)
CSRCS += stm32_adc.c
endif
diff --git a/configs/clicker2-stm32/src/clicker2-stm32.h b/configs/clicker2-stm32/src/clicker2-stm32.h
index 5def0fdce83..7a1867a0b40 100644
--- a/configs/clicker2-stm32/src/clicker2-stm32.h
+++ b/configs/clicker2-stm32/src/clicker2-stm32.h
@@ -297,5 +297,21 @@ int stm32_adc_setup(void);
int stm32_can_setup(void);
#endif
+/****************************************************************************
+ * Name: stm32_mrf24j40_initialize
+ *
+ * Description:
+ * Initialize the MRF24J40 device.
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno value is
+ * returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_CLICKER2_STM32_MB1_BEE) || defined(CONFIG_CLICKER2_STM32_MB2_BEE)
+int stm32_mrf24j40_initialize(void);
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __CONFIGS_CLICKER2_STM32_SRC_CLICKER2_H */
diff --git a/configs/clicker2-stm32/src/stm32_bringup.c b/configs/clicker2-stm32/src/stm32_bringup.c
index 1dcc276812d..b7adf9dcc12 100644
--- a/configs/clicker2-stm32/src/stm32_bringup.c
+++ b/configs/clicker2-stm32/src/stm32_bringup.c
@@ -153,6 +153,16 @@ int stm32_bringup(void)
}
#endif
+#if defined(CONFIG_CLICKER2_STM32_MB1_BEE) || defined(CONFIG_CLICKER2_STM32_MB2_BEE)
+ /* Configure MRF24J40 wireless */
+
+ ret = stm32_mrf24j40_initialize();
+ if (ret < 0)
+ {
+ syslog(LOG_ERR, "ERROR: stm32_mrf24j40_initialize() failed: %d\n", ret);
+ }
+#endif
+
#ifdef CONFIG_BUTTONS
/* Register the BUTTON driver */
diff --git a/configs/clicker2-stm32/src/stm32_buttons.c b/configs/clicker2-stm32/src/stm32_buttons.c
index 00a571c817b..5bcd3ba9e9e 100644
--- a/configs/clicker2-stm32/src/stm32_buttons.c
+++ b/configs/clicker2-stm32/src/stm32_buttons.c
@@ -47,6 +47,7 @@
#include
#include "stm32_gpio.h"
+#include "stm32_exti.h"
#include "clicker2-stm32.h"
diff --git a/configs/clicker2-stm32/src/stm32_mrf24j40.c b/configs/clicker2-stm32/src/stm32_mrf24j40.c
new file mode 100644
index 00000000000..c92b93239b8
--- /dev/null
+++ b/configs/clicker2-stm32/src/stm32_mrf24j40.c
@@ -0,0 +1,336 @@
+/****************************************************************************
+ * configs/freedom-kl25z/src/stm32_mrf24j40.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 "stm32_gpio.h"
+#include "stm32_exti.h"
+#include "stm32_spi.h"
+
+#include "clicker2-stm32.h"
+
+#ifdef CONFIG_IEEE802154_MRF24J40
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_DRIVERS_WIRELESS
+# error Wireless support requires CONFIG_DRIVERS_WIRELESS
+#endif
+
+#if !defined(CONFIG_CLICKER2_STM32_MB1_BEE) && \
+ !defined(CONFIG_CLICKER2_STM32_MB2_BEE)
+# error Only the Mikroe BEE board is supported
+#endif
+
+#ifdef CONFIG_CLICKER2_STM32_MB1_BEE
+# ifndef CONFIG_STM32_SPI3
+# error Mikroe BEE on mikroBUS1 requires CONFIG_STM32_SPI3
+# endif
+#endif
+
+#ifdef CONFIG_CLICKER2_STM32_MB2_BEE
+# ifndef CONFIG_STM32_SPI2
+# error Mikroe BEE on mikroBUS1 requires CONFIG_STM32_SPI2
+# endif
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct stm32_priv_s
+{
+ struct mrf24j40_lower_s dev;
+ xcpt_t handler;
+ FAR void *arg;
+ uint32_t intcfg;
+ uint8_t spidev;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* IRQ/GPIO access callbacks. These operations all hidden behind callbacks
+ * to isolate the MRF24J40 driver from differences in GPIO interrupt handling
+ * varying boards and MCUs.
+ *
+ * irq_attach - Attach the MRF24J40 interrupt handler to the GPIO
+ interrupt
+ * irq_enable - Enable or disable the GPIO interrupt
+ */
+
+static int stm32_attach_irq(FAR const struct mrf24j40_lower_s *lower,
+ xcpt_t handler, FAR void *arg);
+static void stm32_enable_irq(FAR const struct mrf24j40_lower_s *lower,
+ bool state);
+static int stm32_mrf24j40_devsetup(FAR struct stm32_priv_s *priv);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* A reference to a structure of this type must be passed to the MRF24J40
+ * driver. This structure provides information about the configuration
+ * of the MRF24J40 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.
+ */
+
+#ifdef CONFIG_CLICKER2_STM32_MB1_BEE
+static struct stm32_priv_s g_mrf24j40_mb1_priv =
+{
+ .dev.attach = stm32_attach_irq,
+ .dev.enable = stm32_enable_irq,
+ .handler = NULL,
+ .intcfg = GPIO_MB1_INT,
+ .spidev = 3,
+};
+#endif
+
+#ifdef CONFIG_CLICKER2_STM32_MB2_BEE
+static struct stm32_priv_s g_mrf24j40_mb2_priv =
+{
+ .dev.attach = stm32_attach_irq,
+ .dev.enable = stm32_enable_irq,
+ .uint32_t = GPIO_MB2_INT,
+ .spidev = 2,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* IRQ/GPIO access callbacks. These operations all hidden behind
+ * callbacks to isolate the MRF24J40 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.
+ *
+ * irq_attach - Attach the MRF24J40 interrupt handler to the GPIO
+ * interrupt
+ * irq_enable - Enable or disable the GPIO interrupt
+ */
+
+static int stm32_attach_irq(FAR const struct mrf24j40_lower_s *lower,
+ xcpt_t handler, FAR void *arg)
+{
+ FAR struct stm32_priv_s *priv = (FAR struct stm32_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 stm32_enable_irq(FAR const struct mrf24j40_lower_s *lower,
+ bool state)
+{
+ FAR struct stm32_priv_s *priv = (FAR struct stm32_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));
+
+ /* Attach and enable, or detach and disable */
+
+ wlinfo("state:%d\n", (int)state);
+ if (state)
+ {
+ (void)stm32_gpiosetevent(priv->intcfg, true, true, true,
+ priv->handler, priv->arg);
+ }
+ else
+ {
+ (void)stm32_gpiosetevent(priv->intcfg, false, false, false,
+ NULL, NULL);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_mrf24j40_devsetup
+ *
+ * Description:
+ * Initialize one the MRF24J40 device in one mikroBUS slot
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno value is
+ * returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+static int stm32_mrf24j40_devsetup(FAR struct stm32_priv_s *priv)
+{
+ FAR struct ieee802154_radio_s *radio;
+#ifdef CONFIG_IEEE802154_MAC
+ MACHANDLE mac;
+#endif
+ FAR struct spi_dev_s *spi;
+ int ret;
+
+ /* Configure the interrupt pin */
+
+ stm32_configgpio(priv->intcfg);
+
+ /* Initialize the SPI bus and get an instance of the SPI interface */
+
+ spi = stm32_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 MRF24J40 device */
+
+ radio = mrf24j40_init(spi, &priv->dev);
+ if (radio == NULL)
+ {
+ wlerr("ERROR: Failed to initialize SPI bus %d\n", priv->spidev);
+ return -ENODEV;
+ }
+
+#if defined(CONFIG_IEEE802154_MAC)
+ /* Create a 802.15.4 MAC device from a 802.15.4 compatible radio device. */
+
+ mac = mac802154_create(radio);
+ if (mac == NULL)
+ {
+ wlerr("ERROR: Failed to initialize IEEE802.15.4 MAC\n");
+ return -ENODEV;
+ }
+
+#if defined(CONFIG_IEEE802154_NETDEV)
+ /* Use the IEEE802.15.4 MAC interface instance to create a 6loWPAN
+ * network interface by wrapping the MAC intrface instance in a
+ * network device driver via mac802154dev_register().
+ */
+
+ ret = mac802154netdev_register(mac);
+ if (ret < 0)
+ {
+ wlerr("ERROR: Failed to register the MAC network driver wpan%d: %d\n",
+ 0, ret);
+ return ret;
+ }
+#elif defined(CONFIG_IEEE802154_MAC_DEV)
+ /* If want to call these APIs from userspace, you have to wrap the MAC
+ * interface in a character device viamac802154dev_register().
+ */
+
+ ret = mac802154dev_register(mac, 0);
+ if (ret < 0)
+ {
+ wlerr("ERROR: Failed to register the MAC character driver /dev/ieee%d: %d\n",
+ 0, ret);
+ return ret;
+ }
+#endif
+
+#endif /* CONFIG_IEEE802154_MAC */
+
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_mrf24j40_initialize
+ *
+ * Description:
+ * Initialize the MRF24J40 device.
+ *
+ * Returned Value:
+ * Zero is returned on success. Otherwise, a negated errno value is
+ * returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int stm32_mrf24j40_initialize(void)
+{
+ int ret;
+
+#ifdef CONFIG_CLICKER2_STM32_MB1_BEE
+ wlinfo("Configuring BEE in mikroBUS1\n");
+
+ ret = stm32_mrf24j40_devsetup(&g_mrf24j40_mb1_priv);
+ if (ret < 0)
+ {
+ wlerr("ERROR: Failed to initialize BD in mikroBUS1: %d\n", ret);
+ }
+#endif
+
+#ifdef CONFIG_CLICKER2_STM32_MB2_BEE
+ wlinfo("Configuring BEE in mikroBUS2\n");
+
+ ret = stm32_mrf24j40_devsetup(&g_mrf24j40_mb2_priv);
+ if (ret < 0)
+ {
+ wlerr("ERROR: Failed to initialize BD in mikroBUS2: %d\n", ret);
+ }
+#endif
+
+ UNUSED(ret);
+ return OK;
+}
+#endif /* CONFIG_IEEE802154_MRF24J40 */
diff --git a/configs/freedom-kl25z/include/kl_cc3000.h b/configs/freedom-kl25z/include/kl_cc3000.h
index 117fc57eefc..ce252a67a04 100644
--- a/configs/freedom-kl25z/include/kl_cc3000.h
+++ b/configs/freedom-kl25z/include/kl_cc3000.h
@@ -70,9 +70,8 @@ void WriteWlanEnablePin(uint8_t val);
void AssertWlanCS(void);
-/*
- * Deassert CC3000 CS
- */
+/* Deassert CC3000 CS */
+
void DeassertWlanCS(void);
/* Setup needed pins */
diff --git a/configs/nucleo-144/Kconfig b/configs/nucleo-144/Kconfig
index 96427a9a5e2..a6ac8ffbed7 100644
--- a/configs/nucleo-144/Kconfig
+++ b/configs/nucleo-144/Kconfig
@@ -7,7 +7,7 @@ if ARCH_BOARD_NUCLEO_144
choice
prompt "Select Console wiring."
- default NUCLEO_ARDUINO
+ default NUCLEO_CONSOLE_ARDUINO
---help---
Select where you will connect the console.
diff --git a/configs/nucleo-l452re/Kconfig b/configs/nucleo-l452re/Kconfig
new file mode 100644
index 00000000000..e0e29ca22cd
--- /dev/null
+++ b/configs/nucleo-l452re/Kconfig
@@ -0,0 +1,8 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+if ARCH_BOARD_NUCLEO_L452RE
+
+endif
diff --git a/configs/nucleo-l452re/README.txt b/configs/nucleo-l452re/README.txt
new file mode 100644
index 00000000000..386c1ad8f70
--- /dev/null
+++ b/configs/nucleo-l452re/README.txt
@@ -0,0 +1,271 @@
+Nucleo-L452RE README
+====================
+
+ This README file discusses the port of NuttX to the STMicro Nucleo-L452RE
+ board. That board features the STM32L452RET6 MCU with 512KiB of FLASH
+ and 160KiB of SRAM.
+
+Contents
+========
+
+ - Status
+ - Nucleo-64 Boards
+ - LEDs
+ - Buttons
+ - Serial Console
+ - Configurations
+
+Status
+======
+ 2017-05-04: The board now boots and the basic NSH configurations works
+ without problem.
+
+Nucleo-64 Boards
+================
+
+ The Nucleo-L452RE is a member of the Nucleo-64 board family. The Nucleo-64
+ is a standard board for use with several STM32 parts in the LQFP64 package.
+ Variants including:
+
+ Order code Targeted STM32
+ ------------- --------------
+ NUCLEO-F030R8 STM32F030R8T6
+ NUCLEO-F070RB STM32F070RBT6
+ NUCLEO-F072RB STM32F072RBT6
+ NUCLEO-F091RC STM32F091RCT6
+ NUCLEO-F103RB STM32F103RBT6
+ NUCLEO-F302R8 STM32F302R8T6
+ NUCLEO-F303RE STM32F303RET6
+ NUCLEO-F334R8 STM32F334R8T6
+ NUCLEO-F401RE STM32F401RET6
+ NUCLEO-F410RB STM32F410RBT6
+ NUCLEO-F411RE STM32F411RET6
+ NUCLEO-F446RE STM32F446RET6
+ NUCLEO-L053R8 STM32L053R8T6
+ NUCLEO-L073RZ STM32L073RZT6
+ NUCLEO-L152RE STM32L152RET6
+ NUCLEO-L452RE STM32L452RET6
+ NUCLEO-L476RG STM32L476RGT6
+
+LEDs
+====
+
+ The Nucleo-64 board has one user controlable LED, User LD2. This green
+ LED is a user LED connected to Arduino signal D13 corresponding to STM32
+ I/O PA5 (PB13 on other some other Nucleo-64 boards).
+
+ - When the I/O is HIGH value, the LED is on
+ - When the I/O is LOW, the LED is off
+
+ These LEDs are not used by the board port unless CONFIG_ARCH_LEDS is
+ defined. In that case, the usage by the board port is defined in
+ include/board.h and src/stm32_autoleds.c. The LEDs are used to encode
+ OS-related events as follows when the red LED (PE24) is available:
+
+ SYMBOL Meaning LD2
+ ------------------- ----------------------- -----------
+ LED_STARTED NuttX has been started OFF
+ LED_HEAPALLOCATE Heap has been allocated OFF
+ LED_IRQSENABLED Interrupts enabled OFF
+ LED_STACKCREATED Idle stack created ON
+ LED_INIRQ In an interrupt No change
+ LED_SIGNAL In a signal handler No change
+ LED_ASSERTION An assertion failed No change
+ LED_PANIC The system has crashed Blinking
+ LED_IDLE MCU is is sleep mode Not used
+
+ Thus if LD2, NuttX has successfully booted and is, apparently, running
+ normally. If LD2 is flashing at approximately 2Hz, then a fatal error
+ has been detected and the system has halted.
+
+Buttons
+=======
+
+ B1 USER: the user button is connected to the I/O PC13 (pin 2) of the STM32
+ microcontroller.
+
+Serial Console
+==============
+
+ USART1
+ ------
+ Pins and Connectors:
+
+ RXD: PA10 D3 CN9 pin 3, CN10 pin 33
+ PB7 CN7 pin 21
+ TXD: PA9 D8 CN5 pin 1, CN10 pin 21
+ PB6 D10 CN5 pin 3, CN10 pin 17
+
+ NOTE: You may need to edit the include/board.h to select different USART1
+ pin selections.
+
+ TTL to RS-232 converter connection:
+
+ Nucleo CN10 STM32F072RB
+ ----------- ------------
+ Pin 21 PA9 USART1_TX *Warning you make need to reverse RX/TX on
+ Pin 33 PA10 USART1_RX some RS-232 converters
+ Pin 20 GND
+ Pin 8 U5V
+
+ To configure USART1 as the console:
+
+ CONFIG_STM32_USART1=y
+ CONFIG_USART1_SERIALDRIVER=y
+ CONFIG_USART1_SERIAL_CONSOLE=y
+ CONFIG_USART1_RXBUFSIZE=256
+ CONFIG_USART1_TXBUFSIZE=256
+ CONFIG_USART1_BAUD=115200
+ CONFIG_USART1_BITS=8
+ CONFIG_USART1_PARITY=0
+ CONFIG_USART1_2STOP=0
+
+ USART2
+ ------
+ Pins and Connectors:
+
+ RXD: PA3 To be provided
+ PA15
+ PD6
+ TXD: PA2
+ PA14
+ PD5
+
+ See "Virtual COM Port" and "RS-232 Shield" below.
+
+ USART3
+ ------
+ Pins and Connectors:
+
+ RXD: PB11 To be provided
+ PC5
+ PC11
+ D9
+ TXD: PB10
+ PC4
+ PC10
+ D8
+
+ USART3
+ ------
+ Pins and Connectors:
+
+ RXD: PA1 To be provided
+ PC11
+ TXD: PA0
+ PC10
+
+ Virtual COM Port
+ ----------------
+ Yet another option is to use UART2 and the USB virtual COM port. This
+ option may be more convenient for long term development, but is painful
+ to use during board bring-up.
+
+ Solder Bridges. This configuration requires:
+
+ - SB62 and SB63 Open: PA2 and PA3 on STM32 MCU are disconnected to D1
+ and D0 (pin 7 and pin 8) on Arduino connector CN9 and ST Morpho
+ connector CN10.
+
+ - SB13 and SB14 Closed: PA2 and PA3 on STM32F103C8T6 (ST-LINK MCU) are
+ connected to PA3 and PA2 on STM32 MCU to have USART communication
+ between them. Thus SB61, SB62 and SB63 should be OFF.
+
+ Configuring USART2 is the same as given above.
+
+ 115200 8N1 BAUD should be configure to interface with the Virtual COM
+ port.
+
+ Default
+ -------
+ As shipped, SB62 and SB63 are open and SB13 and SB14 closed, so the
+ virtual COM port is enabled.
+
+ RS-232 Shield
+ -------------
+ Supports a single RS-232 connected via
+
+ Nucleo STM32F4x1RE Shield
+ --------- --------------- --------
+ CN9 Pin 1 PA3 USART2_RXD RXD
+ CN9 Pin 2 PA2 USART2_TXD TXD
+
+ Support for this shield is enabled by selecting USART2 and configuring
+ SB13, 14, 62, and 63 as described above under "Virtual COM Port"
+
+Configurations
+==============
+
+ Information Common to All Configurations
+ ----------------------------------------
+ Each configuration is maintained in a sub-directory and can be
+ selected as follow:
+
+ cd tools
+ ./configure.sh nucleo-l452re/
+ cd -
+
+ Before building, make sure the PATH environment variable includes the
+ correct path to the directory than holds your toolchain binaries.
+
+ And then build NuttX by simply typing the following. At the conclusion of
+ the make, the nuttx binary will reside in an ELF file called, simply, nuttx.
+
+ make oldconfig
+ make
+
+ The that is provided above as an argument to the tools/configure.sh
+ must be is one of the following.
+
+ NOTES:
+
+ 1. These configurations use the mconf-based configuration tool. To
+ change any of these configurations using that tool, you should:
+
+ a. Build and install the kconfig-mconf tool. See nuttx/README.txt
+ see additional README.txt files in the NuttX tools repository.
+
+ b. Execute 'make menuconfig' in nuttx/ in order to start the
+ reconfiguration process.
+
+ 2. Unless stated otherwise, all configurations generate console
+ output on USART2, as described above under "Serial Console". The
+ elevant configuration settings are listed below:
+
+ CONFIG_STM32_USART2=y
+ CONFIG_STM32_USART2_SERIALDRIVER=y
+ CONFIG_STM32_USART=y
+
+ CONFIG_USART2_SERIALDRIVER=y
+ CONFIG_USART2_SERIAL_CONSOLE=y
+
+ CONFIG_USART2_RXBUFSIZE=256
+ CONFIG_USART2_TXBUFSIZE=256
+ CONFIG_USART2_BAUD=115200
+ CONFIG_USART2_BITS=8
+ CONFIG_USART2_PARITY=0
+ CONFIG_USART2_2STOP=0
+
+ 3. All of these configurations are set up to build under Linux using the
+ "GNU Tools for ARM Embedded Processors" that is maintained by ARM
+ (unless stated otherwise in the description of the configuration).
+
+ https://launchpad.net/gcc-arm-embedded
+
+ That toolchain selection can easily be reconfigured using
+ 'make menuconfig'. Here are the relevant current settings:
+
+ Build Setup:
+ CONFIG_HOST_LINUX=y : Linux environment
+
+ System Type -> Toolchain:
+ CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y : GNU ARM EABI toolchain
+
+ Configuration sub-directories
+ -----------------------------
+
+ nsh:
+
+ Configures the NuttShell (nsh) located at examples/nsh. This
+ configuration is focused on low level, command-line driver testing.
+
diff --git a/configs/nucleo-l452re/include/board.h b/configs/nucleo-l452re/include/board.h
new file mode 100644
index 00000000000..30e452dca75
--- /dev/null
+++ b/configs/nucleo-l452re/include/board.h
@@ -0,0 +1,272 @@
+/************************************************************************************
+ * configs/nucleo-l452re/include/board.h
+ *
+ * Copyright (C) 2016 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 __CONFIGS_NUCLEO_L452RE_INCLUDE_BOARD_H
+#define __CONFIGS_NUCLEO_L452RE_INCLUDE_BOARD_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+#ifndef __ASSEMBLY__
+# include
+#endif
+
+#include
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Clocking *************************************************************************/
+
+#if defined(CONFIG_ARCH_CHIP_STM32L452RE)
+# include
+#endif
+
+/* DMA Channel/Stream Selections ****************************************************/
+/* Stream selections are arbitrary for now but might become important in the future
+ * is we set aside more DMA channels/streams.
+ */
+
+/* Values defined in arch/arm/src/stm32l4/chip/stm32l4x3xx_dma.h */
+
+#define DMACHAN_SDMMC DMACHAN_SDMMC_1 /* 2 choices */
+
+#define DMACHAN_SPI1_RX DMACHAN_SPI1_RX_1 /* 2 choices */
+#define DMACHAN_SPI1_TX DMACHAN_SPI1_TX_1 /* 2 choices */
+
+/* UART RX DMA configurations */
+
+#define DMACHAN_USART1_RX DMACHAN_USART1_RX_2
+
+/* Alternate function pin selections ************************************************/
+
+/* USART1:
+ * RXD: PA10 CN9 pin 3, CN10 pin 33
+ * PB7 CN7 pin 21
+ * TXD: PA9 CN5 pin 1, CN10 pin 21
+ * PB6 CN5 pin 3, CN10 pin 17
+ */
+
+#if 1
+# define GPIO_USART1_RX GPIO_USART1_RX_1 /* PA10 */
+# define GPIO_USART1_TX GPIO_USART1_TX_1 /* PA9 */
+#else
+# define GPIO_USART1_RX GPIO_USART1_RX_2 /* PB7 */
+# define GPIO_USART1_TX GPIO_USART1_TX_2 /* PB6 */
+#endif
+
+/* USART2: Connected to STLink Debug via PA2, PA3
+ * RXD: PA3 CN9 pin 1 (See SB13, 14, 62, 63). CN10 pin 37
+ * PD6
+ * TXD: PA2 CN9 pin 2 (See SB13, 14, 62, 63). CN10 pin 35
+ * PD5
+ */
+
+#define GPIO_USART2_RX GPIO_USART2_RX_1 /* PA3 */
+#define GPIO_USART2_TX GPIO_USART2_TX_1 /* PA2 */
+#define GPIO_USART2_RTS GPIO_USART2_RTS_2
+#define GPIO_USART2_CTS GPIO_USART2_CTS_2
+
+#define GPIO_USART3_RX GPIO_USART3_RX_3 /* PC11 */
+#define GPIO_USART3_TX GPIO_USART3_TX_3 /* PC10 */
+
+#define GPIO_UART4_RX GPIO_UART4_RX_1 /* PA1 */
+#define GPIO_UART4_TX GPIO_UART4_TX_1 /* PA0 */
+
+/* I2C
+ *
+ * The optional _GPIO configurations allow the I2C driver to manually
+ * reset the bus to clear stuck slaves. They match the pin configuration,
+ * but are normally-high GPIOs.
+ */
+
+#define GPIO_I2C1_SCL \
+ (GPIO_I2C1_SCL_2 | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET)
+#define GPIO_I2C1_SDA \
+ (GPIO_I2C1_SDA_2 | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET)
+#define GPIO_I2C1_SCL_GPIO \
+ (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | \
+ GPIO_PORTB | GPIO_PIN8)
+#define GPIO_I2C1_SDA_GPIO \
+ (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | \
+ GPIO_PORTB | GPIO_PIN9)
+
+#define GPIO_I2C2_SCL \
+ (GPIO_I2C2_SCL_1 | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET)
+#define GPIO_I2C2_SDA \
+ (GPIO_I2C2_SDA_1 | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET)
+#define GPIO_I2C2_SCL_GPIO \
+ (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | \
+ GPIO_PORTB | GPIO_PIN10)
+#define GPIO_I2C2_SDA_GPIO \
+ (GPIO_OUTPUT | GPIO_OPENDRAIN | GPIO_SPEED_50MHz | GPIO_OUTPUT_SET | \
+ GPIO_PORTB | GPIO_PIN11)
+
+/* SPI */
+
+#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1
+#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_1
+#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1
+
+#define GPIO_SPI2_MISO GPIO_SPI2_MISO_1
+#define GPIO_SPI2_MOSI GPIO_SPI2_MOSI_1
+#define GPIO_SPI2_SCK GPIO_SPI2_SCK_2
+
+/* LEDs
+ *
+ * The Nucleo L452RE board provides a single user LED, LD2. LD2
+ * is the green LED connected to Arduino signal D13 corresponding to MCU I/O
+ * PA5 (pin 21) or PB13 (pin 34) depending on the STM32 target.
+ *
+ * - When the I/O is HIGH value, the LED is on.
+ * - When the I/O is LOW, the LED is off.
+ */
+
+/* LED index values for use with board_userled() */
+
+#define BOARD_LD2 0
+#define BOARD_NLEDS 1
+
+/* LED bits for use with board_userled_all() */
+
+#define BOARD_LD2_BIT (1 << BOARD_LD2)
+
+/* These LEDs are not used by the board port unless CONFIG_ARCH_LEDS is
+ * defined. In that case, the usage by the board port is defined in
+ * include/board.h and src/stm32_autoleds.c. The LEDs are used to encode
+ * OS-related events as follows when the red LED (PE24) is available:
+ *
+ * SYMBOL Meaning LD2
+ * ------------------- ----------------------- -----------
+ * LED_STARTED NuttX has been started OFF
+ * LED_HEAPALLOCATE Heap has been allocated OFF
+ * LED_IRQSENABLED Interrupts enabled OFF
+ * LED_STACKCREATED Idle stack created ON
+ * LED_INIRQ In an interrupt No change
+ * LED_SIGNAL In a signal handler No change
+ * LED_ASSERTION An assertion failed No change
+ * LED_PANIC The system has crashed Blinking
+ * LED_IDLE MCU is is sleep mode Not used
+ *
+ * Thus if LD2, NuttX has successfully booted and is, apparently, running
+ * normally. If LD2 is flashing at approximately 2Hz, then a fatal error
+ * has been detected and the system has halted.
+ */
+
+#define LED_STARTED 0
+#define LED_HEAPALLOCATE 0
+#define LED_IRQSENABLED 0
+#define LED_STACKCREATED 1
+#define LED_INIRQ 1
+#define LED_SIGNAL 2
+#define LED_ASSERTION 2
+#define LED_PANIC 1
+
+/* Buttons
+ *
+ * B1 USER: the user button is connected to the I/O PC13 (pin 2) of the STM32
+ * microcontroller.
+ */
+
+#define BUTTON_USER 0
+#define NUM_BUTTONS 1
+
+#define BUTTON_USER_BIT (1 << BUTTON_USER)
+
+/* Quadrature encoder
+ * Default is to use timer 5 (32-bit) and encoder on PA0/PA1
+ */
+
+#define GPIO_TIM2_CH1IN GPIO_TIM2_CH1IN_1
+#define GPIO_TIM2_CH2IN GPIO_TIM2_CH2IN_1
+
+#define GPIO_TIM3_CH1IN GPIO_TIM3_CH1IN_3
+#define GPIO_TIM3_CH2IN GPIO_TIM3_CH2IN_3
+
+#define GPIO_TIM5_CH1IN GPIO_TIM5_CH1IN_1
+#define GPIO_TIM5_CH2IN GPIO_TIM5_CH2IN_1
+
+/* PWM output for full bridge, uses config 1, because port E is N/A on QFP64
+ * CH1 | 1(A8) 2(E9)
+ * CH2 | 1(A9) 2(E11)
+ * CHN1 | 1(A7) 2(B13) 3(E8)
+ * CHN2 | 1(B0) 2(B14) 3(E10)
+ */
+
+#define GPIO_TIM1_CH1OUT GPIO_TIM1_CH1OUT_1
+#define GPIO_TIM1_CH1NOUT GPIO_TIM1_CH1N_1
+#define GPIO_TIM1_CH2OUT GPIO_TIM1_CH2OUT_1
+#define GPIO_TIM1_CH2NOUT GPIO_TIM1_CH2N_1
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+/************************************************************************************
+ * Name: stm32l4_boardinitialize
+ *
+ * Description:
+ * All STM32L4 architectures must provide the following entry point. This entry point
+ * is called early in the initialization -- after all memory has been configured
+ * and mapped but before any devices have been initialized.
+ *
+ ************************************************************************************/
+
+void stm32l4_boardinitialize(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __CONFIGS_NUCLEO_L452RE_INCLUDE_BOARD_H */
diff --git a/configs/nucleo-l452re/include/nucleo-l452re.h b/configs/nucleo-l452re/include/nucleo-l452re.h
new file mode 100644
index 00000000000..0074a64d9b9
--- /dev/null
+++ b/configs/nucleo-l452re/include/nucleo-l452re.h
@@ -0,0 +1,510 @@
+/************************************************************************************
+ * configs/nucleo-l452re/include/nucleo-l452re.h
+ *
+ * Copyright (C) 2016 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 __CONFIGS_NUCLEO_L452RE_INCLUDE_NUCLEO_L452RE_H
+#define __CONFIGS_NUCLEO_L452RE_INCLUDE_NUCLEO_L452RE_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+#ifndef __ASSEMBLY__
+# include
+#endif
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+#if 1
+# define HSI_CLOCK_CONFIG /* HSI-16 clock configuration */
+#elif 0
+/* Make sure you installed one! */
+
+# define HSE_CLOCK_CONFIG /* HSE with 8 MHz xtal */
+#else
+# define MSI_CLOCK_CONFIG /* MSI @ 4 MHz autotrimmed via LSE */
+#endif
+
+/* Clocking *************************************************************************/
+
+#if defined(HSI_CLOCK_CONFIG)
+/* The NUCLEOL452RE supports both HSE and LSE crystals (X2 and X3). However, as
+ * shipped, the X3 crystal is not populated. Therefore the Nucleo-L452RE
+ * will need to run off the 16MHz HSI clock, or the 32khz-synced MSI.
+ *
+ * System Clock source : PLL (HSI)
+ * SYSCLK(Hz) : 80000000 Determined by PLL configuration
+ * HCLK(Hz) : 80000000 (STM32L4_RCC_CFGR_HPRE) (Max 80 MHz)
+ * AHB Prescaler : 1 (STM32L4_RCC_CFGR_HPRE) (Max 80 MHz)
+ * APB1 Prescaler : 1 (STM32L4_RCC_CFGR_PPRE1) (Max 80 MHz)
+ * APB2 Prescaler : 1 (STM32L4_RCC_CFGR_PPRE2) (Max 80 MHz)
+ * HSI Frequency(Hz) : 16000000 (nominal)
+ * PLLM : 1 (STM32L4_PLLCFG_PLLM)
+ * PLLN : 10 (STM32L4_PLLCFG_PLLN)
+ * PLLP : 0 (STM32L4_PLLCFG_PLLP)
+ * PLLQ : 0 (STM32L4_PLLCFG_PLLQ)
+ * PLLR : 2 (STM32L4_PLLCFG_PLLR)
+ * PLLSAI1N : 12
+ * PLLSAI1Q : 4
+ * Flash Latency(WS) : 4
+ * Prefetch Buffer : OFF
+ * 48MHz for USB OTG FS, : Doable if required using PLLSAI1 or MSI
+ * SDIO and RNG clock
+ */
+
+/* HSI - 16 MHz RC factory-trimmed
+ * LSI - 32 KHz RC
+ * MSI - variable up to 48 MHz, synchronized to LSE
+ * HSE - not installed
+ * LSE - 32.768 kHz installed
+ */
+
+#define STM32L4_HSI_FREQUENCY 16000000ul
+#define STM32L4_LSI_FREQUENCY 32000
+#define STM32L4_LSE_FREQUENCY 32768
+
+#define STM32L4_BOARD_USEHSI 1
+
+/* XXX sysclk mux = pllclk */
+
+/* XXX pll source mux = hsi */
+
+/* REVISIT: Trimming of the HSI and MSI is not yet supported. */
+
+/* Main PLL Configuration.
+ *
+ * Formulae:
+ *
+ * VCO input frequency = PLL input clock frequency / PLLM, 1 <= PLLM <= 8
+ * VCO output frequency = VCO input frequency × PLLN, 8 <= PLLN <= 86, frequency range 64 to 344 MHz
+ * PLL output P (SAI3) clock frequency = VCO frequency / PLLP, PLLP = 7, or 17, or 0 to disable
+ * PLL output Q (48M1) clock frequency = VCO frequency / PLLQ, PLLQ = 2, 4, 6, or 8, or 0 to disable
+ * PLL output R (CLK) clock frequency = VCO frequency / PLLR, PLLR = 2, 4, 6, or 8, or 0 to disable
+ *
+ * PLL output P is used for SAI
+ * PLL output Q is used for OTG FS, SDMMC, RNG
+ * PLL output R is used for SYSCLK
+ * PLLP = 0 (not used)
+ * PLLQ = 0 (not used)
+ * PLLR = 2
+ * PLLN = 10
+ * PLLM = 1
+ *
+ * We will configure like this
+ *
+ * PLL source is HSI
+ *
+ * PLL_REF = STM32L4_HSI_FREQUENCY / PLLM
+ * = 16,000,000 / 1
+ * = 16,000,000
+ *
+ * PLL_VCO = PLL_REF * PLLN
+ * = 16,000,000 * 10
+ * = 160,000,000
+ *
+ * PLL_CLK = PLL_VCO / PLLR
+ * = 160,000,000 / 2 = 80,000,000
+ * PLL_48M1 = disabled
+ * PLL_SAI3 = disabled
+ *
+ * ----------------------------------------
+ *
+ * PLLSAI1 Configuration
+ *
+ * The clock input and M divider are identical to the main PLL.
+ * However the multiplier and postscalers are independent.
+ * The PLLSAI1 is configured only if CONFIG_STM32L4_SAI1PLL is defined
+ *
+ * SAI1VCO input frequency = PLL input clock frequency
+ * SAI1VCO output frequency = SAI1VCO input frequency × PLLSAI1N, 8 <= PLLSAI1N <= 86, frequency range 64 to 344 MHz
+ * SAI1PLL output P (SAI1) clock frequency = SAI1VCO frequency / PLLSAI1P, PLLP = 7, or 17, or 0 to disable
+ * SAI1PLL output Q (48M2) clock frequency = SAI1VCO frequency / PLLSAI1Q, PLLQ = 2, 4, 6, or 8, or 0 to disable
+ * SAI1PLL output R (ADC1) clock frequency = SAI1VCO frequency / PLLSAI1R, PLLR = 2, 4, 6, or 8, or 0 to disable
+ *
+ * We will configure like this
+ *
+ * PLLSAI1 disabled
+ *
+ * ----------------------------------------
+ *
+ * PLLSAI2 Configuration
+ *
+ * The clock input and M divider are identical to the main PLL.
+ * However the multiplier and postscalers are independent.
+ * The PLLSAI2 is configured only if CONFIG_STM32L4_SAI2PLL is defined
+ *
+ * SAI2VCO input frequency = PLL input clock frequency
+ * SAI2VCO output frequency = SAI2VCO input frequency × PLLSAI2N, 8 <= PLLSAI1N <= 86, frequency range 64 to 344 MHz
+ * SAI2PLL output P (SAI2) clock frequency = SAI2VCO frequency / PLLSAI2P, PLLP = 7, or 17, or 0 to disable
+ * SAI2PLL output R (ADC2) clock frequency = SAI2VCO frequency / PLLSAI2R, PLLR = 2, 4, 6, or 8, or 0 to disable
+ *
+ * We will configure like this
+ *
+ * PLLSAI2 disabled
+ *
+ * ----------------------------------------
+ *
+ * TODO: The STM32L is a low power peripheral and all these clocks should be configurable at runtime.
+ *
+ * ----------------------------------------
+ *
+ * TODO These clock sources can be configured in Kconfig (this is not a board feature)
+ * USART1
+ * USART2
+ * USART3
+ * UART4
+ * UART5
+ * LPUART1
+ * I2C1
+ * I2C2
+ * I2C3
+ * LPTIM1
+ * LPTIM2
+ * SAI1
+ * SAI2
+ * CLK48
+ * ADC
+ * SWPMI
+ * DFSDM
+ */
+
+/* prescaler common to all PLL inputs; will be 1 (XXX source is implicitly
+ as per comment above HSI) */
+
+#define STM32L4_PLLCFG_PLLM RCC_PLLCFG_PLLM(1)
+
+/* 'main' PLL config; we use this to generate our system clock via the R
+ * output. We set it up as 16 MHz / 1 * 10 / 2 = 80 MHz
+ *
+ * XXX NOTE: currently the main PLL is implicitly turned on and is implicitly
+ * the system clock; this should be configurable since not all applications may
+ * want things done this way.
+ */
+
+#define STM32L4_PLLCFG_PLLN RCC_PLLCFG_PLLN(10)
+#define STM32L4_PLLCFG_PLLP 0
+#undef STM32L4_PLLCFG_PLLP_ENABLED
+#define STM32L4_PLLCFG_PLLQ RCC_PLLCFG_PLLQ_2
+#define STM32L4_PLLCFG_PLLQ_ENABLED
+#define STM32L4_PLLCFG_PLLR RCC_PLLCFG_PLLR(2)
+#define STM32L4_PLLCFG_PLLR_ENABLED
+
+/* 'SAIPLL1' is used to generate the 48 MHz clock, since we can't
+ * do that with the main PLL's N value. We set N = 12, and enable
+ * the Q output (ultimately for CLK48) with /4. So,
+ * 16 MHz / 1 * 12 / 4 = 48 MHz
+ *
+ * XXX NOTE: currently the SAIPLL /must/ be explicitly selected in the
+ * menuconfig, or else all this is a moot point, and the various 48 MHz
+ * peripherals will not work (RNG at present). I would suggest removing
+ * that option from Kconfig altogether, and simply making it an option
+ * that is selected via a #define here, like all these other params.
+ */
+
+#define STM32L4_PLLSAI1CFG_PLLN RCC_PLLSAI1CFG_PLLN(12)
+#define STM32L4_PLLSAI1CFG_PLLP 0
+#undef STM32L4_PLLSAI1CFG_PLLP_ENABLED
+#define STM32L4_PLLSAI1CFG_PLLQ RCC_PLLSAI1CFG_PLLQ_4
+#define STM32L4_PLLSAI1CFG_PLLQ_ENABLED
+#define STM32L4_PLLSAI1CFG_PLLR 0
+#undef STM32L4_PLLSAI1CFG_PLLR_ENABLED
+
+/* 'SAIPLL2' is not used in this application */
+
+#define STM32L4_PLLSAI2CFG_PLLN RCC_PLLSAI2CFG_PLLN(8)
+#define STM32L4_PLLSAI2CFG_PLLP 0
+#undef STM32L4_PLLSAI2CFG_PLLP_ENABLED
+#define STM32L4_PLLSAI2CFG_PLLR 0
+#undef STM32L4_PLLSAI2CFG_PLLR_ENABLED
+
+#define STM32L4_SYSCLK_FREQUENCY 80000000ul
+
+/* CLK48 will come from PLLSAI1 (implicitly Q) */
+
+#define STM32L4_USE_CLK48
+#define STM32L4_CLK48_SEL RCC_CCIPR_CLK48SEL_PLLSAI1
+
+/* enable the LSE oscillator, used automatically trim the MSI, and for RTC */
+
+#define STM32L4_USE_LSE 1
+
+/* AHB clock (HCLK) is SYSCLK (80MHz) */
+
+#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 */
+
+/* APB1 clock (PCLK1) is HCLK/1 (80MHz) */
+
+#define STM32L4_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLK /* PCLK1 = HCLK / 1 */
+#define STM32L4_PCLK1_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
+
+/* Timers driven from APB1 will be twice PCLK1 */
+/* REVISIT : this can be configured */
+
+#define STM32L4_APB1_TIM2_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM3_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM4_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM5_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM6_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM7_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+
+/* APB2 clock (PCLK2) is HCLK (80MHz) */
+
+#define STM32L4_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLK /* PCLK2 = HCLK / 1 */
+#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
+
+/* Timers driven from APB2 will be twice PCLK2 */
+/* REVISIT : this can be configured */
+
+#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
+#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
+
+/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
+ * otherwise frequency is 2xAPBx.
+ * Note: TIM1,8 are on APB2, others on APB1
+ */
+/* REVISIT : this can be configured */
+
+/* TODO SDMMC */
+
+#elif defined(HSE_CLOCK_CONFIG)
+
+/* Use the HSE */
+
+#define STM32L4_BOARD_USEHSE 1
+
+/* XXX sysclk mux = pllclk */
+
+/* XXX pll source mux = hse */
+
+/* Prescaler common to all PLL inputs */
+
+#define STM32L4_PLLCFG_PLLM RCC_PLLCFG_PLLM(1)
+
+/* 'main' PLL config; we use this to generate our system clock */
+
+#define STM32L4_PLLCFG_PLLN RCC_PLLCFG_PLLN(20)
+#define STM32L4_PLLCFG_PLLP 0
+#undef STM32L4_PLLCFG_PLLP_ENABLED
+#define STM32L4_PLLCFG_PLLQ 0
+#undef STM32L4_PLLCFG_PLLQ_ENABLED
+#define STM32L4_PLLCFG_PLLR RCC_PLLCFG_PLLR_2
+#define STM32L4_PLLCFG_PLLR_ENABLED
+
+/* 'SAIPLL1' is used to generate the 48 MHz clock */
+
+#define STM32L4_PLLSAI1CFG_PLLN RCC_PLLSAI1CFG_PLLN(12)
+#define STM32L4_PLLSAI1CFG_PLLP 0
+#undef STM32L4_PLLSAI1CFG_PLLP_ENABLED
+#define STM32L4_PLLSAI1CFG_PLLQ RCC_PLLSAI1CFG_PLLQ_2
+#define STM32L4_PLLSAI1CFG_PLLQ_ENABLED
+#define STM32L4_PLLSAI1CFG_PLLR 0
+#undef STM32L4_PLLSAI1CFG_PLLR_ENABLED
+
+/* 'SAIPLL2' is not used in this application */
+
+#define STM32L4_PLLSAI2CFG_PLLN RCC_PLLSAI2CFG_PLLN(8)
+#define STM32L4_PLLSAI2CFG_PLLP 0
+#undef STM32L4_PLLSAI2CFG_PLLP_ENABLED
+#define STM32L4_PLLSAI2CFG_PLLR 0
+#undef STM32L4_PLLSAI2CFG_PLLR_ENABLED
+
+#define STM32L4_SYSCLK_FREQUENCY 80000000ul
+
+/* Enable CLK48; get it from PLLSAI1 */
+
+#define STM32L4_USE_CLK48
+#define STM32L4_CLK48_SEL RCC_CCIPR_CLK48SEL_PLLSAI1
+
+/* Enable LSE (for the RTC) */
+
+#define STM32L4_USE_LSE 1
+
+/* Configure the HCLK divisor (for the AHB bus, core, memory, and DMA */
+
+#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 */
+
+/* Configure the APB1 prescaler */
+
+#define STM32L4_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLK /* PCLK1 = HCLK / 1 */
+#define STM32L4_PCLK1_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
+
+#define STM32L4_APB1_TIM2_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM3_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM4_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM5_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM6_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM7_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+
+/* Configure the APB2 prescaler */
+
+#define STM32L4_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLK /* PCLK2 = HCLK / 1 */
+#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
+
+#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
+#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
+
+#elif defined(MSI_CLOCK_CONFIG)
+
+/* Use the MSI; frequ = 4 MHz; autotrim from LSE */
+
+#define STM32L4_BOARD_USEMSI 1
+#define STM32L4_BOARD_MSIRANGE RCC_CR_MSIRANGE_4M
+
+/* XXX sysclk mux = pllclk */
+
+/* XXX pll source mux = msi */
+
+/* prescaler common to all PLL inputs */
+
+#define STM32L4_PLLCFG_PLLM RCC_PLLCFG_PLLM(1)
+
+/* 'main' PLL config; we use this to generate our system clock */
+
+#define STM32L4_PLLCFG_PLLN RCC_PLLCFG_PLLN(40)
+#define STM32L4_PLLCFG_PLLP 0
+#undef STM32L4_PLLCFG_PLLP_ENABLED
+#define STM32L4_PLLCFG_PLLQ 0
+#undef STM32L4_PLLCFG_PLLQ_ENABLED
+#define STM32L4_PLLCFG_PLLR RCC_PLLCFG_PLLR_2
+#define STM32L4_PLLCFG_PLLR_ENABLED
+
+/* 'SAIPLL1' is used to generate the 48 MHz clock */
+
+#define STM32L4_PLLSAI1CFG_PLLN RCC_PLLSAI1CFG_PLLN(24)
+#define STM32L4_PLLSAI1CFG_PLLP 0
+#undef STM32L4_PLLSAI1CFG_PLLP_ENABLED
+#define STM32L4_PLLSAI1CFG_PLLQ RCC_PLLSAI1CFG_PLLQ_2
+#define STM32L4_PLLSAI1CFG_PLLQ_ENABLED
+#define STM32L4_PLLSAI1CFG_PLLR 0
+#undef STM32L4_PLLSAI1CFG_PLLR_ENABLED
+
+/* 'SAIPLL2' is not used in this application */
+
+#define STM32L4_PLLSAI2CFG_PLLN RCC_PLLSAI2CFG_PLLN(8)
+#define STM32L4_PLLSAI2CFG_PLLP 0
+#undef STM32L4_PLLSAI2CFG_PLLP_ENABLED
+#define STM32L4_PLLSAI2CFG_PLLR 0
+#undef STM32L4_PLLSAI2CFG_PLLR_ENABLED
+
+#define STM32L4_SYSCLK_FREQUENCY 80000000ul
+
+/* Enable CLK48; get it from PLLSAI1 */
+
+#define STM32L4_USE_CLK48
+#define STM32L4_CLK48_SEL RCC_CCIPR_CLK48SEL_PLLSAI1
+
+/* Enable LSE (for the RTC) */
+
+#define STM32L4_USE_LSE 1
+
+/* Configure the HCLK divisor (for the AHB bus, core, memory, and DMA */
+
+#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 */
+
+/* Configure the APB1 prescaler */
+
+#define STM32L4_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLK /* PCLK1 = HCLK / 1 */
+#define STM32L4_PCLK1_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
+
+#define STM32L4_APB1_TIM2_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM3_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM4_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM5_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM6_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+#define STM32L4_APB1_TIM7_CLKIN (2*STM32L4_PCLK1_FREQUENCY)
+
+/* Configure the APB2 prescaler */
+
+#define STM32L4_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLK /* PCLK2 = HCLK / 1 */
+#define STM32L4_PCLK2_FREQUENCY (STM32L4_HCLK_FREQUENCY/1)
+
+#define STM32L4_APB2_TIM1_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
+#define STM32L4_APB2_TIM8_CLKIN (2*STM32L4_PCLK2_FREQUENCY)
+
+#endif
+
+/* Timer Frequencies, if APBx is set to 1, frequency is same to APBx
+ * otherwise frequency is 2xAPBx.
+ * Note: TIM1,8,15,16,17 are on APB2, others on APB1
+ */
+
+#define BOARD_TIM1_FREQUENCY STM32L4_HCLK_FREQUENCY
+#define BOARD_TIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
+#define BOARD_TIM3_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
+#define BOARD_TIM4_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
+#define BOARD_TIM5_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
+#define BOARD_TIM6_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
+#define BOARD_TIM7_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
+#define BOARD_TIM8_FREQUENCY STM32L4_HCLK_FREQUENCY
+#define BOARD_TIM15_FREQUENCY STM32L4_HCLK_FREQUENCY
+#define BOARD_TIM16_FREQUENCY STM32L4_HCLK_FREQUENCY
+#define BOARD_TIM17_FREQUENCY STM32L4_HCLK_FREQUENCY
+#define BOARD_LPTIM1_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
+#define BOARD_LPTIM2_FREQUENCY (STM32L4_HCLK_FREQUENCY / 2)
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __CONFIGS_NUCLEO_L452RE_INCLUDE_NUCLEO_L452RE_H */
diff --git a/configs/nucleo-l452re/nsh/Make.defs b/configs/nucleo-l452re/nsh/Make.defs
new file mode 100644
index 00000000000..39adcf7611d
--- /dev/null
+++ b/configs/nucleo-l452re/nsh/Make.defs
@@ -0,0 +1,112 @@
+############################################################################
+# configs/nucleo-l452re/nsh/Make.defs
+#
+# Copyright (C) 2014 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 ${TOPDIR}/.config
+include ${TOPDIR}/tools/Config.mk
+include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
+
+LDSCRIPT = l452re-flash.ld
+
+ifeq ($(WINTOOL),y)
+ # Windows-native toolchains
+ DIRLINK = $(TOPDIR)/tools/copydir.sh
+ DIRUNLINK = $(TOPDIR)/tools/unlink.sh
+ MKDEP = $(TOPDIR)/tools/mknulldeps.sh
+ ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
+ ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
+ ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
+else
+ # Linux/Cygwin-native toolchain
+ MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
+ ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
+ ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
+ ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
+endif
+
+CC = $(CROSSDEV)gcc
+CXX = $(CROSSDEV)g++
+CPP = $(CROSSDEV)gcc -E
+LD = $(CROSSDEV)ld
+AR = $(ARCROSSDEV)ar rcs
+NM = $(ARCROSSDEV)nm
+OBJCOPY = $(CROSSDEV)objcopy
+OBJDUMP = $(CROSSDEV)objdump
+
+ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
+ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
+
+ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
+ ARCHOPTIMIZATION = -g
+endif
+
+ifneq ($(CONFIG_DEBUG_NOOPT),y)
+ ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer
+endif
+
+ARCHCFLAGS = -fno-builtin
+ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti
+ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
+ARCHWARNINGSXX = -Wall -Wshadow -Wundef
+ARCHDEFINES =
+ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
+
+CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
+CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
+CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
+AFLAGS = $(CFLAGS) -D__ASSEMBLY__
+
+NXFLATLDFLAGS1 = -r -d -warn-common
+NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
+LDNXFLATFLAGS = -e main -s 2048
+
+ASMEXT = .S
+OBJEXT = .o
+LIBEXT = .a
+EXEEXT =
+
+ifneq ($(CROSSDEV),arm-nuttx-elf-)
+ LDFLAGS += -nostartfiles -nodefaultlibs
+endif
+ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
+ LDFLAGS += -g
+endif
+
+HOSTCC = gcc
+HOSTINCLUDES = -I.
+HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe
+HOSTLDFLAGS =
+
diff --git a/configs/nucleo-l452re/nsh/defconfig b/configs/nucleo-l452re/nsh/defconfig
new file mode 100644
index 00000000000..5030287da06
--- /dev/null
+++ b/configs/nucleo-l452re/nsh/defconfig
@@ -0,0 +1,1258 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Nuttx/ Configuration
+#
+
+#
+# Build Setup
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_DEFAULT_SMALL is not set
+CONFIG_HOST_LINUX=y
+# CONFIG_HOST_OSX is not set
+# CONFIG_HOST_WINDOWS is not set
+# CONFIG_HOST_OTHER is not set
+
+#
+# Build Configuration
+#
+CONFIG_APPS_DIR="../apps"
+CONFIG_BUILD_FLAT=y
+# CONFIG_BUILD_2PASS is not set
+
+#
+# Binary Output Formats
+#
+# CONFIG_RRLOAD_BINARY is not set
+# CONFIG_INTELHEX_BINARY is not set
+# CONFIG_MOTOROLA_SREC is not set
+CONFIG_RAW_BINARY=y
+# CONFIG_UBOOT_UIMAGE is not set
+
+#
+# Customize Header Files
+#
+# CONFIG_ARCH_STDINT_H is not set
+# CONFIG_ARCH_STDBOOL_H is not set
+# CONFIG_ARCH_MATH_H is not set
+# CONFIG_ARCH_FLOAT_H is not set
+# CONFIG_ARCH_STDARG_H is not set
+# CONFIG_ARCH_DEBUG_H is not set
+
+#
+# Debug Options
+#
+CONFIG_DEBUG_ALERT=y
+CONFIG_DEBUG_FEATURES=y
+
+#
+# Debug SYSLOG Output Controls
+#
+CONFIG_DEBUG_ERROR=y
+CONFIG_DEBUG_WARN=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_ASSERTIONS=y
+
+#
+# Subsystem Debug Options
+#
+# CONFIG_DEBUG_BINFMT is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_GRAPHICS is not set
+# CONFIG_DEBUG_LIB is not set
+# CONFIG_DEBUG_MM is not set
+# CONFIG_DEBUG_SCHED is not set
+
+#
+# OS Function Debug Options
+#
+# CONFIG_DEBUG_DMA is not set
+# CONFIG_DEBUG_IRQ is not set
+
+#
+# Driver Debug Options
+#
+# CONFIG_DEBUG_LEDS is not set
+# CONFIG_DEBUG_ANALOG is not set
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_DEBUG_I2C is not set
+# CONFIG_DEBUG_RTC is not set
+# CONFIG_DEBUG_SPI is not set
+# CONFIG_DEBUG_TIMER is not set
+CONFIG_ARCH_HAVE_STACKCHECK=y
+CONFIG_STACK_COLORATION=y
+CONFIG_ARCH_HAVE_HEAPCHECK=y
+# CONFIG_HEAP_COLORATION is not set
+CONFIG_DEBUG_SYMBOLS=y
+CONFIG_ARCH_HAVE_CUSTOMOPT=y
+CONFIG_DEBUG_NOOPT=y
+# CONFIG_DEBUG_CUSTOMOPT is not set
+# CONFIG_DEBUG_FULLOPT is not set
+
+#
+# System Type
+#
+CONFIG_ARCH_ARM=y
+# CONFIG_ARCH_AVR is not set
+# CONFIG_ARCH_HC is not set
+# CONFIG_ARCH_MIPS is not set
+# CONFIG_ARCH_MISOC is not set
+# CONFIG_ARCH_RENESAS is not set
+# CONFIG_ARCH_RISCV is not set
+# CONFIG_ARCH_SIM is not set
+# CONFIG_ARCH_X86 is not set
+# CONFIG_ARCH_XTENSA is not set
+# CONFIG_ARCH_Z16 is not set
+# CONFIG_ARCH_Z80 is not set
+CONFIG_ARCH="arm"
+
+#
+# ARM Options
+#
+# CONFIG_ARCH_CHIP_A1X is not set
+# CONFIG_ARCH_CHIP_C5471 is not set
+# CONFIG_ARCH_CHIP_DM320 is not set
+# CONFIG_ARCH_CHIP_EFM32 is not set
+# CONFIG_ARCH_CHIP_IMX1 is not set
+# CONFIG_ARCH_CHIP_IMX6 is not set
+# CONFIG_ARCH_CHIP_KINETIS is not set
+# CONFIG_ARCH_CHIP_KL is not set
+# CONFIG_ARCH_CHIP_LM is not set
+# CONFIG_ARCH_CHIP_TIVA is not set
+# CONFIG_ARCH_CHIP_LPC11XX is not set
+# CONFIG_ARCH_CHIP_LPC17XX is not set
+# CONFIG_ARCH_CHIP_LPC214X is not set
+# CONFIG_ARCH_CHIP_LPC2378 is not set
+# CONFIG_ARCH_CHIP_LPC31XX is not set
+# CONFIG_ARCH_CHIP_LPC43XX is not set
+# CONFIG_ARCH_CHIP_MOXART is not set
+# CONFIG_ARCH_CHIP_NUC1XX is not set
+# CONFIG_ARCH_CHIP_SAMA5 is not set
+# CONFIG_ARCH_CHIP_SAMD is not set
+# CONFIG_ARCH_CHIP_SAML is not set
+# CONFIG_ARCH_CHIP_SAM34 is not set
+# CONFIG_ARCH_CHIP_SAMV7 is not set
+# CONFIG_ARCH_CHIP_STM32 is not set
+# CONFIG_ARCH_CHIP_STM32F0 is not set
+# CONFIG_ARCH_CHIP_STM32F7 is not set
+CONFIG_ARCH_CHIP_STM32L4=y
+# CONFIG_ARCH_CHIP_STR71X is not set
+# CONFIG_ARCH_CHIP_TMS570 is not set
+# CONFIG_ARCH_CHIP_XMC4 is not set
+# CONFIG_ARCH_ARM7TDMI is not set
+# CONFIG_ARCH_ARM926EJS is not set
+# CONFIG_ARCH_ARM920T is not set
+# CONFIG_ARCH_CORTEXM0 is not set
+# CONFIG_ARCH_CORTEXM23 is not set
+# CONFIG_ARCH_CORTEXM3 is not set
+# CONFIG_ARCH_CORTEXM33 is not set
+CONFIG_ARCH_CORTEXM4=y
+# CONFIG_ARCH_CORTEXM7 is not set
+# CONFIG_ARCH_CORTEXA5 is not set
+# CONFIG_ARCH_CORTEXA8 is not set
+# CONFIG_ARCH_CORTEXA9 is not set
+# CONFIG_ARCH_CORTEXR4 is not set
+# CONFIG_ARCH_CORTEXR4F is not set
+# CONFIG_ARCH_CORTEXR5 is not set
+# CONFIG_ARCH_CORTEX5F is not set
+# CONFIG_ARCH_CORTEXR7 is not set
+# CONFIG_ARCH_CORTEXR7F is not set
+CONFIG_ARCH_FAMILY="armv7-m"
+CONFIG_ARCH_CHIP="stm32l4"
+# CONFIG_ARM_TOOLCHAIN_IAR is not set
+CONFIG_ARM_TOOLCHAIN_GNU=y
+# CONFIG_ARMV7M_USEBASEPRI is not set
+CONFIG_ARCH_HAVE_CMNVECTOR=y
+CONFIG_ARMV7M_CMNVECTOR=y
+# CONFIG_ARMV7M_LAZYFPU is not set
+CONFIG_ARCH_HAVE_FPU=y
+# CONFIG_ARCH_HAVE_DPFPU is not set
+# CONFIG_ARCH_FPU is not set
+# CONFIG_ARCH_HAVE_TRUSTZONE is not set
+CONFIG_ARM_HAVE_MPU_UNIFIED=y
+# CONFIG_ARM_MPU is not set
+# CONFIG_DEBUG_HARDFAULT is not set
+
+#
+# ARMV7M Configuration Options
+#
+# CONFIG_ARMV7M_HAVE_ICACHE is not set
+# CONFIG_ARMV7M_HAVE_DCACHE is not set
+# CONFIG_ARMV7M_HAVE_ITCM is not set
+# CONFIG_ARMV7M_HAVE_DTCM is not set
+# CONFIG_ARMV7M_TOOLCHAIN_IARL is not set
+# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
+# CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set
+# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set
+CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y
+CONFIG_ARMV7M_HAVE_STACKCHECK=y
+CONFIG_ARMV7M_STACKCHECK=y
+# CONFIG_ARMV7M_ITMSYSLOG is not set
+CONFIG_SERIAL_TERMIOS=y
+# CONFIG_USART2_RS485 is not set
+# CONFIG_USART2_RXDMA is not set
+# CONFIG_SERIAL_DISABLE_REORDERING is not set
+
+#
+# STM32L4 Configuration Options
+#
+# CONFIG_ARCH_CHIP_STM32L432KB is not set
+# CONFIG_ARCH_CHIP_STM32L432KC is not set
+# CONFIG_ARCH_CHIP_STM32L442KC is not set
+# CONFIG_ARCH_CHIP_STM32L451CC is not set
+# CONFIG_ARCH_CHIP_STM32L451CE is not set
+# CONFIG_ARCH_CHIP_STM32L451RC is not set
+# CONFIG_ARCH_CHIP_STM32L451RE is not set
+# CONFIG_ARCH_CHIP_STM32L451VC is not set
+# CONFIG_ARCH_CHIP_STM32L451VE is not set
+# CONFIG_ARCH_CHIP_STM32L452CC is not set
+# CONFIG_ARCH_CHIP_STM32L452CE is not set
+# CONFIG_ARCH_CHIP_STM32L452RC is not set
+CONFIG_ARCH_CHIP_STM32L452RE=y
+# CONFIG_ARCH_CHIP_STM32L452VC is not set
+# CONFIG_ARCH_CHIP_STM32L452VE is not set
+# CONFIG_ARCH_CHIP_STM32L462CE is not set
+# CONFIG_ARCH_CHIP_STM32L462RE is not set
+# CONFIG_ARCH_CHIP_STM32L462VE is not set
+# CONFIG_ARCH_CHIP_STM32L476RG is not set
+# CONFIG_ARCH_CHIP_STM32L476RE is not set
+# CONFIG_ARCH_CHIP_STM32L486 is not set
+# CONFIG_ARCH_CHIP_STM32L496ZE is not set
+# CONFIG_ARCH_CHIP_STM32L496ZG is not set
+# CONFIG_ARCH_CHIP_STM32L4A6 is not set
+# CONFIG_STM32L4_STM32L4X1 is not set
+CONFIG_STM32L4_STM32L4X2=y
+CONFIG_STM32L4_STM32L4X3=y
+# CONFIG_STM32L4_STM32L4X5 is not set
+# CONFIG_STM32L4_STM32L4X6 is not set
+# CONFIG_STM32L4_STM32L431XX is not set
+# CONFIG_STM32L4_STM32L432XX is not set
+# CONFIG_STM32L4_STM32L433XX is not set
+# CONFIG_STM32L4_STM32L442XX is not set
+# CONFIG_STM32L4_STM32L443XX is not set
+# CONFIG_STM32L4_STM32L451XX is not set
+CONFIG_STM32L4_STM32L452XX=y
+# CONFIG_STM32L4_STM32L462XX is not set
+# CONFIG_STM32L4_STM32L471XX is not set
+# CONFIG_STM32L4_STM32L476XX is not set
+# CONFIG_STM32L4_STM32L486XX is not set
+# CONFIG_STM32L4_STM32L496XX is not set
+# CONFIG_STM32L4_STM32L4A6XX is not set
+CONFIG_STM32L4_FLASH_OVERRIDE_DEFAULT=y
+# CONFIG_STM32L4_FLASH_OVERRIDE_B is not set
+# CONFIG_STM32L4_FLASH_OVERRIDE_C is not set
+# CONFIG_STM32L4_FLASH_OVERRIDE_E is not set
+# CONFIG_STM32L4_FLASH_OVERRIDE_G is not set
+# CONFIG_STM32L4_FLASH_CONFIG_B is not set
+# CONFIG_STM32L4_FLASH_CONFIG_C is not set
+CONFIG_STM32L4_FLASH_CONFIG_E=y
+# CONFIG_STM32L4_IO_CONFIG_K is not set
+# CONFIG_STM32L4_IO_CONFIG_C is not set
+CONFIG_STM32L4_IO_CONFIG_R=y
+# CONFIG_STM32L4_IO_CONFIG_J is not set
+# CONFIG_STM32L4_IO_CONFIG_M is not set
+# CONFIG_STM32L4_IO_CONFIG_V is not set
+# CONFIG_STM32L4_IO_CONFIG_Q is not set
+# CONFIG_STM32L4_IO_CONFIG_Z is not set
+# CONFIG_STM32L4_IO_CONFIG_A is not set
+
+#
+# STM32L4 SRAM2 Options
+#
+CONFIG_STM32L4_SRAM2_HEAP=y
+CONFIG_STM32L4_SRAM2_INIT=y
+
+#
+# STM32L4 Peripherals
+#
+
+#
+# STM32L4 Peripheral Support
+#
+# CONFIG_STM32L4_HAVE_ADC2 is not set
+# CONFIG_STM32L4_HAVE_ADC3 is not set
+# CONFIG_STM32L4_HAVE_AES is not set
+# CONFIG_STM32L4_HAVE_CAN2 is not set
+CONFIG_STM32L4_HAVE_COMP=y
+# CONFIG_STM32L4_HAVE_DAC2 is not set
+# CONFIG_STM32L4_HAVE_DCMI is not set
+CONFIG_STM32L4_HAVE_DFSDM1=y
+# CONFIG_STM32L4_HAVE_DMA2D is not set
+# CONFIG_STM32L4_HAVE_FSMC is not set
+# CONFIG_STM32L4_HAVE_HASH is not set
+CONFIG_STM32L4_HAVE_I2C4=y
+# CONFIG_STM32L4_HAVE_LCD is not set
+# CONFIG_STM32L4_HAVE_LTDC is not set
+CONFIG_STM32L4_HAVE_LPTIM1=y
+CONFIG_STM32L4_HAVE_LPTIM2=y
+# CONFIG_STM32L4_HAVE_OTGFS is not set
+CONFIG_STM32L4_HAVE_SAI1=y
+# CONFIG_STM32L4_HAVE_SAI2 is not set
+CONFIG_STM32L4_HAVE_SDMMC1=y
+CONFIG_STM32L4_HAVE_TIM3=y
+# CONFIG_STM32L4_HAVE_TIM4 is not set
+# CONFIG_STM32L4_HAVE_TIM5 is not set
+# CONFIG_STM32L4_HAVE_TIM7 is not set
+# CONFIG_STM32L4_HAVE_TIM8 is not set
+# CONFIG_STM32L4_HAVE_TIM17 is not set
+# CONFIG_STM32L4_ADC is not set
+# CONFIG_STM32L4_CAN is not set
+# CONFIG_STM32L4_DAC is not set
+CONFIG_STM32L4_DMA=y
+CONFIG_STM32L4_I2C=y
+# CONFIG_STM32L4_SAI is not set
+CONFIG_STM32L4_SPI=y
+CONFIG_STM32L4_USART=y
+# CONFIG_STM32L4_LPTIM is not set
+
+#
+# AHB1 Peripherals
+#
+CONFIG_STM32L4_DMA1=y
+CONFIG_STM32L4_DMA2=y
+# CONFIG_STM32L4_CRC is not set
+# CONFIG_STM32L4_TSC is not set
+
+#
+# AHB2 Peripherals
+#
+# CONFIG_STM32L4_ADC1 is not set
+CONFIG_STM32L4_RNG=y
+
+#
+# AHB3 Peripherals
+#
+# CONFIG_STM32L4_QSPI is not set
+
+#
+# APB1 Peripherals
+#
+CONFIG_STM32L4_PWR=y
+# CONFIG_STM32L4_TIM2 is not set
+# CONFIG_STM32L4_TIM3 is not set
+# CONFIG_STM32L4_TIM6 is not set
+# CONFIG_STM32L4_SPI2 is not set
+# CONFIG_STM32L4_SPI3 is not set
+# CONFIG_STM32L4_USART1 is not set
+CONFIG_STM32L4_USART2=y
+# CONFIG_STM32L4_USART3 is not set
+# CONFIG_STM32L4_UART4 is not set
+CONFIG_STM32L4_I2C1=y
+# CONFIG_STM32L4_I2C2 is not set
+# CONFIG_STM32L4_I2C3 is not set
+# CONFIG_STM32L4_I2C4 is not set
+# CONFIG_STM32L4_CAN1 is not set
+# CONFIG_STM32L4_DAC1 is not set
+# CONFIG_STM32L4_OPAMP is not set
+# CONFIG_STM32L4_LPTIM1 is not set
+# CONFIG_STM32L4_LPUART1 is not set
+# CONFIG_STM32L4_SWPMI is not set
+# CONFIG_STM32L4_LPTIM2 is not set
+
+#
+# APB2 Peripherals
+#
+CONFIG_STM32L4_SYSCFG=y
+CONFIG_STM32L4_FIREWALL=y
+# CONFIG_STM32L4_SDMMC1 is not set
+# CONFIG_STM32L4_TIM1 is not set
+CONFIG_STM32L4_SPI1=y
+# CONFIG_STM32L4_TIM15 is not set
+# CONFIG_STM32L4_TIM16 is not set
+# CONFIG_STM32L4_COMP is not set
+# CONFIG_STM32L4_SAI1 is not set
+# CONFIG_STM32L4_DFSDM1 is not set
+
+#
+# Other Peripherals
+#
+# CONFIG_STM32L4_BKPSRAM is not set
+# CONFIG_STM32L4_IWDG is not set
+# CONFIG_STM32L4_WWDG is not set
+CONFIG_STM32L4_FLASH_PREFETCH=y
+CONFIG_STM32L4_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
+# CONFIG_ARCH_BOARD_STM32L4_CUSTOM_CLOCKCONFIG is not set
+CONFIG_STM32L4_RTC_LSECLOCK=y
+# CONFIG_STM32L4_RTC_LSICLOCK is not set
+# CONFIG_STM32L4_RTC_HSECLOCK is not set
+CONFIG_STM32L4_SAI1PLL=y
+
+#
+# Timer Configuration
+#
+# CONFIG_STM32L4_ONESHOT is not set
+# CONFIG_STM32L4_FREERUN is not set
+# CONFIG_STM32L4_TIM3_CAP is not set
+CONFIG_STM32L4_HAVE_USART1=y
+CONFIG_STM32L4_HAVE_USART2=y
+CONFIG_STM32L4_HAVE_USART3=y
+CONFIG_STM32L4_HAVE_UART4=y
+# CONFIG_STM32L4_HAVE_UART5 is not set
+
+#
+# U[S]ART Configuration
+#
+# CONFIG_STM32L4_FLOWCONTROL_BROKEN is not set
+# CONFIG_STM32L4_USART_BREAKS is not set
+
+#
+# SPI Configuration
+#
+# CONFIG_STM32L4_SPI_INTERRUPTS is not set
+# CONFIG_STM32L4_SPI_DMA is not set
+
+#
+# I2C Configuration
+#
+# CONFIG_STM32L4_I2C_DYNTIMEO is not set
+CONFIG_STM32L4_I2CTIMEOSEC=0
+CONFIG_STM32L4_I2CTIMEOMS=500
+CONFIG_STM32L4_I2CTIMEOTICKS=500
+# CONFIG_STM32L4_I2C_DUTY16_9 is not set
+
+#
+# Architecture Options
+#
+# CONFIG_ARCH_NOINTC is not set
+# CONFIG_ARCH_VECNOTIRQ is not set
+CONFIG_ARCH_DMA=y
+CONFIG_ARCH_HAVE_IRQPRIO=y
+# CONFIG_ARCH_L2CACHE is not set
+# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set
+# CONFIG_ARCH_HAVE_ADDRENV is not set
+# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set
+# CONFIG_ARCH_HAVE_MULTICPU is not set
+CONFIG_ARCH_HAVE_VFORK=y
+# CONFIG_ARCH_HAVE_MMU is not set
+CONFIG_ARCH_HAVE_MPU=y
+# CONFIG_ARCH_NAND_HWECC is not set
+# CONFIG_ARCH_HAVE_EXTCLK is not set
+# CONFIG_ARCH_HAVE_POWEROFF is not set
+CONFIG_ARCH_HAVE_RESET=y
+# CONFIG_ARCH_HAVE_RTC_SUBSECONDS is not set
+# CONFIG_ARCH_USE_MPU is not set
+# CONFIG_ARCH_IRQPRIO is not set
+CONFIG_ARCH_STACKDUMP=y
+# CONFIG_ENDIAN_BIG is not set
+# CONFIG_ARCH_IDLE_CUSTOM is not set
+# CONFIG_ARCH_HAVE_RAMFUNCS is not set
+CONFIG_ARCH_HAVE_RAMVECTORS=y
+# CONFIG_ARCH_RAMVECTORS is not set
+# CONFIG_ARCH_MINIMAL_VECTORTABLE is not set
+
+#
+# Board Settings
+#
+CONFIG_BOARD_LOOPSPERMSEC=8499
+# CONFIG_ARCH_CALIBRATION is not set
+
+#
+# Interrupt options
+#
+CONFIG_ARCH_HAVE_INTERRUPTSTACK=y
+CONFIG_ARCH_INTERRUPTSTACK=2048
+CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y
+# CONFIG_ARCH_HIPRI_INTERRUPT is not set
+
+#
+# Boot options
+#
+# CONFIG_BOOT_RUNFROMEXTSRAM is not set
+CONFIG_BOOT_RUNFROMFLASH=y
+# CONFIG_BOOT_RUNFROMISRAM is not set
+# CONFIG_BOOT_RUNFROMSDRAM is not set
+# CONFIG_BOOT_COPYTORAM is not set
+
+#
+# Boot Memory Configuration
+#
+CONFIG_RAM_START=0x20000000
+CONFIG_RAM_SIZE=131072
+# CONFIG_ARCH_HAVE_SDRAM is not set
+
+#
+# Board Selection
+#
+CONFIG_ARCH_BOARD_NUCLEO_L452RE=y
+# CONFIG_ARCH_BOARD_CUSTOM is not set
+CONFIG_ARCH_BOARD="nucleo-l452re"
+
+#
+# Common Board Options
+#
+CONFIG_ARCH_HAVE_LEDS=y
+CONFIG_ARCH_LEDS=y
+CONFIG_ARCH_HAVE_BUTTONS=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_HAVE_IRQBUTTONS=y
+CONFIG_ARCH_IRQBUTTONS=y
+
+#
+# Board-Specific Options
+#
+# CONFIG_BOARD_CRASHDUMP is not set
+CONFIG_LIB_BOARDCTL=y
+# CONFIG_BOARDCTL_RESET is not set
+# CONFIG_BOARDCTL_UNIQUEID is not set
+# CONFIG_BOARDCTL_TSCTEST is not set
+# CONFIG_BOARDCTL_GRAPHICS is not set
+# CONFIG_BOARDCTL_IOCTL is not set
+
+#
+# RTOS Features
+#
+CONFIG_DISABLE_OS_API=y
+# CONFIG_DISABLE_POSIX_TIMERS is not set
+# CONFIG_DISABLE_PTHREAD is not set
+# CONFIG_DISABLE_SIGNALS is not set
+# CONFIG_DISABLE_MQUEUE is not set
+# CONFIG_DISABLE_ENVIRON is not set
+
+#
+# Clocks and Timers
+#
+CONFIG_ARCH_HAVE_TICKLESS=y
+# CONFIG_SCHED_TICKLESS is not set
+CONFIG_USEC_PER_TICK=10000
+# CONFIG_SYSTEM_TIME64 is not set
+# CONFIG_CLOCK_MONOTONIC is not set
+# CONFIG_ARCH_HAVE_TIMEKEEPING is not set
+# CONFIG_JULIAN_TIME is not set
+CONFIG_START_YEAR=2017
+CONFIG_START_MONTH=1
+CONFIG_START_DAY=1
+CONFIG_MAX_WDOGPARMS=2
+CONFIG_PREALLOC_WDOGS=8
+CONFIG_WDOG_INTRESERVE=1
+CONFIG_PREALLOC_TIMERS=4
+
+#
+# Tasks and Scheduling
+#
+# CONFIG_SPINLOCK is not set
+# CONFIG_INIT_NONE is not set
+CONFIG_INIT_ENTRYPOINT=y
+# CONFIG_INIT_FILEPATH is not set
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_RR_INTERVAL=200
+# CONFIG_SCHED_SPORADIC is not set
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_MAX_TASKS=16
+# CONFIG_SCHED_HAVE_PARENT is not set
+CONFIG_SCHED_WAITPID=y
+
+#
+# Pthread Options
+#
+# CONFIG_PTHREAD_MUTEX_TYPES is not set
+CONFIG_PTHREAD_MUTEX_ROBUST=y
+# CONFIG_PTHREAD_MUTEX_UNSAFE is not set
+# CONFIG_PTHREAD_MUTEX_BOTH is not set
+CONFIG_NPTHREAD_KEYS=4
+# CONFIG_PTHREAD_CLEANUP is not set
+# CONFIG_CANCELLATION_POINTS is not set
+
+#
+# Performance Monitoring
+#
+# CONFIG_SCHED_CPULOAD is not set
+# CONFIG_SCHED_INSTRUMENTATION is not set
+
+#
+# Files and I/O
+#
+CONFIG_DEV_CONSOLE=y
+# CONFIG_FDCLONE_DISABLE is not set
+# CONFIG_FDCLONE_STDIO is not set
+CONFIG_SDCLONE_DISABLE=y
+CONFIG_NFILE_DESCRIPTORS=8
+CONFIG_NFILE_STREAMS=8
+CONFIG_NAME_MAX=32
+# CONFIG_PRIORITY_INHERITANCE is not set
+
+#
+# RTOS hooks
+#
+# CONFIG_BOARD_INITIALIZE is not set
+# CONFIG_SCHED_STARTHOOK is not set
+# CONFIG_SCHED_ATEXIT is not set
+# CONFIG_SCHED_ONEXIT is not set
+
+#
+# Signal Numbers
+#
+CONFIG_SIG_SIGUSR1=1
+CONFIG_SIG_SIGUSR2=2
+CONFIG_SIG_SIGALARM=3
+CONFIG_SIG_SIGCONDTIMEDOUT=16
+
+#
+# POSIX Message Queue Options
+#
+CONFIG_PREALLOC_MQ_MSGS=4
+CONFIG_MQ_MAXMSGSIZE=32
+# CONFIG_MODULE is not set
+
+#
+# Work queue support
+#
+# CONFIG_SCHED_WORKQUEUE is not set
+# CONFIG_SCHED_HPWORK is not set
+# CONFIG_SCHED_LPWORK is not set
+
+#
+# Stack and heap information
+#
+CONFIG_IDLETHREAD_STACKSIZE=1024
+CONFIG_USERMAIN_STACKSIZE=2048
+CONFIG_PTHREAD_STACK_MIN=256
+CONFIG_PTHREAD_STACK_DEFAULT=2048
+# CONFIG_LIB_SYSCALL is not set
+
+#
+# Device Drivers
+#
+CONFIG_DISABLE_POLL=y
+CONFIG_DEV_NULL=y
+# CONFIG_DEV_ZERO is not set
+CONFIG_ARCH_HAVE_RNG=y
+CONFIG_DEV_RANDOM=y
+# CONFIG_DEV_URANDOM is not set
+# CONFIG_DEV_LOOP is not set
+
+#
+# Buffering
+#
+
+#
+# Common I/O Buffer Support
+#
+# CONFIG_DRIVERS_IOB is not set
+# CONFIG_DRVR_WRITEBUFFER is not set
+# CONFIG_DRVR_READAHEAD is not set
+# CONFIG_RAMDISK is not set
+# CONFIG_CAN is not set
+# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set
+# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set
+# CONFIG_PWM is not set
+CONFIG_ARCH_HAVE_I2CRESET=y
+CONFIG_I2C=y
+# CONFIG_I2C_SLAVE is not set
+# CONFIG_I2C_POLLED is not set
+CONFIG_I2C_RESET=y
+# CONFIG_I2C_TRACE is not set
+CONFIG_I2C_DRIVER=y
+# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set
+# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set
+CONFIG_ARCH_HAVE_SPI_BITORDER=y
+CONFIG_SPI=y
+# CONFIG_SPI_SLAVE is not set
+CONFIG_SPI_EXCHANGE=y
+# CONFIG_SPI_CMDDATA is not set
+# CONFIG_SPI_CALLBACK is not set
+# CONFIG_SPI_HWFEATURES is not set
+# CONFIG_SPI_BITORDER is not set
+# CONFIG_SPI_CS_DELAY_CONTROL is not set
+# CONFIG_SPI_DRIVER is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_I2S is not set
+
+#
+# Timer Driver Support
+#
+# CONFIG_TIMER is not set
+# CONFIG_ONESHOT is not set
+CONFIG_RTC=y
+CONFIG_RTC_DATETIME=y
+CONFIG_RTC_ALARM=y
+CONFIG_RTC_NALARMS=2
+CONFIG_RTC_DRIVER=y
+CONFIG_RTC_IOCTL=y
+# CONFIG_RTC_EXTERNAL is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_TIMERS_CS2100CP is not set
+CONFIG_ANALOG=y
+# CONFIG_ADC is not set
+# CONFIG_COMP is not set
+# CONFIG_DAC is not set
+# CONFIG_OPAMP is not set
+# CONFIG_AUDIO_DEVICES is not set
+# CONFIG_VIDEO_DEVICES is not set
+# CONFIG_BCH is not set
+# CONFIG_INPUT is not set
+
+#
+# IO Expander/GPIO Support
+#
+# CONFIG_IOEXPANDER is not set
+# CONFIG_DEV_GPIO is not set
+
+#
+# LCD Driver Support
+#
+# CONFIG_LCD is not set
+# CONFIG_SLCD is not set
+
+#
+# LED Support
+#
+# CONFIG_USERLED is not set
+# CONFIG_RGBLED is not set
+# CONFIG_PCA9635PW is not set
+# CONFIG_NCP5623C is not set
+# CONFIG_MMCSD is not set
+# CONFIG_MODEM is not set
+# CONFIG_MTD is not set
+# CONFIG_EEPROM is not set
+# CONFIG_PIPES is not set
+# CONFIG_PM is not set
+# CONFIG_POWER is not set
+# CONFIG_SENSORS is not set
+CONFIG_SERIAL=y
+# CONFIG_DEV_LOWCONSOLE is not set
+# CONFIG_SERIAL_REMOVABLE is not set
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_16550_UART is not set
+# CONFIG_UART_SERIALDRIVER is not set
+# CONFIG_UART0_SERIALDRIVER is not set
+# CONFIG_UART1_SERIALDRIVER is not set
+# CONFIG_UART2_SERIALDRIVER is not set
+# CONFIG_UART3_SERIALDRIVER is not set
+# CONFIG_UART4_SERIALDRIVER is not set
+# CONFIG_UART5_SERIALDRIVER is not set
+# CONFIG_UART6_SERIALDRIVER is not set
+# CONFIG_UART7_SERIALDRIVER is not set
+# CONFIG_UART8_SERIALDRIVER is not set
+# CONFIG_SCI0_SERIALDRIVER is not set
+# CONFIG_SCI1_SERIALDRIVER is not set
+# CONFIG_USART0_SERIALDRIVER is not set
+# CONFIG_USART1_SERIALDRIVER is not set
+CONFIG_USART2_SERIALDRIVER=y
+# CONFIG_USART3_SERIALDRIVER is not set
+# CONFIG_USART4_SERIALDRIVER is not set
+# CONFIG_USART5_SERIALDRIVER is not set
+# CONFIG_USART6_SERIALDRIVER is not set
+# CONFIG_USART7_SERIALDRIVER is not set
+# CONFIG_USART8_SERIALDRIVER is not set
+# CONFIG_OTHER_UART_SERIALDRIVER is not set
+CONFIG_MCU_SERIAL=y
+CONFIG_STANDARD_SERIAL=y
+# CONFIG_SERIAL_IFLOWCONTROL is not set
+# CONFIG_SERIAL_OFLOWCONTROL is not set
+# CONFIG_SERIAL_DMA is not set
+# CONFIG_SERIAL_TIOCSERGSTRUCT is not set
+CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y
+CONFIG_USART2_SERIAL_CONSOLE=y
+# CONFIG_OTHER_SERIAL_CONSOLE is not set
+# CONFIG_NO_SERIAL_CONSOLE is not set
+
+#
+# USART2 Configuration
+#
+CONFIG_USART2_RXBUFSIZE=128
+CONFIG_USART2_TXBUFSIZE=128
+CONFIG_USART2_BAUD=115200
+CONFIG_USART2_BITS=8
+CONFIG_USART2_PARITY=0
+CONFIG_USART2_2STOP=0
+# CONFIG_USART2_IFLOWCONTROL is not set
+# CONFIG_USART2_OFLOWCONTROL is not set
+# CONFIG_USART2_DMA is not set
+# CONFIG_PSEUDOTERM is not set
+# CONFIG_USBDEV is not set
+# CONFIG_USBHOST is not set
+# CONFIG_USBMISC is not set
+# CONFIG_HAVE_USBTRACE is not set
+# CONFIG_DRIVERS_WIRELESS is not set
+# CONFIG_DRIVERS_CONTACTLESS is not set
+
+#
+# System Logging
+#
+# CONFIG_ARCH_SYSLOG is not set
+# CONFIG_RAMLOG is not set
+# CONFIG_SYSLOG_INTBUFFER is not set
+# CONFIG_SYSLOG_TIMESTAMP is not set
+CONFIG_SYSLOG_SERIAL_CONSOLE=y
+# CONFIG_SYSLOG_CHAR is not set
+CONFIG_SYSLOG_CONSOLE=y
+# CONFIG_SYSLOG_NONE is not set
+# CONFIG_SYSLOG_FILE is not set
+# CONFIG_SYSLOG_CHARDEV is not set
+
+#
+# Networking Support
+#
+# CONFIG_ARCH_HAVE_NET is not set
+# CONFIG_ARCH_HAVE_PHY is not set
+# CONFIG_NET is not set
+
+#
+# Crypto API
+#
+# CONFIG_CRYPTO is not set
+
+#
+# File Systems
+#
+
+#
+# File system configuration
+#
+# CONFIG_DISABLE_MOUNTPOINT is not set
+# CONFIG_FS_AUTOMOUNTER is not set
+# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
+# CONFIG_PSEUDOFS_SOFTLINKS is not set
+CONFIG_FS_READABLE=y
+# CONFIG_FS_WRITABLE is not set
+# CONFIG_FS_NAMED_SEMAPHORES is not set
+CONFIG_FS_MQUEUE_MPATH="/var/mqueue"
+# CONFIG_FS_RAMMAP is not set
+# CONFIG_FS_FAT is not set
+# CONFIG_FS_NXFFS is not set
+# CONFIG_FS_ROMFS is not set
+# CONFIG_FS_TMPFS is not set
+# CONFIG_FS_SMARTFS is not set
+# CONFIG_FS_BINFS is not set
+CONFIG_FS_PROCFS=y
+CONFIG_FS_PROCFS_REGISTER=y
+
+#
+# Exclude individual procfs entries
+#
+# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set
+# CONFIG_FS_UNIONFS is not set
+
+#
+# Graphics Support
+#
+# CONFIG_NX is not set
+
+#
+# Memory Management
+#
+# CONFIG_MM_SMALL is not set
+CONFIG_MM_REGIONS=2
+# CONFIG_ARCH_HAVE_HEAP2 is not set
+# CONFIG_GRAN is not set
+
+#
+# Audio Support
+#
+# CONFIG_AUDIO is not set
+
+#
+# Wireless Support
+#
+
+#
+# Binary Loader
+#
+# CONFIG_BINFMT_DISABLE is not set
+# CONFIG_BINFMT_EXEPATH is not set
+# CONFIG_NXFLAT is not set
+# CONFIG_ELF is not set
+CONFIG_BUILTIN=y
+# CONFIG_PIC is not set
+# CONFIG_SYMTAB_ORDEREDBYNAME is not set
+
+#
+# Library Routines
+#
+
+#
+# Standard C Library Options
+#
+
+#
+# Standard C I/O
+#
+# CONFIG_STDIO_DISABLE_BUFFERING is not set
+CONFIG_STDIO_BUFFER_SIZE=64
+CONFIG_STDIO_LINEBUFFER=y
+CONFIG_NUNGET_CHARS=2
+# CONFIG_NOPRINTF_FIELDWIDTH is not set
+# CONFIG_LIBC_FLOATINGPOINT is not set
+CONFIG_LIBC_LONG_LONG=y
+# CONFIG_LIBC_SCANSET is not set
+# CONFIG_EOL_IS_CR is not set
+# CONFIG_EOL_IS_LF is not set
+# CONFIG_EOL_IS_BOTH_CRLF is not set
+CONFIG_EOL_IS_EITHER_CRLF=y
+# CONFIG_MEMCPY_VIK is not set
+# CONFIG_LIBM is not set
+
+#
+# Architecture-Specific Support
+#
+CONFIG_ARCH_LOWPUTC=y
+# CONFIG_ARCH_ROMGETC is not set
+# CONFIG_LIBC_ARCH_MEMCPY is not set
+# CONFIG_LIBC_ARCH_MEMCMP is not set
+# CONFIG_LIBC_ARCH_MEMMOVE is not set
+# CONFIG_LIBC_ARCH_MEMSET is not set
+# CONFIG_LIBC_ARCH_STRCHR is not set
+# CONFIG_LIBC_ARCH_STRCMP is not set
+# CONFIG_LIBC_ARCH_STRCPY is not set
+# CONFIG_LIBC_ARCH_STRNCPY is not set
+# CONFIG_LIBC_ARCH_STRLEN is not set
+# CONFIG_LIBC_ARCH_STRNLEN is not set
+# CONFIG_LIBC_ARCH_ELF is not set
+# CONFIG_ARMV7M_MEMCPY is not set
+
+#
+# stdlib Options
+#
+CONFIG_LIB_RAND_ORDER=1
+CONFIG_LIB_HOMEDIR="/"
+
+#
+# Program Execution Options
+#
+# CONFIG_LIBC_EXECFUNCS is not set
+CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024
+CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
+
+#
+# errno Decode Support
+#
+# CONFIG_LIBC_STRERROR is not set
+# CONFIG_LIBC_PERROR_STDOUT is not set
+
+#
+# memcpy/memset Options
+#
+# CONFIG_MEMSET_OPTSPEED is not set
+# CONFIG_LIBC_DLLFCN is not set
+# CONFIG_LIBC_MODLIB is not set
+# CONFIG_LIBC_WCHAR is not set
+# CONFIG_LIBC_LOCALE is not set
+
+#
+# Time/Time Zone Support
+#
+# CONFIG_LIBC_LOCALTIME is not set
+# CONFIG_TIME_EXTENDED is not set
+CONFIG_ARCH_HAVE_TLS=y
+
+#
+# Thread Local Storage (TLS)
+#
+# CONFIG_TLS is not set
+
+#
+# Network-Related Options
+#
+# CONFIG_LIBC_IPv4_ADDRCONV is not set
+# CONFIG_LIBC_IPv6_ADDRCONV is not set
+# CONFIG_LIBC_NETDB is not set
+
+#
+# NETDB Support
+#
+# CONFIG_NETDB_HOSTFILE is not set
+# CONFIG_LIBC_IOCTL_VARIADIC is not set
+CONFIG_LIB_SENDFILE_BUFSIZE=512
+
+#
+# Non-standard Library Support
+#
+# CONFIG_LIB_CRC64_FAST is not set
+# CONFIG_LIB_KBDCODEC is not set
+# CONFIG_LIB_SLCDCODEC is not set
+# CONFIG_LIB_HEX2BIN is not set
+
+#
+# Basic CXX Support
+#
+# CONFIG_C99_BOOL8 is not set
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+# CONFIG_CXX_NEWLONG is not set
+
+#
+# LLVM C++ Library (libcxx)
+#
+# CONFIG_LIBCXX is not set
+
+#
+# uClibc++ Standard C++ Library
+#
+# CONFIG_UCLIBCXX is not set
+
+#
+# Application Configuration
+#
+
+#
+# Built-In Applications
+#
+CONFIG_BUILTIN_PROXY_STACKSIZE=1024
+
+#
+# CAN Utilities
+#
+
+#
+# Examples
+#
+CONFIG_EXAMPLES_ALARM=y
+CONFIG_EXAMPLES_ALARM_PRIORITY=100
+CONFIG_EXAMPLES_ALARM_STACKSIZE=2048
+CONFIG_EXAMPLES_ALARM_DEVPATH="/dev/rtc0"
+CONFIG_EXAMPLES_ALARM_SIGNO=1
+# CONFIG_EXAMPLES_BUTTONS is not set
+# CONFIG_EXAMPLES_CCTYPE is not set
+# CONFIG_EXAMPLES_CHAT is not set
+# CONFIG_EXAMPLES_CONFIGDATA is not set
+# CONFIG_EXAMPLES_CXXTEST is not set
+# CONFIG_EXAMPLES_DHCPD is not set
+# CONFIG_EXAMPLES_ELF is not set
+# CONFIG_EXAMPLES_FTPC is not set
+# CONFIG_EXAMPLES_FTPD is not set
+# CONFIG_EXAMPLES_HELLO is not set
+# CONFIG_EXAMPLES_HELLOXX is not set
+# CONFIG_EXAMPLES_HIDKBD is not set
+# CONFIG_EXAMPLES_IGMP is not set
+# CONFIG_EXAMPLES_JSON is not set
+# CONFIG_EXAMPLES_KEYPADTEST is not set
+# CONFIG_EXAMPLES_MEDIA is not set
+# CONFIG_EXAMPLES_MM is not set
+# CONFIG_EXAMPLES_MODBUS is not set
+# CONFIG_EXAMPLES_MOUNT is not set
+CONFIG_EXAMPLES_NSH=y
+CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
+# CONFIG_EXAMPLES_NULL is not set
+# CONFIG_EXAMPLES_NXFFS is not set
+# CONFIG_EXAMPLES_NXHELLO is not set
+# CONFIG_EXAMPLES_NXIMAGE is not set
+# CONFIG_EXAMPLES_NX is not set
+# CONFIG_EXAMPLES_NXLINES is not set
+# CONFIG_EXAMPLES_NXTERM is not set
+# CONFIG_EXAMPLES_NXTEXT is not set
+CONFIG_EXAMPLES_OSTEST=y
+CONFIG_EXAMPLES_OSTEST_LOOPS=1
+CONFIG_EXAMPLES_OSTEST_STACKSIZE=8192
+CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS=8
+CONFIG_EXAMPLES_OSTEST_RR_RANGE=10000
+CONFIG_EXAMPLES_OSTEST_RR_RUNS=10
+CONFIG_EXAMPLES_OSTEST_WAITRESULT=y
+# CONFIG_EXAMPLES_PCA9635 is not set
+# CONFIG_EXAMPLES_POSIXSPAWN is not set
+# CONFIG_EXAMPLES_PPPD is not set
+CONFIG_EXAMPLES_RANDOM=y
+CONFIG_EXAMPLES_MAXSAMPLES=64
+CONFIG_EXAMPLES_NSAMPLES=8
+# CONFIG_EXAMPLES_RFID_READUID is not set
+# CONFIG_EXAMPLES_RGBLED is not set
+# CONFIG_EXAMPLES_SENDMAIL is not set
+# CONFIG_EXAMPLES_SERIALBLASTER is not set
+# CONFIG_EXAMPLES_SERIALRX is not set
+# CONFIG_EXAMPLES_SERLOOP is not set
+# CONFIG_EXAMPLES_SLCD is not set
+# CONFIG_EXAMPLES_SMART is not set
+# CONFIG_EXAMPLES_SMART_TEST is not set
+# CONFIG_EXAMPLES_SMP is not set
+# CONFIG_EXAMPLES_STAT is not set
+# CONFIG_EXAMPLES_TCPECHO is not set
+# CONFIG_EXAMPLES_TELNETD is not set
+# CONFIG_EXAMPLES_TIFF is not set
+# CONFIG_EXAMPLES_TOUCHSCREEN is not set
+# CONFIG_EXAMPLES_USBSERIAL is not set
+# CONFIG_EXAMPLES_WATCHDOG is not set
+# CONFIG_EXAMPLES_WEBSERVER is not set
+# CONFIG_EXAMPLES_XBC_TEST is not set
+
+#
+# File System Utilities
+#
+# CONFIG_FSUTILS_INIFILE is not set
+# CONFIG_FSUTILS_PASSWD is not set
+
+#
+# GPS Utilities
+#
+# CONFIG_GPSUTILS_MINMEA_LIB is not set
+
+#
+# Graphics Support
+#
+# CONFIG_TIFF is not set
+# CONFIG_GRAPHICS_TRAVELER is not set
+
+#
+# Interpreters
+#
+# CONFIG_INTERPRETERS_BAS is not set
+# CONFIG_INTERPRETERS_FICL is not set
+# CONFIG_INTERPRETERS_MICROPYTHON is not set
+# CONFIG_INTERPRETERS_MINIBASIC is not set
+# CONFIG_INTERPRETERS_PCODE is not set
+
+#
+# FreeModBus
+#
+# CONFIG_MODBUS is not set
+
+#
+# Network Utilities
+#
+# CONFIG_NETUTILS_CODECS is not set
+# CONFIG_NETUTILS_ESP8266 is not set
+# CONFIG_NETUTILS_FTPC is not set
+# CONFIG_NETUTILS_JSON is not set
+# CONFIG_NETUTILS_SMTP is not set
+
+#
+# NSH Library
+#
+CONFIG_NSH_LIBRARY=y
+# CONFIG_NSH_MOTD is not set
+
+#
+# Command Line Configuration
+#
+CONFIG_NSH_READLINE=y
+# CONFIG_NSH_CLE is not set
+CONFIG_NSH_LINELEN=64
+# CONFIG_NSH_DISABLE_SEMICOLON is not set
+# CONFIG_NSH_CMDPARMS is not set
+CONFIG_NSH_MAXARGUMENTS=6
+# CONFIG_NSH_ARGCAT is not set
+CONFIG_NSH_NESTDEPTH=3
+# CONFIG_NSH_DISABLEBG is not set
+CONFIG_NSH_BUILTIN_APPS=y
+
+#
+# Disable Individual commands
+#
+# CONFIG_NSH_DISABLE_ADDROUTE is not set
+# CONFIG_NSH_DISABLE_BASENAME is not set
+# CONFIG_NSH_DISABLE_CAT is not set
+# CONFIG_NSH_DISABLE_CD is not set
+# CONFIG_NSH_DISABLE_CP is not set
+# CONFIG_NSH_DISABLE_CMP is not set
+# CONFIG_NSH_DISABLE_DATE is not set
+# CONFIG_NSH_DISABLE_DD is not set
+# CONFIG_NSH_DISABLE_DF is not set
+# CONFIG_NSH_DISABLE_DELROUTE is not set
+# CONFIG_NSH_DISABLE_DIRNAME is not set
+# CONFIG_NSH_DISABLE_ECHO is not set
+# CONFIG_NSH_DISABLE_EXEC is not set
+# CONFIG_NSH_DISABLE_EXIT is not set
+# CONFIG_NSH_DISABLE_FREE is not set
+# CONFIG_NSH_DISABLE_GET is not set
+# CONFIG_NSH_DISABLE_HELP is not set
+# CONFIG_NSH_DISABLE_HEXDUMP is not set
+# CONFIG_NSH_DISABLE_IFCONFIG is not set
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+# CONFIG_NSH_DISABLE_KILL is not set
+# CONFIG_NSH_DISABLE_LOSETUP is not set
+CONFIG_NSH_DISABLE_LOSMART=y
+# CONFIG_NSH_DISABLE_LS is not set
+# CONFIG_NSH_DISABLE_MB is not set
+# CONFIG_NSH_DISABLE_MKDIR is not set
+# CONFIG_NSH_DISABLE_MKRD is not set
+# CONFIG_NSH_DISABLE_MH is not set
+# CONFIG_NSH_DISABLE_MOUNT is not set
+# CONFIG_NSH_DISABLE_MV is not set
+# CONFIG_NSH_DISABLE_MW is not set
+CONFIG_NSH_DISABLE_PRINTF=y
+# CONFIG_NSH_DISABLE_PS is not set
+# CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set
+# CONFIG_NSH_DISABLE_PUT is not set
+# CONFIG_NSH_DISABLE_PWD is not set
+# CONFIG_NSH_DISABLE_RM is not set
+# CONFIG_NSH_DISABLE_RMDIR is not set
+# CONFIG_NSH_DISABLE_SET is not set
+# CONFIG_NSH_DISABLE_SH is not set
+# CONFIG_NSH_DISABLE_SLEEP is not set
+# CONFIG_NSH_DISABLE_TIME is not set
+# CONFIG_NSH_DISABLE_TEST is not set
+# CONFIG_NSH_DISABLE_UMOUNT is not set
+# CONFIG_NSH_DISABLE_UNAME is not set
+# CONFIG_NSH_DISABLE_UNSET is not set
+# CONFIG_NSH_DISABLE_USLEEP is not set
+# CONFIG_NSH_DISABLE_WGET is not set
+# CONFIG_NSH_DISABLE_XD is not set
+CONFIG_NSH_MMCSDMINOR=0
+
+#
+# Configure Command Options
+#
+# CONFIG_NSH_CMDOPT_DF_H is not set
+# CONFIG_NSH_CMDOPT_DD_STATS is not set
+CONFIG_NSH_CODECS_BUFSIZE=128
+CONFIG_NSH_CMDOPT_HEXDUMP=y
+CONFIG_NSH_PROC_MOUNTPOINT="/proc"
+CONFIG_NSH_FILEIOSIZE=512
+
+#
+# Scripting Support
+#
+# CONFIG_NSH_DISABLESCRIPT is not set
+# CONFIG_NSH_DISABLE_ITEF is not set
+# CONFIG_NSH_DISABLE_LOOPS is not set
+
+#
+# Console Configuration
+#
+CONFIG_NSH_CONSOLE=y
+# CONFIG_NSH_ALTCONDEV is not set
+CONFIG_NSH_ARCHINIT=y
+# CONFIG_NSH_LOGIN is not set
+# CONFIG_NSH_CONSOLE_LOGIN is not set
+
+#
+# NxWidgets/NxWM
+#
+
+#
+# Platform-specific Support
+#
+# CONFIG_PLATFORM_CONFIGDATA is not set
+
+#
+# System Libraries and NSH Add-Ons
+#
+# CONFIG_SYSTEM_CLE is not set
+# CONFIG_SYSTEM_CUTERM is not set
+# CONFIG_SYSTEM_FREE is not set
+# CONFIG_SYSTEM_HEX2BIN is not set
+# CONFIG_SYSTEM_HEXED is not set
+CONFIG_SYSTEM_I2CTOOL=y
+CONFIG_I2CTOOL_MINBUS=0
+CONFIG_I2CTOOL_MAXBUS=3
+CONFIG_I2CTOOL_MINADDR=0x03
+CONFIG_I2CTOOL_MAXADDR=0x77
+CONFIG_I2CTOOL_MAXREGADDR=0xff
+CONFIG_I2CTOOL_DEFFREQ=400000
+# CONFIG_SYSTEM_INSTALL is not set
+# CONFIG_SYSTEM_RAMTEST is not set
+CONFIG_READLINE_HAVE_EXTMATCH=y
+CONFIG_SYSTEM_READLINE=y
+CONFIG_READLINE_ECHO=y
+CONFIG_READLINE_TABCOMPLETION=y
+CONFIG_READLINE_MAX_BUILTINS=64
+CONFIG_READLINE_MAX_EXTCMDS=64
+CONFIG_READLINE_CMD_HISTORY=y
+CONFIG_READLINE_CMD_HISTORY_LINELEN=80
+CONFIG_READLINE_CMD_HISTORY_LEN=16
+CONFIG_SYSTEM_STACKMONITOR=y
+CONFIG_SYSTEM_STACKMONITOR_STACKSIZE=2048
+CONFIG_SYSTEM_STACKMONITOR_PRIORITY=50
+CONFIG_SYSTEM_STACKMONITOR_INTERVAL=2
+# CONFIG_SYSTEM_SUDOKU is not set
+# CONFIG_SYSTEM_SYSTEM is not set
+CONFIG_SYSTEM_TEE=y
+CONFIG_SYSTEM_TEE_STACKSIZE=1536
+CONFIG_SYSTEM_TEE_PRIORITY=100
+# CONFIG_SYSTEM_UBLOXMODEM is not set
+# CONFIG_SYSTEM_VI is not set
+# CONFIG_SYSTEM_ZMODEM is not set
+
+#
+# Wireless Libraries and NSH Add-Ons
+#
diff --git a/configs/nucleo-l452re/scripts/l452re-flash.ld b/configs/nucleo-l452re/scripts/l452re-flash.ld
new file mode 100644
index 00000000000..362a34d600c
--- /dev/null
+++ b/configs/nucleo-l452re/scripts/l452re-flash.ld
@@ -0,0 +1,119 @@
+/****************************************************************************
+ * configs/nucleo-l452re/scripts/l452re-flash.ld
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ * Sebastien Lorquet
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* The STM32L452RE has 512Kb of FLASH beginning at address 0x0800:0000 and
+ * 160Kb of SRAM beginning at address 0x2000:0000. When booting from FLASH,
+ * FLASH memory is aliased to address 0x0000:0000 where the code expects to
+ * begin execution by jumping to the entry point in the 0x0800:0000 address
+ * range.
+ */
+
+MEMORY
+{
+ flash (rx) : ORIGIN = 0x08000000, LENGTH = 512K
+ sram (rwx) : ORIGIN = 0x20000000, LENGTH = 160K
+}
+
+OUTPUT_ARCH(arm)
+ENTRY(_stext)
+SECTIONS
+{
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+ } > flash
+
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ *(.init_array .init_array.*)
+ _einit = ABSOLUTE(.);
+ } > flash
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } > flash
+
+ __exidx_start = ABSOLUTE(.);
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > flash
+ __exidx_end = ABSOLUTE(.);
+
+ _eronly = ABSOLUTE(.);
+
+ /* The STM32L452RE has 160Kb of SRAM beginning at the following address */
+
+ .data : {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ _edata = ABSOLUTE(.);
+ } > sram AT > flash
+
+ .bss : {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ _ebss = ABSOLUTE(.);
+ } > sram
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/configs/nucleo-l452re/src/.gitignore b/configs/nucleo-l452re/src/.gitignore
new file mode 100644
index 00000000000..726d936e1e3
--- /dev/null
+++ b/configs/nucleo-l452re/src/.gitignore
@@ -0,0 +1,2 @@
+/.depend
+/Make.dep
diff --git a/configs/nucleo-l452re/src/Makefile b/configs/nucleo-l452re/src/Makefile
new file mode 100644
index 00000000000..4cd0f2e7c47
--- /dev/null
+++ b/configs/nucleo-l452re/src/Makefile
@@ -0,0 +1,56 @@
+############################################################################
+# configs/nucleo-l452re/src/Makefile
+#
+# Copyright (C) 2017 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt
+# Alan Carvalho de Assis
+#
+# 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 $(TOPDIR)/Make.defs
+
+ASRCS =
+CSRCS = stm32_boot.c stm32_bringup.c stm32_spi.c
+
+ifeq ($(CONFIG_ARCH_LEDS),y)
+CSRCS += stm32_autoleds.c
+else
+CSRCS += stm32_userleds.c
+endif
+
+ifeq ($(CONFIG_ARCH_BUTTONS),y)
+CSRCS += stm32_buttons.c
+endif
+
+ifeq ($(CONFIG_LIB_BOARDCTL),y)
+CSRCS += stm32_appinit.c
+endif
+
+include $(TOPDIR)/configs/Board.mk
diff --git a/configs/nucleo-l452re/src/nucleo-l452re.h b/configs/nucleo-l452re/src/nucleo-l452re.h
new file mode 100644
index 00000000000..4ab3436861b
--- /dev/null
+++ b/configs/nucleo-l452re/src/nucleo-l452re.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+ * configs/nucleo-l452re/src/nucleo-l452re.h
+ *
+ * Copyright (C) 2017 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ * Alan Carvalho de Assis
+ *
+ * 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 __CONFIGS_NUCLEO_L452RE_SRC_NUCLEO_L452RE_H
+#define __CONFIGS_NUCLEO_L452RE_SRC_NUCLEO_L452RE_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+#include
+
+#include "stm32l4_gpio.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#define HAVE_PROC 1
+#define HAVE_RTC_DRIVER 1
+#define HAVE_MMCSD 1
+
+#if !defined(CONFIG_FS_PROCFS)
+# undef HAVE_PROC
+#endif
+
+#if defined(HAVE_PROC) && defined(CONFIG_DISABLE_MOUNTPOINT)
+# warning Mountpoints disabled. No procfs support
+# undef HAVE_PROC
+#endif
+
+/* Check if we can support the RTC driver */
+
+#if !defined(CONFIG_RTC) || !defined(CONFIG_RTC_DRIVER)
+# undef HAVE_RTC_DRIVER
+#endif
+
+#if !defined(CONFIG_STM32L4_SDIO) || !defined(CONFIG_MMCSD) || \
+ !defined(CONFIG_MMCSD_SDIO)
+# undef HAVE_MMCSD
+#endif
+
+/* How many SPI modules does this chip support? */
+
+#if STM32L4_NSPI < 1
+# undef CONFIG_STM32L4_SPI1
+# undef CONFIG_STM32L4_SPI2
+# undef CONFIG_STM32L4_SPI3
+#elif STM32L4_NSPI < 2
+# undef CONFIG_STM32L4_SPI2
+# undef CONFIG_STM32L4_SPI3
+#elif STM32L4_NSPI < 3
+# undef CONFIG_STM32L4_SPI3
+#endif
+
+/* Nucleo-L452RE GPIOs ******************************************************/
+/* LED. User LD2: the green LED is a user LED connected to Arduino signal
+ * D13 corresponding to MCU I/O PA5 (pin 21) or PB13 (pin 34) depending on
+ * the STM32 target.
+ *
+ * - When the I/O is HIGH value, the LED is on.
+ * - When the I/O is LOW, the LED is off.
+ */
+
+#define GPIO_LD2 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_2MHz | \
+ GPIO_OUTPUT_CLEAR | GPIO_PORTA | GPIO_PIN5)
+
+
+/* Button definitions *******************************************************/
+/* B1 USER: the user button is connected to the I/O PC13 (pin 2) of the STM32
+ * microcontroller.
+ */
+
+#define MIN_IRQBUTTON BUTTON_USER
+#define MAX_IRQBUTTON BUTTON_USER
+#define NUM_IRQBUTTONS 1
+
+#define GPIO_BTN_USER (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI | \
+ GPIO_PORTC | GPIO_PIN13)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_bringup
+ *
+ * Description:
+ * Perform architecture-specific initialization
+ *
+ * CONFIG_BOARD_INITIALIZE=y :
+ * Called from board_initialize().
+ *
+ * CONFIG_BOARD_INITIALIZE=n && CONFIG_LIB_BOARDCTL=y :
+ * Called from the NSH library
+ *
+ ****************************************************************************/
+
+int stm32_bringup(void);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __CONFIGS_NUCLEO_L452RE_SRC_NUCLEO_L452RE_H */
diff --git a/configs/nucleo-l452re/src/stm32_appinit.c b/configs/nucleo-l452re/src/stm32_appinit.c
new file mode 100644
index 00000000000..26b1b4f4c51
--- /dev/null
+++ b/configs/nucleo-l452re/src/stm32_appinit.c
@@ -0,0 +1,87 @@
+/****************************************************************************
+ * config/nucleo-l452re/src/stm32_appinit.c
+ *
+ * Copyright (C) 2017 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ * Alan Carvalho de Assis
+ *
+ * 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 "nucleo-l452re.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_app_initialize
+ *
+ * Description:
+ * Perform application specific initialization. This function is never
+ * called directly from application code, but only indirectly via the
+ * (non-standard) boardctl() interface using the command BOARDIOC_INIT.
+ *
+ * Input Parameters:
+ * arg - The boardctl() argument is passed to the board_app_initialize()
+ * implementation without modification. The argument has no
+ * meaning to NuttX; the meaning of the argument is a contract
+ * between the board-specific initalization logic and the the
+ * matching application logic. The value cold be such things as a
+ * mode enumeration value, a set of DIP switch switch settings, a
+ * pointer to configuration data read from a file or serial FLASH,
+ * or whatever you would like to do with it. Every implementation
+ * should accept zero/NULL as a default configuration.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int board_app_initialize(uintptr_t arg)
+{
+ /* Did we already initialize via board_initialize()? */
+
+#ifndef CONFIG_BOARD_INITIALIZE
+ return stm32_bringup();
+#else
+ return OK;
+#endif
+}
diff --git a/include/nuttx/wireless/ieee802154/ieee802154.h b/configs/nucleo-l452re/src/stm32_autoleds.c
similarity index 70%
rename from include/nuttx/wireless/ieee802154/ieee802154.h
rename to configs/nucleo-l452re/src/stm32_autoleds.c
index 02119404145..197478aeaa9 100644
--- a/include/nuttx/wireless/ieee802154/ieee802154.h
+++ b/configs/nucleo-l452re/src/stm32_autoleds.c
@@ -1,12 +1,9 @@
/****************************************************************************
- * include/nuttx/net/ieee802154.h
+ * configs/nucleo-l452re/src/stm32_autoleds.c
*
- * Copyright (C) 2016 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
- * Includes some definitions that a compatible with the LGPL GNU C Library
- * header file of the same name.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -36,27 +33,64 @@
*
****************************************************************************/
-#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H
-#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H
-
/****************************************************************************
* Included Files
****************************************************************************/
#include
-#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "stm32l4_gpio.h"
+#include "nucleo-l452re.h"
+
+#ifdef CONFIG_ARCH_LEDS
/****************************************************************************
- * Public Type Definitions
+ * Public Functions
****************************************************************************/
/****************************************************************************
- * Public Data
+ * Name: board_autoled_initialize
****************************************************************************/
+void board_autoled_initialize(void)
+{
+ /* Configure LD2 GPIO for output */
+
+ stm32l4_configgpio(GPIO_LD2);
+}
+
/****************************************************************************
- * Public Function Prototypes
+ * Name: board_autoled_on
****************************************************************************/
-#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H */
+void board_autoled_on(int led)
+{
+ if (led == 1)
+ {
+ stm32l4_gpiowrite(GPIO_LD2, true);
+ }
+}
+
+/****************************************************************************
+ * Name: board_autoled_off
+ ****************************************************************************/
+
+void board_autoled_off(int led)
+{
+ if (led == 1)
+ {
+ stm32l4_gpiowrite(GPIO_LD2, false);
+ }
+}
+
+#endif /* CONFIG_ARCH_LEDS */
diff --git a/configs/nucleo-l452re/src/stm32_boot.c b/configs/nucleo-l452re/src/stm32_boot.c
new file mode 100644
index 00000000000..9e7c287303d
--- /dev/null
+++ b/configs/nucleo-l452re/src/stm32_boot.c
@@ -0,0 +1,94 @@
+/************************************************************************************
+ * configs/nucleo-l452re/src/stm32_boot.c
+ *
+ * Copyright (C) 2017 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ * Alan Carvalho de Assis
+ *
+ * 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 "up_arch.h"
+#include "nucleo-l452re.h"
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32l4_boardinitialize
+ *
+ * Description:
+ * All STM32 architectures must provide the following entry point. This entry point
+ * is called early in the intitialization -- after all memory has been configured
+ * and mapped but before any devices have been initialized.
+ *
+ ************************************************************************************/
+
+void stm32l4_boardinitialize(void)
+{
+#ifdef CONFIG_ARCH_LEDS
+ /* Configure on-board LEDs if LED support has been selected. */
+
+ board_autoled_initialize();
+#endif
+}
+
+/****************************************************************************
+ * Name: board_initialize
+ *
+ * Description:
+ * If CONFIG_BOARD_INITIALIZE is selected, then an additional
+ * initialization call will be performed in the boot-up sequence to a
+ * function called board_initialize(). board_initialize() will be
+ * called immediately after up_initialize() is called and just before the
+ * initial application is started. This additional initialization phase
+ * may be used, for example, to initialize board-specific device drivers.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_BOARD_INITIALIZE
+void board_initialize(void)
+{
+ /* Perform board-specific initialization here if so configured */
+
+ (void)stm32_bringup();
+}
+#endif
diff --git a/configs/nucleo-l452re/src/stm32_bringup.c b/configs/nucleo-l452re/src/stm32_bringup.c
new file mode 100644
index 00000000000..b50fe958276
--- /dev/null
+++ b/configs/nucleo-l452re/src/stm32_bringup.c
@@ -0,0 +1,117 @@
+/****************************************************************************
+ * config/nucleo-l452re/src/stm32_bringup.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 "stm32l4_i2c.h"
+#include "nucleo-l452re.h"
+
+/****************************************************************************
+ * Pre-processor Defintiionis
+ ****************************************************************************/
+
+#undef HAVE_I2C_DRIVER
+#if defined(CONFIG_STM32L4_I2C1) && defined(CONFIG_I2C_DRIVER)
+# define HAVE_I2C_DRIVER 1
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_bringup
+ *
+ * Description:
+ * Perform architecture-specific initialization
+ *
+ * CONFIG_BOARD_INITIALIZE=y :
+ * Called from board_initialize().
+ *
+ * CONFIG_BOARD_INITIALIZE=n && CONFIG_LIB_BOARDCTL=y :
+ * Called from the NSH library
+ *
+ ****************************************************************************/
+
+int stm32_bringup(void)
+{
+#ifdef HAVE_I2C_DRIVER
+ FAR struct i2c_master_s *i2c;
+#endif
+ int ret;
+
+#ifdef CONFIG_FS_PROCFS
+ /* Mount the procfs file system */
+
+ ret = mount(NULL, "/proc", "procfs", 0, NULL);
+ if (ret < 0)
+ {
+ ferr("ERROR: Failed to mount procfs at /proc: %d\n", ret);
+ }
+#endif
+
+#ifdef HAVE_I2C_DRIVER
+ /* Get the I2C lower half instance */
+
+ i2c = stm32l4_i2cbus_initialize(1);
+ if (i2c == NULL)
+ {
+ i2cerr("ERROR: Initialize I2C1: %d\n", ret);
+ }
+ else
+ {
+ /* Register the I2C character driver */
+
+ ret = i2c_register(i2c, 1);
+ if (ret < 0)
+ {
+ i2cerr("ERROR: Failed to register I2C1 device: %d\n", ret);
+ }
+ }
+#endif
+
+ UNUSED(ret);
+ return OK;
+}
diff --git a/configs/nucleo-l452re/src/stm32_buttons.c b/configs/nucleo-l452re/src/stm32_buttons.c
new file mode 100644
index 00000000000..1d48c1f4a6d
--- /dev/null
+++ b/configs/nucleo-l452re/src/stm32_buttons.c
@@ -0,0 +1,128 @@
+/****************************************************************************
+ * configs/nucleo-l452re/src/stm32_buttons.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 "nucleo-l452re.h"
+
+#ifdef CONFIG_ARCH_BUTTONS
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_button_initialize
+ *
+ * Description:
+ * board_button_initialize() must be called to initialize button resources.
+ * After that, board_buttons() may be called to collect the current state
+ * of all buttons or board_button_irq() may be called to register button
+ * interrupt handlers.
+ *
+ ****************************************************************************/
+
+void board_button_initialize(void)
+{
+ /* Configure the single button as an input. NOTE that EXTI interrupts are
+ * also configured for the pin.
+ */
+
+ stm32l4_configgpio(GPIO_BTN_USER);
+}
+
+/****************************************************************************
+ * Name: board_buttons
+ ****************************************************************************/
+
+uint32_t board_buttons(void)
+{
+ /* Check that state of each USER button. A LOW value means that the key is
+ * pressed.
+ */
+
+ bool released = stm32l4_gpioread(GPIO_BTN_USER);
+ return !released;
+}
+
+/************************************************************************************
+ * Button support.
+ *
+ * Description:
+ * board_button_initialize() must be called to initialize button resources. After
+ * that, board_buttons() may be called to collect the current state of all
+ * buttons or board_button_irq() may be called to register button interrupt
+ * handlers.
+ *
+ * After board_button_initialize() has been called, board_buttons() may be called to
+ * collect the state of all buttons. board_buttons() returns an 32-bit bit set
+ * with each bit associated with a button. See the BUTTON_*_BIT
+ * definitions in board.h for the meaning of each bit.
+ *
+ * board_button_irq() may be called to register an interrupt handler that will
+ * be called when a button is depressed or released. The ID value is a
+ * button enumeration value that uniquely identifies a button resource. See the
+ * BUTTON_* definitions in board.h for the meaning of enumeration
+ * value.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_ARCH_IRQBUTTONS
+int board_button_irq(int id, xcpt_t irqhandler, FAR void *arg)
+{
+ int ret = -EINVAL;
+
+ if (id == BUTTON_USER)
+ {
+ ret = stm32l4_gpiosetevent(GPIO_BTN_USER, true, true, true, irqhandler, arg);
+ }
+
+ return ret;
+}
+#endif
+#endif /* CONFIG_ARCH_BUTTONS */
diff --git a/configs/nucleo-l452re/src/stm32_spi.c b/configs/nucleo-l452re/src/stm32_spi.c
new file mode 100644
index 00000000000..02f17ca6078
--- /dev/null
+++ b/configs/nucleo-l452re/src/stm32_spi.c
@@ -0,0 +1,223 @@
+/****************************************************************************
+ * configs/nucleo-l452re/src/stm32_spi.c
+ *
+ * Copyright (C) 2014 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 "nucleo-l452re.h"
+
+#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
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32l4_spiinitialize
+ *
+ * Description:
+ * Called to configure SPI chip select GPIO pins.
+ *
+ ************************************************************************************/
+
+void weak_function stm32l4_spiinitialize(void)
+{
+#ifdef CONFIG_STM32L4_SPI1
+ /* Configure SPI-based devices */
+
+ g_spi1 = stm32l4_spibus_initialize(1);
+ if (!g_spi1)
+ {
+ spierr("ERROR: FAILED to initialize SPI port 1\n");
+ }
+
+#ifdef HAVE_MMCSD
+ stm32l4_configgpio(GPIO_SPI_CS_SD_CARD);
+#endif
+#endif
+
+#ifdef CONFIG_STM32L4_SPI2
+ /* Configure SPI-based devices */
+
+ g_spi2 = stm32l4_spibus_initialize(2);
+ if (!g_spi2)
+ {
+ spierr("ERROR: FAILED to initialize SPI port 1\n");
+ }
+#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");
+
+#ifdef HAVE_MMCSD
+ if (devid == SPIDEV_MMCSD(0))
+ {
+ stm32l4_gpiowrite(GPIO_SPI_CS_SD_CARD, !selected);
+ }
+#endif
+}
+
+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");
+}
+
+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/nucleo-l452re/src/stm32_userleds.c b/configs/nucleo-l452re/src/stm32_userleds.c
new file mode 100644
index 00000000000..77ba277c342
--- /dev/null
+++ b/configs/nucleo-l452re/src/stm32_userleds.c
@@ -0,0 +1,217 @@
+/****************************************************************************
+ * configs/nucleo-l452re/src/stm32_userleds.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 "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+#include "stm32l4_gpio.h"
+#include "nucleo-l452re.h"
+
+#ifndef CONFIG_ARCH_LEDS
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* LED Power Management */
+
+#ifdef CONFIG_PM
+static void led_pm_notify(struct pm_callback_s *cb, int domain,
+ enum pm_state_e pmstate);
+static int led_pm_prepare(struct pm_callback_s *cb, int domain,
+ enum pm_state_e pmstate);
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_PM
+static struct pm_callback_s g_ledscb =
+{
+ .notify = led_pm_notify,
+ .prepare = led_pm_prepare,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: led_pm_notify
+ *
+ * Description:
+ * Notify the driver of new power state. This callback is called after
+ * all drivers have had the opportunity to prepare for the new power state.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_PM
+static void led_pm_notify(struct pm_callback_s *cb, int domain,
+ enum pm_state_e pmstate)
+{
+ switch (pmstate)
+ {
+ case(PM_NORMAL):
+ {
+ /* Restore normal LEDs operation */
+
+ }
+ break;
+
+ case(PM_IDLE):
+ {
+ /* Entering IDLE mode - Turn leds off */
+
+ }
+ break;
+
+ case(PM_STANDBY):
+ {
+ /* Entering STANDBY mode - Logic for PM_STANDBY goes here */
+
+ }
+ break;
+
+ case(PM_SLEEP):
+ {
+ /* Entering SLEEP mode - Logic for PM_SLEEP goes here */
+
+ }
+ break;
+
+ default:
+ {
+ /* Should not get here */
+
+ }
+ break;
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: led_pm_prepare
+ *
+ * Description:
+ * Request the driver to prepare for a new power state. This is a warning
+ * that the system is about to enter into a new power state. The driver
+ * should begin whatever operations that may be required to enter power
+ * state. The driver may abort the state change mode by returning a
+ * non-zero value from the callback function.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_PM
+static int led_pm_prepare(struct pm_callback_s *cb, int domain,
+ enum pm_state_e pmstate)
+{
+ /* No preparation to change power modes is required by the LEDs driver.
+ * We always accept the state change by returning OK.
+ */
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_userled_initialize
+ ****************************************************************************/
+
+void board_userled_initialize(void)
+{
+ /* Configure LD2 GPIO for output */
+
+ stm32l4_configgpio(GPIO_LD2);
+}
+
+/****************************************************************************
+ * Name: board_userled
+ ****************************************************************************/
+
+void board_userled(int led, bool ledon)
+{
+ if (led == 1)
+ {
+ stm32l4_gpiowrite(GPIO_LD2, ldeon);
+ }
+}
+
+/****************************************************************************
+ * Name: board_userled_all
+ ****************************************************************************/
+
+void board_userled_all(uint8_t ledset)
+{
+ if (led == 1)
+ {
+ stm32l4_gpiowrite(GPIO_LD2, (ledset & BOARD_LD2_BIT) != 0);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32l4_led_pminitialize
+ ****************************************************************************/
+
+#ifdef CONFIG_PM
+void stm32l4_led_pminitialize(void)
+{
+ /* Register to receive power management callbacks */
+
+ int ret = pm_register(&g_ledscb);
+ DEBUGASSERT(ret == OK);
+ UNUSED(ret);
+}
+#endif /* CONFIG_PM */
+
+#endif /* !CONFIG_ARCH_LEDS */
diff --git a/configs/nucleo-l496zg/Kconfig b/configs/nucleo-l496zg/Kconfig
index af61775c0bb..713c28241c8 100644
--- a/configs/nucleo-l496zg/Kconfig
+++ b/configs/nucleo-l496zg/Kconfig
@@ -3,221 +3,6 @@
# see the file kconfig-language.txt in the NuttX tools repository.
#
-if ARCH_BOARD_NUCLEO_144
+if ARCH_BOARD_NUCLEO_L496ZG
-choice
- prompt "Select Console wiring."
- default NUCLEO_ARDUINO
- ---help---
- Select where you will connect the console.
-
- Virtual COM Port:
-
- Advantage: Use the ST-Link as a console. No Extra wiring
- neded.
-
- Disdvantage: Not the best choice for initial bring up.
-
- ARDUINO Connector:
-
- Advantage: You have a shield so it is
- easy.
-
- Disdvantage: You loose the use of the
- other functions on PC6, PC7
-
- STM32F7
- ARDUIONO FUNCTION GPIO
- -- ----- --------- ----
- DO RX USART6_RX PG9
- D1 TX USART6_TX PG14
- -- ----- --------- ---
-
- OR
-
- Morpho Connector:
-
- STM32F7
- MORPHO FUNCTION GPIO
- -------- --------- -----
- CN12-64 USART8_RX PE0
- CN11-61 USART8_TX PE1
- -------- --------- -----
-
-config NUCLEO_CONSOLE_ARDUINO
- bool "ARDUINO Connector"
- select STM32F7_USART6
- select USART6_SERIALDRIVER
- select USART6_SERIAL_CONSOLE
-
-config NUCLEO_CONSOLE_VIRTUAL
- bool "Virtual Comport"
- select STM32F7_USART3
- select USART3_SERIALDRIVER
- select USART3_SERIAL_CONSOLE
-
-config NUCLEO_CONSOLE_MORPHO
- bool "Morpho Connector"
- select STM32F7_UART8
- select UART8_SERIALDRIVER
- select UART8_SERIAL_CONSOLE
-
-config NUCLEO_CONSOLE_NONE
- bool "No Console"
-
-endchoice # "Select Console wiring"
-
-config NUCLEO_SPI_TEST
- bool "Enable SPI test"
- default n
- ---help---
- Enable Spi test - initalize and configure SPI to send
- NUCLEO_SPI_TEST_MESSAGE text. The text is sent on the
- selected SPI Buses with the configured parameters.
- Note the CS lines will not be asserted.
-
-if NUCLEO_SPI_TEST
-
-config NUCLEO_SPI_TEST_MESSAGE
- string "Text to Send on SPI Bus(es)"
- default "Hello World"
- depends on NUCLEO_SPI_TEST
- ---help---
- Text to sent on SPI bus(es)
-
-config NUCLEO_SPI1_TEST
- bool "Test SPI bus 1"
- default n
- depends on NUCLEO_SPI_TEST
- ---help---
- Enable Spi test - on SPI BUS 1
-
-if NUCLEO_SPI1_TEST
-
-config NUCLEO_SPI1_TEST_FREQ
- int "SPI 1 Clock Freq in Hz"
- default 1000000
- depends on NUCLEO_SPI1_TEST
- ---help---
- Sets SPI 1 Clock Freq
-
-config NUCLEO_SPI1_TEST_BITS
- int "SPI 1 number of bits"
- default 8
- depends on NUCLEO_SPI1_TEST
- ---help---
- Sets SPI 1 bit length
-
-choice
- prompt "SPI BUS 1 Clock Mode"
- default NUCLEO_SPI1_TEST_MODE3
- ---help---
- Sets SPI 1 clock mode
-
-config NUCLEO_SPI1_TEST_MODE0
- bool "CPOL=0 CHPHA=0"
-
-config NUCLEO_SPI1_TEST_MODE1
- bool "CPOL=0 CHPHA=1"
-
-config NUCLEO_SPI1_TEST_MODE2
- bool "CPOL=1 CHPHA=0"
-
-config NUCLEO_SPI1_TEST_MODE3
- bool "CPOL=1 CHPHA=1"
-
-endchoice # "SPI BUS 1 Clock Mode"
-
-endif # NUCLEO_SPI1_TEST
-
-config NUCLEO_SPI2_TEST
- bool "Test SPI bus 2"
- default n
- depends on NUCLEO_SPI_TEST
- ---help---
- Enable Spi test - on SPI BUS 2
-
-if NUCLEO_SPI2_TEST
-
-config NUCLEO_SPI2_TEST_FREQ
- int "SPI 2 Clock Freq in Hz"
- default 12000000
- depends on NUCLEO_SPI2_TEST
- ---help---
- Sets SPI 2 Clock Freq
-
-config NUCLEO_SPI2_TEST_BITS
- int "SPI 2 number of bits"
- default 8
- depends on NUCLEO_SPI2_TEST
- ---help---
- Sets SPI 2 bit length
-
-choice
- prompt "SPI BUS 2 Clock Mode"
- default NUCLEO_SPI2_TEST_MODE3
- ---help---
- Sets SPI 2 clock mode
-
-config NUCLEO_SPI2_TEST_MODE0
- bool "CPOL=0 CHPHA=0"
-
-config NUCLEO_SPI2_TEST_MODE1
- bool "CPOL=0 CHPHA=1"
-
-config NUCLEO_SPI2_TEST_MODE2
- bool "CPOL=1 CHPHA=0"
-
-config NUCLEO_SPI2_TEST_MODE3
- bool "CPOL=1 CHPHA=1"
-
-endchoice # "SPI BUS 2 Clock Mode"
-
-endif # NUCLEO_SPI2_TEST
-
-config NUCLEO_SPI3_TEST
- bool "Test SPI bus 3"
- default n
- depends on NUCLEO_SPI_TEST
- ---help---
- Enable Spi test - on SPI BUS 3
-
-if NUCLEO_SPI3_TEST
-
-config NUCLEO_SPI3_TEST_FREQ
- int "SPI 3 Clock Freq in Hz"
- default 40000000
- depends on NUCLEO_SPI3_TEST
- ---help---
- Sets SPI 3 Clock Freq
-
-config NUCLEO_SPI3_TEST_BITS
- int "SPI 3 number of bits"
- default 8
- depends on NUCLEO_SPI3_TEST
- ---help---
- Sets SPI 3 bit length
-
-choice
- prompt "SPI BUS 3 Clock Mode"
- default NUCLEO_SPI3_TEST_MODE3
- ---help---
- Sets SPI 3 clock mode
-
-config NUCLEO_SPI3_TEST_MODE0
- bool "CPOL=0 CHPHA=0"
-
-config NUCLEO_SPI3_TEST_MODE1
- bool "CPOL=0 CHPHA=1"
-
-config NUCLEO_SPI3_TEST_MODE2
- bool "CPOL=1 CHPHA=0"
-
-config NUCLEO_SPI3_TEST_MODE3
- bool "CPOL=1 CHPHA=1"
-
-endchoice # "SPI BUS 3 Clock Mode"
-
-endif # NUCLEO_SPI3_TEST
-endif # NUCLEO_SPI_TEST
-endif # ARCH_BOARD_NUCLEO_144
+endif # ARCH_BOARD_NUCLEO_L496ZG
diff --git a/configs/nucleo-l496zg/nsh/defconfig b/configs/nucleo-l496zg/nsh/defconfig
index 3808958bd41..4bc74debafe 100644
--- a/configs/nucleo-l496zg/nsh/defconfig
+++ b/configs/nucleo-l496zg/nsh/defconfig
@@ -166,7 +166,7 @@ CONFIG_ARCH_HAVE_CMNVECTOR=y
CONFIG_ARMV7M_CMNVECTOR=y
# CONFIG_ARMV7M_LAZYFPU is not set
CONFIG_ARCH_HAVE_FPU=y
-CONFIG_ARCH_HAVE_DPFPU=y
+# CONFIG_ARCH_HAVE_DPFPU is not set
# CONFIG_ARCH_FPU is not set
# CONFIG_ARCH_HAVE_TRUSTZONE is not set
CONFIG_ARM_HAVE_MPU_UNIFIED=y
@@ -178,15 +178,13 @@ CONFIG_ARM_HAVE_MPU_UNIFIED=y
#
# CONFIG_ARMV7M_HAVE_ICACHE is not set
# CONFIG_ARMV7M_HAVE_DCACHE is not set
-CONFIG_ARMV7M_HAVE_ITCM=y
-CONFIG_ARMV7M_HAVE_DTCM=y
-# CONFIG_ARMV7M_ITCM is not set
-# CONFIG_ARMV7M_DTCM is not set
+# CONFIG_ARMV7M_HAVE_ITCM is not set
+# CONFIG_ARMV7M_HAVE_DTCM is not set
# CONFIG_ARMV7M_TOOLCHAIN_IARL is not set
# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set
# CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set
-CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL=y
-# CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL is not set
+# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set
+CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y
CONFIG_ARMV7M_HAVE_STACKCHECK=y
CONFIG_ARMV7M_STACKCHECK=y
# CONFIG_ARMV7M_ITMSYSLOG is not set
@@ -281,6 +279,7 @@ CONFIG_STM32L4_HAVE_DAC2=y
CONFIG_STM32L4_HAVE_DCMI=y
CONFIG_STM32L4_HAVE_DFSDM1=y
CONFIG_STM32L4_HAVE_DMA2D=y
+CONFIG_STM32L4_HAVE_FSMC=y
# CONFIG_STM32L4_HAVE_HASH is not set
CONFIG_STM32L4_HAVE_I2C4=y
CONFIG_STM32L4_HAVE_LCD=y
@@ -292,7 +291,11 @@ CONFIG_STM32L4_HAVE_SAI1=y
CONFIG_STM32L4_HAVE_SAI2=y
CONFIG_STM32L4_HAVE_SDMMC1=y
CONFIG_STM32L4_HAVE_TIM3=y
+CONFIG_STM32L4_HAVE_TIM4=y
+CONFIG_STM32L4_HAVE_TIM5=y
CONFIG_STM32L4_HAVE_TIM7=y
+CONFIG_STM32L4_HAVE_TIM8=y
+CONFIG_STM32L4_HAVE_TIM17=y
CONFIG_STM32L4_ADC=y
# CONFIG_STM32L4_CAN is not set
# CONFIG_STM32L4_DAC is not set
@@ -321,15 +324,11 @@ CONFIG_STM32L4_ADC1=y
# CONFIG_STM32L4_DCMI is not set
# CONFIG_STM32L4_DMA2D is not set
CONFIG_STM32L4_RNG=y
-# CONFIG_STM32L4_SAI1_A is not set
-# CONFIG_STM32L4_SAI1_B is not set
-# CONFIG_STM32L4_SAI2_A is not set
-# CONFIG_STM32L4_SAI2_B is not set
#
# AHB3 Peripherals
#
-# CONFIG_STM32L4_FMC is not set
+CONFIG_STM32L4_FSMC=y
# CONFIG_STM32L4_QSPI is not set
#
@@ -402,6 +401,9 @@ CONFIG_STM32L4_SAI1PLL=y
# CONFIG_STM32L4_ONESHOT is not set
# CONFIG_STM32L4_FREERUN is not set
# CONFIG_STM32L4_TIM3_CAP is not set
+# CONFIG_STM32L4_TIM4_CAP is not set
+# CONFIG_STM32L4_TIM5_CAP is not set
+# CONFIG_STM32L4_TIM8_CAP is not set
#
# ADC Configuration
@@ -698,6 +700,7 @@ CONFIG_ANALOG=y
# CONFIG_ADC is not set
# CONFIG_COMP is not set
# CONFIG_DAC is not set
+# CONFIG_OPAMP is not set
# CONFIG_AUDIO_DEVICES is not set
# CONFIG_VIDEO_DEVICES is not set
# CONFIG_BCH is not set
diff --git a/configs/photon/README.txt b/configs/photon/README.txt
new file mode 100644
index 00000000000..779226e6325
--- /dev/null
+++ b/configs/photon/README.txt
@@ -0,0 +1,125 @@
+README
+======
+
+ This README discusses issues unique to NuttX configurations for the
+ Particle.io Photon board featuring the STM32F205RG MCU.
+ The STM32F205RG is a 120 MHz Cortex-M3 operation with 1Mbit Flash
+ memory and 128kbytes. The board includes a Broadcom BCM43362 WiFi.
+
+Contents
+========
+
+ - Selecting the Photon board on NuttX
+ - Configuring NuttX to use your Wireless Router (aka Access Point)
+ - Flashing NuttX in the Photon board
+ - Serial console configuration
+
+Selecting the Photon board on NuttX
+===================================
+
+ NOTICE: We will not discuss about toolchains and environment configuration
+ here, please take a look at STM32F4Discory board README or other STM32 board
+ because it should work for Photon board as well.
+
+ Let us to consider that you cloned the nuttx and apps repositories, then
+ follow these steps:
+
+ 1) Clear your build system before to start:
+
+ $ make apps_distclean
+ $ make distclean
+
+ 2) Enter inside nuttx/tools and configure to use the Photon board:
+
+ $ cd nuttx
+ $ cd tools
+ $ ./configure.sh photon/wlan
+
+ Now please return to root of nuttx/ directory:
+
+ $ cd ..
+
+Configuring NuttX to use your Wireless Router (aka Access Point)
+================================================================
+
+ Since you are already in the root of nuttx/ repository, execute
+ make menuconfig to define your Wireless Router and your password:
+
+ $ make menuconfig
+
+ Browser the menus this way:
+
+ Application Configuration --->
+ NSH Library --->
+ Networking Configuration --->
+ WAPI Configuration --->
+ (myApSSID) SSID
+ (mySSIDpassphrase) Passprhase
+
+ Replace the SSID from myApSSID with your wireless router name and
+ the Passprhase with your WiFi password.
+
+ Exit and save your configuration.
+
+ Finally just compile NuttX:
+
+ $ make
+
+Flashing NuttX in the Photon board
+==================================
+
+ Connect the Photon board in your computer using a MicroUSB cable. Press and
+ hold both board's buttons (SETUP and RESET), then release the RESET button,
+ the board will start blinking in the Purple color, waiting until it starts
+ blinking in Yellow color. Now you can release the SETUP button as well.
+
+ 1) You can verify if DFU mode in your board is working, using this command:
+
+ $ sudo dfu-util -l
+ dfu-util 0.8
+
+ Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
+ Copyright 2010-2014 Tormod Volden and Stefan Schmidt
+ This program is Free Software and has ABSOLUTELY NO WARRANTY
+ Please report bugs to dfu-util@lists.gnumonks.org
+
+ Found DFU: [2b04:d006] ver=0200, devnum=15, cfg=1, intf=0, alt=1, name="@DCT Flash /0x00000000/01*016Kg", serial="00000000010C"
+ Found DFU: [2b04:d006] ver=0200, devnum=15, cfg=1, intf=0, alt=0, name="@Internal Flash /0x08000000/03*016Ka,01*016Kg,01*064Kg,07*128Kg", serial="00000000010C"
+
+ 2) Flash the nuttx.bin inside the Internal Flash:
+
+ $ sudo dfu-util -d 2b04:d006 -a 0 -s 0x08020000 -D nuttx.bin
+
+ dfu-util 0.8
+
+ Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
+ Copyright 2010-2014 Tormod Volden and Stefan Schmidt
+ This program is Free Software and has ABSOLUTELY NO WARRANTY
+ Please report bugs to dfu-util@lists.gnumonks.org
+
+ dfu-util: Invalid DFU suffix signature
+ dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
+ Opening DFU capable USB device...
+ ID 2b04:d006
+ Run-time device DFU version 011a
+ Claiming USB DFU Interface...
+ Setting Alternate Setting #0 ...
+ Determining device status: state = dfuIDLE, status = 0
+ dfuIDLE, continuing
+ DFU mode device DFU version 011a
+ Device returned transfer size 4096
+ DfuSe interface name: "Internal Flash "
+ Downloading to address = 0x08020000, size = 331348
+ Download [=========================] 100% 331348 bytes
+ Download done.
+ File downloaded successfully
+
+
+Serial console configuration
+============================
+
+ Connect a USB/Serial 3.3V dongle to GND, TX and RX pins of Photon board.
+ Then use some serial console client (minicom, picocom, teraterm, etc) confi-
+ gured to 115200 8n1 without software or hardware flow control.
+
+ Reset the board and you should see NuttX starting in the serial.
diff --git a/configs/photon/wlan/defconfig b/configs/photon/wlan/defconfig
index a616dd914f1..1892e56c10d 100644
--- a/configs/photon/wlan/defconfig
+++ b/configs/photon/wlan/defconfig
@@ -16,7 +16,7 @@ CONFIG_HOST_LINUX=y
#
# Build Configuration
#
-CONFIG_APPS_DIR="../apps"
+# CONFIG_APPS_DIR="../apps"
CONFIG_BUILD_FLAT=y
# CONFIG_BUILD_2PASS is not set
@@ -1552,6 +1552,16 @@ CONFIG_NSH_DRIPADDR=0xc0a80001
CONFIG_NSH_NETMASK=0xffffff00
# CONFIG_NSH_DNS is not set
# CONFIG_NSH_NOMAC is not set
+
+#
+# WAPI Configuration
+#
+CONFIG_NSH_WAPI_STAMODE=2
+CONFIG_NSH_WAPI_AUTHWPA=0x00000004
+CONFIG_NSH_WAPI_CIPHERMODE=0x00000008
+CONFIG_NSH_WAPI_ALG=3
+CONFIG_NSH_WAPI_SSID="myApSSID"
+CONFIG_NSH_WAPI_PASSPHRASE="mySSIDpassphrase"
CONFIG_NSH_MAX_ROUNDTRIP=20
# CONFIG_NSH_LOGIN is not set
# CONFIG_NSH_CONSOLE_LOGIN is not set
@@ -1595,4 +1605,3 @@ CONFIG_WIRELESS_WAPI=y
CONFIG_WIRELESS_WAPI_CMDTOOL=y
CONFIG_WIRELESS_WAPI_STACKSIZE=2048
CONFIG_WIRELESS_WAPI_PRIORITY=100
-CONFIG_WIRELESS_WEXT=y
diff --git a/configs/sim/sixlowpan/defconfig b/configs/sim/sixlowpan/defconfig
index 5c64eb13e65..f46639d0039 100644
--- a/configs/sim/sixlowpan/defconfig
+++ b/configs/sim/sixlowpan/defconfig
@@ -548,7 +548,7 @@ CONFIG_NET_6LOWPAN_MAXADDRCONTEXT=1
CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_0=0xaa
CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_0_1=0xaa
# CONFIG_NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_1 is not set
-# CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED is not set
+# CONFIG_NET_6LOWPAN_EXTENDEDADDR is not set
CONFIG_NET_6LOWPAN_MAXAGE=20
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS=4
CONFIG_NET_6LOWPAN_MTU=1294
diff --git a/drivers/wireless/Kconfig b/drivers/wireless/Kconfig
index a3bab81d211..39622d66fd7 100644
--- a/drivers/wireless/Kconfig
+++ b/drivers/wireless/Kconfig
@@ -20,7 +20,6 @@ source drivers/wireless/cc3000/Kconfig
menuconfig DRIVERS_IEEE802154
bool "IEEE 802.15.4 Device Support"
default n
- depends on EXPERIMENTAL
---help---
This directory holds implementations of IEEE802.15.4 device drivers.
@@ -29,7 +28,6 @@ source drivers/wireless/ieee802154/Kconfig
menuconfig DRIVERS_IEEE80211
bool "IEEE 802.11 Device Support"
default n
- depends on EXPERIMENTAL
---help---
This directory holds implementations of IEEE802.11 device drivers.
diff --git a/drivers/wireless/ieee802154/Kconfig b/drivers/wireless/ieee802154/Kconfig
index 93e802323df..d0d8c550ece 100644
--- a/drivers/wireless/ieee802154/Kconfig
+++ b/drivers/wireless/ieee802154/Kconfig
@@ -11,4 +11,10 @@ config IEEE802154_MRF24J40
---help---
This selection enables support for the Microchip MRF24J40 device.
+config IEEE802154_AT86RF233
+ bool "ATMEL RF233 IEEE 802.15.4 transceiver"
+ default n
+ ---help---
+ This selection enables support for the Atmel RF233 device.
+
endif # DRIVERS_IEEE802154
diff --git a/drivers/wireless/ieee802154/Make.defs b/drivers/wireless/ieee802154/Make.defs
index b0a1406baa4..8e0924d67ff 100644
--- a/drivers/wireless/ieee802154/Make.defs
+++ b/drivers/wireless/ieee802154/Make.defs
@@ -45,6 +45,10 @@ ifeq ($(CONFIG_IEEE802154_MRF24J40),y)
CSRCS += mrf24j40.c
endif
+ifeq ($(CONFIG_IEEE802154_AT86RF233),y)
+ CSRCS += at86rf23x.c
+endif
+
# Include IEEE 802.15.4 build support
DEPPATH += --dep-path wireless$(DELIM)ieee802154
diff --git a/drivers/wireless/ieee802154/at86rf23x.c b/drivers/wireless/ieee802154/at86rf23x.c
new file mode 100644
index 00000000000..90d99351baf
--- /dev/null
+++ b/drivers/wireless/ieee802154/at86rf23x.c
@@ -0,0 +1,1561 @@
+/****************************************************************************
+ * drivers/wireless/ieee802154/at86rf23x.c
+ *
+ * Copyright (C) 2016 Matt Poppe. All rights reserved.
+ * Author: Matt Poppe
+ *
+ * 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 "at86rf23x.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+#ifndef CONFIG_SCHED_HPWORK
+# error High priority work queue required in this driver
+#endif
+
+#ifndef CONFIG_SPI_EXCHANGE
+# error CONFIG_SPI_EXCHANGE required for this driver
+#endif
+
+#ifndef CONFIG_IEEE802154_at86rf23x_SPIMODE
+# define CONFIG_IEEE802154_at86rf23x_SPIMODE SPIDEV_MODE0
+#endif
+
+#ifndef CONFIG_IEEE802154_at86rf23x_FREQUENCY
+# define CONFIG_IEEE802154_at86rf23x_FREQUENCY 1000000
+#endif
+
+/* Definitions for the device structure */
+
+#define AT86RF23X_RXMODE_NORMAL 0
+#define AT86RF23X_RXMODE_PROMISC 1
+#define AT86RF23X_RXMODE_NOCRC 2
+#define AT86RF23X_RXMODE_AUTOACK 3
+
+/* Definitions for PA control on high power modules */
+
+#define AT86RF23X_PA_AUTO 1
+#define AT86RF23X_PA_ED 2
+#define AT86RF23X_PA_SLEEP 3
+
+/************************************************************************************
+ * Private Types
+ ************************************************************************************/
+
+/* AT86RF23x device instance
+ *
+ * Make sure that struct ieee802154_radio_s remains first. If not it will break the
+ * code
+ */
+
+struct at86rf23x_dev_s
+{
+ struct ieee802154_radio_s ieee; /* Public device instance */
+ FAR struct spi_dev_s *spi; /* Saved SPI interface instance */
+ struct work_s irqwork; /* Interrupt continuation work queue support */
+ FAR const struct at86rf23x_lower_s *lower; /* Low-level MCU-specific support */
+ uint16_t panid; /* 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
+ ****************************************************************************/
+
+/* Internal operations */
+
+static void at86rf23x_lock(FAR struct spi_dev_s *spi);
+static void at86rf23x_unlock(FAR struct spi_dev_s *spi);
+static void at86rf23x_setreg(FAR struct spi_dev_s *spi, uint32_t addr,
+ uint8_t val);
+static uint8_t at86rf23x_getreg(FAR struct spi_dev_s *spi, uint32_t addr);
+static int at86rf23x_writeframe(FAR struct spi_dev_s *spi, FAR uint8_t *frame,
+ uint8_t len);
+static uint8_t at86rf23x_readframe(FAR struct spi_dev_s *spi,
+ FAR uint8_t *frame_rx);
+static int at86rf23x_setTRXstate(FAR struct at86rf23x_dev_s *dev,
+ uint8_t state, uint8_t force);
+static uint8_t at86rf23x_getTRXstate(FAR struct at86rf23x_dev_s *dev);
+static int at86rf23x_resetrf(FAR struct at86rf23x_dev_s *dev);
+static int at86rf23x_initialize(FAR struct at86rf23x_dev_s *dev);
+
+static int at86rf23x_regdump(FAR struct at86rf23x_dev_s *dev);
+static void at86rf23x_irqwork_rx(FAR struct at86rf23x_dev_s *dev);
+static void at86rf23x_irqwork_tx(FAR struct at86rf23x_dev_s *dev);
+static void at86rf23x_irqworker(FAR void *arg);
+static int at86rf23x_interrupt(int irq, FAR void *context, FAR void *arg);
+
+
+static int at86rf23x_setchannel(FAR struct ieee802154_radio_s *ieee,
+ uint8_t chan);
+static int at86rf23x_getchannel(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *chan);
+static int at86rf23x_setpanid(FAR struct ieee802154_radio_s *ieee,
+ uint16_t panid);
+static int at86rf23x_getpanid(FAR struct ieee802154_radio_s *ieee,
+ FAR uint16_t *panid);
+static int at86rf23x_setsaddr(FAR struct ieee802154_radio_s *ieee,
+ uint16_t saddr);
+static int at86rf23x_getsaddr(FAR struct ieee802154_radio_s *ieee,
+ FAR uint16_t *saddr);
+static int at86rf23x_seteaddr(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *eaddr);
+static int at86rf23x_geteaddr(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *eaddr);
+static int at86rf23x_setpromisc(FAR struct ieee802154_radio_s *ieee,
+ bool promisc);
+static int at86rf23x_getpromisc(FAR struct ieee802154_radio_s *ieee,
+ FAR bool *promisc);
+static int at86rf23x_setdevmode(FAR struct ieee802154_radio_s *ieee,
+ uint8_t mode);
+static int at86rf23x_getdevmode(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *mode);
+static int at86rf23x_settxpower(FAR struct ieee802154_radio_s *ieee,
+ int32_t txpwr);
+static int at86rf23x_gettxpower(FAR struct ieee802154_radio_s *ieee,
+ FAR int32_t *txpwr);
+static int at86rf23x_setcca(FAR struct ieee802154_radio_s *ieee,
+ FAR struct ieee802154_cca_s *cca);
+static int at86rf23x_getcca(FAR struct ieee802154_radio_s *ieee,
+ FAR struct ieee802154_cca_s *cca);
+static int at86rf23x_energydetect(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *energy);
+
+/* Driver operations */
+
+static int at86rf23x_rxenable(FAR struct ieee802154_radio_s *ieee,
+ bool state, FAR struct ieee802154_packet_s *packet);
+static int at86rf23x_transmit(FAR struct ieee802154_radio_s *ieee,
+ FAR struct ieee802154_packet_s *packet);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* These are pointers to ALL registered at86rf23x devices.
+ * This table is used during irqs to find the context
+ * Only one device is supported for now.
+ * More devices can be supported in the future by lookup them up
+ * using the IRQ number. See the ENC28J60 or CC3000 drivers for reference.
+ */
+
+static struct at86rf23x_dev_s g_at86rf23x_devices[1];
+
+static const struct ieee802154_radioops_s at86rf23x_devops =
+{
+ .ioctl = at86rf23x_ioctl,
+ .rxenable = at86rf23x_rxenable,
+ .transmit = at86rf23x_transmit
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: at86rf23x_lock
+ *
+ * Description:
+ * Acquire exclusive access to the shared SPI bus.
+ *
+ ****************************************************************************/
+
+static void at86rf23x_lock(FAR struct spi_dev_s *spi)
+{
+ SPI_LOCK(spi, 1);
+ SPI_SETBITS(spi, 8);
+ SPI_SETMODE(spi, CONFIG_IEEE802154_at86rf23x_SPIMODE);
+ SPI_SETFREQUENCY(spi, CONFIG_IEEE802154_at86rf23x_FREQUENCY);
+}
+
+/****************************************************************************
+ * Name: at86rf23x_unlock
+ *
+ * Description:
+ * Release exclusive access to the shared SPI bus.
+ *
+ ****************************************************************************/
+
+static void at86rf23x_unlock(FAR struct spi_dev_s *spi)
+{
+ SPI_LOCK(spi, 0);
+}
+
+/****************************************************************************
+ * Name: at86rf23x_setreg
+ *
+ * Description:
+ * Define the value of an at86rf23x device register
+ *
+ ****************************************************************************/
+
+static void at86rf23x_setreg(FAR struct spi_dev_s *spi, uint32_t addr,
+ uint8_t val)
+{
+ uint8_t reg[2];
+
+ reg[0] = addr;
+ reg[0] |= RF23X_SPI_REG_WRITE;
+
+ reg[1] = val;
+ at86rf23x_lock(spi);
+ SPI_SELECT(spi, SPIDEV_IEEE802154(0), true);
+ SPI_SNDBLOCK(spi, reg, 2);
+ SPI_SELECT(spi, SPIDEV_IEEE802154(0), false);
+ at86rf23x_unlock(spi);
+
+ wlinfo("0x%02X->r[0x%02X]\n", val, addr);
+}
+
+/****************************************************************************
+ * Name: at86rf23x_getreg
+ *
+ * Description:
+ * Return the value of an at86rf23x device register
+ *
+ ****************************************************************************/
+
+static uint8_t at86rf23x_getreg(FAR struct spi_dev_s *spi, uint32_t addr)
+{
+ uint8_t reg[2];
+ uint8_t val[2];
+
+ /* Add Read mask to desired register */
+
+ reg[0] = addr | RF23X_SPI_REG_READ;
+
+ at86rf23x_lock (spi);
+
+ SPI_SELECT(spi, SPIDEV_IEEE802154(0), true);
+ SPI_EXCHANGE(spi, reg, val, 2);
+ SPI_SELECT(spi, SPIDEV_IEEE802154(0), false);
+
+ at86rf23x_unlock(spi);
+
+ wlinfo("r[0x%02X]=0x%02X\n",addr,val[1]);
+
+ return val[1];
+}
+
+/****************************************************************************
+ * Name: at86rf23x_setregbits
+ *
+ * Description:
+ * Read the current value of the register. Change only the portion
+ * of the register we need to change and write the value back to the
+ * register.
+ *
+ ****************************************************************************/
+
+static void at86rf23x_setregbits(FAR struct spi_dev_s *spi, uint8_t addr,
+ uint8_t pos, uint8_t mask, uint8_t val)
+{
+ uint8_t reg;
+
+ reg = at86rf23x_getreg(spi, addr);
+ reg = (reg & ~(mask << pos)) | (val << pos);
+ at86rf23x_setreg(spi, addr, reg);
+}
+
+/****************************************************************************
+ * Name: at86rf23x_getregbits
+ *
+ * Description:
+ * Return the value of an section of the at86rf23x device register.
+ *
+ ****************************************************************************/
+
+static uint8_t at86rf23x_getregbits(FAR struct spi_dev_s *spi, uint8_t addr,
+ uint8_t pos, uint8_t mask)
+{
+ uint8_t val;
+
+ val = at86rf23x_getreg(spi, addr);
+ val = (val >> pos) & mask;
+
+ return val;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_writebuffer
+ *
+ * Description:
+ * Write frame to the transmit buffer of the radio. This does not
+ * initiate the transfer, just write to the buffer.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_writeframe(FAR struct spi_dev_s *spi, FAR uint8_t *frame,
+ uint8_t len)
+{
+//report_packet(frame_wr, len);
+ uint8_t reg = RF23X_SPI_FRAME_WRITE;
+
+ at86rf23x_lock(spi);
+
+ SPI_SELECT(spi, SPIDEV_IEEE802154(0), true);
+
+ SPI_SNDBLOCK(spi, ®, 1);
+ SPI_SNDBLOCK(spi, &frame, len);
+
+ SPI_SELECT(spi, SPIDEV_IEEE802154(0), false);
+
+ at86rf23x_unlock(spi);
+
+ return len;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_readframe
+ *
+ * Description:
+ * Read the buffer memory of the radio. This is used when the radio
+ * indicates a frame has been received.
+ *
+ ****************************************************************************/
+
+static uint8_t at86rf23x_readframe(FAR struct spi_dev_s *spi,
+ FAR uint8_t *frame_rx)
+{
+ uint8_t len, reg;
+
+ reg = RF23X_SPI_FRAME_READ;
+
+ at86rf23x_lock(spi);
+ SPI_SELECT(spi, SPIDEV_IEEE802154(0), true);
+
+ SPI_SNDBLOCK(spi, ®, 1);
+ SPI_RECVBLOCK(spi, &len, 1);
+ SPI_RECVBLOCK(spi, frame_rx, len+3);
+
+ SPI_SELECT(spi, SPIDEV_IEEE802154(0), false);
+ at86rf23x_unlock(spi);
+
+ return len;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_getTRXstate
+ *
+ * Description:
+ * Return the current status of the TRX state machine.
+ *
+ ****************************************************************************/
+
+static uint8_t at86rf23x_getTRXstate(FAR struct at86rf23x_dev_s *dev)
+{
+ return at86rf23x_getregbits(dev->spi, RF23X_TRXSTATUS_STATUS);
+}
+
+/****************************************************************************
+ * Name: at86rf23x_setTRXstate
+ *
+ * Description:
+ * Set the TRX state machine to the desired state. If the state machine
+ * cannot move to the desired state an ERROR is returned. If the transistion
+ * is successful an OK is returned. This is a long running function due to
+ * waiting for the transistion delay between states. This can be as long as
+ * 510us.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_setTRXstate(FAR struct at86rf23x_dev_s *dev,
+ uint8_t state, uint8_t force)
+{
+ /* Get the current state of the transceiver */
+
+ uint8_t status = at86rf23x_getTRXstate(dev);
+
+ int ret = OK;
+
+ /* TODO I don't have every state included verify this will work with SLEEP */
+
+ if ((status != TRX_STATUS_TRXOFF) &&
+ (status != TRX_STATUS_RXON) &&
+ (status != TRX_STATUS_PLLON) &&
+ (status != TRX_STATUS_RXAACKON) &&
+ (status != TRX_STATUS_TXARETON) &&
+ (status != TRX_STATUS_PON))
+ {
+ wlerr("ERROR: Invalid State\n");
+ return ERROR;
+ }
+
+ int8_t init_status = status;
+
+ /* Start the state change */
+
+ switch(state)
+ {
+ case TRX_CMD_TRXOFF:
+ if (status == TRX_STATUS_TRXOFF)
+ {
+ break;
+ }
+
+ /* verify in a state that will transfer to TRX_OFF if not check if
+ * force is required.
+ */
+
+ if ((status == TRX_STATUS_RXON) ||
+ (status == TRX_STATUS_PLLON) ||
+ (status == TRX_STATUS_RXAACKON) ||
+ (status == TRX_STATUS_TXARETON))
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_TRXOFF);
+ up_udelay(RF23X_TIME_TRANSITION_PLL_ACTIVE);
+ }
+ else if (status == TRX_STATUS_PON)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_TRXOFF);
+ up_udelay(RF23X_TIME_P_ON_TO_TRXOFF);
+ }
+ else if (force)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_FORCETRXOFF);
+ up_udelay(RF23X_TIME_FORCE_TRXOFF);
+ }
+
+ status = at86rf23x_getregbits(dev->spi, RF23X_TRXSTATUS_STATUS);
+ if (status != TRX_STATUS_TRXOFF)
+ {
+ ret = ERROR;
+ }
+
+ break;
+
+ case TRX_CMD_RX_ON:
+ if (status == TRX_STATUS_RXON)
+ {
+ break;
+ }
+
+ if (status == TRX_STATUS_TRXOFF)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_RX_ON);
+ up_udelay(RF23X_TIME_TRXOFF_TO_PLL);
+ }
+ else if ((status == TRX_STATUS_RXAACKON) ||
+ (status == TRX_STATUS_RXON) ||
+ (status == TRX_STATUS_PLLON) ||
+ (status == TRX_STATUS_TXARETON))
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_RX_ON);
+ up_udelay(RF23X_TIME_TRANSITION_PLL_ACTIVE);
+ }
+
+ status = at86rf23x_getregbits(dev->spi, RF23X_TRXSTATUS_STATUS);
+ if (status != TRX_STATUS_RXON)
+ {
+ ret = ERROR;
+ }
+
+ break;
+
+ /* Transition to PLL_ON */
+
+ case TRX_CMD_PLL_ON:
+ if (status == TRX_STATUS_PLLON)
+ {
+ break;
+ }
+
+ if (status == TRX_STATUS_TRXOFF)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_PLL_ON);
+ up_udelay(RF23X_TIME_TRXOFF_TO_PLL);
+ }
+ else
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_PLL_ON);
+ up_udelay(RF23X_TIME_TRANSITION_PLL_ACTIVE);
+ }
+
+ status = at86rf23x_getregbits(dev->spi, RF23X_TRXSTATUS_STATUS);
+ if (status != TRX_STATUS_PLLON)
+ {
+ ret = ERROR;
+ }
+
+ break;
+
+ case TRX_CMD_RX_AACK_ON:
+ if (status == TRX_STATUS_RXAACKON)
+ {
+ break;
+ }
+
+ if (status == TRX_STATUS_TRXOFF || status == TRX_STATUS_TXARETON)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_RX_ON);
+
+ (status == TRX_STATUS_TRXOFF) ? up_udelay(RF23X_TIME_TRXOFF_TO_PLL) :
+ up_udelay(RF23X_TIME_TRANSITION_PLL_ACTIVE);
+ }
+
+ status = at86rf23x_getTRXstate(dev);
+ if ((status == TRX_STATUS_RXON) || (status == TRX_STATUS_PLLON))
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_RX_AACK_ON);
+ up_udelay(RF23X_TIME_TRANSITION_PLL_ACTIVE);
+ }
+
+ status = at86rf23x_getregbits(dev->spi, RF23X_TRXSTATUS_STATUS);
+ if (status != TRX_STATUS_RXAACKON)
+ {
+ ret = ERROR;
+ }
+
+ break;
+
+ case TRX_STATUS_TXARETON:
+ if (status == TRX_STATUS_TXARETON)
+ {
+ break;
+ }
+
+ if (status == TRX_STATUS_TRXOFF)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_RX_ON);
+ up_udelay(RF23X_TIME_TRXOFF_TO_PLL);
+ }
+
+ if ((status == TRX_STATUS_RXON) || (status == TRX_STATUS_PLLON))
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_TX_ARET_ON);
+ up_udelay(RF23X_TIME_TRANSITION_PLL_ACTIVE);
+ }
+ else if (status == TRX_STATUS_RXAACKON)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_RX_ON);
+ up_udelay(RF23X_TIME_TRANSITION_PLL_ACTIVE);
+
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_TX_ARET_ON);
+ up_udelay(RF23X_TIME_TRANSITION_PLL_ACTIVE);
+ }
+
+ status = at86rf23x_getregbits(dev->spi, RF23X_TRXSTATUS_STATUS);
+ if (status != TRX_STATUS_TXARETON)
+ {
+ ret = ERROR;
+ }
+
+ break;
+
+ case TRX_STATUS_SLEEP:
+ at86rf23x_setregbits(dev->spi, RF23X_TRXCMD_STATE, TRX_CMD_FORCETRXOFF);
+ up_udelay(RF23X_TIME_CMD_FORCE_TRX_OFF);
+
+ dev->lower->slptr(dev->lower, true);
+ up_udelay(RF23X_TIME_TRXOFF_TO_SLEEP);
+
+ status = at86rf23x_getregbits(dev->spi, RF23X_TRXSTATUS_STATUS);
+ break;
+
+ default:
+ wlerr("ERRPR: %s \n", EINVAL_STR);
+ init_status = 0;/* Placed this here to keep compiler happy when not in debug */
+ return -EINVAL;
+ }
+
+ if (ret == ERROR)
+ {
+ wlerr("ERROR: State Transistion Error\n");
+ }
+
+ wlinfo("Radio state change state[0x%02x]->state[0x%02x]\n", init_status, status);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_setchannel
+ *
+ * Description:
+ * Define the current radio channel the device is operating on.
+ * In the 2.4 GHz, there are 16 channels, each 2 MHz wide, 5 MHz spacing:
+ * Chan MHz Chan MHz Chan MHz Chan MHz
+ * 11 2405 15 2425 19 2445 23 2465
+ * 12 2410 16 2430 20 2450 24 2470
+ * 13 2415 17 2435 21 2455 25 2475
+ * 14 2420 18 2440 22 2460 26 2480
+ *
+ *
+ ****************************************************************************/
+
+static int at86rf23x_setchannel(FAR struct ieee802154_radio_s *ieee,
+ uint8_t chan)
+{
+ FAR struct at86rf23x_dev_s *dev = (FAR struct at86rf23x_dev_s *)ieee;
+ uint8_t state;
+
+ /* Validate if chan is a valid channel */
+
+ if (chan < 11 || chan > 26)
+ {
+ wlerr("ERROR: Invalid requested chan: %d\n",chan);
+ return -EINVAL;
+ }
+
+ /* Validate we are in an acceptable mode to change the channel */
+
+ state = at86rf23x_getTRXstate(dev);
+
+ if ((TRX_STATUS_SLEEP == state) || (TRX_STATUS_PON == state))
+ {
+ wlerr("ERROR: Radio in invalid mode [%02x] to set the channel\n", state);
+ return ERROR;
+ }
+
+ /* Set the Channel on the transceiver */
+
+ at86rf23x_setregbits(dev->spi, RF23X_CCA_BITS_CHANNEL, chan);
+
+ /* Set the channel within local device */
+
+ dev->channel = chan;
+
+ wlinfo("CHANNEL Changed to %d\n", chan);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_getchannel
+ *
+ * Description:
+ * Define the current radio channel the device is operating on.
+ * In the 2.4 GHz, there are 16 channels, each 2 MHz wide, 5 MHz spacing:
+ * Chan MHz Chan MHz Chan MHz Chan MHz
+ * 11 2405 15 2425 19 2445 23 2465
+ * 12 2410 16 2430 20 2450 24 2470
+ * 13 2415 17 2435 21 2455 25 2475
+ * 14 2420 18 2440 22 2460 26 2480
+ *
+ * This section assumes that the transceiver is not in SLEEP or P_ON state.
+ *
+ *
+ ****************************************************************************/
+
+static int at86rf23x_getchannel(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *chan)
+{
+ FAR struct at86rf23x_dev_s *dev = (FAR struct at86rf23x_dev_s *)ieee;
+
+ /* Set the Channel on the transceiver */
+
+ *chan = at86rf23x_getregbits(dev->spi, RF23X_CCA_BITS_CHANNEL);
+
+ /* Set the channel within local device */
+
+ dev->channel = *chan;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_setpanid
+ *
+ * Description:
+ * Define the PAN ID for the network.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_setpanid(FAR struct ieee802154_radio_s *ieee,
+ uint16_t panid)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+ uint8_t *pan = (uint8_t *)&panid;
+
+ at86rf23x_setreg(dev->spi, RF23X_REG_PANID0, pan[0]);
+ at86rf23x_setreg(dev->spi, RF23X_REG_PANID1, pan[1]);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_getpanid
+ *
+ * Description:
+ * Define the PAN ID for the network.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_getpanid(FAR struct ieee802154_radio_s *ieee,
+ FAR uint16_t *panid)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+ uint8_t *pan = (uint8_t *)panid;
+
+ /* TODO: Check if we need to pay attention to endianness */
+
+ pan[0] = at86rf23x_getreg(dev->spi, RF23X_REG_PANID0);
+ pan[1] = at86rf23x_getreg(dev->spi, RF23X_REG_PANID1);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_setsaddr
+ *
+ * Description:
+ * Define the Short Address for the device.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_setsaddr(FAR struct ieee802154_radio_s *ieee,
+ uint16_t saddr)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+ uint8_t *addr = (uint8_t *)&saddr;
+
+ at86rf23x_setreg(dev->spi, RF23X_REG_SADDR0, addr[0]);
+ at86rf23x_setreg(dev->spi, RF23X_REG_SADDR1, addr[1]);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_getsaddr
+ *
+ * Description:
+ * Get the short address of the device.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_getsaddr(FAR struct ieee802154_radio_s *ieee,
+ FAR uint16_t *saddr)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+ uint8_t *addr = (uint8_t *)saddr;
+
+ /* TODO: Check if we need to pay attention to endianness */
+
+ addr[0] = at86rf23x_getreg(dev->spi, RF23X_REG_SADDR0);
+ addr[1] = at86rf23x_getreg(dev->spi, RF23X_REG_SADDR1);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_seteaddr
+ *
+ * Description:
+ * Set the IEEE address of the device.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_seteaddr(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *eaddr)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+
+ /* TODO: Check if we need to pay attention to endianness */
+
+ at86rf23x_setreg(dev->spi, RF23X_REG_IEEEADDR0, eaddr[0]);
+ at86rf23x_setreg(dev->spi, RF23X_REG_IEEEADDR1, eaddr[1]);
+ at86rf23x_setreg(dev->spi, RF23X_REG_IEEEADDR2, eaddr[2]);
+ at86rf23x_setreg(dev->spi, RF23X_REG_IEEEADDR3, eaddr[3]);
+ at86rf23x_setreg(dev->spi, RF23X_REG_IEEEADDR4, eaddr[4]);
+ at86rf23x_setreg(dev->spi, RF23X_REG_IEEEADDR5, eaddr[5]);
+ at86rf23x_setreg(dev->spi, RF23X_REG_IEEEADDR6, eaddr[6]);
+ at86rf23x_setreg(dev->spi, RF23X_REG_IEEEADDR7, eaddr[7]);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_geteaddr
+ *
+ * Description:
+ * Get the IEEE address of the device.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_geteaddr(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *eaddr)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+
+ /* TODO: Check if we need to pay attention to endianness */
+
+ eaddr[0] = at86rf23x_getreg(dev->spi, RF23X_REG_IEEEADDR0);
+ eaddr[1] = at86rf23x_getreg(dev->spi, RF23X_REG_IEEEADDR1);
+ eaddr[2] = at86rf23x_getreg(dev->spi, RF23X_REG_IEEEADDR2);
+ eaddr[3] = at86rf23x_getreg(dev->spi, RF23X_REG_IEEEADDR3);
+ eaddr[4] = at86rf23x_getreg(dev->spi, RF23X_REG_IEEEADDR4);
+ eaddr[5] = at86rf23x_getreg(dev->spi, RF23X_REG_IEEEADDR5);
+ eaddr[6] = at86rf23x_getreg(dev->spi, RF23X_REG_IEEEADDR6);
+ eaddr[7] = at86rf23x_getreg(dev->spi, RF23X_REG_IEEEADDR7);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_setpromisc
+ *
+ * Description:
+ * enable/disable promiscuous mode.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_setpromisc(FAR struct ieee802154_radio_s *ieee,
+ bool promisc)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+
+ /* TODO: Check what mode I should be in to activate promiscuous mode:
+ * This is way to simple of an implementation. Many other things should be set
+ * and/or checked before we set the device into promiscuous mode
+ */
+
+ at86rf23x_setregbits(dev->spi, RF23X_XAHCTRL1_BITS_PROM_MODE, promisc);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_getpromisc
+ *
+ * Description:
+ * Check if the device is in promiscuous mode.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_getpromisc(FAR struct ieee802154_radio_s *ieee,
+ FAR bool *promisc)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+
+ *promisc = at86rf23x_getregbits(dev->spi, RF23X_XAHCTRL1_BITS_PROM_MODE);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_setdevmode
+ *
+ * Description:
+ * Check if the device is in promiscuous mode.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_setdevmode(FAR struct ieee802154_radio_s *ieee,
+ uint8_t mode)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+
+ /* Define dev mode */
+
+ if (mode == IEEE802154_MODE_PANCOORD)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_CSMASEED1_IAMCOORD_BITS, 0x01);
+ }
+ else if (mode == IEEE802154_MODE_COORD)
+ {
+ /* ????? */
+ }
+ else if (mode == IEEE802154_MODE_DEVICE)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_CSMASEED1_IAMCOORD_BITS, 0x00);
+ }
+ else
+ {
+ return -EINVAL;
+ }
+
+ dev->devmode = mode;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_getdevmode
+ *
+ * Description:
+ * get the device mode type of the radio.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_getdevmode(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *mode)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+ int val;
+
+ val = at86rf23x_getregbits(dev->spi, RF23X_CSMASEED1_IAMCOORD_BITS);
+ if (val == 1)
+ {
+ *mode = IEEE802154_MODE_PANCOORD;
+ }
+ else
+ {
+ *mode = IEEE802154_MODE_DEVICE;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_settxpower
+ *
+ * Description:
+ * set the tx power attenuation or amplification
+ *
+ ****************************************************************************/
+
+static int at86rf23x_settxpower(FAR struct ieee802154_radio_s *ieee,
+ int32_t txpwr)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+
+ /* TODO: this needs alot of work to make sure all chips can share this function */
+
+ /* Right now we only set tx power to 0 */
+
+ at86rf23x_setreg(dev->spi, RF23X_REG_TXPWR, RF23X_TXPWR_0);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_gettxpower
+ *
+ * Description:
+ * get the tx power attenuation or amplification.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_gettxpower(FAR struct ieee802154_radio_s *ieee,
+ FAR int32_t *txpwr)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+ uint8_t reg;
+
+ /* TODO: this needs alot of work to make sure all chips can share this
+ * function.
+ */
+
+ /* Right now we only get negative values */
+
+ reg = at86rf23x_getreg(dev->spi, RF23X_REG_TXPWR);
+ switch (reg)
+ {
+ case RF23X_TXPWR_POS_4:
+ *txpwr = 0;
+ break;
+
+ case RF23X_TXPWR_POS_3_7:
+ *txpwr = 0;
+ break;
+
+ case RF23X_TXPWR_POS_3_4:
+ *txpwr = 0;
+ break;
+
+ case RF23X_TXPWR_POS_3:
+ *txpwr = 0;
+ break;
+
+ case RF23X_TXPWR_POS_2_5:
+ *txpwr = 0;
+ break;
+
+ case RF23X_TXPWR_POS_2:
+ *txpwr = 0;
+ break;
+
+ case RF23X_TXPWR_POS_1:
+ *txpwr = 0;
+ break;
+
+ case RF23X_TXPWR_0:
+ *txpwr = 0;
+ break;
+
+ case RF23X_TXPWR_NEG_1:
+ *txpwr = 1000;
+ break;
+
+ case RF23X_TXPWR_NEG_2:
+ *txpwr = 2000;
+ break;
+
+ case RF23X_TXPWR_NEG_3:
+ *txpwr = 3000;
+ break;
+
+ case RF23X_TXPWR_NEG_4:
+ *txpwr = 4000;
+ break;
+
+ case RF23X_TXPWR_NEG_6:
+ *txpwr = 6000;
+ break;
+
+ case RF23X_TXPWR_NEG_8:
+ *txpwr = 8000;
+ break;
+
+ case RF23X_TXPWR_NEG_12:
+ *txpwr = 12000;
+ break;
+
+ case RF23X_TXPWR_NEG_17:
+ *txpwr = 17000;
+ break;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_setcca
+ *
+ * Description:
+ * Configures if energy detection is used or carrier sense. The base
+ * measurement is configured here as well
+ *
+ *
+ ****************************************************************************/
+
+static int at86rf23x_setcca(FAR struct ieee802154_radio_s *ieee,
+ FAR struct ieee802154_cca_s *cca)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+
+ /* TODO: This doesn't fit the RF233 completely come back to this */
+
+ if (!cca->use_ed && !cca->use_cs)
+ {
+ return -EINVAL;
+ }
+
+ if (cca->use_cs && cca->csth > 0x0f)
+ {
+ return -EINVAL;
+ }
+
+ if (cca->use_ed)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_CCA_BITS_MODE, RF23X_CCA_MODE_ED);
+ }
+
+ if (cca->use_cs)
+ {
+ at86rf23x_setregbits(dev->spi, RF23X_CCA_BITS_MODE, RF23X_CCA_MODE_CS);
+ }
+
+ memcpy(&dev->cca, cca, sizeof(struct ieee802154_cca_s));
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_getcca
+ *
+ * Description:
+ * Get CCA for ???: TODO: need to implement
+ *
+ ****************************************************************************/
+
+static int at86rf23x_getcca(FAR struct ieee802154_radio_s *ieee,
+ FAR struct ieee802154_cca_s *cca)
+{
+ FAR struct at86rf23x_dev_s *dev = (struct at86rf23x_dev_s *)ieee;
+
+#warning at86rf23x_getcca not implemented.
+
+ UNUSED(dev);
+ UNUSED(cca);
+
+ return ERROR;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_energydetect
+ *
+ * Description:
+ * Perform energy detection scan. TODO: Need to implement.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_energydetect(FAR struct ieee802154_radio_s *ieee,
+ FAR uint8_t *energy)
+{
+#warning at86rf23x_energydetect not implemented.
+
+ /* Not yet implemented */
+
+ return ERROR;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_initialize
+ *
+ * Description:
+ * Initialize the radio.
+ *
+ ****************************************************************************/
+
+int at86rf23x_initialize(FAR struct at86rf23x_dev_s *dev)
+{
+ uint8_t part;
+ uint8_t version;
+
+ at86rf23x_resetrf(dev);
+
+ part = at86rf23x_getreg(dev->spi, RF23X_REG_PART);
+ version = at86rf23x_getreg(dev->spi, RF23X_REG_VERSION);
+
+ wlinfo("Radio part: 0x%02x version: 0x%02x found\n", part, version);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_resetrf
+ *
+ * Description:
+ * Hard Reset of the radio. The reset also brings the radio into the
+ * TRX_OFF state.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_resetrf(FAR struct at86rf23x_dev_s *dev)
+{
+ FAR const struct at86rf23x_lower_s *lower = dev->lower;
+ uint8_t trx_status, retry_cnt = 0;
+
+ /* Reset the radio */
+
+ lower->reset(lower, false);
+ lower->slptr(lower, false);
+
+ up_udelay(RF23X_TIME_RESET);
+ lower->reset(lower, true);
+
+ /* Dummy read of IRQ register */
+
+ at86rf23x_getreg(dev->spi, RF23X_REG_IRQ_STATUS);
+
+ do
+ {
+ trx_status = at86rf23x_setTRXstate(dev, TRX_CMD_TRXOFF, true);
+
+ if (retry_cnt == RF23X_MAX_RETRY_RESET_TO_TRX_OFF)
+ {
+ wlerr("ERROR: Reset of transceiver failed\n");
+ return ERROR;
+ }
+
+ retry_cnt++;
+ }
+ while (trx_status != OK);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_rxenable
+ *
+ * Description:
+ * puts the radio into RX mode and brings in the buffer to handle
+ * RX messages.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_rxenable(FAR struct ieee802154_radio_s *ieee, bool state,
+ FAR struct ieee802154_packet_s *packet)
+{
+ FAR struct at86rf23x_dev_s *dev = (FAR struct at86rf23x_dev_s *)ieee;
+
+ /* Set the radio to the receive state */
+
+ return at86rf23x_setTRXstate(dev, TRX_CMD_RX_ON, false);
+
+ /* Enable the RX IRQ */
+
+ /* TODO:
+ * I am not sure what to do here since the at86rf23x shares the
+ * irq with the tx finished. Better planning needs to be done on
+ * my end.
+ */
+
+ /* Set buffer to receive next packet */
+
+ ieee->rxbuf = packet;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_interrupt
+ *
+ * Description:
+ * Actual interrupt handler ran inside privileged space.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_interrupt(int irq, FAR void *context, FAR void *arg)
+{
+ FAR struct at86rf23x_dev_s *dev = (FAR struct at86rf23x_dev_s *)arg;
+
+ DEBUGASSERT(dev != NULL);
+
+ /* 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.
+ */
+
+ DEBUGASSERT(work_available(&dev->irqwork));
+
+ /* 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->irqwork, at86rf23x_irqworker,
+ (FAR void *)dev, 0);
+}
+
+/****************************************************************************
+ * Name: at86rf23x_regdump
+ *
+ * Description:
+ * Dumps all the RF23X radios registers from 00 - 2F there are a few other
+ * registers that don't get dumped but just fore the ease of code I left
+ * them out.
+ *
+ ****************************************************************************/
+
+static int at86rf23x_regdump(FAR struct at86rf23x_dev_s *dev)
+{
+ uint32_t i;
+ char buf[4+16*3+2+1];
+ int len=0;
+
+ printf("RF23X regs:\n");
+
+ for (i=0;i<0x30;i++)
+ {
+ /* First row and every 15 regs */
+
+ if ((i & 0x0f) == 0)
+ {
+ len = sprintf(buf, "%02x: ",i&0xFF);
+ }
+
+ /* Print the register value */
+
+ len += sprintf(buf+len, "%02x ", at86rf23x_getreg(dev->spi, i));
+
+ /* At the end of each 15 regs or end of rf233s regs and actually print
+ * debug message.
+ */
+
+ if ((i&15) == 15 || i == 0x2f)
+ {
+ sprintf(buf+len, "\n");
+ printf("%s",buf);
+ }
+ }
+
+ /* TODO: I have a few more regs that are not consecutive. Will print later */
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: at86rf23x_irqworker
+ *
+ * Description:
+ * Actual thread to handle the irq outside of privaleged mode.
+ *
+ ****************************************************************************/
+
+static void at86rf23x_irqworker(FAR void *arg)
+{
+ FAR struct at86rf23x_dev_s *dev = (FAR struct at86rf23x_dev_s *)arg;
+ uint8_t irq_status = at86rf23x_getreg(dev->spi, RF23X_REG_IRQ_STATUS);
+
+ wlinfo("IRQ: 0x%02X\n", irq_status);
+
+ if ((irq_status & (1<<3)) != 0)
+ {
+ if ((irq_status & (1<<2)) != 0)
+ {
+ at86rf23x_irqwork_rx(dev);
+ }
+ else
+ {
+ at86rf23x_irqwork_tx(dev);
+ }
+ }
+ else
+ {
+ wlerr("ERROR: Unknown IRQ Status: %d\n", irq_status);
+
+ /* Re-enable the IRQ even if we don't know how to handle previous
+ * status.
+ */
+
+ dev->lower->enable(dev->lower, true);
+ }
+}
+
+/****************************************************************************
+ * Name: at86rf23x_irqwork_rx
+ *
+ * Description:
+ * Misc/unofficial device controls.
+ *
+ ****************************************************************************/
+
+static void at86rf23x_irqwork_rx(FAR struct at86rf23x_dev_s *dev)
+{
+ uint8_t rx_len;
+
+ wlinfo("6LOWPAN:Rx IRQ\n");
+
+ rx_len = at86rf23x_readframe(dev->spi, dev->ieee.rxbuf->data);
+
+ dev->ieee.rxbuf->len = rx_len;
+ dev->ieee.rxbuf->lqi = 0;
+ dev->ieee.rxbuf->rssi = 0;
+
+ sem_post(&dev->ieee.rxsem);
+
+ /* TODO:
+ * Not to sure yet what I should do here. I will something
+ * soon.
+ */
+
+ /* Re-enable the IRQ */
+
+ dev->lower->enable(dev->lower, true);
+}
+
+/****************************************************************************
+ * Name: at86rf23x_irqwork_tx
+ *
+ * Description:
+ * Misc/unofficial device controls.
+ *
+ ****************************************************************************/
+
+static void at86rf23x_irqwork_tx(FAR struct at86rf23x_dev_s *dev)
+{
+ wlinfo("6LOWPAN:Tx IRQ\n");
+
+ /* TODO:
+ * There needs to be more here but for now just alert the waiting
+ * thread. Maybe put it back into Rx mode
+ */
+
+ /* Re enable the IRQ */
+
+ dev->lower->enable(dev->lower, true);
+
+ sem_post(&dev->ieee.txsem);
+}
+
+/****************************************************************************
+ * Name: at86rf23x_transmit
+ *
+ * Description:
+ * transmission the packet. Send the packet to the radio and initiate the
+ * transmit process. Then block the function till we have a successful
+ * transmission
+ *
+ ****************************************************************************/
+
+static int at86rf23x_transmit(FAR struct ieee802154_radio_s *ieee,
+ FAR struct ieee802154_packet_s *packet)
+{
+ FAR struct at86rf23x_dev_s *dev = (FAR struct at86rf23x_dev_s *)ieee;
+
+ /* TODO:
+ * A plan needs to be made on when we declare the transmission successful.
+ * 1. If the packet is sent
+ * 2. If we receive an ACK.
+ * 3. Where do we control the retry process?
+ */
+
+ if (at86rf23x_setTRXstate(dev, TRX_CMD_PLL_ON, false))
+ {
+ at86rf23x_writeframe(dev->spi, packet->data, packet->len);
+ }
+ else
+ {
+ wlerr("ERROR: Transmit could not put the radio in a Tx state\n");
+ return ERROR;
+ }
+
+ /* Put the thread that requested transfer to a waiting state */
+
+ sem_wait(&dev->ieee.txsem);
+
+ /* TODO Verify that I want to stay in the PLL state or if I want to roll
+ * back to RX_ON.
+ */
+
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: at86rf23x_init
+ *
+ * Description:
+ * Return an at86rf23x device for use by other drivers.
+ *
+ ****************************************************************************/
+
+FAR struct ieee802154_radio_s *at86rf23x_init(FAR struct spi_dev_s *spi,
+ FAR const struct at86rf23x_lower_s *lower)
+{
+ FAR struct at86rf23x_dev_s *dev;
+ struct ieee802154_cca_s cca;
+
+ dev = &g_at86rf23x_devices[0];
+
+ /* Attach the interface, lower driver, and devops */
+
+ dev->spi = spi;
+ dev->lower = lower;
+ dev->ieee.ops = &at86rf23x_devops;
+
+ /* Attach irq */
+
+ if (lower->attach(lower, at86rf23x_interrupt, dev) != OK)
+ {
+ return NULL;
+ }
+
+ sem_init(&dev->ieee.rxsem, 0, 0);
+ sem_init(&dev->ieee.txsem, 0, 0);
+
+ /* Initialize device */
+
+ at86rf23x_initialize(dev);
+
+ /* Configure the desired IRQs of the devices */
+
+ at86rf23x_setreg(dev->spi, RF23X_REG_IRQ_MASK, RF23X_IRQ_MASK_DEFAULT);
+
+ /* Turn the PLL to the on state */
+
+ at86rf23x_setTRXstate(dev, TRX_CMD_PLL_ON, false);
+
+ /* SEED value of the CSMA backoff algorithm. */
+
+#ifdef RF23X_ANTENNA_DIVERSITY
+ /* Use antenna diversity */
+
+ trx_bit_write(SR_ANT_CTRL, ANTENNA_DEFAULT);
+ trx_bit_write(SR_PDT_THRES, THRES_ANT_DIV_ENABLE);
+ trx_bit_write(SR_ANT_DIV_EN, ANT_DIV_ENABLE);
+ trx_bit_write(SR_ANT_EXT_SW_EN, ANT_EXT_SW_ENABLE);
+#endif
+
+#ifdef RF23X_TIMESTAMP
+ /* Enable timestamp init code goes here */
+
+#endif
+
+#ifdef RF23X_RF_FRONTEND_CTRL
+ /* Init front end control code goes here */
+
+#endif
+
+ /* Set the channel of the radio */
+
+ at86rf23x_setchannel(&dev->ieee, 12);
+
+ /* Configure the Pan id */
+
+ //at86rf23x_setpanid (&dev->ieee, IEEE802154_PAN_DEFAULT);
+
+ /* Configure the Short Addr */
+
+ //at86rf23x_setsaddr (&dev->ieee, IEEE802154_SADDR_UNSPEC);
+
+ /* Configure the IEEE Addr */
+
+ //at86rf23x_seteaddr (&dev->ieee, IEEE802154_EADDR_UNSPEC);
+
+ /* Default device params at86rf23x defaults to energy detect only */
+
+ cca.use_ed = 1;
+ cca.use_cs = 0;
+ cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED
+ * threshold -69 dBm */
+ at86rf23x_setcca(&dev->ieee, &cca);
+
+ /* Put the Device to RX ON Mode */
+ //at86rf23x_setTRXstate(dev, TRX_CMD_RX_ON, false);
+
+ /* Enable Radio IRQ */
+
+ lower->enable(lower, true);
+ return &dev->ieee;
+}
diff --git a/drivers/wireless/ieee802154/at86rf23x.h b/drivers/wireless/ieee802154/at86rf23x.h
new file mode 100644
index 00000000000..4d64fed0c8b
--- /dev/null
+++ b/drivers/wireless/ieee802154/at86rf23x.h
@@ -0,0 +1,221 @@
+/****************************************************************************
+ * drivers/wireless/ieee802154/at86rf23x.c
+ *
+ * Copyright (C) 2016 Matt Poppe. All rights reserved.
+ * Author: Matt Poppe
+ *
+ * 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_IEEE802154_AT86RF23X_H
+#define __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define RF23X_SPI_REG_READ 0x80
+#define RF23X_SPI_REG_WRITE 0xc0
+#define RF23X_SPI_FRAME_WRITE 0x60
+#define RF23X_SPI_FRAME_READ 0x20
+#define RF23X_SPI_SRAM_READ 0x00
+#define RF23X_SPI_SRAM_WRITE 0x40
+
+/* US Times Constants for the RF233 */
+
+#define RF23X_TIME_RESET_BOOT 510
+#define RF23X_TIME_FORCE_TRXOFF 100
+#define RF23X_TIME_P_ON_TO_TRXOFF 510
+#define RF23X_TIME_SLEEP_TO_TRXOFF 1200
+#define RF23X_TIME_RESET 6
+#define RF23X_TIME_ED_MEASUREMENT 140
+#define RF23X_TIME_CCA 140
+#define RF23X_TIME_PLL_LOCK 150
+#define RF23X_TIME_FTN_TUNNING 25
+#define RF23X_TIME_NOCLK_TO_WAKE 6
+#define RF23X_TIME_CMD_FORCE_TRX_OFF 1
+#define RF23X_TIME_TRXOFF_TO_PLL 180
+#define RF23X_TIME_TRANSITION_PLL_ACTIVE 1
+#define RF23X_TIME_TRXOFF_TO_SLEEP 1200
+
+#define RF23X_MAX_RETRY_RESET_TO_TRX_OFF 5
+
+#define RF23X_REG_TRXSTATUS 0x01
+#define RF23X_REG_TRXSTATE 0x02
+#define RF23X_REG_TRXCTRL0 0x03
+#define RF23X_REG_TRXCTRL1 0x04
+#define RF23X_REG_TXPWR 0x05
+#define RF23X_REG_RSSI 0x06
+#define RF23X_REG_EDLEVEL 0x07
+#define RF23X_REG_CCA 0x08
+#define RF23X_REG_THRES 0x09
+#define RF23X_REG_RXCTRL 0x0a
+#define RF23X_REG_SFD 0x0b
+#define RF23X_REG_TRXCTRL2 0x0c
+#define RF23X_REG_ANT_DIV 0x0d
+#define RF23X_REG_IRQ_MASK 0x0e
+#define RF23X_REG_IRQ_STATUS 0x0f
+#define RF23X_REG_VREG_CTRL 0x10
+#define RF23X_REG_BATMON 0x11
+#define RF23X_REG_XOSC_CTRL 0x12
+#define RF23X_REG_CCCTRL0 0x13
+#define RF23X_REG_CCCTRL1 0x14
+#define RF23X_REG_RXSYN 0x15
+#define RF23X_REG_TRXRPC 0x16
+#define RF23X_REG_XAHCTRL1 0x17
+#define RF23X_REG_FTNCTRL 0x18
+#define RF23X_REG_XAHCTRL2 0x19
+#define RF23X_REG_PLLCF 0x1a
+#define RF23X_REG_PLLDCU 0x1b
+#define RF23X_REG_PART 0x1c
+#define RF23X_REG_VERSION 0x1d
+#define RF23X_REG_MANID0 0x1e
+#define RF23X_REG_MANID1 0x1f
+#define RF23X_REG_SADDR0 0x20
+#define RF23X_REG_SADDR1 0x21
+#define RF23X_REG_PANID0 0x22
+#define RF23X_REG_PANID1 0x23
+#define RF23X_REG_IEEEADDR0 0x24
+#define RF23X_REG_IEEEADDR1 0x25
+#define RF23X_REG_IEEEADDR2 0x26
+#define RF23X_REG_IEEEADDR3 0x27
+#define RF23X_REG_IEEEADDR4 0x28
+#define RF23X_REG_IEEEADDR5 0x29
+#define RF23X_REG_IEEEADDR6 0x2a
+#define RF23X_REG_IEEEADDR7 0x2b
+#define RF23X_REG_XAHCTRL0 0x2c
+#define RF23X_REG_CSMASEED0 0x2d
+#define RF23X_REG_CSMASEED1 0x2e
+#define RF23X_REG_CSMABE 0x2f
+#define RF23X_REG_TSTCTRLDIGI 0x36
+#define RF23X_REG_TSTAGC 0x3c
+#define RF23X_REG_SDM 0x3d
+#define RF23X_REG_PHYTXTIME 0x3b
+#define RF23X_REG_PHYPMUVALUE 0x3b
+
+#define RF23X_TRXSTATUS_POS 0
+#define RF23X_TRXSTATUS_MASK 0x1f
+#define RF23X_TRXSTATUS_STATUS RF23X_REG_TRXSTATUS, RF23X_TRXSTATUS_POS, RF23X_TRXSTATUS_MASK
+
+#define RF23X_TRXCMD_POS 0
+#define RF23X_TRXCMD_MASK 0x1f
+#define RF23X_TRXCMD_STATE RF23X_REG_TRXSTATE, RF23X_TRXCMD_POS, RF23X_TRXCMD_MASK
+
+#define RF23X_TXPWR_POS_4 0x00
+#define RF23X_TXPWR_POS_3_7 0x01
+#define RF23X_TXPWR_POS_3_4 0x02
+#define RF23X_TXPWR_POS_3 0x03
+#define RF23X_TXPWR_POS_2_5 0x04
+#define RF23X_TXPWR_POS_2 0x05
+#define RF23X_TXPWR_POS_1 0x06
+#define RF23X_TXPWR_0 0x07
+#define RF23X_TXPWR_NEG_1 0x08
+#define RF23X_TXPWR_NEG_2 0x09
+#define RF23X_TXPWR_NEG_3 0x0a
+#define RF23X_TXPWR_NEG_4 0x0b
+#define RF23X_TXPWR_NEG_6 0x0c
+#define RF23X_TXPWR_NEG_8 0x0d
+#define RF23X_TXPWR_NEG_12 0x0e
+#define RF23X_TXPWR_NEG_17 0x0f
+
+/* CCA_STATUS */
+
+#define RF23X_CCA_MODE_CS_OR_ED 0x00
+#define RF23X_CCA_MODE_ED 0x01
+#define RF23X_CCA_MODE_CS 0x02
+#define RF23X_CCA_MODE_CS_AND_ED 0x03
+
+#define RF23X_CCA_CHANNEL_POS 0
+#define RF23X_CCA_CHANNEL_MASK 0x1f
+#define RF23X_CCA_BITS_CHANNEL RF23X_REG_CCA, RF23X_CCA_CHANNEL_POS, RF23X_CCA_CHANNEL_MASK
+#define RF23X_CCA_MODE_POS 5
+#define RF23X_CCA_MODE_MASK 0x03
+#define RF23X_CCA_BITS_MODE RF23X_REG_CCA, RF23X_CCA_MODE_POS, RF23X_CCA_MODE_MASK
+
+/* XAH CTRL 1 */
+
+#define RF23X_XAHCTRL1_PROM_MODE_POS 1
+#define RF23X_XAHCTRL1_PROM_MODE_MASK 0x01
+#define RF23X_XAHCTRL1_BITS_PROM_MODE RF23X_REG_XAHCTRL1, RF23X_XAHCTRL1_PROM_MODE_POS, RF23X_XAHCTRL1_PROM_MODE_MASK
+
+/* CSMA SEED 0 */
+
+/* CSMA SEED 1 */
+
+#define RF23X_CSMASEED1_IAMCOORD_POS 3
+#define RF23X_CSMASEED1_IAMCOORD_MASK 0x1
+#define RF23X_CSMASEED1_IAMCOORD_BITS RF23X_REG_CSMASEED1, RF23X_CSMASEED1_IAMCOORD_POS, RF23X_CSMASEED1_IAMCOORD_MASK
+
+#define RF23X_CSMASEED1_AACK_DIS_ACK_POS
+#define RF23X_CSMASEED1_AACK_SET_PD_POS
+#define RF23X_CSMASEED1_AACK_FVN_MODE_POS
+
+/* TRX Status */
+
+#define TRX_STATUS_PON 0x00
+#define TRX_STATUS_BUSYRX 0x01
+#define TRX_STATUS_BUSYTX 0x02
+#define TRX_STATUS_RXON 0x06
+#define TRX_STATUS_TRXOFF 0x08
+#define TRX_STATUS_PLLON 0x09
+#define TRX_STATUS_SLEEP 0x0f
+#define TRX_STATUS_DEEPSLEEP 0x10
+#define TRX_STATUS_BUSYRXACK 0x11
+#define TRX_STATUS_BUSYTXARET 0x12
+#define TRX_STATUS_RXAACKON 0x16
+#define TRX_STATUS_TXARETON 0x19
+#define TRX_STATUS_STATEINTRANS 0x1f
+
+/* TRX Command */
+
+#define TRX_CMD_NOP 0x00
+#define TRX_CMD_TX 0x02
+#define TRX_CMD_FORCETRXOFF 0x03
+#define TRX_CMD_FORCE_PLLON 0x04
+#define TRX_CMD_RX_ON 0x06
+#define TRX_CMD_TRXOFF 0x08
+#define TRX_CMD_PLL_ON 0x09
+#define TRX_CMD_PREP_DEEPSLEEP 0x10
+#define TRX_CMD_RX_AACK_ON 0x16
+#define TRX_CMD_TX_ARET_ON 0x19
+
+/* IRQ MASK 0x0e */
+
+#define RF23X_IRQ_MASK_LOCK_PLL (1 << 0)
+#define RF23X_IRQ_MASK_UNLOCK_PLL (1 << 1)
+#define RF23X_IRQ_MASK_RX_START (1 << 2)
+#define RF23X_IRQ_MASK_TRX_END (1 << 3)
+#define RF23X_IRQ_MASK_CCA_ED_DONE (1 << 4)
+#define RF23X_IRQ_MASK_AMI (1 << 5)
+#define RF23X_IRQ_MASK_TRX_UR (1 << 6)
+#define RF23X_IRQ_MASK_BAT_LOW (1 << 7)
+
+#define RF23X_IRQ_MASK_DEFAULT (RF23X_IRQ_MASK_TRX_END)
+
+#endif /* __DRIVERS_WIRELESS_IEEE802154_AT86RF23X_H */
diff --git a/drivers/wireless/ieee802154/mrf24j40.c b/drivers/wireless/ieee802154/mrf24j40.c
index 41558b9dfad..8283278d3c9 100644
--- a/drivers/wireless/ieee802154/mrf24j40.c
+++ b/drivers/wireless/ieee802154/mrf24j40.c
@@ -2,7 +2,9 @@
* drivers/wireless/ieee802154/mrf24j40.c
*
* Copyright (C) 2015-2016 Sebastien Lorquet. All rights reserved.
+ * Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Sebastien Lorquet
+ * Author: Anthony Merlino
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -55,8 +57,11 @@
#include
#include
+#include
+
#include
#include
+#include
#include "mrf24j40.h"
@@ -65,7 +70,7 @@
****************************************************************************/
#ifndef CONFIG_SCHED_HPWORK
-#error High priority work queue required in this driver
+# error High priority work queue required in this driver
#endif
#ifndef CONFIG_IEEE802154_MRF24J40_SPIMODE
@@ -86,34 +91,65 @@
#define MRF24J40_RXMODE_PROMISC 1
#define MRF24J40_RXMODE_NOCRC 2
+#define MRF24J40_MODE_DEVICE 0
+#define MRF24J40_MODE_COORD 1
+#define MRF24J40_MODE_PANCOORD 2
+
/* Definitions for PA control on high power modules */
-#define MRF24J40_PA_AUTO 1
-#define MRF24J40_PA_ED 2
-#define MRF24J40_PA_SLEEP 3
+#define MRF24J40_PA_AUTO 1
+#define MRF24J40_PA_ED 2
+#define MRF24J40_PA_SLEEP 3
+
+#define MRF24J40_GTS_SLOTS 2
/****************************************************************************
* Private Types
****************************************************************************/
+struct mrf24j40_txdesc_s
+{
+ struct ieee802154_txdesc_s pub;
+
+ uint8_t busy : 1; /* Is this txdesc being used */
+};
+
/* A MRF24J40 device instance */
-struct mrf24j40_dev_s
+struct mrf24j40_radio_s
{
- struct ieee802154_dev_s ieee; /* The public device instance */
- FAR struct spi_dev_s *spi; /* Saved SPI interface instance */
- struct work_s irqwork; /* Interrupt continuation work queue support */
- FAR const struct mrf24j40_lower_s *lower; /* Low-level MCU-specific support */
+ struct ieee802154_radio_s radio; /* The public device instance */
+ FAR struct ieee802154_radiocb_s *radiocb; /* Registered callbacks */
- uint16_t panid; /* 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 */
+ /* MAC Attributes */
+
+ bool rxonidle : 1;
+
+ /* Low-level MCU-specific support */
+
+ FAR const struct mrf24j40_lower_s *lower;
+ FAR struct spi_dev_s *spi; /* Saved SPI interface instance */
+
+ struct work_s irqwork; /* For deferring interrupt work to work queue */
+ struct work_s pollwork; /* For deferring poll work to the work queue */
+ sem_t exclsem; /* Exclusive access to this struct */
+
+ struct ieee802154_addr_s addr;
+
+ 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 */
+
+ /* Buffer Allocations */
+
+ struct mrf24j40_txdesc_s csma_desc;
+ FAR struct iob_s *csma_frame;
+
+ struct mrf24j40_txdesc_s gts_desc[MRF24J40_GTS_SLOTS];
+ FAR struct iob_s *gts_frame[MRF24J40_GTS_SLOTS];
};
/****************************************************************************
@@ -122,44 +158,90 @@ struct mrf24j40_dev_s
/* Internal operations */
-static void mrf24j40_lock (FAR struct spi_dev_s *spi);
+static void mrf24j40_spi_lock(FAR struct spi_dev_s *spi);
-static void mrf24j40_setreg (FAR struct spi_dev_s *spi, uint32_t addr, uint8_t val);
-static uint8_t mrf24j40_getreg (FAR struct spi_dev_s *spi, uint32_t addr);
+static void mrf24j40_setreg(FAR struct spi_dev_s *spi, uint32_t addr,
+ uint8_t val);
+static uint8_t mrf24j40_getreg(FAR struct spi_dev_s *spi, uint32_t addr);
-static int mrf24j40_resetrfsm (FAR struct mrf24j40_dev_s *dev);
-static int mrf24j40_pacontrol (FAR struct mrf24j40_dev_s *dev, int mode);
-static int mrf24j40_initialize(FAR struct mrf24j40_dev_s *dev);
+static int mrf24j40_resetrfsm(FAR struct mrf24j40_radio_s *dev);
+static int mrf24j40_pacontrol(FAR struct mrf24j40_radio_s *dev, int mode);
+static int mrf24j40_initialize(FAR struct mrf24j40_radio_s *dev);
-static int mrf24j40_setrxmode (FAR struct mrf24j40_dev_s *dev, int mode);
-static int mrf24j40_regdump (FAR struct mrf24j40_dev_s *dev);
-static void mrf24j40_irqwork_rx(FAR struct mrf24j40_dev_s *dev);
-static void mrf24j40_irqwork_tx(FAR struct mrf24j40_dev_s *dev);
-static void mrf24j40_irqworker (FAR void *arg);
-static int mrf24j40_interrupt (int irq, FAR void *context);
+static int mrf24j40_setrxmode(FAR struct mrf24j40_radio_s *dev, int mode);
+static int mrf24j40_regdump(FAR struct mrf24j40_radio_s *dev);
+
+static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev);
+static void mrf24j40_irqwork_txnorm(FAR struct mrf24j40_radio_s *dev);
+static void mrf24j40_irqwork_txgts(FAR struct mrf24j40_radio_s *dev,
+ uint8_t gts_num);
+
+static void mrf24j40_irqworker(FAR void *arg);
+static int mrf24j40_interrupt(int irq, FAR void *context, FAR void *arg);
+
+static void mrf24j40_dopoll_csma(FAR void *arg);
+static void mrf24j40_dopoll_gts(FAR void *arg);
+
+static int mrf24j40_csma_setup(FAR struct mrf24j40_radio_s *dev,
+ FAR struct iob_s *frame);
+static int mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t gts,
+ FAR struct iob_s *frame);
+static int mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev,
+ FAR struct iob_s *frame, uint32_t fifo_addr);
+
+
+static int mrf24j40_setchannel(FAR struct mrf24j40_radio_s *dev,
+ uint8_t chan);
+static int mrf24j40_getchannel(FAR struct mrf24j40_radio_s *dev,
+ FAR uint8_t *chan);
+static int mrf24j40_setpanid(FAR struct mrf24j40_radio_s *dev,
+ uint16_t panid);
+static int mrf24j40_getpanid(FAR struct mrf24j40_radio_s *dev,
+ FAR uint16_t *panid);
+static int mrf24j40_setsaddr(FAR struct mrf24j40_radio_s *dev,
+ uint16_t saddr);
+static int mrf24j40_getsaddr(FAR struct mrf24j40_radio_s *dev,
+ FAR uint16_t *saddr);
+static int mrf24j40_seteaddr(FAR struct mrf24j40_radio_s *dev,
+ FAR const uint8_t *eaddr);
+static int mrf24j40_geteaddr(FAR struct mrf24j40_radio_s *dev,
+ FAR uint8_t *eaddr);
+static int mrf24j40_setpromisc(FAR struct mrf24j40_radio_s *dev,
+ bool promisc);
+static int mrf24j40_getpromisc(FAR struct mrf24j40_radio_s *dev,
+ FAR bool *promisc);
+static int mrf24j40_setdevmode(FAR struct mrf24j40_radio_s *dev,
+ uint8_t mode);
+static int mrf24j40_getdevmode(FAR struct mrf24j40_radio_s *dev,
+ FAR uint8_t *mode);
+static int mrf24j40_settxpower(FAR struct mrf24j40_radio_s *dev,
+ int32_t txpwr);
+static int mrf24j40_gettxpower(FAR struct mrf24j40_radio_s *dev,
+ FAR int32_t *txpwr);
+static int mrf24j40_setcca(FAR struct mrf24j40_radio_s *dev,
+ FAR struct ieee802154_cca_s *cca);
+static int mrf24j40_getcca(FAR struct mrf24j40_radio_s *dev,
+ FAR struct ieee802154_cca_s *cca);
+static int mrf24j40_energydetect(FAR struct mrf24j40_radio_s *dev,
+ FAR uint8_t *energy);
+static int mrf24j40_rxenable(FAR struct mrf24j40_radio_s *dev, bool enable);
/* Driver operations */
-static int mrf24j40_setchannel (FAR struct ieee802154_dev_s *ieee, uint8_t chan);
-static int mrf24j40_getchannel (FAR struct ieee802154_dev_s *ieee, FAR uint8_t *chan);
-static int mrf24j40_setpanid (FAR struct ieee802154_dev_s *ieee, uint16_t panid);
-static int mrf24j40_getpanid (FAR struct ieee802154_dev_s *ieee, FAR uint16_t *panid);
-static int mrf24j40_setsaddr (FAR struct ieee802154_dev_s *ieee, uint16_t saddr);
-static int mrf24j40_getsaddr (FAR struct ieee802154_dev_s *ieee, FAR uint16_t *saddr);
-static int mrf24j40_seteaddr (FAR struct ieee802154_dev_s *ieee, FAR uint8_t *eaddr);
-static int mrf24j40_geteaddr (FAR struct ieee802154_dev_s *ieee, FAR uint8_t *eaddr);
-static int mrf24j40_setpromisc (FAR struct ieee802154_dev_s *ieee, bool promisc);
-static int mrf24j40_getpromisc (FAR struct ieee802154_dev_s *ieee, FAR bool *promisc);
-static int mrf24j40_setdevmode (FAR struct ieee802154_dev_s *ieee, uint8_t mode);
-static int mrf24j40_getdevmode (FAR struct ieee802154_dev_s *ieee, FAR uint8_t *mode);
-static int mrf24j40_settxpower (FAR struct ieee802154_dev_s *ieee, int32_t txpwr);
-static int mrf24j40_gettxpower (FAR struct ieee802154_dev_s *ieee, FAR int32_t *txpwr);
-static int mrf24j40_setcca (FAR struct ieee802154_dev_s *ieee, FAR struct ieee802154_cca_s *cca);
-static int mrf24j40_getcca (FAR struct ieee802154_dev_s *ieee, FAR struct ieee802154_cca_s *cca);
-static int mrf24j40_ioctl (FAR struct ieee802154_dev_s *ieee, int cmd, unsigned long arg);
-static int mrf24j40_energydetect(FAR struct ieee802154_dev_s *ieee, FAR uint8_t *energy);
-static int mrf24j40_rxenable (FAR struct ieee802154_dev_s *ieee, bool state, FAR struct ieee802154_packet_s *packet);
-static int mrf24j40_transmit (FAR struct ieee802154_dev_s *ieee, FAR struct ieee802154_packet_s *packet);
+static int mrf24j40_bind(FAR struct ieee802154_radio_s *radio,
+ FAR struct ieee802154_radiocb_s *radiocb);
+static int mrf24j40_txnotify_csma(FAR struct ieee802154_radio_s *radio);
+static int mrf24j40_txnotify_gts(FAR struct ieee802154_radio_s *radio);
+static int mrf24j40_get_attr(FAR struct ieee802154_radio_s *radio,
+ enum ieee802154_pib_attr_e pib_attr,
+ FAR union ieee802154_attr_val_u *attr_value);
+static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio,
+ enum ieee802154_pib_attr_e pib_attr,
+ FAR const union ieee802154_attr_val_u *attr_value);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
/* These are pointers to ALL registered MRF24J40 devices.
* This table is used during irqs to find the context
@@ -168,55 +250,302 @@ static int mrf24j40_transmit (FAR struct ieee802154_dev_s *ieee, FAR stru
* using the IRQ number. See the ENC28J60 or CC3000 drivers for reference.
*/
-static struct mrf24j40_dev_s g_mrf24j40_devices[1];
-
-static const struct ieee802154_devops_s mrf24j40_devops =
+static const struct ieee802154_radioops_s mrf24j40_devops =
{
- mrf24j40_setchannel, mrf24j40_getchannel,
- mrf24j40_setpanid , mrf24j40_getpanid,
- mrf24j40_setsaddr , mrf24j40_getsaddr,
- mrf24j40_seteaddr , mrf24j40_geteaddr,
- mrf24j40_setpromisc, mrf24j40_getpromisc,
- mrf24j40_setdevmode, mrf24j40_getdevmode,
- mrf24j40_settxpower, mrf24j40_gettxpower,
- mrf24j40_setcca , mrf24j40_getcca,
- mrf24j40_ioctl,
- mrf24j40_energydetect,
- mrf24j40_rxenable,
- mrf24j40_transmit
+ mrf24j40_bind,
+ mrf24j40_txnotify_csma,
+ mrf24j40_txnotify_gts,
+ mrf24j40_get_attr,
+ mrf24j40_set_attr
};
/****************************************************************************
- * Private Functions
+ * Radio Interface Functions
****************************************************************************/
-/* Hardware access routines */
+static int mrf24j40_bind(FAR struct ieee802154_radio_s *radio,
+ FAR struct ieee802154_radiocb_s *radiocb)
+{
+ FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
+
+ DEBUGASSERT(dev != NULL);
+ dev->radiocb = radiocb;
+ return OK;
+}
/****************************************************************************
- * Name: mrf24j40_lock
+ * Function: mrf24j40_txnotify_csma
+ *
+ * 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:
+ * radio - Reference to the radio driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int mrf24j40_txnotify_csma(FAR struct ieee802154_radio_s *radio)
+{
+ FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
+
+ /* 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(&dev->pollwork))
+ {
+ /* Schedule to serialize the poll on the worker thread. */
+
+ work_queue(HPWORK, &dev->pollwork, mrf24j40_dopoll_csma, dev, 0);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Function: mrf24j40_txnotify_gts
+ *
+ * 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:
+ * radio - Reference to the radio driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int mrf24j40_txnotify_gts(FAR struct ieee802154_radio_s *radio)
+{
+ FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
+
+ /* 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(&dev->pollwork))
+ {
+ /* Schedule to serialize the poll on the worker thread. */
+
+ work_queue(HPWORK, &dev->pollwork, mrf24j40_dopoll_gts, dev, 0);
+ }
+
+ return OK;
+}
+
+static int mrf24j40_get_attr(FAR struct ieee802154_radio_s *radio,
+ enum ieee802154_pib_attr_e pib_attr,
+ FAR union ieee802154_attr_val_u *attr_value)
+{
+ FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
+ int ret;
+
+ switch (pib_attr)
+ {
+ case IEEE802154_PIB_MAC_EXTENDED_ADDR:
+ {
+ memcpy(&attr_value->mac.eaddr[0], &dev->addr.eaddr[0], 8);
+ ret = IEEE802154_STATUS_SUCCESS;
+ }
+ break;
+ default:
+ ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE;
+ }
+ return ret;
+}
+
+static int mrf24j40_set_attr(FAR struct ieee802154_radio_s *radio,
+ enum ieee802154_pib_attr_e pib_attr,
+ FAR const union ieee802154_attr_val_u *attr_value)
+{
+ FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)radio;
+ int ret;
+
+ switch (pib_attr)
+ {
+ case IEEE802154_PIB_MAC_EXTENDED_ADDR:
+ {
+ mrf24j40_seteaddr(dev, &attr_value->mac.eaddr[0]);
+ ret = IEEE802154_STATUS_SUCCESS;
+ }
+ break;
+ case IEEE802154_PIB_MAC_PROMISCUOUS_MODE:
+ {
+ if (attr_value->mac.promisc_mode)
+ {
+ mrf24j40_setrxmode(dev, MRF24J40_RXMODE_PROMISC);
+ }
+ else
+ {
+ mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL);
+ }
+
+ ret = IEEE802154_STATUS_SUCCESS;
+ }
+ break;
+ case IEEE802154_PIB_MAC_RX_ON_WHEN_IDLE:
+ {
+ dev->rxonidle = attr_value->mac.rxonidle;
+ mrf24j40_rxenable(dev, dev->rxonidle);
+ }
+ break;
+ default:
+ ret = IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE;
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Internal Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: mrf24j40_dopoll_csma
+ *
+ * Description:
+ * This function is called in order to preform an out-of-sequence TX poll.
+ * This is done:
+ *
+ * 1. After completion of a transmission (mrf24j40_txdone_csma),
+ * 2. When new TX data is available (mrf24j40_txnotify_csma), and
+ * 3. After a TX timeout to restart the sending process
+ * (mrf24j40_txtimeout_csma).
+ *
+ * Parameters:
+ * radio - Reference to the radio driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void mrf24j40_dopoll_csma(FAR void *arg)
+{
+ FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg;
+ int len = 0;
+
+ /* Get exclusive access to the driver */
+
+ while (sem_wait(&dev->exclsem) != 0) { }
+
+ /* If this a CSMA transaction and we have room in the CSMA fifo */
+
+ if (!dev->csma_desc.busy)
+ {
+ /* need to somehow allow for a handle to be passed */
+
+ len = dev->radiocb->poll_csma(dev->radiocb, &dev->csma_desc.pub,
+ &dev->csma_frame);
+ if (len > 0)
+ {
+ /* Now the txdesc is in use */
+
+ dev->csma_desc.busy = 1;
+
+ /* Setup the transaction on the device in the CSMA FIFO */
+
+ mrf24j40_csma_setup(dev, dev->csma_frame);
+ }
+ }
+
+ sem_post(&dev->exclsem);
+}
+
+/****************************************************************************
+ * Function: mrf24j40_dopoll_gts
+ *
+ * Description:
+ * This function is called in order to preform an out-of-sequence TX poll.
+ * This is done:
+ *
+ * 1. After completion of a transmission (mrf24j40_txdone_gts),
+ * 2. When new TX data is available (mrf24j40_txnotify_gts), and
+ * 3. After a TX timeout to restart the sending process
+ * (mrf24j40_txtimeout_gts).
+ *
+ * Parameters:
+ * arg - Reference to the radio driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void mrf24j40_dopoll_gts(FAR void *arg)
+{
+ FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg;
+ int gts = 0;
+ int len = 0;
+
+ /* Get exclusive access to the driver */
+
+ while (sem_wait(&dev->exclsem) != 0) { }
+
+ for (gts = 0; gts < MRF24J40_GTS_SLOTS; gts++)
+ {
+ if (!dev->gts_desc[gts].busy)
+ {
+ len = dev->radiocb->poll_gts(dev->radiocb, &dev->gts_desc[gts].pub,
+ &dev->gts_frame[0]);
+ if (len > 0)
+ {
+ /* Now the txdesc is in use */
+
+ dev->gts_desc[gts].busy = 1;
+
+ /* Setup the transaction on the device in the open GTS FIFO */
+
+ mrf24j40_gts_setup(dev, gts, dev->gts_frame[0]);
+ }
+ }
+ }
+
+ sem_post(&dev->exclsem);
+}
+
+/****************************************************************************
+ * Name: mrf24j40_spi_lock
*
* Description:
* Acquire exclusive access to the shared SPI bus.
*
****************************************************************************/
-static void mrf24j40_lock(FAR struct spi_dev_s *spi)
+static void mrf24j40_spi_lock(FAR struct spi_dev_s *spi)
{
- SPI_LOCK (spi, 1);
- SPI_SETBITS (spi, 8);
- SPI_SETMODE (spi, CONFIG_IEEE802154_MRF24J40_SPIMODE);
+ SPI_LOCK(spi, 1);
+ SPI_SETBITS(spi, 8);
+ SPI_SETMODE(spi, CONFIG_IEEE802154_MRF24J40_SPIMODE);
SPI_SETFREQUENCY(spi, CONFIG_IEEE802154_MRF24J40_FREQUENCY);
}
/****************************************************************************
- * Name: mrf24j40_unlock
+ * Name: mrf24j40_spi_unlock
*
* Description:
* Release exclusive access to the shared SPI bus.
*
****************************************************************************/
-static inline void mrf24j40_unlock(FAR struct spi_dev_s *spi)
+static inline void mrf24j40_spi_unlock(FAR struct spi_dev_s *spi)
{
SPI_LOCK(spi,0);
}
@@ -229,7 +558,8 @@ static inline void mrf24j40_unlock(FAR struct spi_dev_s *spi)
*
****************************************************************************/
-static void mrf24j40_setreg(FAR struct spi_dev_s *spi, uint32_t addr, uint8_t val)
+static void mrf24j40_setreg(FAR struct spi_dev_s *spi, uint32_t addr,
+ uint8_t val)
{
uint8_t buf[3];
int len;
@@ -254,11 +584,11 @@ static void mrf24j40_setreg(FAR struct spi_dev_s *spi, uint32_t addr, uint8_t va
buf[len++] = val;
- mrf24j40_lock(spi);
+ mrf24j40_spi_lock(spi);
SPI_SELECT(spi, SPIDEV_IEEE802154(0), true);
SPI_SNDBLOCK(spi, buf, len);
SPI_SELECT(spi, SPIDEV_IEEE802154(0), false);
- mrf24j40_unlock(spi);
+ mrf24j40_spi_unlock(spi);
}
/****************************************************************************
@@ -298,14 +628,14 @@ static uint8_t mrf24j40_getreg(FAR struct spi_dev_s *spi, uint32_t addr)
buf[len++] = 0xFF; /* dummy */
- mrf24j40_lock (spi);
+ mrf24j40_spi_lock (spi);
SPI_SELECT (spi, SPIDEV_IEEE802154(0), true);
SPI_EXCHANGE (spi, buf, rx, len);
SPI_SELECT (spi, SPIDEV_IEEE802154(0), false);
- mrf24j40_unlock(spi);
+ mrf24j40_spi_unlock(spi);
- /*winfo("r[%04X]=%02X\n", addr, rx[len-1]);*/
- return rx[len-1];
+ /* wlinfo("r[%04X]=%02X\n", addr, rx[len - 1]); */
+ return rx[len - 1];
}
/****************************************************************************
@@ -317,7 +647,7 @@ static uint8_t mrf24j40_getreg(FAR struct spi_dev_s *spi, uint32_t addr)
*
****************************************************************************/
-static int mrf24j40_resetrfsm(FAR struct mrf24j40_dev_s *dev)
+static int mrf24j40_resetrfsm(FAR struct mrf24j40_radio_s *dev)
{
uint8_t reg;
@@ -342,7 +672,7 @@ static int mrf24j40_resetrfsm(FAR struct mrf24j40_dev_s *dev)
* GPIO 3: PA power enable (not required on MB)
****************************************************************************/
-static int mrf24j40_pacontrol(FAR struct mrf24j40_dev_s *dev, int mode)
+static int mrf24j40_pacontrol(FAR struct mrf24j40_radio_s *dev, int mode)
{
if (!dev->paenabled)
{
@@ -384,7 +714,7 @@ static int mrf24j40_pacontrol(FAR struct mrf24j40_dev_s *dev, int mode)
*
****************************************************************************/
-static int mrf24j40_initialize(FAR struct mrf24j40_dev_s *dev)
+static int mrf24j40_initialize(FAR struct mrf24j40_radio_s *dev)
{
/* Software reset */
@@ -416,15 +746,16 @@ static int mrf24j40_initialize(FAR struct mrf24j40_dev_s *dev)
*
****************************************************************************/
-static int mrf24j40_setrxmode(FAR struct mrf24j40_dev_s *dev, int mode)
+static int mrf24j40_setrxmode(FAR struct mrf24j40_radio_s *dev, int mode)
{
uint8_t reg;
+
if (mode < MRF24J40_RXMODE_NORMAL || mode > MRF24J40_RXMODE_NOCRC)
{
return -EINVAL;
}
- reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR);
+ reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR);
reg &= ~0x03;
reg |= mode;
@@ -433,23 +764,23 @@ static int mrf24j40_setrxmode(FAR struct mrf24j40_dev_s *dev, int mode)
if (mode != MRF24J40_RXMODE_NORMAL)
{
/* Promisc and error modes: Disable auto ACK */
+
reg |= MRF24J40_RXMCR_NOACKRSP;
}
else
{
/* Normal mode : enable auto-ACK */
+
reg &= ~MRF24J40_RXMCR_NOACKRSP;
}
mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg);
dev->rxmode = mode;
- winfo("%u\n", (unsigned)mode);
+ wlinfo("%u\n", (unsigned)mode);
return OK;
}
-/* Publicized driver routines */
-
/****************************************************************************
* Name: mrf24j40_setchannel
*
@@ -464,14 +795,11 @@ static int mrf24j40_setrxmode(FAR struct mrf24j40_dev_s *dev, int mode)
*
****************************************************************************/
-static int mrf24j40_setchannel(FAR struct ieee802154_dev_s *ieee,
- uint8_t chan)
+static int mrf24j40_setchannel(FAR struct mrf24j40_radio_s *dev, uint8_t chan)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
- if (chan<11 || chan>26)
+ if (chan < 11 || chan > 26)
{
- werr("ERROR: Invalid chan: %d\n",chan);
+ wlerr("ERROR: Invalid chan: %d\n",chan);
return -EINVAL;
}
@@ -486,7 +814,7 @@ static int mrf24j40_setchannel(FAR struct ieee802154_dev_s *ieee,
mrf24j40_resetrfsm(dev);
dev->channel = chan;
- //winfo("%u\n", (unsigned)chan);
+ //wlinfo("%u\n", (unsigned)chan);
return OK;
}
@@ -495,15 +823,13 @@ static int mrf24j40_setchannel(FAR struct ieee802154_dev_s *ieee,
* Name: mrf24j40_getchannel
*
* Description:
- * Define the current radio channel the device is operating on.
+ * Get the channel the device is operating on.
*
****************************************************************************/
-static int mrf24j40_getchannel(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_getchannel(FAR struct mrf24j40_radio_s *dev,
FAR uint8_t *chan)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
*chan = dev->channel;
return OK;
@@ -517,16 +843,14 @@ static int mrf24j40_getchannel(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_setpanid(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_setpanid(FAR struct mrf24j40_radio_s *dev,
uint16_t panid)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
mrf24j40_setreg(dev->spi, MRF24J40_PANIDH, (uint8_t)(panid>>8));
mrf24j40_setreg(dev->spi, MRF24J40_PANIDL, (uint8_t)(panid&0xFF));
- dev->panid = panid;
- winfo("%04X\n", (unsigned)panid);
+ dev->addr.panid = panid;
+ wlinfo("%04X\n", (unsigned)panid);
return OK;
}
@@ -539,12 +863,10 @@ static int mrf24j40_setpanid(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_getpanid(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_getpanid(FAR struct mrf24j40_radio_s *dev,
FAR uint16_t *panid)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
- *panid = dev->panid;
+ *panid = dev->addr.panid;
return OK;
}
@@ -559,16 +881,14 @@ static int mrf24j40_getpanid(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_setsaddr(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_setsaddr(FAR struct mrf24j40_radio_s *dev,
uint16_t saddr)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
mrf24j40_setreg(dev->spi, MRF24J40_SADRH, (uint8_t)(saddr>>8));
mrf24j40_setreg(dev->spi, MRF24J40_SADRL, (uint8_t)(saddr&0xFF));
- dev->saddr = saddr;
- winfo("%04X\n", (unsigned)saddr);
+ dev->addr.saddr = saddr;
+ wlinfo("%04X\n", (unsigned)saddr);
return OK;
}
@@ -580,12 +900,10 @@ static int mrf24j40_setsaddr(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_getsaddr(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_getsaddr(FAR struct mrf24j40_radio_s *dev,
FAR uint16_t *saddr)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
- *saddr = dev->saddr;
+ *saddr = dev->addr.saddr;
return OK;
}
@@ -599,17 +917,15 @@ static int mrf24j40_getsaddr(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_seteaddr(FAR struct ieee802154_dev_s *ieee,
- FAR uint8_t *eaddr)
+static int mrf24j40_seteaddr(FAR struct mrf24j40_radio_s *dev,
+ FAR const uint8_t *eaddr)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
int i;
- for (i=0; i<8; i++)
+ for (i = 0; i < 8; i++)
{
mrf24j40_setreg(dev->spi, MRF24J40_EADR0 + i, eaddr[i]);
- dev->eaddr[i] = eaddr[i];
+ dev->addr.eaddr[i] = eaddr[i];
}
return OK;
@@ -623,48 +939,10 @@ static int mrf24j40_seteaddr(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_geteaddr(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_geteaddr(FAR struct mrf24j40_radio_s *dev,
FAR uint8_t *eaddr)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
- memcpy(eaddr, dev->eaddr, 8);
-
- return OK;
-}
-
-/****************************************************************************
- * Name: mrf24j40_setpromisc
- *
- * Description:
- * Set the device into promiscuous mode, e.g do not filter any incoming
- * frame.
- *
- ****************************************************************************/
-
-static int mrf24j40_setpromisc(FAR struct ieee802154_dev_s *ieee,
- bool promisc)
-{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
- return mrf24j40_setrxmode(dev, promisc ? MRF24J40_RXMODE_PROMISC :
- MRF24J40_RXMODE_NORMAL);
-}
-
-/****************************************************************************
- * Name: mrf24j40_getpromisc
- *
- * Description:
- * Get the device receive mode.
- *
- ****************************************************************************/
-
-static int mrf24j40_getpromisc(FAR struct ieee802154_dev_s *ieee,
- FAR bool *promisc)
-{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
- *promisc = (dev->rxmode == MRF24J40_RXMODE_PROMISC);
+ memcpy(eaddr, dev->addr.eaddr, 8);
return OK;
}
@@ -677,10 +955,9 @@ static int mrf24j40_getpromisc(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_setdevmode(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_setdevmode(FAR struct mrf24j40_radio_s *dev,
uint8_t mode)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
int ret = OK;
uint8_t reg;
@@ -695,29 +972,28 @@ static int mrf24j40_setdevmode(FAR struct ieee802154_dev_s *ieee,
reg = mrf24j40_getreg(dev->spi, MRF24J40_RXMCR);
- if (mode == IEEE802154_MODE_PANCOORD)
+ if (mode == MRF24J40_MODE_PANCOORD)
{
reg |= MRF24J40_RXMCR_PANCOORD;
reg &= ~MRF24J40_RXMCR_COORD;
}
- else if (mode == IEEE802154_MODE_COORD)
+ else if (mode == MRF24J40_MODE_COORD)
{
reg |= MRF24J40_RXMCR_COORD;
reg &= ~MRF24J40_RXMCR_PANCOORD;
}
- else if (mode == IEEE802154_MODE_DEVICE)
+ else if (mode == MRF24J40_MODE_DEVICE)
{
reg &= ~MRF24J40_RXMCR_PANCOORD;
reg &= ~MRF24J40_RXMCR_COORD;
}
else
{
- return -EINVAL;
+ return -EINVAL;
}
mrf24j40_setreg(dev->spi, MRF24J40_RXMCR, reg);
dev->devmode = mode;
-
return ret;
}
@@ -729,13 +1005,10 @@ static int mrf24j40_setdevmode(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_getdevmode(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_getdevmode(FAR struct mrf24j40_radio_s *dev,
FAR uint8_t *mode)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
*mode = dev->devmode;
-
return OK;
}
@@ -749,10 +1022,9 @@ static int mrf24j40_getdevmode(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_settxpower(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_settxpower(FAR struct mrf24j40_radio_s *dev,
int32_t txpwr)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
uint8_t reg;
int save_txpwr = txpwr;
@@ -780,21 +1052,43 @@ static int mrf24j40_settxpower(FAR struct ieee802154_dev_s *ieee,
return -EINVAL;
}
- winfo("remaining attenuation: %d mBm\n",txpwr);
+ wlinfo("remaining attenuation: %d mBm\n",txpwr);
switch(txpwr/100)
{
case -9:
case -8:
case -7:
- case -6: reg |= 0x07; break;
- case -5: reg |= 0x06; break;
- case -4: reg |= 0x05; break;
- case -3: reg |= 0x04; break;
- case -2: reg |= 0x03; break;
- case -1: reg |= 0x02; break;
- case 0: reg |= 0x00; break; /* value 0x01 is 0.5 db, not used */
- default: return -EINVAL;
+ case -6:
+ reg |= 0x07;
+ break;
+
+ case -5:
+ reg |= 0x06;
+ break;
+
+ case -4:
+ reg |= 0x05;
+ break;
+
+ case -3:
+ reg |= 0x04;
+ break;
+
+ case -2:
+ reg |= 0x03;
+ break;
+
+ case -1:
+ reg |= 0x02;
+ break;
+
+ case 0:
+ reg |= 0x00; /* value 0x01 is 0.5 db, not used */
+ break;
+
+ default:
+ return -EINVAL;
}
mrf24j40_setreg(dev->spi, MRF24J40_RFCON3, reg);
@@ -810,13 +1104,10 @@ static int mrf24j40_settxpower(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_gettxpower(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_gettxpower(FAR struct mrf24j40_radio_s *dev,
FAR int32_t *txpwr)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
*txpwr = dev->txpower;
-
return OK;
}
@@ -828,10 +1119,9 @@ static int mrf24j40_gettxpower(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_setcca(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_setcca(FAR struct mrf24j40_radio_s *dev,
FAR struct ieee802154_cca_s *cca)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
uint8_t mode;
if (!cca->use_ed && !cca->use_cs)
@@ -862,7 +1152,6 @@ static int mrf24j40_setcca(FAR struct ieee802154_dev_s *ieee,
mrf24j40_setreg(dev->spi, MRF24J40_BBREG2, mode);
memcpy(&dev->cca, cca, sizeof(struct ieee802154_cca_s));
-
return OK;
}
@@ -874,13 +1163,10 @@ static int mrf24j40_setcca(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_getcca(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_getcca(FAR struct mrf24j40_radio_s *dev,
FAR struct ieee802154_cca_s *cca)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
memcpy(cca, &dev->cca, sizeof(struct ieee802154_cca_s));
-
return OK;
}
@@ -892,13 +1178,13 @@ static int mrf24j40_getcca(FAR struct ieee802154_dev_s *ieee,
*
****************************************************************************/
-static int mrf24j40_regdump(FAR struct mrf24j40_dev_s *dev)
+static int mrf24j40_regdump(FAR struct mrf24j40_radio_s *dev)
{
uint32_t i;
char buf[4+16*3+2+1];
- int len=0;
+ int len = 0;
- winfo("Short regs:\n");
+ wlinfo("Short regs:\n");
for (i = 0; i < 0x40; i++)
{
@@ -911,14 +1197,14 @@ static int mrf24j40_regdump(FAR struct mrf24j40_dev_s *dev)
if ((i & 15) == 15)
{
sprintf(buf+len, "\n");
- winfo("%s", buf);
+ wlinfo("%s", buf);
}
}
- winfo("Long regs:\n");
- for (i=0x80000200;i<0x80000250;i++)
+ wlinfo("Long regs:\n");
+ for (i = 0x80000200; i < 0x80000250; i++)
{
- if ((i&15)==0)
+ if ((i & 15) == 0)
{
len=sprintf(buf, "%02x: ",i&0xFF);
}
@@ -927,40 +1213,13 @@ static int mrf24j40_regdump(FAR struct mrf24j40_dev_s *dev)
if ((i & 15) == 15)
{
sprintf(buf+len, "\n");
- winfo("%s", buf);
+ wlinfo("%s", buf);
}
}
return 0;
}
-/****************************************************************************
- * Name: mrf24j40_ioctl
- *
- * Description:
- * Misc/unofficial device controls.
- *
- ****************************************************************************/
-
-static int mrf24j40_ioctl(FAR struct ieee802154_dev_s *ieee, int cmd,
- unsigned long arg)
-{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
-
- switch(cmd)
- {
- case 1000:
- return mrf24j40_regdump(dev);
-
- case 1001: dev->paenabled = (uint8_t)arg;
- winfo("PA %sabled\n", arg ? "en" : "dis");
- return OK;
-
- default:
- return -ENOTTY;
- }
-}
-
/****************************************************************************
* Name: mrf24j40_energydetect
*
@@ -969,10 +1228,9 @@ static int mrf24j40_ioctl(FAR struct ieee802154_dev_s *ieee, int cmd,
*
****************************************************************************/
-static int mrf24j40_energydetect(FAR struct ieee802154_dev_s *ieee,
+static int mrf24j40_energydetect(FAR struct mrf24j40_radio_s *dev,
FAR uint8_t *energy)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
uint8_t reg;
/* Manually enable the LNA*/
@@ -1006,32 +1264,22 @@ static int mrf24j40_energydetect(FAR struct ieee802154_dev_s *ieee,
/* Back to automatic control */
mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO);
-
return OK;
}
-/* Packet exchange */
-
/****************************************************************************
- * Name: mrf24j40_transmit
+ * Name: mrf24j40_csma_setup
*
* Description:
- * Send a regular packet over the air.
+ * Setup a CSMA transaction in the normal TX FIFO
*
****************************************************************************/
-static int mrf24j40_transmit(FAR struct ieee802154_dev_s *ieee, FAR struct ieee802154_packet_s *packet)
+static int mrf24j40_csma_setup(FAR struct mrf24j40_radio_s *dev,
+ FAR struct iob_s *frame)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
- uint32_t addr;
- uint8_t reg;
- int ret;
- int hlen = 3; /* include frame control and seq number */
- uint8_t fc1, fc2;
-
- mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO);
-
- addr = 0x80000000;
+ uint8_t reg;
+ int ret;
/* Enable tx int */
@@ -1039,57 +1287,9 @@ static int mrf24j40_transmit(FAR struct ieee802154_dev_s *ieee, FAR struct ieee8
reg &= ~MRF24J40_INTCON_TXNIE;
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
- /* Analyze frame control to compute header length */
+ /* Setup the FIFO */
- fc1 = packet->data[0];
- fc2 = packet->data[1];
-
- // winfo("fc1 %02X fc2 %02X\n", fc1,fc2);
-
- if ((fc2 & IEEE802154_FC2_DADDR) == IEEE802154_DADDR_SHORT)
- {
- hlen += 2 + 2; /* Destination PAN + shortaddr */
- }
- else if ((fc2 & IEEE802154_FC2_DADDR) == IEEE802154_DADDR_EXT)
- {
- hlen += 2 + 8; /* Destination PAN + extaddr */
- }
-
- if ((fc2 & IEEE802154_FC2_SADDR) == IEEE802154_SADDR_SHORT)
- {
- if ((fc1 & IEEE802154_FC1_INTRA) != IEEE802154_INTRA)
- {
- hlen += 2; /* No PAN compression, source PAN is different from dest PAN */
- }
-
- hlen += 2; /* Source saddr */
- }
- else if ((fc2 & IEEE802154_FC2_SADDR) == IEEE802154_SADDR_EXT)
- {
- if ((fc1 & IEEE802154_FC1_INTRA) != IEEE802154_INTRA)
- {
- hlen += 2; /* No PAN compression, source PAN is different from dest PAN */
- }
-
- hlen += 8; /* Ext saddr */
- }
-
-// winfo("hlen %d\n",hlen);
-
- /* Header len, 0, TODO for security modes */
-
- mrf24j40_setreg(dev->spi, addr++, hlen);
-
- /* Frame length */
-
- mrf24j40_setreg(dev->spi, addr++, packet->len);
-
- /* Frame data */
-
- for (ret = 0; ret < packet->len; ret++) /* this sets the correct val for ret */
- {
- mrf24j40_setreg(dev->spi, addr++, packet->data[ret]);
- }
+ ret = mrf24j40_setup_fifo(dev, frame, MRF24J40_TXNORM_FIFO);
/* If the frame control field contains
* an acknowledgment request, set the TXNACKREQ bit.
@@ -1097,7 +1297,7 @@ static int mrf24j40_transmit(FAR struct ieee802154_dev_s *ieee, FAR struct ieee8
*/
reg = MRF24J40_TXNCON_TXNTRIG;
- if (fc1 & IEEE802154_FC1_ACKREQ)
+ if (frame->io_data[0] & IEEE802154_FRAMECTRL_ACKREQ)
{
reg |= MRF24J40_TXNCON_TXNACKREQ;
}
@@ -1105,67 +1305,188 @@ static int mrf24j40_transmit(FAR struct ieee802154_dev_s *ieee, FAR struct ieee8
/* Trigger packet emission */
mrf24j40_setreg(dev->spi, MRF24J40_TXNCON, reg);
-
- /* Suspend calling thread until transmit is complete */
-
- return sem_wait(&ieee->txsem);
+ return ret;
}
/****************************************************************************
- * Name: mrf24j40_irqwork_tx
+ * Name: mrf24j40_gts_setup
+ *
+ * Description:
+ * Setup a GTS transaction in one of the GTS FIFOs
+ *
+ ****************************************************************************/
+
+static int mrf24j40_gts_setup(FAR struct mrf24j40_radio_s *dev, uint8_t fifo,
+ FAR struct iob_s *frame)
+{
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mrf24j40_setup_fifo
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+static int mrf24j40_setup_fifo(FAR struct mrf24j40_radio_s *dev,
+ FAR struct iob_s *frame, uint32_t fifo_addr)
+{
+ int ret;
+ int hlen = 3; /* Include frame control and seq number */
+ uint16_t frame_ctrl;
+
+ /* Analyze frame control to compute header length */
+
+ frame_ctrl = frame->io_data[0];
+ frame_ctrl |= (frame->io_data[1] << 8);
+
+ if ((frame_ctrl & IEEE802154_FRAMECTRL_DADDR)== IEEE802154_ADDRMODE_SHORT)
+ {
+ hlen += 2 + 2; /* Destination PAN + shortaddr */
+ }
+ else if ((frame_ctrl & IEEE802154_FRAMECTRL_DADDR) == IEEE802154_ADDRMODE_EXTENDED)
+ {
+ hlen += 2 + 8; /* Destination PAN + extaddr */
+ }
+
+ if (!(frame_ctrl & IEEE802154_FRAMECTRL_PANIDCOMP))
+ {
+ hlen += 2; /* No PAN compression, source PAN is different from dest PAN */
+ }
+
+ if ((frame_ctrl & IEEE802154_FRAMECTRL_SADDR)== IEEE802154_ADDRMODE_SHORT)
+ {
+ hlen += 2; /* Source saddr */
+ }
+ else if ((frame_ctrl & IEEE802154_FRAMECTRL_SADDR) == IEEE802154_ADDRMODE_EXTENDED)
+ {
+ hlen += 8; /* Ext saddr */
+ }
+
+ /* Header len, 0, TODO for security modes */
+
+ mrf24j40_setreg(dev->spi, fifo_addr++, hlen);
+
+ /* Frame length */
+
+ mrf24j40_setreg(dev->spi, fifo_addr++, frame->io_len);
+
+ /* Frame data */
+
+ for (ret = 0; ret < frame->io_len; ret++) /* this sets the correct val for ret */
+ {
+ mrf24j40_setreg(dev->spi, fifo_addr++, frame->io_data[ret]);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: mrf24j40_irqwork_txnorm
*
* Description:
* Manage completion of packet transmission.
*
****************************************************************************/
-static void mrf24j40_irqwork_tx(FAR struct mrf24j40_dev_s *dev)
+static void mrf24j40_irqwork_txnorm(FAR struct mrf24j40_radio_s *dev)
{
uint8_t txstat;
- uint8_t reg;
-
- txstat = mrf24j40_getreg(dev->spi, MRF24J40_TXSTAT);
-
- /* 1 means it failed, we want 1 to mean it worked.
- * tx_ok = !(tmp & ~(1 << TXNSTAT));
- * retries = tmp >> 6;
- * channel_busy = (tmp & (1 << CCAFAIL));
- */
-
- //winfo("TXSTAT%02X!\n", txstat);
-#warning TODO report errors
- UNUSED(txstat);
/* Disable tx int */
- reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
- reg |= MRF24J40_INTCON_TXNIE;
- mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
+ txstat = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
+ txstat |= MRF24J40_INTCON_TXNIE;
+ mrf24j40_setreg(dev->spi, MRF24J40_INTCON, txstat);
- /* Wake up the thread that triggered the transmission */
+ /* Get the status from the device and copy the status into the tx desc.
+ * The status for the normal FIFO is represented with bit TXNSTAT where
+ * 0=success, 1= failure.
+ */
- sem_post(&dev->ieee.txsem);
+ txstat = mrf24j40_getreg(dev->spi, MRF24J40_TXSTAT);
+ dev->csma_desc.pub.status = txstat & MRF24J40_TXSTAT_TXNSTAT;
+
+ /* Inform the next layer of the transmission success/failure */
+
+ dev->radiocb->txdone(dev->radiocb, &dev->csma_desc.pub);
+
+ /* We are now done with the transaction */
+
+ dev->csma_desc.busy = 0;
+
+ /* Free the IOB */
+
+ iob_free(dev->csma_frame);
+
+ mrf24j40_dopoll_csma(dev);
}
/****************************************************************************
- * Name: mrf24j40_enablerx
+ * Name: mrf24j40_irqwork_gts
*
* Description:
- * Enable reception of a packet. The interrupt will signal the rx semaphore.
+ * Manage completion of packet transmission.
*
****************************************************************************/
-static int mrf24j40_rxenable(FAR struct ieee802154_dev_s *ieee, bool state,
- FAR struct ieee802154_packet_s *packet)
+static void mrf24j40_irqwork_txgts(FAR struct mrf24j40_radio_s *dev,
+ uint8_t gts)
+{
+ uint8_t txstat;
+
+ /* Disable tx int */
+
+ txstat = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
+ txstat |= MRF24J40_INTCON_TXNIE;
+ mrf24j40_setreg(dev->spi, MRF24J40_INTCON, txstat);
+
+ /* Get the status from the device and copy the status into the tx desc.
+ * The status for the normal FIFO is represented with bit TXNSTAT where
+ * 0=success, 1= failure.
+ */
+
+ txstat = mrf24j40_getreg(dev->spi, MRF24J40_TXSTAT);
+
+ if (gts == 0)
+ {
+ dev->csma_desc.pub.status = txstat & MRF24J40_TXSTAT_TXG1STAT;
+ }
+ else if (gts == 1)
+ {
+ dev->csma_desc.pub.status = txstat & MRF24J40_TXSTAT_TXG2STAT;
+ }
+
+ /* Inform the next layer of the transmission success/failure */
+
+ dev->radiocb->txdone(dev->radiocb, &dev->gts_desc[gts].pub);
+
+ /* We are now done with the transaction */
+
+ dev->gts_desc[gts].busy = 0;
+
+ /* Free the IOB */
+
+ iob_free(dev->gts_frame[gts]);
+
+ mrf24j40_dopoll_gts(dev);
+}
+
+/****************************************************************************
+ * Name: mrf24j40_rxenable
+ *
+ * Description:
+ * Enable/Disable receiver.
+ *
+ ****************************************************************************/
+
+static int mrf24j40_rxenable(FAR struct mrf24j40_radio_s *dev, bool enable)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)ieee;
uint8_t reg;
- if (state)
+ if (enable)
{
- mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO);
- ieee->rxbuf = packet;
-
/* Enable rx int */
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
@@ -1174,7 +1495,11 @@ static int mrf24j40_rxenable(FAR struct ieee802154_dev_s *ieee, bool state,
}
else
{
- ieee->rxbuf = NULL;
+ /* Disable rx int */
+
+ reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
+ reg |= MRF24J40_INTCON_RXIE;
+ mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
}
return OK;
@@ -1188,42 +1513,60 @@ static int mrf24j40_rxenable(FAR struct ieee802154_dev_s *ieee, bool state,
*
****************************************************************************/
-static void mrf24j40_irqwork_rx(FAR struct mrf24j40_dev_s *dev)
+static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev)
{
+ FAR struct ieee802154_data_ind_s *ind;
uint32_t addr;
uint32_t index;
uint8_t reg;
- /*winfo("!\n");*/
-
/* Disable rx int */
reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
reg |= MRF24J40_INTCON_RXIE;
mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
- /* Disable packet reception */
+ /* Disable packet reception. See pg. 109 of datasheet */
mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, MRF24J40_BBREG1_RXDECINV);
- /* Read packet */
+ /* Allocate a data_ind to put the frame in */
- addr = 0x80000300;
- dev->ieee.rxbuf->len = mrf24j40_getreg(dev->spi, addr++);
- /*winfo("len %3d\n", dev->ieee.rxbuf->len);*/
-
- for (index = 0; index < dev->ieee.rxbuf->len; index++)
+ ind = ieee802154_ind_allocate();
+ if (ind == NULL)
{
- dev->ieee.rxbuf->data[index] = mrf24j40_getreg(dev->spi, addr++);
+ wlerr("ERROR: Unable to allocate data_ind. Discarding frame");
+ goto done;
}
- dev->ieee.rxbuf->lqi = mrf24j40_getreg(dev->spi, addr++);
- dev->ieee.rxbuf->rssi = mrf24j40_getreg(dev->spi, addr++);
+ /* Read packet */
- /* Reduce len by 2, we only receive frames with correct crc, no check required */
+ addr = MRF24J40_RXBUF_BASE;
- dev->ieee.rxbuf->len -= 2;
+ ind->frame->io_len= mrf24j40_getreg(dev->spi, addr++);
+ /* TODO: This needs to be changed. It is inefficient to do the SPI read byte
+ * by byte */
+
+ for (index = 0; index < ind->frame->io_len; index++)
+ {
+ ind->frame->io_data[index] = mrf24j40_getreg(dev->spi, addr++);
+ }
+
+ ind->lqi = mrf24j40_getreg(dev->spi, addr++);
+ ind->rssi = mrf24j40_getreg(dev->spi, addr++);
+
+ /* Reduce len by 2, we only receive frames with correct crc, no check
+ * required.
+ */
+
+ ind->frame->io_len -= 2;
+
+ /* Callback the receiver in the next highest layer */
+
+ dev->radiocb->rxframe(dev->radiocb, ind);
+
+done:
/* Enable reception of next packet by flushing the fifo.
* This is an MRF24J40 errata (no. 1).
*/
@@ -1234,7 +1577,14 @@ static void mrf24j40_irqwork_rx(FAR struct mrf24j40_dev_s *dev)
mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, 0);
- sem_post(&dev->ieee.rxsem);
+ /* Only enable RX interrupt if we are to be listening when IDLE */
+
+ if (dev->rxonidle)
+ {
+ reg = mrf24j40_getreg(dev->spi, MRF24J40_INTCON);
+ reg &= ~MRF24J40_INTCON_RXIE;
+ mrf24j40_setreg(dev->spi, MRF24J40_INTCON, reg);
+ }
}
/****************************************************************************
@@ -1256,7 +1606,7 @@ static void mrf24j40_irqwork_rx(FAR struct mrf24j40_dev_s *dev)
static void mrf24j40_irqworker(FAR void *arg)
{
- FAR struct mrf24j40_dev_s *dev = (FAR struct mrf24j40_dev_s *)arg;
+ FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg;
uint8_t intstat;
DEBUGASSERT(dev);
@@ -1265,7 +1615,7 @@ static void mrf24j40_irqworker(FAR void *arg)
/* Read and store INTSTAT - this clears the register. */
intstat = mrf24j40_getreg(dev->spi, MRF24J40_INTSTAT);
-// winfo("INT%02X\n", intstat);
+ //wlinfo("INT%02X\n", intstat);
/* Do work according to the pending interrupts */
@@ -1280,12 +1630,26 @@ static void mrf24j40_irqworker(FAR void *arg)
{
/* A packet was transmitted or failed*/
- mrf24j40_irqwork_tx(dev);
+ mrf24j40_irqwork_txnorm(dev);
}
- /* Re-Enable GPIO interrupts */
+ if ((intstat & MRF24J40_INTSTAT_TXG1IF))
+ {
+ /* A packet was transmitted or failed*/
- dev->lower->enable(dev->lower, TRUE);
+ mrf24j40_irqwork_txgts(dev, 0);
+ }
+
+ if ((intstat & MRF24J40_INTSTAT_TXG1IF))
+ {
+ /* A packet was transmitted or failed*/
+
+ mrf24j40_irqwork_txgts(dev, 1);
+ }
+
+ /* Re-enable GPIO interrupts */
+
+ dev->lower->enable(dev->lower, true);
}
/****************************************************************************
@@ -1305,13 +1669,11 @@ static void mrf24j40_irqworker(FAR void *arg)
*
****************************************************************************/
-static int mrf24j40_interrupt(int irq, FAR void *context)
+static int mrf24j40_interrupt(int irq, FAR void *context, FAR void *arg)
{
- /* To support multiple devices,
- * retrieve the priv structure using the irq number
- */
+ FAR struct mrf24j40_radio_s *dev = (FAR struct mrf24j40_radio_s *)arg;
- register FAR struct mrf24j40_dev_s *dev = &g_mrf24j40_devices[0];
+ DEBUGASSERT(dev != NULL);
/* In complex environments, we cannot do SPI transfers from the interrupt
* handler because semaphores are probably used to lock the SPI bus. In
@@ -1327,7 +1689,7 @@ static int mrf24j40_interrupt(int irq, FAR void *context)
* Interrupts are re-enabled in enc_irqworker() when the work is completed.
*/
- dev->lower->enable(dev->lower, FALSE);
+ dev->lower->enable(dev->lower, false);
return work_queue(HPWORK, &dev->irqwork, mrf24j40_irqworker, (FAR void *)dev, 0);
}
@@ -1343,26 +1705,21 @@ static int mrf24j40_interrupt(int irq, FAR void *context)
*
****************************************************************************/
-FAR struct ieee802154_dev_s *mrf24j40_init(FAR struct spi_dev_s *spi,
- FAR const struct mrf24j40_lower_s *lower)
+FAR struct ieee802154_radio_s *mrf24j40_init(FAR struct spi_dev_s *spi,
+ FAR const struct mrf24j40_lower_s *lower)
{
- FAR struct mrf24j40_dev_s *dev;
+ FAR struct mrf24j40_radio_s *dev;
struct ieee802154_cca_s cca;
-#if 0
- dev = kmm_zalloc(sizeof(struct mrf24j40_dev_s));
-
- if (!dev)
+ dev = kmm_zalloc(sizeof(struct mrf24j40_radio_s));
+ if (dev == NULL)
{
return NULL;
}
-#else
- dev = &g_mrf24j40_devices[0];
-#endif
/* Attach irq */
- if (lower->attach(lower, mrf24j40_interrupt) != OK)
+ if (lower->attach(lower, mrf24j40_interrupt, dev) != OK)
{
#if 0
free(dev);
@@ -1370,44 +1727,35 @@ FAR struct ieee802154_dev_s *mrf24j40_init(FAR struct spi_dev_s *spi,
return NULL;
}
- dev->ieee.ops = &mrf24j40_devops;
+ /* Allow exclusive access to the privmac struct */
- /* Initialize semaphores */
+ sem_init(&dev->exclsem, 0, 1);
- sem_init(&dev->ieee.rxsem, 0, 0);
- sem_init(&dev->ieee.txsem, 0, 0);
-
- /* These semaphores are all used for signaling and, hence, should
- * not have priority inheritance enabled.
- */
-
- sem_setprotocol(&dev->ieee.rxsem, SEM_PRIO_NONE);
- sem_setprotocol(&dev->ieee.txsem, SEM_PRIO_NONE);
+ dev->radio.ops = &mrf24j40_devops;
dev->lower = lower;
dev->spi = spi;
mrf24j40_initialize(dev);
- mrf24j40_setchannel(&dev->ieee, 11);
- mrf24j40_setpanid (&dev->ieee, IEEE802154_PAN_DEFAULT);
- mrf24j40_setsaddr (&dev->ieee, IEEE802154_SADDR_UNSPEC);
- mrf24j40_seteaddr (&dev->ieee, IEEE802154_EADDR_UNSPEC);
+ mrf24j40_setchannel(dev, 11);
+ mrf24j40_setpanid (dev, 0xFFFF);
+ mrf24j40_setsaddr (dev, 0xFFFF);
+ mrf24j40_seteaddr (dev, (uint8_t*)"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
/* Default device params */
cca.use_ed = 1;
cca.use_cs = 0;
cca.edth = 0x60; /* CCA mode ED, no carrier sense, recommenced ED threshold -69 dBm */
- mrf24j40_setcca(&dev->ieee, &cca);
+ mrf24j40_setcca(dev, &cca);
mrf24j40_setrxmode(dev, MRF24J40_RXMODE_NORMAL);
- mrf24j40_settxpower(&dev->ieee, 0); /*16. Set transmitter power .*/
+ mrf24j40_settxpower(dev, 0); /*16. Set transmitter power .*/
mrf24j40_pacontrol(dev, MRF24J40_PA_AUTO);
- dev->lower->enable(dev->lower, TRUE);
-
- return &dev->ieee;
+ dev->lower->enable(dev->lower, true);
+ return &dev->radio;
}
diff --git a/drivers/wireless/ieee802154/mrf24j40.h b/drivers/wireless/ieee802154/mrf24j40.h
index de3131e4df4..f9a8a35a5d0 100644
--- a/drivers/wireless/ieee802154/mrf24j40.h
+++ b/drivers/wireless/ieee802154/mrf24j40.h
@@ -33,8 +33,8 @@
*
****************************************************************************/
-#ifndef __DRIVERS_IEEE802154_MRF24J40_H
-#define __DRIVERS_IEEE802154_MRF24J40_H
+#ifndef __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H
+#define __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H
/* MRF24J40 Registers *******************************************************/
@@ -97,18 +97,27 @@
#define MRF24J40_BBREG6 0x3E
#define MRF24J40_CCAEDTH 0x3F
-#define MRF24J40_RFCON0 0x80000200
-#define MRF24J40_RFCON1 0x80000201
-#define MRF24J40_RFCON2 0x80000202
-#define MRF24J40_RFCON3 0x80000203
-#define MRF24J40_RFCON5 0x80000205
-#define MRF24J40_RFCON6 0x80000206
-#define MRF24J40_RFCON7 0x80000207
-#define MRF24J40_RFCON8 0x80000208
-#define MRF24J40_SLPCAL0 0x80000209
-#define MRF24J40_SLPCAL1 0x8000020A
-#define MRF24J40_SLPCAL2 0x8000020B
-#define MRF24J40_RFSTATE 0x8000020F
+#define MRF24J40_FIFO_BASE 0x80000000
+#define MRF24J40_LONGREG_BASE 0x80000200
+#define MRF24J40_RXBUF_BASE 0x80000300
+
+#define MRF24J40_TXNORM_FIFO (MRF24J40_FIFO_BASE + 0x000)
+#define MRF24J40_BEACON_FIFO (MRF24J40_FIFO_BASE + 0x080)
+#define MRF24J40_GTS1_FIFO (MRF24J40_FIFO_BASE + 0x100)
+#define MRF24J40_GTS2_FIFO (MRF24J40_FIFO_BASE + 0x180)
+
+#define MRF24J40_RFCON0 (MRF24J40_LONGREG_BASE + 0x00)
+#define MRF24J40_RFCON1 (MRF24J40_LONGREG_BASE + 0x01)
+#define MRF24J40_RFCON2 (MRF24J40_LONGREG_BASE + 0x02)
+#define MRF24J40_RFCON3 (MRF24J40_LONGREG_BASE + 0x03)
+#define MRF24J40_RFCON5 (MRF24J40_LONGREG_BASE + 0x05)
+#define MRF24J40_RFCON6 (MRF24J40_LONGREG_BASE + 0x06)
+#define MRF24J40_RFCON7 (MRF24J40_LONGREG_BASE + 0x07)
+#define MRF24J40_RFCON8 (MRF24J40_LONGREG_BASE + 0x08)
+#define MRF24J40_SLPCAL0 (MRF24J40_LONGREG_BASE + 0x09)
+#define MRF24J40_SLPCAL1 (MRF24J40_LONGREG_BASE + 0x0A)
+#define MRF24J40_SLPCAL2 (MRF24J40_LONGREG_BASE + 0x0B)
+#define MRF24J40_RFSTATE (MRF24J40_LONGREG_BASE + 0x0F)
#define MRF24J40_RSSI 0x80000210
#define MRF24J40_SLPCON0 0x80000211
#define MRF24J40_SLPCON1 0x80000220
@@ -147,26 +156,26 @@
/* INTSTAT bits */
-#define MRF24J40_INTSTAT_SLPIF 0x80
-#define MRF24J40_INTSTAT_WAKEIF 0x40
-#define MRF24J40_INTSTAT_HSYMTMRIF 0x20
-#define MRF24J40_INTSTAT_SECIF 0x10
-#define MRF24J40_INTSTAT_RXIF 0x08
-#define MRF24J40_INTSTAT_TXG2IF 0x04
-#define MRF24J40_INTSTAT_TXG1IF 0x02
-#define MRF24J40_INTSTAT_TXNIF 0x01
+#define MRF24J40_INTSTAT_TXNIF (1 << 0)
+#define MRF24J40_INTSTAT_TXG1IF (1 << 1)
+#define MRF24J40_INTSTAT_TXG2IF (1 << 2)
+#define MRF24J40_INTSTAT_RXIF (1 << 3)
+#define MRF24J40_INTSTAT_SECIF (1 << 4)
+#define MRF24J40_INTSTAT_HSYMTMRIF (1 << 5)
+#define MRF24J40_INTSTAT_WAKEIF (1 << 6)
+#define MRF24J40_INTSTAT_SLPIF (1 << 7)
/* RXMCR bits */
-#define MRF24J40_RXMCR_PROMI 0x01 /* Enable promisc mode (rx all valid packets) */
-#define MRF24J40_RXMCR_ERRPKT 0x02 /* Do not check CRC */
+#define MRF24J40_RXMCR_PROMI (1 << 0) /* Enable promisc mode (rx all valid packets) */
+#define MRF24J40_RXMCR_ERRPKT 0x02 /* Do not check CRC */
#define MRF24J40_RXMCR_COORD 0x04 /* Enable coordinator mode ??? DIFFERENCE ??? - not used in datasheet! */
-#define MRF24J40_RXMCR_PANCOORD 0x08 /* Enable PAN coordinator mode ??? DIFFERENCE ??? */
+#define MRF24J40_RXMCR_PANCOORD 0x08 /* Enable PAN coordinator mode ??? DIFFERENCE ??? */
#define MRF24J40_RXMCR_NOACKRSP 0x20 /* Enable auto ACK when a packet is rxed */
/* TXMCR bits */
-#define MRF24J40_TXMCR_CSMABF0 0x01
+#define MRF24J40_TXMCR_CSMABF0 (1 << 0)
#define MRF24J40_TXMCR_CSMABF1 0x02
#define MRF24J40_TXMCR_CSMABF2 0x04
#define MRF24J40_TXMCR_MACMINBE0 0x08
@@ -184,7 +193,7 @@
#define MRF24J40_INTCON_RXIE 0x08
#define MRF24J40_INTCON_TXG2IE 0x04
#define MRF24J40_INTCON_TXG1IE 0x02
-#define MRF24J40_INTCON_TXNIE 0x01
+#define MRF24J40_INTCON_TXNIE (1 << 0)
/* BBREG1 bits */
@@ -197,10 +206,19 @@
/* TXNCON bits */
-#define MRF24J40_TXNCON_TXNTRIG 0x01 /* Trigger packet tx, automatically cleared */
+#define MRF24J40_TXNCON_TXNTRIG (1 << 0) /* Trigger packet tx, automatically cleared */
#define MRF24J40_TXNCON_TXNSECEN 0x02 /* Enable security */
#define MRF24J40_TXNCON_TXNACKREQ 0x04 /* An ACK is requested for this pkt */
#define MRF24J40_TXNCON_INDIRECT 0x08 /* Activate indirect tx bit (for coordinators) */
#define MRF24J40_TXNCON_FPSTAT 0x10 /* Status of the frame pending big in txed acks */
-#endif /* __DRIVERS_IEEE802154_MRF24J40_H */
+/* TXSTAT bits */
+
+#define MRF24J40_TXSTAT_TXNSTAT (1 << 0)
+#define MRF24J40_TXSTAT_TXG1STAT (1 << 1)
+#define MRF24J40_TXSTAT_TXG2STAT (1 << 2)
+#define MRF24J40_TXSTAT_CCAFAIL (1 << 5)
+#define MRF24J40_TXSTAT_X_SHIFT 6
+#define MRF24J40_TXSTAT_X_MASK (3 << MRF24J40_TXSTAT_X_SHIFT)
+
+#endif /* __DRIVERS_WIRELESS_IEEE802154_MRF24J40_H */
diff --git a/include/nuttx/fs/ioctl.h b/include/nuttx/fs/ioctl.h
index 674eafc1d7e..cfcc4507d60 100644
--- a/include/nuttx/fs/ioctl.h
+++ b/include/nuttx/fs/ioctl.h
@@ -1,7 +1,7 @@
/****************************************************************************
* include/nuttx/fs/ioctl.h
*
- * Copyright (C) 2008, 2009, 2011-2014 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2008, 2009, 2011-2014, 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
* Redistribution and use in source and binary forms, with or without
@@ -88,6 +88,7 @@
#define _GPIOBASE (0x2300) /* GPIO driver commands */
#define _CLIOCBASE (0x2400) /* Contactless modules ioctl commands */
#define _USBCBASE (0x2500) /* USB-C controller ioctl commands */
+#define _MAC802154BASE (0x2600) /* 802.15.4 MAC ioctl commands */
/* boardctl() commands share the same number space */
@@ -421,6 +422,12 @@
#define _USBCIOCVALID(c) (_IOC_TYPE(c)==_USBCBASE)
#define _USBCIOC(nr) _IOC(_USBCBASE,nr)
+/* 802.15.4 MAC driver ioctl definitions ************************************/
+/* (see nuttx/include/wireless/ieee802154/ieee802154_mac.h */
+
+#define _MAC802154IOCVALID(c) (_IOC_TYPE(c)==_MAC802154BASE)
+#define _MAC802154IOC(nr) _IOC(_MAC802154BASE,nr)
+
/* boardctl() command definitions *******************************************/
#define _BOARDIOCVALID(c) (_IOC_TYPE(c)==_BOARDBASE)
diff --git a/include/nuttx/net/ieee802154.h b/include/nuttx/net/ieee802154.h
index 6132d3d02bc..736141a3515 100644
--- a/include/nuttx/net/ieee802154.h
+++ b/include/nuttx/net/ieee802154.h
@@ -58,61 +58,20 @@
* Pre-processor Definitions
****************************************************************************/
-/* By default, a 2-byte Rime address is used for the IEEE802.15.4 MAC
- * device's link layer address. If CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
- * is selected, then an 8-byte Rime address will be used.
+/* By default, a 2-byte short address is used for the IEEE802.15.4 MAC
+ * device's link layer address. If CONFIG_NET_6LOWPAN_EXTENDEDADDR
+ * is selected, then an 8-byte extended address will be used.
*/
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
-# define NET_6LOWPAN_RIMEADDR_SIZE 8
+#define NET_6LOWPAN_SADDRSIZE 2
+#define NET_6LOWPAN_EADDRSIZE 8
+
+#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
+# define NET_6LOWPAN_ADDRSIZE NET_6LOWPAN_EADDRSIZE
#else
-# define NET_6LOWPAN_RIMEADDR_SIZE 2
+# define NET_6LOWPAN_ADDRSIZE NET_6LOWPAN_SADDRSIZE
#endif
-/* Frame format definitions *************************************************/
-/* These are some definitions of element values used in the FCF. See the
- * IEEE802.15.4 spec for details.
- */
-
-#define FRAME802154_FRAMETYPE_SHIFT (0) /* Bits 0-2: Frame type */
-#define FRAME802154_FRAMETYPE_MASK (7 << FRAME802154_FRAMETYPE_SHIFT)
-#define FRAME802154_SECENABLED_SHIFT (3) /* Bit 3: Security enabled */
-#define FRAME802154_FRAMEPENDING_SHIFT (4) /* Bit 4: Frame pending */
-#define FRAME802154_ACKREQUEST_SHIFT (5) /* Bit 5: ACK request */
-#define FRAME802154_PANIDCOMP_SHIFT (6) /* Bit 6: PANID compression */
- /* Bits 7-9: Reserved */
-#define FRAME802154_DSTADDR_SHIFT (2) /* Bits 10-11: Dest address mode */
-#define FRAME802154_DSTADDR_MASK (3 << FRAME802154_DSTADDR_SHIFT)
-#define FRAME802154_VERSION_SHIFT (4) /* Bit 12-13: Frame version */
-#define FRAME802154_VERSION_MASK (3 << FRAME802154_VERSION_SHIFT)
-#define FRAME802154_SRCADDR_SHIFT (6) /* Bits 14-15: Source address mode */
-#define FRAME802154_SRCADDR_MASK (3 << FRAME802154_SRCADDR_SHIFT)
-
-/* Unshifted values for use in struct frame802154_fcf_s */
-
-#define FRAME802154_BEACONFRAME (0)
-#define FRAME802154_DATAFRAME (1)
-#define FRAME802154_ACKFRAME (2)
-#define FRAME802154_CMDFRAME (3)
-
-#define FRAME802154_BEACONREQ (7)
-
-#define FRAME802154_IEEERESERVED (0)
-#define FRAME802154_NOADDR (0) /* Only valid for ACK or Beacon frames */
-#define FRAME802154_SHORTADDRMODE (2)
-#define FRAME802154_LONGADDRMODE (3)
-
-#define FRAME802154_NOBEACONS 0x0f
-
-#define FRAME802154_BROADCASTADDR 0xffff
-#define FRAME802154_BROADCASTPANDID 0xffff
-
-#define FRAME802154_IEEE802154_2003 (0)
-#define FRAME802154_IEEE802154_2006 (1)
-
-#define FRAME802154_SECURITY_LEVEL_NONE (0)
-#define FRAME802154_SECURITY_LEVEL_128 (3)
-
/* This maximum size of an IEEE802.15.4 frame. Certain, non-standard
* devices may exceed this value, however.
*/
@@ -123,11 +82,35 @@
* Public Types
****************************************************************************/
-/* Rime address representation */
+/* IEEE 802.15.4 address representations */
-struct rimeaddr_s
+struct sixlowpan_saddr_s
{
- uint8_t u8[NET_6LOWPAN_RIMEADDR_SIZE];
+ uint8_t u8[NET_6LOWPAN_SADDRSIZE];
+};
+
+struct sixlowpan_eaddr_s
+{
+ uint8_t u8[NET_6LOWPAN_EADDRSIZE];
+};
+
+union sixlowpan_anyaddr_u
+{
+ struct sixlowpan_saddr_s saddr;
+ struct sixlowpan_eaddr_s eaddr;
+};
+
+struct sixlowpan_tagaddr_s
+{
+ bool extended;
+ union sixlowpan_anyaddr_u u;
+};
+
+/* Represents the configured address size */
+
+struct sixlowpan_addr_s
+{
+ uint8_t u8[NET_6LOWPAN_ADDRSIZE];
};
/****************************************************************************
diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h
index eb84a7774fd..782c2e33990 100644
--- a/include/nuttx/net/netdev.h
+++ b/include/nuttx/net/netdev.h
@@ -224,7 +224,7 @@ struct net_driver_s
#ifdef CONFIG_NET_6LOWPAN
/* The address assigned to an IEEE 802.15.4 radio. */
- struct rimeaddr_s ieee802154; /* IEEE 802.15.4 Radio address */
+ struct sixlowpan_addr_s ieee802154; /* IEEE 802.15.4 Radio address */
#endif
} d_mac;
#endif
@@ -436,8 +436,12 @@ int ipv6_input(FAR struct net_driver_s *dev);
#endif
#ifdef CONFIG_NET_6LOWPAN
-struct ieee802154_driver_s; /* See sixlowpan.h */
-int sixlowpan_input(FAR struct ieee802154_driver_s *ieee);
+struct ieee802154_driver_s; /* See sixlowpan.h */
+struct ieee802154_data_ind_s; /* See ieee8021454_mac.h */
+struct iob_s; /* See iob.h */
+int sixlowpan_input(FAR struct ieee802154_driver_s *ieee,
+ FAR struct iob_s *framelist,
+ FAR const struct ieee802154_data_ind_s *ind);
#endif
/****************************************************************************
@@ -513,7 +517,7 @@ int devif_timer(FAR struct net_driver_s *dev, devif_poll_callback_t callback);
*
* If no Neighbor Table entry is found for the destination IPv6 address,
* the packet in the d_buf[] is replaced by an ICMPv6 Neighbor Solict
- * request packet for the IPv6 address. The IPv6 packet is dropped and
+ * request packet for the IPv6 address. The IPv6 packet is dropped and
* it is assumed that the higher level protocols (e.g., TCP) eventually
* will retransmit the dropped packet.
*
diff --git a/include/nuttx/net/sixlowpan.h b/include/nuttx/net/sixlowpan.h
index 328723b2f8b..a99f0e5e677 100644
--- a/include/nuttx/net/sixlowpan.h
+++ b/include/nuttx/net/sixlowpan.h
@@ -1,6 +1,7 @@
/****************************************************************************
* include/nuttx/net/sixlowpan.h
- * Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01)
+ * Header file for the 6lowpan implementation (RFC4944 and
+ * draft-hui-6lowpan-hc-01)
*
* Copyright (C) 2017, Gregory Nutt, all rights reserved
* Author: Gregory Nutt
@@ -81,132 +82,132 @@
* bytes for all subsequent headers.
*/
-#define RIME_FRAG_DISPATCH_SIZE 0 /* 16 bit */
-#define RIME_FRAG_TAG 2 /* 16 bit */
-#define RIME_FRAG_OFFSET 4 /* 8 bit */
+#define SIXLOWPAN_FRAG_DISPATCH_SIZE 0 /* 16 bit */
+#define SIXLOWPAN_FRAG_TAG 2 /* 16 bit */
+#define SIXLOWPAN_FRAG_OFFSET 4 /* 8 bit */
-/* Define the Rime buffer as a byte array */
+/* Define the frame buffer as a byte array */
-#define RIME_HC1_DISPATCH 0 /* 8 bit */
-#define RIME_HC1_ENCODING 1 /* 8 bit */
-#define RIME_HC1_TTL 2 /* 8 bit */
+#define SIXLOWPAN_HC1_DISPATCH 0 /* 8 bit */
+#define SIXLOWPAN_HC1_ENCODING 1 /* 8 bit */
+#define SIXLOWPAN_HC1_TTL 2 /* 8 bit */
-#define RIME_HC1_HC_UDP_DISPATCH 0 /* 8 bit */
-#define RIME_HC1_HC_UDP_HC1_ENCODING 1 /* 8 bit */
-#define RIME_HC1_HC_UDP_UDP_ENCODING 2 /* 8 bit */
-#define RIME_HC1_HC_UDP_TTL 3 /* 8 bit */
-#define RIME_HC1_HC_UDP_PORTS 4 /* 8 bit */
-#define RIME_HC1_HC_UDP_CHKSUM 5 /* 16 bit */
+#define SIXLOWPAN_HC1_HC_UDP_DISPATCH 0 /* 8 bit */
+#define SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING 1 /* 8 bit */
+#define SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING 2 /* 8 bit */
+#define SIXLOWPAN_HC1_HC_UDP_TTL 3 /* 8 bit */
+#define SIXLOWPAN_HC1_HC_UDP_PORTS 4 /* 8 bit */
+#define SIXLOWPAN_HC1_HC_UDP_CHKSUM 5 /* 16 bit */
/* Min and Max compressible UDP ports - HC06 */
-#define SIXLOWPAN_UDP_4_BIT_PORT_MIN 0xf0b0
-#define SIXLOWPAN_UDP_4_BIT_PORT_MAX 0xf0bf /* f0b0 + 15 */
-#define SIXLOWPAN_UDP_8_BIT_PORT_MIN 0xf000
-#define SIXLOWPAN_UDP_8_BIT_PORT_MAX 0xf0ff /* f000 + 255 */
+#define SIXLOWPAN_UDP_4_BIT_PORT_MIN 0xf0b0
+#define SIXLOWPAN_UDP_4_BIT_PORT_MAX 0xf0bf /* f0b0 + 15 */
+#define SIXLOWPAN_UDP_8_BIT_PORT_MIN 0xf000
+#define SIXLOWPAN_UDP_8_BIT_PORT_MAX 0xf0ff /* f000 + 255 */
/* 6lowpan dispatches */
-#define SIXLOWPAN_DISPATCH_NALP 0x00 /* 00xxxxxx Not a LoWPAN packet */
-#define SIXLOWPAN_DISPATCH_NALP_MASK 0xc0 /* 11000000 */
+#define SIXLOWPAN_DISPATCH_NALP 0x00 /* 00xxxxxx Not a LoWPAN packet */
+#define SIXLOWPAN_DISPATCH_NALP_MASK 0xc0 /* 11000000 */
-#define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 Uncompressed IPv6 addresses */
-#define SIXLOWPAN_DISPATCH_HC1 0x42 /* 01000010 HC1 Compressed IPv6 header */
-#define SIXLOWPAN_DISPATCH_BC0 0x50 /* 01010000 BC0 Broadcast header */
-#define SIXLOWPAN_DISPATCH_ESC 0x7f /* 01111111 Additional Dispatch octet follows */
+#define SIXLOWPAN_DISPATCH_IPV6 0x41 /* 01000001 Uncompressed IPv6 addresses */
+#define SIXLOWPAN_DISPATCH_HC1 0x42 /* 01000010 HC1 Compressed IPv6 header */
+#define SIXLOWPAN_DISPATCH_BC0 0x50 /* 01010000 BC0 Broadcast header */
+#define SIXLOWPAN_DISPATCH_ESC 0x7f /* 01111111 Additional Dispatch octet follows */
-#define SIXLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx IP Header Compression (IPHC)*/
-#define SIXLOWPAN_DISPATCH_IPHC_MASK 0xe0 /* 11100000 */
+#define SIXLOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx IP Header Compression (IPHC)*/
+#define SIXLOWPAN_DISPATCH_IPHC_MASK 0xe0 /* 11100000 */
-#define SIXLOWPAN_DISPATCH_MESH 0x80 /* 10xxxxxx Mesh routing header */
-#define SIXLOWPAN_DISPATCH_MESH_MASK 0xc0 /* 11000000 */
+#define SIXLOWPAN_DISPATCH_MESH 0x80 /* 10xxxxxx Mesh routing header */
+#define SIXLOWPAN_DISPATCH_MESH_MASK 0xc0 /* 11000000 */
-#define SIXLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx Fragmentation header (first) */
-#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx Fragmentation header (subsequent) */
-#define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf8 /* 11111000 */
+#define SIXLOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx Fragmentation header (first) */
+#define SIXLOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx Fragmentation header (subsequent) */
+#define SIXLOWPAN_DISPATCH_FRAG_MASK 0xf8 /* 11111000 */
/* HC1 encoding */
-#define SIXLOWPAN_HC1_NH_UDP 0x02
-#define SIXLOWPAN_HC1_NH_TCP 0x06
-#define SIXLOWPAN_HC1_NH_ICMP6 0x04
+#define SIXLOWPAN_HC1_NH_UDP 0x02
+#define SIXLOWPAN_HC1_NH_TCP 0x06
+#define SIXLOWPAN_HC1_NH_ICMP6 0x04
/* HC_UDP encoding (works together with HC1) */
-#define SIXLOWPAN_HC_UDP_ALL_C 0xe0
+#define SIXLOWPAN_HC_UDP_ALL_C 0xe0
/* IPHC encoding
*
* Values of fields within the IPHC encoding first byte
* (Using MS-to-LS bit numbering of the draft RFC)
*/
- /* Bits 0-2: 011 */
-#define SIXLOWPAN_IPHC_TC_MASK 0x18 /* Bits 3-4: Traffic Class, Flow Label */
-# define SIXLOWPAN_IPHC_TC_00 0x00 /* ECN+DSCP+4-bit Pad+Flow Label (4 bytes) */
-# define SIXLOWPAN_IPHC_TC_01 0x08 /* ECN+2-bit Pad+ Flow Label (3 bytes), DSCP is elided. */
-# define SIXLOWPAN_IPHC_TC_10 0x10 /* ECN+DSCP (1 byte), Flow Label is elided */
-# define SIXLOWPAN_IPHC_TC_11 0x11 /* Traffic Class and Flow Label are elided */
-#define SIXLOWPAN_IPHC_NH 0x04 /* Bit 5: Next Header Compressed */
-#define SIXLOWPAN_IPHC_HLIM_MASK 0x03 /* Bits 6-7: Hop Limit */
-# define SIXLOWPAN_IPHC_HLIM_INLINE 0x00 /* Carried in-line */
-# define SIXLOWPAN_IPHC_HLIM_1 0x01 /* Compressed hop limit of 1 */
-# define SIXLOWPAN_IPHC_HLIM_64 0x02 /* Compressed hop limit of 64 */
-# define SIXLOWPAN_IPHC_HLIM_255 0x03 /* Compressed hop limit of 255 */
+ /* Bits 0-2: 011 */
+#define SIXLOWPAN_IPHC_TC_MASK 0x18 /* Bits 3-4: Traffic Class, Flow Label */
+# define SIXLOWPAN_IPHC_TC_00 0x00 /* ECN+DSCP+4-bit Pad+Flow Label (4 bytes) */
+# define SIXLOWPAN_IPHC_TC_01 0x08 /* ECN+2-bit Pad+ Flow Label (3 bytes), DSCP is elided. */
+# define SIXLOWPAN_IPHC_TC_10 0x10 /* ECN+DSCP (1 byte), Flow Label is elided */
+# define SIXLOWPAN_IPHC_TC_11 0x11 /* Traffic Class and Flow Label are elided */
+#define SIXLOWPAN_IPHC_NH 0x04 /* Bit 5: Next Header Compressed */
+#define SIXLOWPAN_IPHC_HLIM_MASK 0x03 /* Bits 6-7: Hop Limit */
+# define SIXLOWPAN_IPHC_HLIM_INLINE 0x00 /* Carried in-line */
+# define SIXLOWPAN_IPHC_HLIM_1 0x01 /* Compressed hop limit of 1 */
+# define SIXLOWPAN_IPHC_HLIM_64 0x02 /* Compressed hop limit of 64 */
+# define SIXLOWPAN_IPHC_HLIM_255 0x03 /* Compressed hop limit of 255 */
/* Values of fields within the IPHC encoding second byte */
-#define SIXLOWPAN_IPHC_CID 0x80 /* Bit 8: Context identifier extension */
-#define SIXLOWPAN_IPHC_SAC 0x40 /* Bit 9: Source address compression */
-#define SIXLOWPAN_IPHC_SAM_MASK 0x30 /* Bits 10-11: Source address mode */
-# define SIXLOWPAN_IPHC_SAM_128 0x00 /* 128-bits */
-# define SIXLOWPAN_IPHC_SAM_64 0x10 /* 64-bits */
-# define SIXLOWPAN_IPHC_SAM_16 0x20 /* 16-bits */
-# define SIXLOWPAN_IPHC_SAM_0 0x30 /* 0-bits */
-#define SIXLOWPAN_IPHC_M 0x08 /* Bit 12: Multicast compression */
-#define SIXLOWPAN_IPHC_DAC 0x04 /* Bit 13: Destination address compression */
-#define SIXLOWPAN_IPHC_DAM_MASK 0x03 /* Bits 14-15: Destination address mode */
-# define SIXLOWPAN_IPHC_DAM_128 0x00 /* 128-bits */
-# define SIXLOWPAN_IPHC_DAM_64 0x01 /* 64-bits */
-# define SIXLOWPAN_IPHC_DAM_16 0x02 /* 16-bits */
-# define SIXLOWPAN_IPHC_DAM_0 0x03 /* 0-bits */
+#define SIXLOWPAN_IPHC_CID 0x80 /* Bit 8: Context identifier extension */
+#define SIXLOWPAN_IPHC_SAC 0x40 /* Bit 9: Source address compression */
+#define SIXLOWPAN_IPHC_SAM_MASK 0x30 /* Bits 10-11: Source address mode */
+# define SIXLOWPAN_IPHC_SAM_128 0x00 /* 128-bits */
+# define SIXLOWPAN_IPHC_SAM_64 0x10 /* 64-bits */
+# define SIXLOWPAN_IPHC_SAM_16 0x20 /* 16-bits */
+# define SIXLOWPAN_IPHC_SAM_0 0x30 /* 0-bits */
+#define SIXLOWPAN_IPHC_M 0x08 /* Bit 12: Multicast compression */
+#define SIXLOWPAN_IPHC_DAC 0x04 /* Bit 13: Destination address compression */
+#define SIXLOWPAN_IPHC_DAM_MASK 0x03 /* Bits 14-15: Destination address mode */
+# define SIXLOWPAN_IPHC_DAM_128 0x00 /* 128-bits */
+# define SIXLOWPAN_IPHC_DAM_64 0x01 /* 64-bits */
+# define SIXLOWPAN_IPHC_DAM_16 0x02 /* 16-bits */
+# define SIXLOWPAN_IPHC_DAM_0 0x03 /* 0-bits */
-#define SIXLOWPAN_IPHC_SAM_BIT 4
-#define SIXLOWPAN_IPHC_DAM_BIT 0
+#define SIXLOWPAN_IPHC_SAM_BIT 4
+#define SIXLOWPAN_IPHC_DAM_BIT 0
/* Link local context number */
-#define SIXLOWPAN_IPHC_ADDR_CONTEXT_LL 0
+#define SIXLOWPAN_IPHC_ADDR_CONTEXT_LL 0
/* 16-bit multicast addresses compression */
-#define SIXLOWPAN_IPHC_MCAST_RANGE 0xa0
+#define SIXLOWPAN_IPHC_MCAST_RANGE 0xa0
/* NHC_EXT_HDR */
-#define SIXLOWPAN_NHC_MASK 0xf0
-#define SIXLOWPAN_NHC_EXT_HDR 0xe0
+#define SIXLOWPAN_NHC_MASK 0xf0
+#define SIXLOWPAN_NHC_EXT_HDR 0xe0
/* LOWPAN_UDP encoding (works together with IPHC) */
-#define SIXLOWPAN_NHC_UDP_MASK 0xf8
-#define SIXLOWPAN_NHC_UDP_ID 0xf0
-#define SIXLOWPAN_NHC_UDP_CHECKSUMC 0x04
-#define SIXLOWPAN_NHC_UDP_CHECKSUMI 0x00
+#define SIXLOWPAN_NHC_UDP_MASK 0xf8
+#define SIXLOWPAN_NHC_UDP_ID 0xf0
+#define SIXLOWPAN_NHC_UDP_CHECKSUMC 0x04
+#define SIXLOWPAN_NHC_UDP_CHECKSUMI 0x00
/* Values for port compression, _with checksum_ ie bit 5 set to 0 */
-#define SIXLOWPAN_NHC_UDP_CS_P_00 0xf0 /* All inline */
-#define SIXLOWPAN_NHC_UDP_CS_P_01 0xf1 /* Source 16bit inline, dest = 0xf0 + 8 bit inline */
-#define SIXLOWPAN_NHC_UDP_CS_P_10 0xf2 /* Source = 0xf0 + 8bit inline, dest = 16 bit inline */
-#define SIXLOWPAN_NHC_UDP_CS_P_11 0xf3 /* Source & dest = 0xf0b + 4bit inline */
+#define SIXLOWPAN_NHC_UDP_CS_P_00 0xf0 /* All inline */
+#define SIXLOWPAN_NHC_UDP_CS_P_01 0xf1 /* Source 16bit inline, dest = 0xf0 + 8 bit inline */
+#define SIXLOWPAN_NHC_UDP_CS_P_10 0xf2 /* Source = 0xf0 + 8bit inline, dest = 16 bit inline */
+#define SIXLOWPAN_NHC_UDP_CS_P_11 0xf3 /* Source & dest = 0xf0b + 4bit inline */
/* The 6lowpan "headers" length */
-#define SIXLOWPAN_IPV6_HDR_LEN 1 /* One byte */
-#define SIXLOWPAN_HC1_HDR_LEN 3
-#define SIXLOWPAN_HC1_HC_UDP_HDR_LEN 7
-#define SIXLOWPAN_FRAG1_HDR_LEN 4
-#define SIXLOWPAN_FRAGN_HDR_LEN 5
+#define SIXLOWPAN_IPV6_HDR_LEN 1 /* One byte */
+#define SIXLOWPAN_HC1_HDR_LEN 3
+#define SIXLOWPAN_HC1_HC_UDP_HDR_LEN 7
+#define SIXLOWPAN_FRAG1_HDR_LEN 4
+#define SIXLOWPAN_FRAGN_HDR_LEN 5
/* Address compressibility test macros **************************************/
@@ -227,7 +228,7 @@
#define SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(a) \
((((a)[4]) == 0x0000) && (((a)[5]) == HTONS(0x00ff)) && \
- (((a)[6]) == 0xfe00))
+ (((a)[6]) == HTONS(0xfe00)))
/* Check whether the 9-bit group-id of the compressed multicast address is
* known. It is true if the 9-bit group is the all nodes or all routers
@@ -271,61 +272,6 @@
(a)[4] == 0 && (a)[5] == 0 && (a)[6] == 0 && \
(((a)[7] & HTONS(0xff00)) == 0x0000))
-/* Frame buffer helper macros ***********************************************/
-/* The IEEE802.15.4 MAC driver structures includes a list of IOB
- * structures, i_framelist, containing frames to be sent by the driver or
- * that were received by the driver. The IOB structure is defined in
- * include/nuttx/drivers/iob.h. The length of data in the IOB is provided by
- * the io_len field of the IOB structure.
- *
- * NOTE that IOBs must be configured such that CONFIG_IOB_BUFSIZE >=
- * CONFIG_NET_6LOWPAN_FRAMELEN
- *
- * 1. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver
- * structure with i_framelist set to NULL. At the conclusion of the
- * poll, if there are frames to be sent, they will have been added to
- * the i_framelist. The non-empty frame list is the indication that
- * there is data to be sent.
- *
- * The IEEE802.15.4 may use the FRAME_IOB_EMPTY() macro to determine
- * if there there frames to be sent. If so, it should remove each
- * frame from the frame list using the FRAME_IOB_REMOVE() macro and send
- * it. That macro will return NULL when all of the frames have been
- * sent.
- *
- * After sending each frame, the driver must return the IOB to the pool
- * of free IOBs using the FROM_IOB_FREE() macro.
- */
-
-
-#define FRAME_IOB_EMPTY(ieee) ((ieee)->i_framelist == NULL)
-#define FRAME_IOB_REMOVE(ieee, iob) \
- do \
- { \
- (iob) = (ieee)->i_framelist; \
- (ieee)->i_framelist = (iob)->io_flink; \
- (iob)->io_flink = NULL; \
- } \
- while (0)
-#define FRAME_IOB_FREE(iob) iob_free(iob)
-
-/* 2. When receiving data, the IEEE802.15.4 MAC driver should receive the
- * frame data directly into the payload area of an IOB structure. That
- * IOB structure may be obtained using the FRAME_IOB_ALLOC() macro. The
- * single frame should be added to the frame list using FRAME_IOB_ADD()
- * (it will be a list of length one) . The MAC driver should then inform
- * the network of the by calling sixlowpan_input().
- */
-
-#define FRAME_IOB_ALLOC() iob_alloc(false)
-#define FRAME_IOB_ADD(ieee, iob) \
- do \
- { \
- (iob)->io_flink = (ieee)->i_framelist; \
- (ieee)->i_framelist = (iob); \
- } \
- while (0)
-
/****************************************************************************
* Public Types
****************************************************************************/
@@ -335,18 +281,21 @@
* difference is that fragmentation must be supported.
*
* The IEEE802.15.4 MAC does not use the d_buf packet buffer directly.
- * Rather, it uses a list smaller frame buffers, i_framelist.
+ * Rather, it uses a list smaller frame buffers.
*
- * - The packet fragment data is provided to an IOB in the i_framelist
- * buffer each time that the IEEE802.15.4 MAC needs to send more data.
- * The length of the frame is provided in the io_len field of the IOB.
+ * - The packet fragment data is provided in an IOB in the via the
+ * i_req_data() interface method each time that the IEEE802.15.4 MAC
+ * needs to send more data. The length of the frame is provided in the
+ * io_len field of the IOB.
*
* In this case, the d_buf is not used at all and, if fact, may be
* NULL.
*
* - Received frames are provided by IEEE802.15.4 MAC to the network
- * via and IOB in i_framelist with length io_len for reassembly in
- * d_buf; d_len will hold the size of the reassembled packet.
+ * via an IOB parameter in the sixlowpan_submit() interface. The
+ * length of the frawme is io_len and will be uncompressed and possibly
+ * reassembled in the d_buf; d_len will hold the size of the
+ * reassembled packet.
*
* In this case, a d_buf of size CONFIG_NET_6LOWPAN_MTU must be provided.
*
@@ -360,51 +309,42 @@
* this structure. In general, all fields must be set to NULL. In
* addtion:
*
- * 1. i_panid must be set to identify the network. It may be set to 0xfff
- * if the device is not associated.
+ * 1. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver
+ * structure. During the course of the poll, the networking layer may
+ * generate outgoing frames. These frames will by provided to the MAC
+ * driver via the req_data() method.
*
- * 2. i_dsn must be set to a random value. After that, it will be managed
- * by the network.
+ * After sending each frame through the radio, the MAC driver must
+ * return the frame to the pool of free IOBs using the iob_free().
*
- * 3. On a TX poll, the IEEE802.15.4 MAC driver should provide its driver
- * structure with i_framelist set to NULL. At the conclusion of the
- * poll, if there are frames to be sent, they will have been added to
- * the i_framelist. The non-empty frame list at the conclusion of the
- * TX poll is the indication that is data to be sent.
- *
- * The IEEE802.15.4 may use the FRAME_IOB_EMPTY() macro to determine
- * if there there frames to be sent. If so, it should remove each
- * frame from the frame list using the FRAME_IOB_REMOVE() macro and send
- * it. That macro will return NULL when all of the frames have been
- * sent.
- *
- * After sending each frame, the driver must return the IOB to the pool
- * of free IOBs using the FROM_IOB_FREE() macro.
- *
- * 4. When receiving data both buffers must be provided:
+ * 2. When receiving data both buffers must be provided:
*
* The IEEE802.15.4 MAC driver should receive the frame data directly
- * into the payload area of an IOB structure. That IOB structure may be
- * obtained using the FRAME_IOB_ALLOC() macro. The single frame should
- * be added to the frame list using FRAME_IOB_ADD() (it will be a list of
- * length one).
+ * into the payload area of an IOB frame structure. That IOB structure
+ * may be obtained using the iob_alloc() function.
*
* The larger dev.d_buf must have a size of at least the advertised MTU
- * of the protocol, CONFIG_NET_6LOWPAN_MTU. If fragmentation is enabled,
- * then the logical packet size may be significantly larger than the
- * size of the frame buffer. The dev.d_buf is used for de-compressing
- * each frame and reassembling any fragmented packets to create the full
- * input packet that is provided to the application.
+ * of the protocol, CONFIG_NET_6LOWPAN_MTU, plus CONFIG_NET_GUARDSIZE.
+ * If fragmentation is enabled, then the logical packet size may be
+ * significantly larger than the size of the frame buffer. The dev.d_buf
+ * is used for de-compressing each frame and reassembling any fragmented
+ * packets to create the full input packet that is provided to the
+ * application.
*
* The MAC driver should then inform the network of the by calling
- * sixlowpan_input().
+ * sixlowpan_input(). That single frame (or, perhaps, list of frames)
+ * should be provided as second argument of that call.
*
- * Normally, the network will free the IOB and will nullify the frame
- * list. But ss a complexity, the result of receiving a frame may be
- * that the network may respond provide an outgoing frames in the
- * frame list.
+ * The network will free the IOB by calling iob_free after it has
+ * processed the incoming frame. As a complexity, the result of
+ * receiving a frame may be that the network may respond provide an
+ * outgoing frames in the via a nested calle to the req_data() method.
*/
+struct ieee802154_frame_meta_s; /* Forward reference */
+struct ieee802154_data_ind_s; /* Forward reference */
+struct iob_s; /* Forward reference */
+
struct ieee802154_driver_s
{
/* This definitiona must appear first in the structure definition to
@@ -415,43 +355,22 @@ struct ieee802154_driver_s
/* IEEE802.15.4 MAC-specific definitions follow. */
- /* The i_framelist is used to hold a outgoing frames contained in IOB
- * structures. When the IEEE802.15.4 device polls for new TX data, the
- * outgoing frame(s) containing the packet fragments are placed in IOBs
- * and queued in i_framelist.
+ /* The msdu_handle is basically an id for the frame. The standard just
+ * says that the next highest layer should determine it. It is used in
+ * three places
*
- * The i_framelist is similary used to hold incoming frames in IOB
- * structures. The IEEE802.15.4 MAC driver must receive frames in an IOB,
- * place the IOB in the i_framelist, and call sixlowpan_input().
+ * 1. When you do that data request
+ * 2. When the transmission is complete, the conf_data is called with
+ * that handle so that the user can be notified of the frames success/
+ * failure
+ * 3. For a req_purge, to basically "cancel" the transaction. This is
+ * often particularly useful on a coordinator that has indirect data
+ * waiting to be requested from another device
*
- * The IEEE802.15.4 MAC driver design may be concurrently sending and
- * requesting new frames using lists of IOBs. That IOB frame buffer
- * management must be managed by the IEEE802.15.4 MAC driver.
+ * Here is a simple frame counter.
*/
- FAR struct iob_s *i_framelist;
-
- /* Driver Configuration ***************************************************/
- /* i_panid. The PAN ID is 16-bit number that identifies the network. It
- * must be unique to differentiate a network. All the nodes in the same
- * network should have the same PAN ID. This value must be provided to
- * the network from the IEEE802.15.4 MAC driver.
- *
- * If this value is 0xffff, the device is not associated.
- */
-
- uint16_t i_panid;
-
- /* i_dsn. The sequence number in the range 0x00-0xff added to the
- * transmitted data or MAC command frame. The default is a random value
- * within that range.
- *
- * This field must be initialized to a random number by the IEEE802.15.4
- * MAC driver. It sill be subsequently incremented on each frame by the
- * network logic.
- */
-
- uint8_t i_dsn;
+ uint8_t i_msdu_handle;
#if CONFIG_NET_6LOWPAN_FRAG
/* Fragmentation Support *************************************************/
@@ -502,7 +421,7 @@ struct ieee802154_driver_s
/* The source MAC address of the fragments being merged */
- struct rimeaddr_s i_fragsrc;
+ struct sixlowpan_tagaddr_s i_fragsrc;
/* That time at which reassembly was started. If the elapsed time
* exceeds CONFIG_NET_6LOWPAN_MAXAGE, then the reassembly will
@@ -511,6 +430,47 @@ struct ieee802154_driver_s
systime_t i_time;
#endif /* CONFIG_NET_6LOWPAN_FRAG */
+
+ /* MAC network driver callback functions **********************************/
+ /**************************************************************************
+ * Name: mac802154_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.
+ *
+ **************************************************************************/
+
+ CODE int (*i_get_mhrlen)(FAR struct ieee802154_driver_s *netdev,
+ FAR const struct ieee802154_frame_meta_s *meta);
+
+ /**************************************************************************
+ * Name: mac802154_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.
+ *
+ **************************************************************************/
+
+ CODE int (*i_req_data)(FAR struct ieee802154_driver_s *netdev,
+ FAR const struct ieee802154_frame_meta_s *meta,
+ FAR struct iob_s *framelist);
};
/****************************************************************************
@@ -523,25 +483,32 @@ struct ieee802154_driver_s
* Description:
* Process an incoming 6loWPAN frame.
*
- * This function is called when the device driver has received a 6loWPAN
- * frame from the network. The frame from the device driver must be
- * provided in a IOB present in the i_framelist: The frame data is in the
- * IOB io_data[] buffer and the length of the frame is in the IOB io_len
- * field. Only a single IOB is expected in the i_framelist. This incoming
- * data will be processed one frame at a time.
+ * This function is called when the device driver has received an
+ * IEEE802.15.4 frame from the network. The frame from the device
+ * driver must be provided in by the IOB frame argument of the
+ * function call:
*
- * An non-NULL d_buf of size CONFIG_NET_6LOWPAN_MTU must also be provided.
- * The frame will be decompressed and placed in the d_buf. Fragmented
- * packets will also be reassembled in the d_buf as they are received
- * (meaning for the driver, that two packet buffers are required: One for
- * reassembly of RX packets and one used for TX polling).
+ * - The frame data is in the IOB io_data[] buffer,
+ * - The length of the frame is in the IOB io_len field, and
+ * - The offset past the IEEE802.15.4 MAC header is provided in the
+ * io_offset field.
*
- * After each frame is processed into d_buf, the IOB is removed and
- * deallocated. i_framelist will be nullified. If reassembly is
- * incomplete, this function will return to called with i_framelist
- * equal to NULL. The partially reassembled packet must be preserved by
- * the IEEE802.15.4 MAC and provided again when the next frame is
- * received.
+ * The frame argument may refer to a single frame (a list of length one)
+ * or may it be the head of a list of multiple frames.
+ *
+ * - The io_flink field points to the next frame in the list (if enable)
+ * - The last frame in the list will have io_flink == NULL.
+ *
+ * An non-NULL d_buf of size CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE
+ * must also be provided. The frame will be decompressed and placed in
+ * the d_buf. Fragmented packets will also be reassembled in the d_buf as
+ * they are received (meaning for the driver, that two packet buffers are
+ * required: One for reassembly of RX packets and one used for TX polling).
+ *
+ * After each frame is processed into d_buf, the IOB is deallocated. If
+ * reassembly is incomplete, the partially reassembled packet must be
+ * preserved by the IEEE802.15.4 MAC network drvier sand provided again
+ * when the next frame is received.
*
* When the packet in the d_buf is fully reassembled, it will be provided
* to the network as with any other received packet. d_len will be set
@@ -549,28 +516,31 @@ struct ieee802154_driver_s
*
* After the network processes the packet, d_len will be set to zero.
* Network logic may also decide to send a response to the packet. In
- * that case, the outgoing network packet will be placed in d_buf the
- * d_buf and d_len will be set to a non-zero value. That case is handled
- * by this function.
+ * that case, the outgoing network packet will be placed in d_buf and
+ * d_len will be set to a non-zero value. That case is handled by this
+ * function.
*
* If that case occurs, the packet will be converted to a list of
- * compressed and possibly fragmented frames in i_framelist as with other
- * TX operations.
- *
- * So from the standpoint of the IEEE802.15.4 MAC driver, there are two
- * possible results: (1) i_framelist is NULL meaning that the frame
- * was fully processed and freed, or (2) i_framelist is non-NULL meaning
- * that there are outgoing frame(s) to be sent.
+ * compressed and possibly fragmented frames and provided to the MAC
+ * network driver via the req_data() method as with other TX operations.
*
* Input Parameters:
- * ieee - The IEEE802.15.4 MAC network driver interface.
+ * ieee - The IEEE802.15.4 MAC network driver interface.
+ * framelist - The head of an incoming list of frames. Normally this
+ * would be a single frame. A list may be provided if
+ * appropriate, however.
+ * ind - Meta data characterizing the received packet. If there are
+ * multilple frames in the list, this meta data must apply to
+ * all of the frames!
*
* Returned Value:
* Ok is returned on success; Othewise a negated errno value is returned.
*
****************************************************************************/
-int sixlowpan_input(FAR struct ieee802154_driver_s *ieee);
+int sixlowpan_input(FAR struct ieee802154_driver_s *ieee,
+ FAR struct iob_s *framelist,
+ FAR const struct ieee802154_data_ind_s *ind);
#endif /* CONFIG_NET_6LOWPAN */
#endif /* __INCLUDE_NUTTX_NET_SIXLOWPAN_H */
diff --git a/include/nuttx/wireless/ieee802154/at86rf23x.h b/include/nuttx/wireless/ieee802154/at86rf23x.h
new file mode 100644
index 00000000000..2cdf6218cf6
--- /dev/null
+++ b/include/nuttx/wireless/ieee802154/at86rf23x.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * include/nuttx/ieee802154/at86rf23x.h
+ *
+ * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
+ * Author: Sebastien Lorquet
+ *
+ * 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_IEEE802154_AT86RF23X_H
+#define __INCLUDE_NUTTX_IEEE802154_AT86RF23X_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* The at86rf23x provides interrupts to the MCU via a GPIO pin. The
+ * following structure provides an MCU-independent mechanixm for controlling
+ * the at86rf23x GPIO interrupt.
+ *
+ * The at86rf23x interrupt is an active low, *level* interrupt. From Datasheet:
+ * "Note 1: The INTEDGE polarity defaults to: 0 = Falling Edge. Ensure that
+ * the interrupt polarity matches the interrupt pin polarity of the host
+ * microcontroller.
+ * "Note 2: The INT pin will remain high or low, depending on INTEDGE polarity
+ * setting, until INTSTAT register is read."
+ */
+
+struct at86rf23x_lower_s
+{
+ int (*attach)(FAR const struct at86rf23x_lower_s *lower, xcpt_t handler,
+ FAR void *arg);
+ void (*enable)(FAR const struct at86rf23x_lower_s *lower, bool state);
+ void (*slptr)(FAR const struct at86rf23x_lower_s *lower, bool state);
+ void (*reset)(FAR const struct at86rf23x_lower_s *lower, bool state);
+};
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: at86rf23x_init
+ *
+ * Description:
+ * Initialize the IEEE802.15.4 driver. The at86rf23x device is assumed to be
+ * in the post-reset state upon entry to this function.
+ *
+ * Parameters:
+ * spi - A reference to the platform's SPI driver for the at86rf23x
+ * lower - The MCU-specific interrupt used to control low-level MCU
+ * functions (i.e., at86rf23x GPIO interrupts).
+ * devno - If more than one at86rf23x is supported, then this is the
+ * zero based number that identifies the at86rf23x;
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+FAR struct ieee802154_radio_s *
+ at86rf23x_init(FAR struct spi_dev_s *spi,
+ FAR const struct at86rf23x_lower_s *lower);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_IEEE802154__AT86RF23X_H */
diff --git a/include/nuttx/wireless/ieee802154/ieee802154_ioctl.h b/include/nuttx/wireless/ieee802154/ieee802154_ioctl.h
new file mode 100644
index 00000000000..5f14f2e2c6e
--- /dev/null
+++ b/include/nuttx/wireless/ieee802154/ieee802154_ioctl.h
@@ -0,0 +1,92 @@
+/************************************************************************************
+ * include/nuttx/wireless/ieee802154/ieee802154_ioctl.h
+ * IEEE802.15.4 character driver IOCTL commands
+ *
+ * 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.
+ *
+ ************************************************************************************/
+
+/* This file includes common definitions to be used in all wireless character drivers
+ * (when applicable).
+ */
+
+#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_IOCTL_H
+#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_IOCTL_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+#include
+
+#include
+
+#ifdef CONFIG_WIRELESS_IEEE802154
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* IEEE 802.15.4 Radio Character Driver IOCTL commands ******************************/
+/* None defined */
+
+/* IEEE 802.15.4 MAC Character Driver IOCTL commands ********************************/
+
+
+#define MAC802154IOC_MCPS_REGISTER _WLCIOC(IEEE802154_FIRST)
+#define MAC802154IOC_MLME_REGISTER _WLCIOC(IEEE802154_FIRST+1)
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+struct mac802154dev_notify_s
+{
+ uint8_t mn_signo; /* Signal number to use in the notification */
+};
+
+struct mac802154dev_txframe_s
+{
+ struct ieee802154_frame_meta_s meta;
+ FAR uint8_t *payload;
+ uint16_t length;
+};
+
+struct mac802154dev_rxframe_s
+{
+ struct ieee802154_data_ind_s meta;
+ uint8_t payload[IEEE802154_MAX_MAC_PAYLOAD_SIZE];
+ uint16_t length;
+};
+
+#endif /* CONFIG_WIRELESS_IEEE802154 */
+#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_IOCTL_H */
diff --git a/include/nuttx/wireless/ieee802154/ieee802154_mac.h b/include/nuttx/wireless/ieee802154/ieee802154_mac.h
new file mode 100644
index 00000000000..2c6a846af76
--- /dev/null
+++ b/include/nuttx/wireless/ieee802154/ieee802154_mac.h
@@ -0,0 +1,1566 @@
+/****************************************************************************
+ * include/nuttx/wireless/ieee802154/ieee802154_mac.h
+ *
+ * Copyright (C) 2016 Sebastien Lorquet. All rights reserved.
+ * Copyright (C) 2017 Verge Inc. All rights reserved.
+ *
+ * Author: Sebastien Lorquet
+ * Author: Anthony Merlino
+ *
+ * The naming and comments for various fields are taken directly
+ * from the IEEE 802.15.4 2011 standard.
+ *
+ * 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_IEEE802154_IEEE802154_MAC_H
+#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_MAC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+
+#ifdef CONFIG_NET_6LOWPAN
+# include
+#endif
+
+#include
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+/* None at the moment */
+
+/* IEEE 802.15.4 MAC Character Driver IOCTL Commands ************************/
+
+/* The IEEE 802.15.4 standard specifies a MLME Service Access Point (SAP)
+ * including a series of primitives that are used as an interface between
+ * the MLME and the next highest layer. There are 4 types of primitives:
+ *
+ * - Request
+ * - Indication
+ * - Response
+ * - Confirm
+ *
+ * Of these, Request and Response primitives are sent from the next highest layer
+ * to the MLME. Indication and Confirm primitives are used to notify the next
+ * highest layer of changes or actions that have taken place.
+ *
+ * The MAC802154 character driver exposed here provides IOCTL hooks for all
+ * Request and Response primitives.
+ */
+
+#define MAC802154IOC_MLME_ASSOC_REQUEST _MAC802154IOC(0x0003)
+#define MAC802154IOC_MLME_ASSOC_RESPONSE _MAC802154IOC(0x0004)
+#define MAC802154IOC_MLME_DISASSOC_REQUEST _MAC802154IOC(0x0005)
+#define MAC802154IOC_MLME_GET_REQUEST _MAC802154IOC(0x0006)
+#define MAC802154IOC_MLME_GTS_REQUEST _MAC802154IOC(0x0007)
+#define MAC802154IOC_MLME_ORPHAN_RESPONSE _MAC802154IOC(0x0008)
+#define MAC802154IOC_MLME_RESET_REQUEST _MAC802154IOC(0x0009)
+#define MAC802154IOC_MLME_RXENABLE_REQUEST _MAC802154IOC(0x000A)
+#define MAC802154IOC_MLME_SCAN_REQUEST _MAC802154IOC(0x000B)
+#define MAC802154IOC_MLME_SET_REQUEST _MAC802154IOC(0x000C)
+#define MAC802154IOC_MLME_START_REQUEST _MAC802154IOC(0x000D)
+#define MAC802154IOC_MLME_SYNC_REQUEST _MAC802154IOC(0x000E)
+#define MAC802154IOC_MLME_POLL_REQUEST _MAC802154IOC(0x000F)
+#define MAC802154IOC_MLME_DPS_REQUEST _MAC802154IOC(0x0010)
+#define MAC802154IOC_MLME_SOUNDING_REQUEST _MAC802154IOC(0x0011)
+#define MAC802154IOC_MLME_CALIBRATE_REQUEST _MAC802154IOC(0x0012)
+
+/* IEEE 802.15.4 MAC Interface **********************************************/
+
+/* Frame Type */
+
+#define IEEE802154_FRAME_BEACON 0x00
+#define IEEE802154_FRAME_DATA 0x01
+#define IEEE802154_FRAME_ACK 0x02
+#define IEEE802154_FRAME_COMMAND 0x03
+
+/* MAC commands */
+
+#define IEEE802154_CMD_ASSOC_REQ 0x01
+#define IEEE802154_CMD_ASSOC_RESP 0x02
+#define IEEE802154_CMD_DISASSOC_NOT 0x03
+#define IEEE802154_CMD_DATA_REQ 0x04
+#define IEEE802154_CMD_PANID_CONF_NOT 0x05
+#define IEEE802154_CMD_ORPHAN_NOT 0x06
+#define IEEE802154_CMD_BEACON_REQ 0x07
+#define IEEE802154_CMD_COORD_REALIGN 0x08
+#define IEEE802154_CMD_GTS_REQ 0x09
+
+/* Some addresses */
+
+#define IEEE802154_PAN_UNSPEC (uint16_t)0xFFFF
+#define IEEE802154_SADDR_UNSPEC (uint16_t)0xFFFF
+#define IEEE802154_SADDR_BCAST (uint16_t)0xFFFE
+#define IEEE802154_EADDR_UNSPEC (uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff"
+
+/* Frame control field masks, 2 bytes
+ * Seee IEEE 802.15.4/2011 5.2.1.1 page 57
+ */
+
+#define IEEE802154_FRAMECTRL_FTYPE 0x0007 /* Frame type, bits 0-2 */
+#define IEEE802154_FRAMECTRL_SEC 0x0008 /* Security Enabled, bit 3 */
+#define IEEE802154_FRAMECTRL_PEND 0x0010 /* Frame pending, bit 4 */
+#define IEEE802154_FRAMECTRL_ACKREQ 0x0020 /* Acknowledge request, bit 5 */
+#define IEEE802154_FRAMECTRL_PANIDCOMP 0x0040 /* PAN ID Compression, bit 6 */
+#define IEEE802154_FRAMECTRL_DADDR 0x0C00 /* Dest addressing mode, bits 10-11 */
+#define IEEE802154_FRAMECTRL_VERSION 0x3000 /* Source addressing mode, bits 12-13 */
+#define IEEE802154_FRAMECTRL_SADDR 0xC000 /* Source addressing mode, bits 14-15 */
+
+#define IEEE802154_FRAMECTRL_SHIFT_FTYPE 0 /* Frame type, bits 0-2 */
+#define IEEE802154_FRAMECTRL_SHIFT_SEC 3 /* Security Enabled, bit 3 */
+#define IEEE802154_FRAMECTRL_SHIFT_PEND 4 /* Frame pending, bit 4 */
+#define IEEE802154_FRAMECTRL_SHIFT_ACKREQ 5 /* Acknowledge request, bit 5 */
+#define IEEE802154_FRAMECTRL_SHIFT_PANIDCOMP 6 /* PAN ID Compression, bit 6 */
+#define IEEE802154_FRAMECTRL_SHIFT_DADDR 10 /* Dest addressing mode, bits 10-11 */
+#define IEEE802154_FRAMECTRL_SHIFT_VERSION 12 /* Source addressing mode, bits 12-13 */
+#define IEEE802154_FRAMECTRL_SHIFT_SADDR 14 /* Source addressing mode, bits 14-15 */
+
+/* IEEE 802.15.4 PHY constants */
+
+#define IEEE802154_MAX_PHY_PACKET_SIZE 127
+#define IEEE802154_TURN_AROUND_TIME 12 /*symbol periods*/
+
+/* IEEE 802.15.4 MAC constants */
+
+#define IEEE802154_BASE_SLOT_DURATION 60
+#define IEEE802154_NUM_SUPERFRAME_SLOTS 16
+
+#define IEEE802154_BASE_SUPERFRAME_DURATION \
+ (IEEE802154_BASE_SLOT_DURATION * IEEE802154_NUM_SUPERFRAME_SLOTS)
+
+#define IEEE802154_GTS_DESC_PERSISTENCE_TIME 4
+#define IEEE802154_MAX_BEACON_OVERHEAD 75
+
+#define IEEE802154_MAX_BEACON_PAYLOAD_LEN \
+ (IEEE802154_MAX_PHY_PACKET_SIZE - IEEE802154_MAX_BEACON_OVERHEAD)
+
+#define IEEE802154_MAX_LOST_BEACONS 4
+#define IEEE802154_MIN_MPDU_OVERHEAD 9
+#define IEEE802154_MAX_UNSEC_MHR_OVERHEAD 23
+#define IEEE802154_MFR_LENGTH 2
+
+#define IEEE802154_MAX_MPDU_UNSEC_OVERHEAD \
+ (IEEE802154_MAX_UNSEC_MHR_OVERHEAD + IEEE802154_MFR_LENGTH)
+
+
+#define IEEE802154_MAX_SAFE_MAC_PAYLOAD_SIZE \
+ (IEEE802154_MAX_PHY_PACKET_SIZE - IEEE802154_MAX_MPDU_UNSEC_OVERHEAD)
+
+#define IEEE802154_MAX_MAC_PAYLOAD_SIZE \
+ (IEEE802154_MAX_PHY_PACKET_SIZE - IEEE802154_MIN_MPDU_OVERHEAD)
+
+#define IEEE802154_MAX_SIFS_FRAME_SIZE 18
+#define IEEE802154_MIN_CAP_LENGTH 440
+#define IEEE802154_UNIT_BACKOFF_PERIOD 20
+
+/* IEEE 802.15.4 MAC PIB Attribut Defaults */
+
+/* Definitions used by IOCTL calls */
+
+#define MAX_ORPHAN_ADDR 32 /* REVISIT */
+
+// TODO: Add macros
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* IEEE 802.15.4 MAC status codes */
+
+enum ieee802154_status_e
+{
+ IEEE802154_STATUS_SUCCESS = 0,
+ IEEE802154_STATUS_BEACON_LOSS = 0xE0,
+ IEEE802154_STATUS_CHANNEL_ACCESS_FAILURE,
+ IEEE802154_STATUS_DENIED,
+ IEEE802154_STATUS_DISABLE_TRX_FAILURE,
+ IEEE802154_STATUS_FAILED_SECURITY_CHECK,
+ IEEE802154_STATUS_FRAME_TOO_LONG,
+ IEEE802154_STATUS_INVALID_GTS,
+ IEEE802154_STATUS_INVALID_HANDLE,
+ IEEE802154_STATUS_INVALID_PARAMETER,
+ IEEE802154_STATUS_NO_ACK,
+ IEEE802154_STATUS_NO_BEACON,
+ IEEE802154_STATUS_NO_DATA,
+ IEEE802154_STATUS_NO_SHORT_ADDRESS,
+ IEEE802154_STATUS_OUT_OF_CAP,
+ IEEE802154_STATUS_PAN_ID_CONFLICT,
+ IEEE802154_STATUS_REALIGNMENT,
+ IEEE802154_STATUS_TRANSACTION_EXPIRED,
+ IEEE802154_STATUS_TRANSACTION_OVERFLOW,
+ IEEE802154_STATUS_TX_ACTIVE,
+ IEEE802154_STATUS_UNAVAILABLE_KEY,
+ IEEE802154_STATUS_UNSUPPORTED_ATTRIBUTE,
+ IEEE802154_STATUS_FAILED /* This value is not outlined in the standard. It is
+ * a catch-all for any failures that are not outlined
+ * in the standard */
+};
+
+/* IEEE 802.15.4 PHY/MAC PIB attributes IDs */
+
+enum ieee802154_pib_attr_e
+{
+ /* PHY PIB Attributes */
+
+ IEEE802154_PIB_PHY_CURRENT_CHANNEL = 0x00,
+ IEEE802154_PIB_PHY_CHANNELS_SUPPORTED,
+ IEEE802154_PIB_PHY_TX_POWER_TOLERANCE,
+ IEEE802154_PIB_PHY_TX_POWER,
+ IEEE802154_PIB_PHY_CCA_MODE,
+ IEEE802154_PIB_PHY_CURRENT_PAGE,
+ IEEE802154_PIB_PHY_MAX_FRAME_DURATION,
+ IEEE802154_PIB_PHY_SHR_DURATION,
+ IEEE802154_PIB_PHY_SYM_PER_OCTET,
+ IEEE802154_PIB_PHY_PREAMBLE_SYM_LEN,
+ IEEE802154_PIB_PHY_UWB_DATARATES_SUP,
+ IEEE802154_PIB_PHY_CSS_LOW_DATARATE_SUP,
+ IEEE802154_PIB_PHY_UWB_COU_PULSES_SUP,
+ IEEE802154_PIB_PHY_UWB_CS_PULSES_SUP,
+ IEEE802154_PIB_PHY_UWB_LCP_PULSES_SUP,
+ IEEE802154_PIB_PHY_UWB_CURR_PULSE_SHAPE,
+ IEEE802154_PIB_PHY_UWB_COU_PULSE,
+ IEEE802154_PIB_PHY_UWB_CS_PULSE,
+ IEEE802154_PIB_PHY_UWB_LCP_WEIGHT1,
+ IEEE802154_PIB_PHY_UWB_LCP_WEIGHT2,
+ IEEE802154_PIB_PHY_UWB_LCP_WEIGHT3,
+ IEEE802154_PIB_PHY_UWB_LCP_WEIGHT4,
+ IEEE802154_PIB_PHY_UWB_LCP_DELAY2,
+ IEEE802154_PIB_PHY_UWB_LCP_DELAY3,
+ IEEE802154_PIB_PHY_UWB_LCP_DELAY4,
+ IEEE802154_PIB_PHY_RANGING,
+ IEEE802154_PIB_PHY_RANGING_CRYSTAL_OFFSET,
+ IEEE802154_PIB_PHY_RANGING_DPS,
+ IEEE802154_PIB_PHY_CURRENT_CODE,
+ IEEE802154_PIB_PHY_NATIVE_PRF,
+ IEEE802154_PIB_PHY_UWB_SCAN_BINS_PER_CHAN,
+ IEEE802154_PIB_PHY_UWB_INS_PREAMBLE_INTERVAL,
+ IEEE802154_PIB_PHY_UWB_TX_RMARKER,
+ IEEE802154_PIB_PHY_UWB_RX_RMARKER,
+ IEEE802154_PIB_PHY_RFRAME_PROC_TIME,
+ IEEE802154_PIB_PHY_CCA_DURATION,
+
+ /* MAC PIB Attributes */
+
+ IEEE802154_PIB_MAC_EXTENDED_ADDR = 0x40,
+ IEEE802154_PIB_MAC_ACK_WAIT_DUR,
+ IEEE802154_PIB_MAC_ASSOCIATED_PANCOORD,
+ IEEE802154_PIB_MAC_ASSOCIATION_PERMIT,
+ IEEE802154_PIB_MAC_AUTO_REQUEST,
+ IEEE802154_PIB_MAC_BATT_LIFE_EXT,
+ IEEE802154_PIB_MAC_BATT_LIFE_EXT_PERIODS,
+ IEEE802154_PIB_MAC_BEACON_PAYLOAD,
+ IEEE802154_PIB_MAC_BEACON_PAYLOAD_LEN,
+ IEEE802154_PIB_MAC_BEACON_ORDER,
+ IEEE802154_PIB_MAC_BEACON_TX_TIME,
+ IEEE802154_PIB_MAC_BSN,
+ IEEE802154_PIB_MAC_COORD_EXT_ADDR,
+ IEEE802154_PIB_MAC_COORD_SHORT_ADDR,
+ IEEE802154_PIB_MAC_DSN,
+ IEEE802154_PIB_MAC_GTS_PERMIT,
+ IEEE802154_PIB_MAC_MAX_BE,
+ IEEE802154_PIB_MAC_MAX_CSMA_BACKOFFS,
+ IEEE802154_PIB_MAC_FRAME_TOTAL_WAIT_TIME,
+ IEEE802154_PIB_MAC_MAX_FRAME_RETRIES,
+ IEEE802154_PIB_MAC_MIN_BE,
+ IEEE802154_PIB_MAC_LIFS_PERIOD,
+ IEEE802154_PIB_MAC_SIFS_PERIOD,
+ IEEE802154_PIB_MAC_PAN_ID,
+ IEEE802154_PIB_MAC_PROMISCUOUS_MODE,
+ IEEE802154_PIB_MAC_RANGING_SUPPORT,
+ IEEE802154_PIB_MAC_RESPONSE_WAIT_TIME,
+ IEEE802154_PIB_MAC_RX_ON_WHEN_IDLE,
+ IEEE802154_PIB_MAC_SECURITY_ENABLED,
+ IEEE802154_PIB_MAC_SHORT_ADDRESS,
+ IEEE802154_PIB_MAC_SUPERFRAME_ORDER,
+ IEEE802154_PIB_MAC_SYNC_SYMBOL_OFFSET,
+ IEEE802154_PIB_MAC_TIMESTAMP_SUPPORT,
+ IEEE802154_PIB_MAC_TRANSACTION_PERSIST_TIME,
+ IEEE802154_PIB_MAC_TX_CTRL_ACTIVE_DUR,
+ IEEE802154_PIB_MAC_TX_CTRL_PAUSE_DUR,
+ IEEE802154_PIB_MAC_TX_TOTAL_DUR,
+
+ /* MAC Security Attributes */
+
+ IEEE802154_PIB_MAC_KEY_TABLE = 0x70,
+ IEEE802154_PIB_MAC_DEV_TABLE,
+ IEEE802154_PIB_MAC_SEC_LVL_TABLE,
+ IEEE802154_PIB_MAC_FRAME_COUNTER,
+ IEEE802154_PIB_MAC_AUTOREQ_SEC_LVL,
+ IEEE802154_PIB_MAC_AUTOREQ_KEY_ID_MODE,
+ IEEE802154_PIB_MAC_AUTOREQ_KEY_SOURCE,
+ IEEE802154_PIB_MAC_AUTOREQ_KEY_INDEX,
+ IEEE802154_PIB_MAC_DEFAULT_KEY_SRC,
+ IEEE802154_PIB_MAC_PANCOORD_EXT_ADDR,
+ IEEE802154_PIB_MAC_PANCOORD_SHORT_ADDR,
+};
+
+#define IEEE802154_EADDR_LEN 8
+
+/* IEEE 802.15.4 Device address
+ * The addresses in ieee802154 have several formats:
+ * No address : [none]
+ * Short address + PAN id : PPPP/SSSS
+ * Extended address + PAN id : PPPP/LLLLLLLLLLLLLLLL
+ */
+
+enum ieee802154_addr_mode_e
+{
+ IEEE802154_ADDRMODE_NONE = 0,
+ IEEE802154_ADDRMODE_SHORT = 2,
+ IEEE802154_ADDRMODE_EXTENDED
+};
+
+struct ieee802154_addr_s
+{
+ /* Address mode. Short or Extended */
+
+ enum ieee802154_addr_mode_e mode;
+
+ uint16_t panid; /* PAN identifier, can be
+ * IEEE802154_PAN_UNSPEC */
+ uint16_t saddr; /* short address */
+ uint8_t eaddr[IEEE802154_EADDR_LEN]; /* extended address */
+};
+
+#define IEEE802154_ADDRSTRLEN 22 /* (2*2+1+8*2, PPPP/EEEEEEEEEEEEEEEE) */
+
+#ifdef CONFIG_IEEE802154_SECURITY
+struct ieee802154_security_s
+{
+ uint8_t level; /* Security level to be used */
+ uint8_t key_id_mode; /* Mode used to identify the key to be used */
+ uint8_t key_source[8]; /* Originator of the key to be used */
+ uint8_t key_index; /* Index of the key to be used */
+};
+#endif
+
+#ifdef CONFIG_IEEE802154_UWB
+enum ieee802154_uwbprf_e
+{
+ IEEE802154_UWBPRF_OFF = 0,
+ IEEE802154_UWBPRF_4M,
+ IEEE802154_UWBPRF_16M,
+ IEEE802154_UWBPRF_64M
+};
+
+enum ieee802154_uwb_datarate_e
+{
+ IEEE802154_UWB_DATARATE_0 = 0,
+ IEEE802154_UWB_DATARATE_16,
+ IEEE802154_UWB_DATARATE_64,
+ IEEE802154_UWB_DATARATE_1024,
+ IEEE802154_UWB_DATARATE_4096
+};
+#endif
+
+enum ieee802154_ranging_e
+{
+ IEEE802154_NON_RANGING = 0,
+ IEEE802154_ALL_RANGING,
+ IEEE802154_PHY_HEADER_ONLY
+};
+
+struct ieee802154_capability_info_s
+{
+ uint8_t reserved_0 : 1; /* Reserved */
+ uint8_t device_type : 1; /* 0=RFD, 1=FFD */
+ uint8_t power_source : 1; /* 1=AC, 0=Other */
+ uint8_t rx_on_idle : 1; /* 0=Receiver off when idle
+ * 1=Receiver on when idle */
+ uint8_t reserved_45 : 2; /* Reserved */
+ uint8_t security : 1; /* 0=disabled, 1=enabled */
+ uint8_t allocate_addr : 1; /* 1=Coordinator allocates short address
+ * 0=otherwise */
+};
+
+struct ieee802154_superframe_spec_s
+{
+ uint16_t beacon_order : 4; /* Transmission interval of beacon */
+ uint16_t superframe_order : 4; /* Length of superframe */
+ uint16_t final_cap_slot : 4; /* Last slot utilized by CAP */
+ uint16_t ble : 1; /* Battery Life Extension (BLE) */
+ uint16_t reserved : 1; /* Reserved bit */
+ uint16_t pan_coordinator : 1; /* 1 if beacon sent by pan coordinator */
+ uint16_t assoc_permit : 1; /* 1 if coordinator is accepting associaton */
+};
+
+struct ieee802154_pan_desc_s
+{
+ /* The coordinator address of the received beacon frame */
+
+ struct ieee802154_addr_s coord_addr;
+
+ uint8_t channel; /* current channel occupied by the network */
+ uint8_t channel_page; /* current channel page occupied by the network */
+
+ /* The superframe specifications received in the beacon frame */
+
+ struct ieee802154_superframe_spec_s superframe_spec;
+
+ uint8_t gts_permit; /* 0=No GTS requests allowed
+ * 1=GTS request allowed */
+ uint8_t lqi; /* Link Quality Indication of the beacon */
+ uint32_t timestamp; /* Time at which the beacon frame was received
+ * in symbols */
+};
+
+struct ieee802154_pend_addr_s
+{
+ union
+ {
+ uint8_t pa_spec;
+ struct
+ {
+ uint8_t num_short_addr : 3; /* Number of short addresses pending */
+ uint8_t reserved_3 : 1; /* Reserved bit */
+ uint8_t num_ext_addr : 3; /* Number of extended addresses pending */
+ uint8_t reserved_7 : 1; /* Reserved bit */
+ } pa_addr;
+ } u;
+ struct ieee802154_addr_s addr[7]; /* Array of at most 7 addresses */
+};
+
+#ifdef CONFIG_IEEE802154_RANGING
+#define IEEE802154_TXDESC_FIELDS \
+ uint8_t handle; \
+ uint32_t timestamp; \
+ uint8_t status;
+#else
+#define IEEE802154_TXDESC_FIELDS \
+ uint8_t handle; \
+ uint32_t timestamp; \
+ uint8_t status;
+ bool rng_rcvd; \
+ uint32_t rng_counter_start; \
+ uint32_t rng_counter_stop; \
+ uint32_t rng_tracking_interval; \
+ uint32_t rng_offset;\
+ uint8_t rng_fom;
+#endif
+
+struct ieee802154_txdesc_s
+{
+ IEEE802154_TXDESC_FIELDS
+
+ /* TODO: Add slotting information for GTS transactions */
+};
+
+struct ieee802154_cca_s
+{
+ uint8_t use_ed : 1; /* CCA using ED */
+ uint8_t use_cs : 1; /* CCA using carrier sense */
+ uint8_t edth; /* Energy detection threshold for CCA */
+ uint8_t csth; /* Carrier sense threshold for CCA */
+};
+
+/* Primitive Support Types ***************************************************/
+
+union ieee802154_macattr_u
+{
+ uint8_t eaddr[IEEE802154_EADDR_LEN];
+ uint16_t saddr;
+ uint16_t panid;
+
+ uint8_t coord_eaddr[IEEE802154_EADDR_LEN];
+ uint16_t coord_saddr;
+
+ bool is_assoc;
+ bool assoc_permit;
+ bool auto_req;
+ bool batt_life_ext;
+ bool gts_permit;
+ bool promisc_mode;
+ bool rng_support;
+ bool resp_wait_time;
+ bool rxonidle;
+ bool sec_enabled;
+ bool timestamp_support;
+
+ uint32_t ack_wait_dur;
+ uint8_t batt_life_ext_periods;
+ uint8_t max_csma_backoffs : 3;
+ uint8_t max_be : 4;
+ uint8_t min_be : 4;
+ uint32_t max_frame_wait_time;
+ uint8_t max_retries;
+ uint8_t lifs_period;
+ uint8_t sifs_period;
+ uint32_t sync_symb_offset : 12;
+ uint16_t trans_persist_time;
+ uint32_t tx_ctrl_active_dur;
+ uint32_t tx_ctrl_pause_dur;
+ uint32_t tx_total_dur;
+
+ uint8_t beacon_payload[IEEE802154_PIB_MAC_BEACON_PAYLOAD_LEN];
+ uint8_t beacon_payload_len;
+ uint8_t beacon_order;
+ uint32_t beacon_tx_time : 24;
+
+ uint8_t superframe_order;
+
+ uint8_t bsn;
+ uint8_t dsn;
+};
+
+union ieee802154_phyattr_u
+{
+ uint8_t channel;
+ int32_t txpwr
+ /* TODO: Fill this out as we implement supported get/set commands */
+};
+
+union ieee802154_secattr_u
+{
+ /* TODO: Fill this out as we implement supported get/set commands */
+};
+
+union ieee802154_attr_val_u
+{
+ union ieee802154_macattr_u mac;
+ union ieee802154_phyattr_u phy;
+ union ieee802154_secattr_u sec;
+};
+
+struct ieee802154_gts_info_s
+{
+ uint8_t length : 4; /* Number of SF slots for GTS */
+ uint8_t direction : 1; /* 0=transmit-only, 1=receive-only */
+ uint8_t type : 1; /* 0=GTS deallocation, 1= GTS allocation */
+ uint8_t reserved : 2;
+};
+
+enum ieee802154_scantype_e
+{
+ IEEE802154_SCANTYPE_ED,
+ IEEE802154_SCANTYPE_ACTIVE,
+ IEEE802154_SCANTYPE_PASSIVE,
+ IEEE802154_SCANTYPE_ORPHAN
+};
+
+struct ieee802154_frame_meta_s
+{
+ enum ieee802154_addr_mode_e src_addr_mode; /* Source Address Mode */
+ struct ieee802154_addr_s dest_addr; /* Destination Address */
+
+ uint8_t msdu_handle; /* Handle assoc. with MSDU */
+
+ struct
+ {
+ uint8_t ack_tx : 1; /* Acknowledge TX? */
+ uint8_t gts_tx : 1; /* 1=GTS used for TX, 0=CAP used for TX */
+ uint8_t indirect_tx : 1; /* Should indirect transmission be used? */
+ } msdu_flags;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+
+#ifdef CONFIG_IEEE802154_UWB
+ /* The UWB Pulse Repetition Frequency to be used for the transmission */
+
+ enum ieee802154_uwbprf_e uwb_prf;
+
+ /* The UWB preamble symbol repititions
+ * Should be one of:
+ * 0, 16, 64, 1024, 4096
+ */
+
+ uint16_t uwb_presym_rep;
+
+ /* The UWB Data Rate to be used for the transmission */
+
+ enum ieee802154_uwb_datarate_e data_rate;
+#endif
+
+ enum ieee802154_ranging_e ranging;
+};
+
+/* Primitive Semantics *******************************************************/
+
+/*****************************************************************************
+ * Primitive: MCPS-DATA.confirm
+ *
+ * Description:
+ * Reports the results of a request to transfer data to another device.
+ *
+ *****************************************************************************/
+
+struct ieee802154_data_conf_s
+{
+ IEEE802154_TXDESC_FIELDS
+};
+
+/*****************************************************************************
+ * Primitive: MCPS-DATA.indication
+ *
+ * Description:
+ * Indicates the reception of data from another device.
+ *
+ *****************************************************************************/
+
+struct ieee802154_data_ind_s
+{
+ FAR struct ieee802154_data_ind_s *flink;
+
+ FAR struct iob_s *frame;
+
+ struct ieee802154_addr_s src; /* Source addressing information */
+ struct ieee802154_addr_s dest; /* Destination addressing infromation */
+ uint8_t lqi; /* Link Quality Index */
+ uint8_t rssi; /* Non-standard field */
+ uint8_t dsn; /* Data Sequence Number */
+ uint32_t timestamp; /* Time of received frame */
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif /* CONFIG_IEEE802154_SECURITY */
+
+#ifdef CONFIG_IEEE802154_UWB
+ /* The UWB Pulse Repetition Frequency to be used for the transmission */
+
+ enum ieee802154_uwbprf_e uwb_prf;
+
+ /* The UWB preamble symbol repititions
+ * Should be one of:
+ * 0, 16, 64, 1024, 4096
+ */
+
+ uint16_t uwb_presym_rep;
+
+ /* The UWB Data Rate to be used for the transmission */
+
+ enum ieee802154_uwb_datarate_e data_rate;
+#endif /* CONFIG_IEEE802154_UWB */
+
+#ifdef CONFIG_IEEE802154_RANGING
+ bool rng_rcvd; /* Ranging indicated by MSDU */
+
+ /* A count of the time units corresponding to an RMARKER at the antenna at
+ * the beginning of the ranging exchange
+ */
+
+ uint32_t rng_counter_start;
+
+ /* A count of the time units corresponding to an RMARKER at the antenna at
+ * end of the ranging exchange
+ */
+
+ uint32_t rng_counter_stop;
+
+ /* A count of the time units in a message exchange over which the tracking
+ * offset was measured
+ */
+
+ uint34_t rng_tracking_interval;
+
+ /* A count of the time units slipped or advanced by the radio tracking
+ * system over the course of the entire tracking interval
+ */
+
+ uint32_t rng_offset;
+
+ /* The Figure of Merit (FoM) characterizing the ranging measurement */
+
+ uint8_t rng_fom;
+#endif /* CONFIG_IEEE802154_RANGING */
+};
+
+/*****************************************************************************
+ * Primitive: MCPS-PURGE.request
+ *
+ * Description:
+ * Allows the next higher layer to purge an MSDU from the transaction queue.
+ *
+ *****************************************************************************/
+
+struct ieee802154_purge_req_s
+{
+ uint8_t msdu_handle; /* Handle assoc. with MSDU */
+};
+
+/*****************************************************************************
+ * Primitive: MLME-ASSOCIATE.request
+ *
+ * Description:
+ * Used by a device to request an association with a coordinator.
+ *
+ *****************************************************************************/
+
+struct ieee802154_assoc_req_s
+{
+ uint8_t channel; /* Channel number to attempt association */
+ uint8_t channel_page; /* Channel page to attempt association */
+
+ /* Coordinator Address with which to associate */
+
+ struct ieee802154_addr_s coord_addr;
+
+ /* Capabilities of associating device */
+
+ struct ieee802154_capability_info_s capabilities;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-ASSOCIATE.indication
+ *
+ * Description:
+ * Used to indicate the reception of an association request command.
+ *
+ *****************************************************************************/
+
+struct ieee802154_assoc_ind_s
+{
+ /* Address of device requesting association. Always in extended mode */
+
+ struct ieee802154_addr_s dev_addr;
+
+ /* Capabilities of associating device */
+
+ struct ieee802154_capability_info_s capabilities;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-ASSOCIATE.response
+ *
+ * Description:
+ * Used to initiate a response to an MLME-ASSOCIATE.indication primitive.
+ *
+ *****************************************************************************/
+
+struct ieee802154_assoc_resp_s
+{
+ /* Address of device requesting association. Always in extended mode */
+
+ struct ieee802154_addr_s dev_addr;
+
+ /* Status of association attempt */
+
+ enum ieee802154_status_e status;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-ASSOCIATE.confirm
+ *
+ * Description:
+ * Used to inform the next higher layer of the initiating device whether its
+ * request to associate was successful or unsuccessful.
+ *
+ *****************************************************************************/
+
+struct ieee802154_assoc_conf_s
+{
+ /* Associated device address ALWAYS passed in short address mode. The
+ * address will be IEEE802154_SADDR_UNSPEC if association was
+ * unsuccessful.
+ */
+
+ struct ieee802154_addr_s dev_addr;
+
+ /* Status of association attempt */
+
+ enum ieee802154_status_e status;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-DISASSOCIATE.request
+ *
+ * Description:
+ * Used by an associated device to notify the coordinator of its intent to
+ * leave the PAN. It is also used by the coordinator to instruct an
+ * associated device to leave the PAN.
+ *
+ *****************************************************************************/
+
+struct ieee802154_disassoc_req_s
+{
+ /* Address of device to send disassociation notification */
+
+ struct ieee802154_addr_s dev_addr;
+
+ /* Reason for the disassosiation */
+
+ enum ieee802154_status_e disassoc_reason;
+
+ uint8_t tx_indirect; /* 0=Send Direct, 1=Send Indirect */
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-DISASSOCIATE.indication
+ *
+ * Description:
+ * Used to indicate the reception of a disassociation notification command.
+ *
+ *****************************************************************************/
+
+struct ieee802154_disassoc_ind_s
+{
+ /* Address of device requesting disassociation. Always extended mode */
+
+ struct ieee802154_addr_s dev_addr;
+
+ /* Reason for the disassosiation */
+
+ enum ieee802154_status_e disassoc_reason;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-DISASSOCIATE.confirm
+ *
+ * Description:
+ * Reports the results of an MLME-DISASSOCIATE.request primitive.
+ *
+ *****************************************************************************/
+
+struct ieee802154_disassoc_conf_s
+{
+ /* Status of the disassociation attempt */
+
+ enum ieee802154_status_e status;
+
+ /* Address of device either requesting or being intructed to disassociate */
+
+ struct ieee802154_addr_s dev_addr;
+};
+
+/*****************************************************************************
+ * Primitive: MLME-BEACONNOTIFY.indication
+ *
+ * Description:
+ * Used to send parameters contained within a beacon frame received by the
+ * MAC sublayer to the next higher layer when either macAutoRequest is set to
+ * FALSE or when the beacon frame contains one or more octets of payload. The
+ * primitive also sends a measure of the LQI and the time the beacon frame
+ * was received.
+ *
+ *****************************************************************************/
+
+struct ieee802154_beaconnotify_ind_s
+{
+ uint8_t bsn; /* Beacon sequence number */
+
+ /* PAN descriptor for the received beacon */
+
+ struct ieee802154_pan_desc_s pan_desc;
+
+ /* Beacon pending addresses */
+
+ struct ieee802154_pend_addr_s pend_addr;
+
+ uint8_t sdu_length; /* Number of octets contained in the beacon
+ * payload of the received beacond frame */
+
+ /* Beacon payload */
+
+ uint8_t sdu[IEEE802154_MAX_BEACON_PAYLOAD_LEN];
+};
+
+#define SIZEOF_IEEE802154_BEACONNOTIFY_IND_S(n) \
+ (sizeof(struct ieee802154_beaconnotify_ind_s) \
+ - IEEE802154_MAX_BEACON_PAYLOAD_LEN + (n))
+
+/*****************************************************************************
+ * Primitive: MLME-COMM-STATUS.indication
+ *
+ * Description:
+ * Allows the MLME to indicate a communications status.
+ *
+ *****************************************************************************/
+
+struct ieee802154_commstatus_ind_s
+{
+ struct ieee802154_addr_s src_addr;
+ struct ieee802154_addr_s dest_addr;
+ enum ieee802154_status_e status;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-GTS.request
+ *
+ * Description:
+ * Allows a device to send a request to the PAN coordinator to allocate a new
+ * GTS or to deallocate an existing GTS. This primitive is also used by the
+ * PAN coordinator to initiate a GTS deallocation.
+ *
+ *****************************************************************************/
+
+struct ieee802154_gts_req_s
+{
+ struct ieee802154_gts_info_s gts_info;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-GTS.confirm
+ *
+ * Description:
+ * Reports the results of a request to allocate a new GTS or to deallocate an
+ * existing GTS.
+ *
+ *****************************************************************************/
+
+struct ieee802154_gts_conf_s
+{
+ struct ieee802154_gts_info_s gts_info;
+ enum ieee802154_status_e status;
+};
+
+/*****************************************************************************
+ * Primitive: MLME-GTS.indication
+ *
+ * Description:
+ * Indicates that a GTS has been allocated or that a previously allocated
+ * GTS has been deallocated.
+ *
+ *****************************************************************************/
+
+struct ieee802154_gts_ind_s
+{
+ uint16_t dev_addr;
+ struct ieee802154_gts_info_s gts_info;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-ORPHAN.indication
+ *
+ * Description:
+ * Generated by the MLME of a coordinator and issued to its next higher layer
+ * on receipt of an orphan notification command.
+ *
+ *****************************************************************************/
+
+struct ieee802154_orphan_ind_s
+{
+ uint8_t orphan_addr[8];
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-ORPHAN.response
+ *
+ * Description:
+ * Allows the next higher layer of a coordinator to respond to the
+ * MLME-ORPHAN.indication primitive.
+ *
+ *****************************************************************************/
+
+struct ieee802154_orphan_resp_s
+{
+ uint8_t orphan_addr[8];
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-RESET.request
+ *
+ * Description:
+ * Used by the next higher layer to request that the MLME performs a reset
+ * operation.
+ *
+ *****************************************************************************/
+
+struct ieee802154_reset_req_s
+{
+ bool rst_pibattr;
+};
+
+/*****************************************************************************
+ * Primitive: MLME-RXENABLE.request
+ *
+ * Description:
+ * Allows the next higher layer to request that the receiver is either
+ * enabled for a finite period of time or disabled.
+ *
+ *****************************************************************************/
+
+struct ieee802154_rxenable_req_s
+{
+ /* Number of symbols measured from the start of the superframe before the
+ * receiver is to be enabled or disabled.
+ */
+
+ uint32_t rxon_time;
+
+ /* Number of symbols for which the receiver is to be enabled */
+
+ uint32_t rxon_dur;
+
+ uint8_t defer_permit : 1; /* 0=Only attempt operation on current superframe
+ * 1=Operation can be deferred to next superframe */
+ uint8_t rng_rxctrl : 1; /* 0=RANGING_OFF, 1=RANGING_OFF */
+};
+
+/*****************************************************************************
+ * Primitive: MLME-RXENABLE.confirm
+ *
+ * Description:
+ * Reports the results of the attempt to enable or disable the receiver.
+ *
+ *****************************************************************************/
+
+struct ieee802154_rxenable_conf_s
+{
+ enum ieee802154_status_e status;
+};
+
+/*****************************************************************************
+ * Primitive: MLME-SCAN.request
+ *
+ * Description:
+ * Used to initiate a channel scan over a given list of channels.
+ *
+ *****************************************************************************/
+
+struct ieee802154_scan_req_s
+{
+ enum ieee802154_scantype_e type;
+ uint8_t duration;
+ uint8_t ch_page;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+
+ uint8_t channels[1];
+};
+
+#define SIZEOF_IEEE802154_SCAN_REQ_S(n) \
+ (sizeof(struct ieee802154_scan_req_s) + (n) - 1)
+
+/*****************************************************************************
+ * Primitive: MLME-SCAN.confirm
+ *
+ * Description:
+ * Reports the result of the channel scan request.
+ *
+ *****************************************************************************/
+
+struct ieee802154_scan_conf_s
+{
+ enum ieee802154_status_e status;
+ enum ieee802154_scantype_e type;
+ uint8_t ch_page;
+ uint8_t num_channels;
+
+#warning Figure out how to handle missing primitive semantics. See standard.
+};
+
+/*****************************************************************************
+ * Primitive: MLME-GET.request
+ *
+ * Description:
+ * Requests information about a given PIB attribute.
+ *
+ *****************************************************************************/
+
+struct ieee802154_get_req_s
+{
+ enum ieee802154_pib_attr_e pib_attr;
+ union ieee802154_attr_val_u attr_value;
+};
+
+/*****************************************************************************
+ * Primitive: MLME-SET.request
+ *
+ * Description:
+ * Attempts to write the given value to the indicated PIB attribute.
+ *
+ * NOTE: The standard specifies that confirmation should be indicated via
+ * the asynchronous MLME-SET.confirm primitve. However, in our implementation
+ * there is no reason not to synchronously return the status immediately.
+ * Therefore, we do merge the functionality of the MLME-SET.request and
+ * MLME-SET.confirm primitives together.
+ *
+ *****************************************************************************/
+
+struct ieee802154_set_req_s
+{
+ enum ieee802154_pib_attr_e pib_attr;
+ union ieee802154_attr_val_u attr_value;
+};
+
+/*****************************************************************************
+ * Primitive: MLME-START.request
+ *
+ * Description:
+ * Used by the PAN coordinator to initiate a new PAN or to begin using a new
+ * superframe configuration. This primitive is also used by a device already
+ * associated with an existing PAN to begin using a new superframe
+ * configuration.
+ *
+ *****************************************************************************/
+
+struct ieee802154_start_req_s
+{
+ uint16_t pan_id;
+ uint8_t ch_num;
+ uint8_t ch_page;
+
+ uint32_t start_time : 24;
+ uint32_t beacon_order : 8;
+
+ uint8_t sf_order;
+
+ uint8_t pan_coord : 1;
+ uint8_t batt_life_ext : 1;
+ uint8_t coord_realign : 1;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s coord_realign;
+ struct ieee802154_security_s beacon;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-START.confirm
+ *
+ * Description:
+ * Reports the results of the attempt to start using a new superframe
+ * configuration.
+ *
+ *****************************************************************************/
+
+struct ieee802154_start_conf_s
+{
+ enum ieee802154_status_e status;
+};
+
+/*****************************************************************************
+ * Primitive: MLME-SYNC.request
+ *
+ * Description:
+ * Requests to synchronize with the coordinator by acquiring and, if
+ * specified, tracking its beacons.
+ *
+ *****************************************************************************/
+
+struct ieee802154_sync_req_s
+{
+ uint8_t ch_num;
+ uint8_t ch_page;
+ bool track_beacon;
+};
+
+/*****************************************************************************
+ * Primitive: MLME-SYNC-LOSS.indication
+ *
+ * Description:
+ * Indicates the loss of synchronization with a coordinator.
+ *
+ *****************************************************************************/
+
+struct ieee802154_syncloss_ind_s
+{
+ enum ieee802154_status_e loss_reason;
+ uint16_t pan_id;
+ uint8_t ch_num;
+ uint8_t ch_page;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-POLL.request
+ *
+ * Description:
+ * Prompts the device to request data from the coordinator.
+ *
+ *****************************************************************************/
+
+struct ieee802154_poll_req_s
+{
+ struct ieee802154_addr_s coord_addr;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+ /* Security information if enabled */
+
+ struct ieee802154_security_s security;
+#endif
+};
+
+/*****************************************************************************
+ * Primitive: MLME-POLL.confirm
+ *
+ * Description:
+ * Reports the results of a request to poll the coordinator for data.
+ *
+ *****************************************************************************/
+
+struct ieee802154_poll_conf_s
+{
+ enum ieee802154_status_e status;
+};
+
+union ieee802154_mlme_notify_u
+{
+ struct ieee802154_assoc_conf_s assocconf;
+ struct ieee802154_disassoc_conf_s disassocconf;
+ struct ieee802154_gts_conf_s gtsconf;
+ struct ieee802154_rxenable_conf_s rxenableconf;
+ struct ieee802154_scan_conf_s scanconf;
+ struct ieee802154_start_conf_s startconf;
+ struct ieee802154_poll_conf_s pollconf;
+
+ struct ieee802154_assoc_ind_s assocind;
+ struct ieee802154_disassoc_ind_s disassocind;
+ struct ieee802154_beaconnotify_ind_s beaconnotifyind;
+ struct ieee802154_gts_ind_s gtsind;
+ struct ieee802154_orphan_ind_s orphanind;
+ struct ieee802154_commstatus_ind_s commstatusind;
+ struct ieee802154_syncloss_ind_s synclossind;
+};
+
+union ieee802154_mcps_notify_u
+{
+ struct ieee802154_data_conf_s dataconf;
+ struct ieee802154_data_ind_s *dataind;
+};
+
+/* A pointer to this structure is passed as the argument of each IOCTL
+ * command.
+ */
+
+union ieee802154_macarg_u
+{
+ struct ieee802154_assoc_req_s assocreq; /* MAC802154IOC_MLME_ASSOC_REQUEST */
+ struct ieee802154_assoc_resp_s assocresp; /* MAC802154IOC_MLME_ASSOC_RESPONSE */
+ struct ieee802154_disassoc_req_s disassocreq; /* MAC802154IOC_MLME_DISASSOC_REQUEST */
+ struct ieee802154_get_req_s getreq; /* MAC802154IOC_MLME_GET_REQUEST */
+ struct ieee802154_gts_req_s gtsreq; /* MAC802154IOC_MLME_GTS_REQUEST */
+ struct ieee802154_orphan_resp_s orphanresp; /* MAC802154IOC_MLME_ORPHAN_RESPONSE */
+ struct ieee802154_reset_req_s resetreq; /* MAC802154IOC_MLME_RESET_REQUEST */
+ struct ieee802154_rxenable_req_s rxenabreq; /* MAC802154IOC_MLME_RXENABLE_REQUEST */
+ struct ieee802154_scan_req_s scanreq; /* MAC802154IOC_MLME_SCAN_REQUEST */
+ struct ieee802154_set_req_s setreq; /* MAC802154IOC_MLME_SET_REQUEST */
+ struct ieee802154_start_req_s startreq; /* MAC802154IOC_MLME_START_REQUEST */
+ struct ieee802154_sync_req_s syncreq; /* MAC802154IOC_MLME_SYNC_REQUEST */
+ struct ieee802154_poll_req_s pollreq; /* MAC802154IOC_MLME_POLL_REQUEST */
+ /* To be determined */ /* MAC802154IOC_MLME_DPS_REQUEST */
+ /* To be determined */ /* MAC802154IOC_MLME_SOUNDING_REQUEST */
+ /* To be determined */ /* MAC802154IOC_MLME_CALIBRATE_REQUEST */
+};
+
+#ifdef CONFIG_NET_6LOWPAN
+/* For the case of network IOCTLs, the network IOCTL to the MAC network
+ * driver will include a device name like "wpan0" as the destination of
+ * the IOCTL command.
+ */
+
+struct ieee802154_netmac_s
+{
+ char ifr_name[IFNAMSIZ]; /* Interface name, e.g. "wpan0" */
+ union ieee802154_macarg_u u; /* Data payload */
+};
+#endif
+
+/* This is an opaque reference to the MAC's internal private state. It is
+ * returned by mac802154_create() when it is created. It may then be used
+ * at other interfaces in order to interact with the MAC.
+ */
+
+typedef FAR void *MACHANDLE;
+
+/* MAC Service Notifications */
+
+enum ieee802154_macnotify_e
+{
+ /* MCPS Notifications */
+
+ IEEE802154_NOTIFY_CONF_DATA = 0x00,
+ IEEE802154_NOTIFY_IND_DATA,
+
+ /* MLME Notifications */
+
+ IEEE802154_NOTIFY_CONF_ASSOC,
+ IEEE802154_NOTIFY_CONF_DISASSOC,
+ IEEE802154_NOTIFY_CONF_GTS,
+ IEEE802154_NOTIFY_CONF_RESET,
+ IEEE802154_NOTIFY_CONF_RXENABLE,
+ IEEE802154_NOTIFY_CONF_SCAN,
+ IEEE802154_NOTIFY_CONF_START,
+ IEEE802154_NOTIFY_CONF_POLL,
+
+ IEEE802154_NOTIFY_IND_ASSOC,
+ IEEE802154_NOTIFY_IND_DISASSOC,
+ IEEE802154_NOTIFY_IND_BEACONNOTIFY,
+ IEEE802154_NOTIFY_IND_GTS,
+ IEEE802154_NOTIFY_IND_ORPHAN,
+ IEEE802154_NOTIFY_IND_COMMSTATUS,
+ IEEE802154_NOTIFY_IND_SYNCLOSS
+};
+
+/* Callback operations to notify the next highest layer of various asynchronous
+ * events, usually triggered by some previous request or response invoked by the
+ * upper layer.
+ */
+
+struct ieee802154_maccb_s
+{
+ CODE void (*mlme_notify)(FAR const struct ieee802154_maccb_s *maccb,
+ enum ieee802154_macnotify_e notif,
+ FAR const union ieee802154_mlme_notify_u *arg);
+
+ CODE void (*mcps_notify)(FAR const struct ieee802154_maccb_s *maccb,
+ enum ieee802154_macnotify_e notif,
+ FAR const union ieee802154_mcps_notify_u *arg);
+};
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+struct ieee802154_radio_s; /* Forward reference */
+
+/****************************************************************************
+ * Name: mac802154_create
+ *
+ * Description:
+ * Create a 802.15.4 MAC device from a 802.15.4 compatible radio device.
+ *
+ * The returned MAC structure should be passed to either the next highest
+ * layer in the network stack, or registered with a mac802154dev character
+ * or network drivers. In any of these scenarios, the next highest layer
+ * should register a set of callbacks with the MAC layer by setting the
+ * mac->cbs member.
+ *
+ * NOTE: This API does not create any device accessible to userspace. If you
+ * want to call these APIs from userspace, you have to wrap your mac in a
+ * character device via mac802154_device.c.
+ *
+ * Input Parameters:
+ * radiodev - an instance of an IEEE 802.15.4 radio
+ *
+ * Returned Value:
+ * An opaque reference to the MAC state data.
+ *
+ ****************************************************************************/
+
+MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev);
+
+/****************************************************************************
+ * Name: mac802154dev_register
+ *
+ * Description:
+ * Register a character driver to access the IEEE 802.15.4 MAC layer from
+ * user-space
+ *
+ * Input Parameters:
+ * mac - Pointer to the mac layer struct to be registered.
+ * minor - The device minor number. The IEEE802.15.4 MAC character device
+ * will be registered as /dev/ieeeN where N is the minor number
+ *
+ * Returned Values:
+ * Zero (OK) is returned on success. Otherwise a negated errno value is
+ * returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int mac802154dev_register(MACHANDLE mac, int minor);
+
+/****************************************************************************
+ * Name: mac802154netdev_register
+ *
+ * Description:
+ * Register a network driver to access the IEEE 802.15.4 MAC layer from
+ * a socket using 6loWPAN
+ *
+ * Input Parameters:
+ * mac - Pointer to the mac layer struct to be registered.
+ *
+ * Returned Values:
+ * Zero (OK) is returned on success. Otherwise a negated errno value is
+ * returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int mac802154netdev_register(MACHANDLE mac);
+
+/****************************************************************************
+ * Name: ieee802154_indpool_initialize
+ *
+ * Description:
+ * This function initializes the meta-data allocator. This function must
+ * be called early in the initialization sequence before any radios
+ * begin operation.
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * None
+ *
+ ****************************************************************************/
+
+void ieee802154_indpool_initialize(void);
+
+/****************************************************************************
+ * Name: ieee802154_ind_allocate
+ *
+ * Description:
+ * The ieee802154_ind_allocate function will get a free meta-data
+ * structure for use by the IEEE 802.15.4 MAC.
+ *
+ * Interrupt handling logic will first attempt to allocate from the
+ * g_indfree list. If that list is empty, it will attempt to allocate
+ * from its reserve, g_indfree_irq. If that list is empty, then the
+ * allocation fails (NULL is returned).
+ *
+ * Non-interrupt handler logic will attempt to allocate from g_indfree
+ * list. If that the list is empty, then the meta-data structure will be
+ * allocated from the dynamic memory pool.
+ *
+ * Inputs:
+ * None
+ *
+ * Return Value:
+ * A reference to the allocated msg structure. All user fields in this
+ * structure have been zeroed. On a failure to allocate, NULL is
+ * returned.
+ *
+ ****************************************************************************/
+
+FAR struct ieee802154_data_ind_s *ieee802154_ind_allocate(void);
+
+/****************************************************************************
+ * Name: ieee802154_ind_free
+ *
+ * Description:
+ * The ieee802154_ind_free function will return a meta-data structure to
+ * the free pool of messages if it was a pre-allocated meta-data
+ * structure. If the meta-data structure was allocated dynamically it will
+ * be deallocated.
+ *
+ * Inputs:
+ * ind - meta-data structure to free
+ *
+ * Return Value:
+ * None
+ *
+ ****************************************************************************/
+
+void ieee802154_ind_free(FAR struct ieee802154_data_ind_s *ind);
+
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_MAC_H */
diff --git a/include/nuttx/wireless/ieee802154/ieee802154_radio.h b/include/nuttx/wireless/ieee802154/ieee802154_radio.h
index c3439feb897..fcbc7ec1b7e 100644
--- a/include/nuttx/wireless/ieee802154/ieee802154_radio.h
+++ b/include/nuttx/wireless/ieee802154/ieee802154_radio.h
@@ -2,7 +2,9 @@
* include/nuttx/wireless/ieee802154/ieee802154_radio.h
*
* Copyright (C) 2014-2016 Sebastien Lorquet. All rights reserved.
+ * Copyright (C) 2017 Verge Inc. All rights reserved.
* Author: Sebastien Lorquet
+ * Author: Anthony Merlino
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,175 +35,64 @@
*
****************************************************************************/
-#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H
-#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_H
+#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_RADIO_H
+#define __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_RADIO_H
/****************************************************************************
* Included Files
****************************************************************************/
#include
+
#include
#include
#include
+#include
+
/****************************************************************************
* Pre-Processor Definitions
****************************************************************************/
-/* Configuration ************************************************************/
-/* None at the moment */
-
-/* IEEE 802.15.4 MAC Interface **********************************************/
-
-/* Frame control field masks, 2 bytes
- * Seee IEEE 802.15.4/2003 7.2.1.1 page 112
- */
-
-#define IEEE802154_FC1_FTYPE 0x03 /* Frame type, bits 0-2 */
-#define IEEE802154_FC1_SEC 0x08 /* Security Enabled, bit 3 */
-#define IEEE802154_FC1_PEND 0x10 /* Frame pending, bit 4 */
-#define IEEE802154_FC1_ACKREQ 0x20 /* Acknowledge request, bit 5 */
-#define IEEE802154_FC1_INTRA 0x40 /* Intra PAN, bit 6 */
-#define IEEE802154_FC2_DADDR 0x0C /* Dest addressing mode, bits 10-11 */
-#define IEEE802154_FC2_VERSION 0x30 /* Source addressing mode, bits 12-13 */
-#define IEEE802154_FC2_SADDR 0xC0 /* Source addressing mode, bits 14-15 */
-
-/* Frame Type */
-
-#define IEEE802154_FRAME_BEACON 0x00
-#define IEEE802154_FRAME_DATA 0x01
-#define IEEE802154_FRAME_ACK 0x02
-#define IEEE802154_FRAME_COMMAND 0x03
-
-/* Security Enabled */
-
-#define IEEE802154_SEC_OFF 0x00
-#define IEEE802154_SEC_ON 0x08
-
-/* Flags */
-
-#define IEEE802154_PEND 0x10
-#define IEEE802154_ACK_REQ 0x20
-#define IEEE802154_INTRA 0x40
-
-/* Dest Addressing modes */
-
-#define IEEE802154_DADDR_NONE 0x00
-#define IEEE802154_DADDR_SHORT 0x08
-#define IEEE802154_DADDR_EXT 0x0A
-
-/* Src Addressing modes */
-
-#define IEEE802154_SADDR_NONE 0x00
-#define IEEE802154_SADDR_SHORT 0x80
-#define IEEE802154_SADDR_EXT 0xA0
-
-/* Some addresses */
-
-#define IEEE802154_PAN_DEFAULT (uint16_t)0xFFFF
-#define IEEE802154_SADDR_UNSPEC (uint16_t)0xFFFF
-#define IEEE802154_SADDR_BCAST (uint16_t)0xFFFE
-#define IEEE802154_EADDR_UNSPEC (uint8_t*)"\xff\xff\xff\xff\xff\xff\xff\xff"
-
-#define IEEE802154_CMD_ASSOC_REQ 0x01
-#define IEEE802154_CMD_ASSOC_RSP 0x02
-#define IEEE802154_CMD_DIS_NOT 0x03
-#define IEEE802154_CMD_DATA_REQ 0x04
-#define IEEE802154_CMD_PANID_CONF_NOT 0x05
-#define IEEE802154_CMD_ORPHAN_NOT 0x06
-#define IEEE802154_CMD_BEACON_REQ 0x07
-#define IEEE802154_CMD_COORD_REALIGN 0x08
-#define IEEE802154_CMD_GTS_REQ 0x09
-
-/* Device modes */
-
-#define IEEE802154_MODE_DEVICE 0x00
-#define IEEE802154_MODE_COORD 0x01 /* avail in mrf24j40, but why? */
-#define IEEE802154_MODE_PANCOORD 0x02
/****************************************************************************
* Public Types
****************************************************************************/
-struct ieee802154_packet_s
+/* IEEE802.15.4 Radio Interface Operations **********************************/
+
+struct ieee802154_radiocb_s
{
- uint8_t len;
- uint8_t data[127];
- uint8_t lqi;
- uint8_t rssi;
+ CODE int (*poll_csma) (FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR struct ieee802154_txdesc_s *tx_desc,
+ FAR struct iob_s **frame);
+ CODE int (*poll_gts) (FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR struct ieee802154_txdesc_s *tx_desc,
+ FAR struct iob_s **frame);
+ CODE void (*txdone) (FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR const struct ieee802154_txdesc_s *tx_desc);
+ CODE void (*rxframe) (FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR struct ieee802154_data_ind_s *ind);
};
-struct ieee802154_cca_s
+struct ieee802154_radio_s; /* Forward reference */
+
+struct ieee802154_radioops_s
{
- uint8_t use_ed : 1; /* CCA using ED */
- uint8_t use_cs : 1; /* CCA using carrier sense */
- uint8_t edth; /* Energy detection threshold for CCA */
- uint8_t csth; /* Carrier sense threshold for CCA */
+ CODE int (*bind) (FAR struct ieee802154_radio_s *radio,
+ FAR struct ieee802154_radiocb_s *radiocb);
+ CODE int (*txnotify_csma)(FAR struct ieee802154_radio_s *radio);
+ CODE int (*txnotify_gts)(FAR struct ieee802154_radio_s *radio);
+ CODE int (*get_attr) (FAR struct ieee802154_radio_s *radio,
+ enum ieee802154_pib_attr_e pib_attr,
+ FAR union ieee802154_attr_val_u *attr_value);
+ CODE int (*set_attr) (FAR struct ieee802154_radio_s *radio,
+ enum ieee802154_pib_attr_e pib_attr,
+ FAR const union ieee802154_attr_val_u *attr_value);
};
-struct ieee802154_dev_s;
-
-struct ieee802154_devops_s
+struct ieee802154_radio_s
{
- CODE int (*setchannel)(FAR struct ieee802154_dev_s *dev, uint8_t channel);
- CODE int (*getchannel)(FAR struct ieee802154_dev_s *dev,
- FAR uint8_t *channel);
-
- CODE int (*setpanid)(FAR struct ieee802154_dev_s *dev, uint16_t panid);
- CODE int (*getpanid)(FAR struct ieee802154_dev_s *dev,
- FAR uint16_t *panid);
-
- CODE int (*setsaddr)(FAR struct ieee802154_dev_s *dev, uint16_t saddr);
- CODE int (*getsaddr)(FAR struct ieee802154_dev_s *dev,
- FAR uint16_t *saddr);
-
- CODE int (*seteaddr)(FAR struct ieee802154_dev_s *dev,
- FAR uint8_t *laddr);
- CODE int (*geteaddr)(FAR struct ieee802154_dev_s *dev,
- FAR uint8_t *laddr);
-
- CODE int (*setpromisc)(FAR struct ieee802154_dev_s *dev, bool promisc);
- CODE int (*getpromisc)(FAR struct ieee802154_dev_s *dev,
- FAR bool *promisc);
-
- CODE int (*setdevmode)(FAR struct ieee802154_dev_s *dev, uint8_t devmode);
- CODE int (*getdevmode)(FAR struct ieee802154_dev_s *dev,
- FAR uint8_t *devmode);
-
- CODE int (*settxpower)(FAR struct ieee802154_dev_s *dev,
- int32_t txpwr); /* unit = 1 mBm = 1/100 dBm */
- CODE int (*gettxpower)(FAR struct ieee802154_dev_s *dev,
- FAR int32_t *txpwr);
-
- CODE int (*setcca)(FAR struct ieee802154_dev_s *dev,
- FAR struct ieee802154_cca_s *cca);
- CODE int (*getcca)(FAR struct ieee802154_dev_s *dev,
- FAR struct ieee802154_cca_s *cca);
-
- CODE int (*ioctl)(FAR struct ieee802154_dev_s *ieee, int cmd,
- unsigned long arg);
- CODE int (*energydetect)(FAR struct ieee802154_dev_s *dev,
- FAR uint8_t *energy);
- CODE int (*rxenable)(FAR struct ieee802154_dev_s *dev, bool state,
- FAR struct ieee802154_packet_s *packet);
- CODE int (*transmit)(FAR struct ieee802154_dev_s *dev,
- FAR struct ieee802154_packet_s *packet);
-
- /*TODO beacon/sf order*/
-};
-
-struct ieee802154_dev_s
-{
- FAR const struct ieee802154_devops_s *ops;
-
- /* Packet reception management */
-
- struct ieee802154_packet_s *rxbuf;
- sem_t rxsem;
-
- /* Packet transmission management */
-
- sem_t txsem;
+ FAR const struct ieee802154_radioops_s *ops;
};
#ifdef __cplusplus
@@ -221,4 +112,4 @@ extern "C"
}
#endif
-#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_MRF24J40_H */
+#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE802154_IEEE802154_RADIO_H */
diff --git a/include/nuttx/wireless/ieee802154/mrf24j40.h b/include/nuttx/wireless/ieee802154/mrf24j40.h
index 878f7d9b453..136c947a48b 100644
--- a/include/nuttx/wireless/ieee802154/mrf24j40.h
+++ b/include/nuttx/wireless/ieee802154/mrf24j40.h
@@ -40,6 +40,8 @@
* Included files
****************************************************************************/
+#include
+#include
#include
/****************************************************************************
@@ -52,18 +54,19 @@
*
* The MRF24J40 interrupt is an active low, *level* interrupt. From Datasheet:
* "Note 1: The INTEDGE polarity defaults to:
- * 0 = Falling Edge. Ensure that the inter-
- * rupt polarity matches the interrupt pin
- * polarity of the host microcontroller.
- * Note 2: The INT pin will remain high or low,
- * depending on INTEDGE polarity setting,
- * until INTSTAT register is read."
+ *
+ * 0 = Falling Edge. Ensure that the interrupt polarity matches the
+ * interrupt pin polarity of the host microcontroller.
+ *
+ * Note 2: The INT pin will remain high or low, depending on INTEDGE
+ * polarity setting, until INTSTAT register is read."
*/
struct mrf24j40_lower_s
{
- int (*attach)(FAR const struct mrf24j40_lower_s *lower, xcpt_t handler);
- void (*enable)(FAR const struct mrf24j40_lower_s *lower, int state);
+ int (*attach)(FAR const struct mrf24j40_lower_s *lower, xcpt_t handler,
+ FAR void *arg);
+ void (*enable)(FAR const struct mrf24j40_lower_s *lower, bool state);
};
#ifdef __cplusplus
@@ -100,8 +103,9 @@ extern "C"
****************************************************************************/
struct spi_dev_s; /* Forward reference */
-FAR struct ieee802154_dev_s *mrf24j40_init(FAR struct spi_dev_s *spi,
- FAR const struct mrf24j40_lower_s *lower);
+FAR struct ieee802154_radio_s *
+ mrf24j40_init(FAR struct spi_dev_s *spi,
+ FAR const struct mrf24j40_lower_s *lower);
#undef EXTERN
#ifdef __cplusplus
diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h
index acbcc1d3e66..76abe7f01fb 100644
--- a/include/sys/ioctl.h
+++ b/include/sys/ioctl.h
@@ -63,6 +63,22 @@
# include
#endif
+
+#ifdef CONFIG_WIRELESS_IEEE802154
+
+#ifdef CONFIG_IEEE802154_MAC
+/* Include ieee802.15.4 MAC IOCTL definitions */
+
+# include
+#endif
+
+#ifdef CONFIG_IEEE802154_MAC_DEV
+/* Include ieee802.15.4 character driver IOCTL definitions */
+
+# include
+#endif
+
+#endif /* CONFIG_WIRELESS_IEEE802154 */
#endif /* CONFIG_NSOCKET_DESCRIPTORS > 0 */
/****************************************************************************
diff --git a/net/Kconfig b/net/Kconfig
index 313f7a05f85..c5f7d26117c 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -136,6 +136,7 @@ config NET_6LOWPAN
default n
select NETDEV_MULTINIC if NET_ETHERNET || NET_LOOPBACK || NET_SLIP || NET_TUN
select NET_MULTILINK if NET_ETHERNET || NET_LOOPBACK || NET_SLIP || NET_TUN
+ select NETDEV_IOCTL
depends on EXPERIMENTAL && NET_IPv6
---help---
Enable support for IEEE 802.15.4 Low power Wireless Personal Area
diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c
index 8bb44c82fc0..dae80646457 100644
--- a/net/netdev/netdev_ioctl.c
+++ b/net/netdev/netdev_ioctl.c
@@ -72,6 +72,10 @@
# include
#endif
+#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
+# include
+#endif
+
#include "arp/arp.h"
#include "socket/socket.h"
#include "netdev/netdev.h"
@@ -320,6 +324,67 @@ static void ioctl_set_ipv6addr(FAR net_ipv6addr_t outaddr,
}
#endif
+/****************************************************************************
+ * Name: netdev_iee802154_ioctl
+ *
+ * Description:
+ * Perform IEEE802.15.4 network device specific operations.
+ *
+ * Parameters:
+ * psock Socket structure
+ * dev Ethernet driver device structure
+ * cmd The ioctl command
+ * req The argument of the ioctl cmd
+ *
+ * Return:
+ * >=0 on success (positive non-zero values are cmd-specific)
+ * Negated errno returned on failure.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
+static int netdev_iee802154_ioctl(FAR struct socket *psock, int cmd,
+ unsigned long arg)
+{
+ FAR struct net_driver_s *dev;
+ FAR char *ifname;
+ int ret = -ENOTTY;
+
+ if (arg != 0ul)
+ {
+ if (_MAC802154IOCVALID(cmd))
+ {
+ /* Get the IEEE802.15.4 MAC device to receive the radio IOCTL
+ * commdand
+ */
+
+ FAR struct ieee802154_netmac_s *netmac =
+ (FAR struct ieee802154_netmac_s *)((uintptr_t)arg);
+
+ ifname = netmac->ifr_name;
+ }
+ else
+ {
+ /* The IOCTL command is neither */
+
+ return -ENOTTY;
+ }
+
+ /* Find the device with this name */
+
+ dev = netdev_findbyname(ifname);
+ if (dev != NULL)
+ {
+ /* Perform the device IOCTL */
+
+ ret = dev->d_ioctl(dev, cmd, arg);
+ }
+ }
+
+ return ret;
+}
+#endif
+
/****************************************************************************
* Name: netdev_wifr_ioctl
*
@@ -709,7 +774,7 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
{
req->ifr_hwaddr.sa_family = AF_INETX;
memcpy(req->ifr_hwaddr.sa_data,
- dev->d_mac.ieee802154.u8, NET_6LOWPAN_RIMEADDR_SIZE);
+ dev->d_mac.ieee802154.u8, NET_6LOWPAN_ADDRSIZE);
}
else
#endif
@@ -747,7 +812,7 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
#endif
{
memcpy(dev->d_mac.ieee802154.u8,
- req->ifr_hwaddr.sa_data, NET_6LOWPAN_RIMEADDR_SIZE);
+ req->ifr_hwaddr.sa_data, NET_6LOWPAN_ADDRSIZE);
ret = OK;
}
else
@@ -1192,6 +1257,15 @@ int psock_ioctl(FAR struct socket *psock, int cmd, unsigned long arg)
}
#endif
+#if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_NET_6LOWPAN)
+ /* Check for a IEEE802.15.4 network device command */
+
+ if (ret == -ENOTTY)
+ {
+ ret = netdev_iee802154_ioctl(psock, cmd, arg);
+ }
+#endif
+
#ifdef CONFIG_NET_IGMP
/* Check for address filtering commands */
diff --git a/net/procfs/netdev_statistics.c b/net/procfs/netdev_statistics.c
index 5383adfc6a4..109f4cdca28 100644
--- a/net/procfs/netdev_statistics.c
+++ b/net/procfs/netdev_statistics.c
@@ -151,7 +151,7 @@ static int netprocfs_linklayer(FAR struct netprocfs_file_s *netfile)
#ifdef CONFIG_NET_6LOWPAN
case NET_LL_IEEE802154:
{
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
+#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
len += snprintf(&netfile->line[len], NET_LINELEN - len,
"%s\tLink encap:6loWPAN HWaddr "
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
@@ -213,7 +213,7 @@ static int netprocfs_linklayer(FAR struct netprocfs_file_s *netfile)
dev->d_ifname, ether_ntoa(&dev->d_mac.ether), status);
#elif defined(CONFIG_NET_6LOWPAN)
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
+#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
len += snprintf(&netfile->line[len], NET_LINELEN - len,
"%s\tLink encap:6loWPAN HWaddr "
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x at %s\n",
diff --git a/net/sixlowpan/Kconfig b/net/sixlowpan/Kconfig
index 021571fbd01..674eff01f6e 100644
--- a/net/sixlowpan/Kconfig
+++ b/net/sixlowpan/Kconfig
@@ -133,13 +133,13 @@ config NET_6LOWPAN_MAXADDRCONTEXT_PREFIX_2_1
endif # NET_6LOWPAN_MAXADDRCONTEXT_PREINIT_0
endif # NET_6LOWPAN_COMPRESSION_HC06
-config NET_6LOWPAN_RIMEADDR_EXTENDED
- bool "Extended Rime address"
+config NET_6LOWPAN_EXTENDEDADDR
+ bool "Extended IEEE 802.15.4 address"
default n
---help---
- By default, a 2-byte Rime address is used for the IEEE802.15.4 MAC
+ By default, a 2-byte short address is used for the IEEE802.15.4 MAC
device's link layer address. If this option is selected, then an
- 8-byte Rime address will be used.
+ 8-byte extended address will be used.
config NET_6LOWPAN_MAXAGE
int "Packet reassembly timeout"
@@ -151,6 +151,7 @@ config NET_6LOWPAN_MAXAGE
config NET_6LOWPAN_MAX_MACTRANSMITS
int "Max MAC transmissions"
default 4
+ range 1 255
---help---
CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS specifies how many times the MAC
layer should resend packets if no link-layer ACK wasreceived. This
diff --git a/net/sixlowpan/README.txt b/net/sixlowpan/README.txt
index 5b6b4e298d2..9eb848144e8 100644
--- a/net/sixlowpan/README.txt
+++ b/net/sixlowpan/README.txt
@@ -10,12 +10,12 @@ Optimal 6loWPAN Configuration
128 112 96 80 64 48 32 16
---- ---- ---- ---- ---- ---- ---- ----
- AAAA xxxx xxxx xxxx xxxx 00ff fe00 MMMM 2-byte Rime address IEEE 48-bit MAC
- AAAA 0000 0000 0000 NNNN NNNN NNNN NNNN 8-byte Rime address IEEE EUI-64
+ AAAA xxxx xxxx xxxx xxxx 00ff fe00 MMMM 2-byte short address IEEE 48-bit MAC
+ AAAA 0000 0000 0000 NNNN NNNN NNNN NNNN 8-byte extended address IEEE EUI-64
- Where MMM is the 2-byte rime address XORed 0x0200. For example, the MAC
+ Where MMM is the 2-byte short address XORed 0x0200. For example, the MAC
address of 0xabcd would be 0xa9cd. And NNNN NNNN NNNN NNNN is the 8-byte
- rime address address XOR 02000 0000 0000 0000.
+ extended address address XOR 02000 0000 0000 0000.
For link-local address, AAAA is 0xfe80
@@ -23,8 +23,8 @@ Optimal 6loWPAN Configuration
128 112 96 80 64 48 32 16
---- ---- ---- ---- ---- ---- ---- ----
- fe80 0000 0000 0000 0000 00ff fe00 MMMM 2-byte Rime address IEEE 48-bit MAC
- fe80 0000 0000 0000 NNNN NNNN NNNN NNNN 8-byte Rime address IEEE EUI-64
+ fe80 0000 0000 0000 0000 00ff fe00 MMMM 2-byte short address IEEE 48-bit MAC
+ fe80 0000 0000 0000 NNNN NNNN NNNN NNNN 8-byte extended address IEEE EUI-64
4. Compressable port numbers in the rangs 0xf0b0-0xf0bf
@@ -52,11 +52,11 @@ this is a HC1 compressed first frame of a packet
41 88 2a cefa 3412 cdab ### 9-byte MAC header
c50e 000b ### 4-byte FRAG1 header
42 ### SIXLOWPAN_DISPATCH_HC1
- fb ### RIME_HC1_HC_UDP_HC1_ENCODING
- e0 ### RIME_HC1_HC_UDP_UDP_ENCODING
- 00 ### RIME_HC1_HC_UDP_TTL
- 10 ### RIME_HC1_HC_UDP_PORTS
- 0000 ### RIME_HC1_HC_UDP_CHKSUM
+ fb ### SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING
+ e0 ### SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING
+ 00 ### SIXLOWPAN_HC1_HC_UDP_TTL
+ 10 ### SIXLOWPAN_HC1_HC_UDP_PORTS
+ 0000 ### SIXLOWPAN_HC1_HC_UDP_CHKSUM
104 byte Payload follows:
4f4e452064617920 48656e6e792d7065 6e6e792077617320 7069636b696e6720
@@ -69,11 +69,11 @@ This is the second frame of the same transfer:
41 88 2b cefa 3412 cdab ### 9-byte MAC header
e50e 000b 0d ### 5 byte FRAGN header
42 ### SIXLOWPAN_DISPATCH_HC1
- fb ### RIME_HC1_HC_UDP_HC1_ENCODING
- e0 ### RIME_HC1_HC_UDP_UDP_ENCODING
- 00 ### RIME_HC1_HC_UDP_TTL
- 10 ### RIME_HC1_HC_UDP_PORTS
- 0000 ### RIME_HC1_HC_UDP_CHKSUM
+ fb ### SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING
+ e0 ### SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING
+ 00 ### SIXLOWPAN_HC1_HC_UDP_TTL
+ 10 ### SIXLOWPAN_HC1_HC_UDP_PORTS
+ 0000 ### SIXLOWPAN_HC1_HC_UDP_CHKSUM
104 byte Payload follows:
476f6f646e657373 2067726163696f75 73206d6521272073 6169642048656e6e
diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c
index 9f7a68a1f7b..697bec1a816 100644
--- a/net/sixlowpan/sixlowpan_framelist.c
+++ b/net/sixlowpan/sixlowpan_framelist.c
@@ -55,6 +55,7 @@
#include
#include
+#include
#include "sixlowpan/sixlowpan_internal.h"
@@ -77,7 +78,7 @@
*/
#if CONFIG_NET_6LOWPAN_MTU > (CONFIG_IOB_BUFSIZE * CONFIG_IOB_NBUFFERS)
-# error Not enough IOBs to hold one full IEEE802.14.5 packet
+# error Not enough IOBs to hold one full 6LoWPAN packet
#endif
/****************************************************************************
@@ -183,9 +184,8 @@ static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr,
*
* The payload data is in the caller 'buf' and is of length 'buflen'.
* Compressed headers will be added and if necessary the packet is
- * fragmented. The resulting packet/fragments are put in ieee->i_framelist
- * and the entire list of frames will be delivered to the 802.15.4 MAC via
- * ieee->i_framelist.
+ * fragmented. The resulting packet/fragments are submitted to the MAC
+ * where they are queue for transfer.
*
* Input Parameters:
* ieee - The IEEE802.15.4 MAC driver instance
@@ -209,17 +209,20 @@ static void sixlowpan_compress_ipv6hdr(FAR const struct ipv6_hdr_s *ipv6hdr,
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *destip,
FAR const void *buf, size_t buflen,
- FAR const struct rimeaddr_s *destmac)
+ FAR const struct sixlowpan_tagaddr_s *destmac)
{
+ struct packet_metadata_s pktmeta;
+ struct ieee802154_frame_meta_s meta;
FAR struct iob_s *iob;
FAR uint8_t *fptr;
int framer_hdrlen;
- struct rimeaddr_s bcastmac;
+ struct sixlowpan_tagaddr_s bcastmac;
uint16_t pktlen;
uint16_t paysize;
#ifdef CONFIG_NET_6LOWPAN_FRAG
uint16_t outlen = 0;
#endif
+ int ret;
/* Initialize global data. Locking the network guarantees that we have
* exclusive use of the global values for intermediate calculations.
@@ -228,16 +231,14 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
g_uncomp_hdrlen = 0;
g_frame_hdrlen = 0;
- /* Reset rime buffer, packet buffer metatadata */
+ /* Reset frame meta data */
- memset(g_pktattrs, 0, PACKETBUF_NUM_ATTRS * sizeof(uint16_t));
- memset(g_pktaddrs, 0, PACKETBUF_NUM_ADDRS * sizeof(struct rimeaddr_s));
-
- g_pktattrs[PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS] =
- CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
+ memset(&pktmeta, 0, sizeof(struct packet_metadata_s));
+ pktmeta.xmits = CONFIG_NET_6LOWPAN_MAX_MACTRANSMITS;
/* Set stream mode for all TCP packets, except FIN packets. */
+#if 0 /* Currently the frame type is always data */
if (destip->proto == IP_PROTO_TCP)
{
FAR const struct tcp_hdr_s *tcp =
@@ -246,13 +247,14 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
if ((tcp->flags & TCP_FIN) == 0 &&
(tcp->flags & TCP_CTL) != TCP_ACK)
{
- g_pktattrs[PACKETBUF_ATTR_PACKET_TYPE] = PACKETBUF_ATTR_PACKET_TYPE_STREAM;
+ pktmeta.type = FRAME_ATTR_TYPE_STREAM;
}
else if ((tcp->flags & TCP_FIN) == TCP_FIN)
{
- g_pktattrs[PACKETBUF_ATTR_PACKET_TYPE] = PACKETBUF_ATTR_PACKET_TYPE_STREAM_END;
+ pktmeta.type = FRAME_ATTR_TYPE_STREAM_END;
}
}
+#endif
/* The destination address will be tagged to each outbound packet. If the
* argument destmac is NULL, we are sending a broadcast packet.
@@ -260,7 +262,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
if (destmac == NULL)
{
- memset(&bcastmac, 0, sizeof(struct rimeaddr_s));
+ memset(&bcastmac, 0, sizeof(struct sixlowpan_tagaddr_s));
destmac = &bcastmac;
}
@@ -281,24 +283,67 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
ninfo("Sending packet length %d\n", buflen);
- /* Set the source and destination address */
+ /* Set the source and destination address. The source MAC address
+ * is a fixed size, determined by a configuration setting. The
+ * destination MAC address many be either short or extended.
+ */
- rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_SENDER],
- &ieee->i_dev.d_mac.ieee802154);
- rimeaddr_copy(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER], destmac);
+#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
+ pktmeta.sextended = TRUE;
+ sixlowpan_eaddrcopy(pktmeta.source.eaddr.u8,
+ &ieee->i_dev.d_mac.ieee802154);
+#else
+ sixlowpan_saddrcopy(pktmeta.source.saddr.u8,
+ &ieee->i_dev.d_mac.ieee802154);
+#endif
+
+ if (destmac->extended)
+ {
+ pktmeta.dextended = TRUE;
+ sixlowpan_eaddrcopy(pktmeta.dest.eaddr.u8, destmac->u.eaddr.u8);
+ }
+ else
+ {
+ sixlowpan_saddrcopy(pktmeta.dest.saddr.u8, destmac->u.saddr.u8);
+ }
+
+ /* Get the destination PAN ID.
+ *
+ * REVISIT: For now I am assuming that the source and destination
+ * PAN IDs are the same.
+ */
+
+ pktmeta.dpanid = 0xffff;
+ (void)sixlowpan_src_panid(ieee, &pktmeta.dpanid);
+
+ /* Based on the collected attributes and addresses, construct the MAC meta
+ * data structure that we need to interface with the IEEE802.15.4 MAC (we
+ * will update the MSDU payload size when the IOB has been setup).
+ */
+
+ ret = sixlowpan_meta_data(ieee, &pktmeta, &meta, 0);
+ if (ret < 0)
+ {
+ nerr("ERROR: sixlowpan_meta_data() failed: %d\n", ret);
+ }
/* Pre-calculate frame header length. */
- framer_hdrlen = sixlowpan_send_hdrlen(ieee, ieee->i_panid);
+ framer_hdrlen = sixlowpan_frame_hdrlen(ieee, &meta);
if (framer_hdrlen < 0)
{
/* Failed to determine the size of the header failed. */
- nerr("ERROR: sixlowpan_send_hdrlen() failed: %d\n", framer_hdrlen);
+ nerr("ERROR: sixlowpan_frame_hdrlen() failed: %d\n", framer_hdrlen);
return framer_hdrlen;
}
- g_frame_hdrlen = framer_hdrlen;
+ /* This sill be the initial offset into io_data. Valid data begins at
+ * this offset and must be reflected in io_offset.
+ */
+
+ g_frame_hdrlen = framer_hdrlen;
+ iob->io_offset = framer_hdrlen;
#ifndef CONFIG_NET_6LOWPAN_COMPRESSION_IPv6
if (buflen >= CONFIG_NET_6LOWPAN_COMPRESSION_THRESHOLD)
@@ -328,15 +373,15 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
if (buflen > (CONFIG_NET_6LOWPAN_FRAMELEN - g_frame_hdrlen))
{
#ifdef CONFIG_NET_6LOWPAN_FRAG
- /* ieee->i_framelist will hold the generated frames; frames will be
+ /* qhead will hold the generated frame list; frames will be
* added at qtail.
*/
+ FAR struct iob_s *qhead;
FAR struct iob_s *qtail;
FAR uint8_t *frame1;
FAR uint8_t *fragptr;
uint16_t frag1_hdrlen;
- int verify;
/* The outbound IPv6 packet is too large to fit into a single 15.4
* packet, so we fragment it into multiple packets and send them.
@@ -348,13 +393,6 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
ninfo("Sending fragmented packet length %d\n", buflen);
/* Create 1st Fragment */
- /* Add the frame header using the pre-allocated IOB using the DSN
- * selected by sixlowpan_send_hdrlen().
- */
-
- verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
- DEBUGASSERT(verify == framer_hdrlen);
- UNUSED(verify);
/* Move HC1/HC06/IPv6 header to make space for the FRAG1 header at the
* beginning of the frame.
@@ -380,9 +418,9 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
*/
pktlen = buflen + g_uncomp_hdrlen;
- PUTINT16(fragptr, RIME_FRAG_DISPATCH_SIZE,
- ((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen));
- PUTINT16(fragptr, RIME_FRAG_TAG, ieee->i_dgramtag);
+ PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE,
+ ((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen));
+ PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, ieee->i_dgramtag);
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
@@ -395,8 +433,8 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Set outlen to what we already sent from the IP payload */
- iob->io_len = paysize + g_frame_hdrlen;
- outlen = paysize;
+ iob->io_len = paysize + g_frame_hdrlen;
+ outlen = paysize;
ninfo("First fragment: length %d, tag %d\n",
paysize, ieee->i_dgramtag);
@@ -405,17 +443,17 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Add the first frame to the IOB queue */
- ieee->i_framelist = iob;
- qtail = iob;
+ qhead = iob;
+ qtail = iob;
/* Keep track of the total amount of data queue */
- iob->io_pktlen = iob->io_len;
+ iob->io_pktlen = iob->io_len;
/* Create following fragments */
- frame1 = iob->io_data;
- frag1_hdrlen = g_frame_hdrlen;
+ frame1 = iob->io_data;
+ frag1_hdrlen = g_frame_hdrlen;
while (outlen < buflen)
{
@@ -432,20 +470,10 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
iob->io_flink = NULL;
iob->io_len = 0;
- iob->io_offset = 0;
+ iob->io_offset = framer_hdrlen;
iob->io_pktlen = 0;
fptr = iob->io_data;
- /* Add a new frame header to the IOB (same as the first but with a
- * different DSN).
- */
-
- g_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] = 0;
-
- verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
- DEBUGASSERT(verify == framer_hdrlen);
- UNUSED(verify);
-
/* Copy the HC1/HC06/IPv6 header the frame header from first
* frame, into the correct location after the FRAGN header
* of subsequent frames.
@@ -459,10 +487,10 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Setup up the FRAGN header after the frame header. */
- PUTINT16(fragptr, RIME_FRAG_DISPATCH_SIZE,
- ((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen));
- PUTINT16(fragptr, RIME_FRAG_TAG, ieee->i_dgramtag);
- fragptr[RIME_FRAG_OFFSET] = outlen >> 3;
+ PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE,
+ ((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen));
+ PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, ieee->i_dgramtag);
+ fragptr[SIXLOWPAN_FRAG_OFFSET] = outlen >> 3;
fragn_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
@@ -498,7 +526,28 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
/* Keep track of the total amount of data queue */
- ieee->i_framelist->io_pktlen += iob->io_len;
+ qhead->io_pktlen += iob->io_len;
+ }
+
+ /* Submit all of the fragments to the MAC. We send all frames back-
+ * to-back like this to minimize any possible condition where some
+ * frame which is not a fragment from this sequence from intervening.
+ */
+
+ for (iob = qhead; iob != NULL; iob = qhead)
+ {
+ /* Remove the IOB containing the frame from the list */
+
+ qhead = iob->io_flink;
+ iob->io_flink = NULL;
+
+ /* And submit the frame to the MAC */
+
+ ret = sixlowpan_frame_submit(ieee, &meta, iob);
+ if (ret < 0)
+ {
+ nerr("ERROR: sixlowpan_frame_submit() failed: %d\n", ret);
+ }
}
/* Update the datagram TAG value */
@@ -514,34 +563,27 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
}
else
{
- int verify;
-
/* The packet does not need to be fragmented just copy the "payload"
* and send in one frame.
*/
- /* Add the frame header to the preallocated IOB. */
-
- verify = sixlowpan_framecreate(ieee, iob, ieee->i_panid);
- DEBUGASSERT(verify == framer_hdrlen);
- UNUSED(verify);
-
- /* Copy the payload and queue */
+ /* Copy the payload into the frame. */
memcpy(fptr + g_frame_hdrlen, buf, buflen);
- iob->io_len = buflen + g_frame_hdrlen;
+ iob->io_len = buflen + g_frame_hdrlen;
+ iob->io_pktlen = iob->io_len;
ninfo("Non-fragmented: length %d\n", iob->io_len);
sixlowpan_dumpbuffer("Outgoing frame",
(FAR const uint8_t *)iob->io_data, iob->io_len);
- /* Add the first frame to the IOB queue */
+ /* And submit the frame to the MAC */
- ieee->i_framelist = iob;
-
- /* Keep track of the total amount of data queue */
-
- iob->io_pktlen = iob->io_len;
+ ret = sixlowpan_frame_submit(ieee, &meta, iob);
+ if (ret < 0)
+ {
+ nerr("ERROR: sixlowpan_frame_submit() failed: %d\n", ret);
+ }
}
return OK;
diff --git a/net/sixlowpan/sixlowpan_framer.c b/net/sixlowpan/sixlowpan_framer.c
index da52303c6cd..d52a5cd30ca 100644
--- a/net/sixlowpan/sixlowpan_framer.c
+++ b/net/sixlowpan/sixlowpan_framer.c
@@ -4,18 +4,6 @@
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
*
- * Derives from Contiki:
- *
- * Copyright (c) 2008, Swedish Institute of Computer Science.
- * All rights reserved.
- * Authors: Adam Dunkels
- * Nicolas Tsiftes
- * Niclas Finne
- * Mathilde Durvy
- * Julien Abeille
- * Joakim Eriksson
- * Joel Hoglund
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -23,23 +11,25 @@
* 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 the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
+ * 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 INSTITUTE 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 INSTITUTE 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.
+ * 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.
*
****************************************************************************/
@@ -52,84 +42,41 @@
#include
#include
#include
+#include
#include
#include "nuttx/net/net.h"
+#include "nuttx/wireless/ieee802154/ieee802154_mac.h"
#include "sixlowpan/sixlowpan_internal.h"
#ifdef CONFIG_NET_6LOWPAN
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/* Structure that contains the lengths of the various addressing and
- * security fields in the 802.15.4 header.
- */
-
-struct field_length_s
-{
- uint8_t dest_pid_len; /* Length (in bytes) of destination PAN ID field */
- uint8_t dest_addr_len; /* Length (in bytes) of destination address field */
- uint8_t src_pid_len; /* Length (in bytes) of source PAN ID field */
- uint8_t src_addr_len; /* Length (in bytes) of source address field */
- uint8_t aux_sec_len; /* Length (in bytes) of aux security header field */
-};
-
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
- * Name: sixlowpan_addrlen
+ * Name: sixlowpan_anyaddrnull
*
* Description:
- * Return the address length associated with a 2-bit address mode
+ * If the destination address is all zero in the MAC header buf, then it is
+ * broadcast on the 802.15.4 network.
*
* Input parameters:
- * addrmode - The address mode
+ * addr - The address to check
+ * addrlen - The length of the address in bytes
*
* Returned Value:
- * The address length associated with the address mode.
+ * True if the address is all zero.
*
****************************************************************************/
-static inline uint8_t sixlowpan_addrlen(uint8_t addrmode)
+static bool sixlowpan_anyaddrnull(FAR uint8_t *addr, uint8_t addrlen)
{
- switch (addrmode)
+ while (addrlen-- > 0)
{
- case FRAME802154_SHORTADDRMODE: /* 16-bit address */
- return 2;
- case FRAME802154_LONGADDRMODE: /* 64-bit address */
- return 8;
- default:
- return 0;
- }
-}
-
-/****************************************************************************
- * Name: sixlowpan_addrnull
- *
- * Description:
- * If the output address is NULL in the Rime buf, then it is broadcast
- * on the 802.15.4 network.
- *
- * Input parameters:
- * addrmode - The address mode
- *
- * Returned Value:
- * The address length associated with the address mode.
- *
- ****************************************************************************/
-
-static bool sixlowpan_addrnull(FAR uint8_t *addr)
-{
- int i = NET_6LOWPAN_RIMEADDR_SIZE;
-
- while (i-- > 0)
- {
- if (addr[i] != 0x00)
+ if (addr[addrlen] != 0x00)
{
return false;
}
@@ -138,244 +85,44 @@ static bool sixlowpan_addrnull(FAR uint8_t *addr)
return true;
}
-
/****************************************************************************
- * Name: sixlowpan_fieldlengths
+ * Name: sixlowpan_saddrnull
*
* Description:
- * Return the lengths associated fields of the IEEE802.15.4 header.
+ * If the destination address is all zero in the MAC header buf, then it is
+ * broadcast on the 802.15.4 network.
*
* Input parameters:
- * finfo - IEEE802.15.4 header info (input)
- * flen - Field length info (output)
+ * eaddr - The short address to check
*
* Returned Value:
- * None
+ * The address length associated with the address mode.
*
****************************************************************************/
-static void sixlowpan_fieldlengths(FAR struct frame802154_s *finfo,
- FAR struct field_length_s *flen)
+static inline bool sixlowpan_saddrnull(FAR const uint8_t *saddr)
{
- /* Initialize to all zero */
-
- memset(flen, 0, sizeof(struct field_length_s));
-
- /* Determine lengths of each field based on fcf and other args */
-
- if ((finfo->fcf.dest_addr_mode & 3) != 0)
- {
- flen->dest_pid_len = 2;
- }
-
- if ((finfo->fcf.src_addr_mode & 3) != 0)
- {
- flen->src_pid_len = 2;
- }
-
- /* Set PAN ID compression bit if src pan id matches dest pan id. */
-
- if ((finfo->fcf.dest_addr_mode & 3) != 0 &&
- (finfo->fcf.src_addr_mode & 3) != 0 &&
- finfo->src_pid == finfo->dest_pid)
- {
- /* Indicate source PANID compression */
-
- finfo->fcf.panid_compression = 1;
-
- /* Compressed header, only do dest pid.
- *
- * REVISIT: This was commented out in corresponding Contiki logic, but
- * is needed to match sixlowpan_recv_hdrlen().
- */
-
- flen->src_pid_len = 0;
- }
-
- /* Determine address lengths */
-
- flen->dest_addr_len = sixlowpan_addrlen(finfo->fcf.dest_addr_mode & 3);
- flen->src_addr_len = sixlowpan_addrlen(finfo->fcf.src_addr_mode & 3);
-
- /* Aux security header */
-
-#if 0 /* TODO Aux security header not yet implemented */
- if ((finfo->fcf.security_enabled & 1) != 0)
- {
- switch(finfo->aux_hdr.security_control.key_id_mode)
- {
- case 0:
- flen->aux_sec_len = 5; /* Minimum value */
- break;
-
- case 1:
- flen->aux_sec_len = 6;
- break;
-
- case 2:
- flen->aux_sec_len = 10;
- break;
-
- case 3:
- flen->aux_sec_len = 14;
- break;
-
- default:
- break;
- }
- }
-#endif
+ return sixlowpan_anyaddrnull(saddr, NET_6LOWPAN_SADDRSIZE);
}
/****************************************************************************
- * Name: sixlowpan_fieldlengths
+ * Name: sixlowpan_eaddrnull
*
* Description:
- * Return the lengths associated fields of the IEEE802.15.4 header.
+ * If the destination address is all zero in the MAC header buf, then it is
+ * broadcast on the 802.15.4 network.
*
* Input parameters:
- * finfo - IEEE802.15.4 header info (input)
- * flen - Field length info (output)
+ * eaddr - The extended address to check
*
* Returned Value:
- * None
+ * The address length associated with the address mode.
*
****************************************************************************/
-static int sixlowpan_flen_hdrlen(FAR const struct field_length_s *flen)
+static inline bool sixlowpan_eaddrnull(FAR const uint8_t *eaddr)
{
- return 3 + flen->dest_pid_len + flen->dest_addr_len +
- flen->src_pid_len + flen->src_addr_len + flen->aux_sec_len;
-}
-
-/****************************************************************************
- * Name: sixlowpan_802154_hdrlen
- *
- * Description:
- * Calculates the length of the frame header. This function is meant to
- * be called by a higher level function, that interfaces to a MAC.
- *
- * Input parameters:
- * finfo - IEEE802.15.4 header info that specifies the frame to send.
- *
- * Returned Value:
- * The length of the frame header.
- *
- ****************************************************************************/
-
-static int sixlowpan_802154_hdrlen(FAR struct frame802154_s *finfo)
-{
- struct field_length_s flen;
-
- sixlowpan_fieldlengths(finfo, &flen);
- return sixlowpan_flen_hdrlen(&flen);
-}
-
-/****************************************************************************
- * Name: sixlowpan_setup_params
- *
- * Description:
- * Configure frame parmeters structure.
- *
- * Input parameters:
- * ieee - A reference IEEE802.15.4 MAC network device structure.
- * iob - The IOB in which to create the frame.
- * dest_panid - PAN ID of the destination. May be 0xffff if the destination
- * is not associated.
- * params - Where to put the parmeters
- *
- * Returned Value:
- * None.
- *
- ****************************************************************************/
-
-static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
- uint16_t dest_panid,
- FAR struct frame802154_s *params)
-{
- bool rcvrnull;
-
- /* Initialize all prameters to all zero */
-
- memset(params, 0, sizeof(params));
-
- /* Build the FCF (Only non-zero elements need to be initialized). */
-
- params->fcf.frame_type = FRAME802154_DATAFRAME;
- params->fcf.frame_pending = g_pktattrs[PACKETBUF_ATTR_PENDING];
-
- /* If the output address is NULL in the Rime buf, then it is broadcast
- * on the 802.15.4 network.
- */
-
- rcvrnull = sixlowpan_addrnull(g_pktaddrs[PACKETBUF_ADDR_RECEIVER].u8);
- if (rcvrnull)
- {
- params->fcf.ack_required = g_pktattrs[PACKETBUF_ATTR_MAC_ACK];
- }
-
- /* Insert IEEE 802.15.4 (2003) version bit. */
-
- params->fcf.frame_version = FRAME802154_IEEE802154_2003;
-
- /* Increment and set the data sequence number. */
-
- if (g_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] != 0)
- {
- params->seq = g_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] & 0xff;
- }
- else
- {
- params->seq = ieee->i_dsn++;
- g_pktattrs[PACKETBUF_ATTR_MAC_SEQNO] = params->seq | 0x100;
- }
-
- /* Complete the addressing fields. */
- /* Set the source and destination PAN ID. */
-
- params->src_pid = ieee->i_panid;
- params->dest_pid = dest_panid;
-
- /* If the output address is NULL in the Rime buf, then it is broadcast
- * on the 802.15.4 network.
- */
-
- if (rcvrnull)
- {
- /* Broadcast requires short address mode. */
-
- params->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
- params->dest_addr[0] = 0xff;
- params->dest_addr[1] = 0xff;
- }
- else
- {
- /* Copy the destination address */
-
- rimeaddr_copy((struct rimeaddr_s *)¶ms->dest_addr,
- g_pktaddrs[PACKETBUF_ADDR_RECEIVER].u8);
-
- /* Use short destination address mode if so configured */
-
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
- params->fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
-#else
- params->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
-#endif
- }
-
- /* Set the source address to the node address assigned to the device */
-
- rimeaddr_copy((struct rimeaddr_s *)¶ms->src_addr,
- &ieee->i_dev.d_mac.ieee802154);
-
- /* Use short soruce address mode if so configured */
-
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
- params->fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
-#else
- params->fcf.src_addr_mode = FRAME802154_SHORTADDRMODE;
-#endif
+ return sixlowpan_anyaddrnull(eaddr, NET_6LOWPAN_EADDRSIZE);
}
/****************************************************************************
@@ -383,7 +130,115 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
****************************************************************************/
/****************************************************************************
- * Name: sixlowpan_send_hdrlen
+ * Name: sixlowpan_meta_data
+ *
+ * Description:
+ * Based on the collected attributes and addresses, construct the MAC meta
+ * data structure that we need to interface with the IEEE802.15.4 MAC.
+ *
+ * Input Parameters:
+ * ieee - IEEE 802.15.4 MAC driver state reference.
+ * pktmeta - Meta-data specific to the current outgoing frame
+ * meta - Location to return the corresponding meta data.
+ * paylen - The size of the data payload to be sent.
+ *
+ * Returned Value:
+ * Ok is returned on success; Othewise a negated errno value is returned.
+ *
+ * Assumptions:
+ * Called with the network locked.
+ *
+ ****************************************************************************/
+
+int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee,
+ FAR const struct packet_metadata_s *pktmeta,
+ FAR struct ieee802154_frame_meta_s *meta,
+ uint16_t paylen)
+{
+ bool rcvrnull;
+
+ /* Initialize all settings to all zero */
+
+ memset(meta, 0, sizeof(struct ieee802154_frame_meta_s));
+
+ /* Source address mode */
+
+ meta->src_addr_mode = pktmeta->sextended != 0?
+ IEEE802154_ADDRMODE_EXTENDED :
+ IEEE802154_ADDRMODE_SHORT;
+
+ /* Check for a broadcast destination address (all zero) */
+
+ if (pktmeta->dextended != 0)
+ {
+ /* Extended destination address mode */
+
+ rcvrnull = sixlowpan_eaddrnull(pktmeta->dest.eaddr.u8);
+ }
+ else
+ {
+ /* Short destination address mode */
+
+ rcvrnull = sixlowpan_saddrnull(pktmeta->dest.saddr.u8);
+ }
+
+ if (rcvrnull)
+ {
+ meta->msdu_flags.ack_tx = TRUE;
+ }
+
+ /* Destination address */
+
+ /* If the output address is NULL, then it is broadcast on the 802.15.4
+ * network.
+ */
+
+ if (rcvrnull)
+ {
+ /* Broadcast requires short address mode. */
+
+ meta->dest_addr.mode = IEEE802154_ADDRMODE_SHORT;
+ meta->dest_addr.saddr = 0;
+ }
+ else if (pktmeta->dextended != 0)
+ {
+ /* Extended destination address mode */
+
+ meta->dest_addr.mode = IEEE802154_ADDRMODE_EXTENDED;
+ sixlowpan_eaddrcopy(&meta->dest_addr.eaddr, pktmeta->dest.eaddr.u8);
+ }
+ else
+ {
+ /* Short destination address mode */
+
+ meta->dest_addr.mode = IEEE802154_ADDRMODE_SHORT;
+ sixlowpan_saddrcopy(&meta->dest_addr.saddr, pktmeta->dest.saddr.u8);
+ }
+
+ meta->dest_addr.panid = pktmeta->dpanid;
+
+ /* Handle associated with MSDU. Will increment once per packet, not
+ * necesarily per frame: The same MSDU handle will be used for each
+ * fragment of a disassembled packet.
+ */
+
+ meta->msdu_handle = ieee->i_msdu_handle++;
+
+#ifdef CONFIG_IEEE802154_SECURITY
+# warning CONFIG_IEEE802154_SECURITY not yet supported
+#endif
+
+#ifdef CONFIG_IEEE802154_UWB
+# warning CONFIG_IEEE802154_UWB not yet supported
+#endif
+
+ /* Ranging left zero */
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: sixlowpan_frame_hdrlen
*
* Description:
* This function is before the first frame has been sent in order to
@@ -391,9 +246,8 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
* buffer is required to make this determination.
*
* Input parameters:
- * ieee - A reference IEEE802.15.4 MAC network device structure.
- * dest_panid - PAN ID of the destination. May be 0xffff if the destination
- * is not associated.
+ * ieee - A reference IEEE802.15.4 MAC network device structure.
+ * meta - Meta data that describes the MAC header
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
@@ -401,171 +255,37 @@ static void sixlowpan_setup_params(FAR struct ieee802154_driver_s *ieee,
*
****************************************************************************/
-int sixlowpan_send_hdrlen(FAR struct ieee802154_driver_s *ieee,
- uint16_t dest_panid)
+int sixlowpan_frame_hdrlen(FAR struct ieee802154_driver_s *ieee,
+ FAR const struct ieee802154_frame_meta_s *meta)
{
- struct frame802154_s params;
-
- /* Set up the frame parameters */
-
- sixlowpan_setup_params(ieee, dest_panid, ¶ms);
-
- /* Return the length of the header */
-
- return sixlowpan_802154_hdrlen(¶ms);
+ return ieee->i_get_mhrlen(ieee, meta);
}
/****************************************************************************
- * Name: sixlowpan_802154_framecreate
- *
- * Description:
- * Creates a frame for transmission over the air. This function is meant
- * to be called by a higher level function, that interfaces to a MAC.
- *
- * Input parameters:
- * finfo - Pointer to struct EEE802.15.4 header structure that specifies
- * the frame to send.
- * buf - Pointer to the buffer to use for the frame.
- * buflen - The length of the buffer to use for the frame.
- * finfo - Specifies the frame to send.
- *
- * Returned Value:
- * The length of the frame header or 0 if there was insufficient space in
- * the buffer for the frame headers.
- *
- ****************************************************************************/
-
-int sixlowpan_802154_framecreate(FAR struct frame802154_s *finfo,
- FAR uint8_t *buf, int buflen)
-{
- struct field_length_s flen;
- uint8_t pos;
- int hdrlen;
- int i;
-
- sixlowpan_fieldlengths(finfo, &flen);
-
- hdrlen = sixlowpan_flen_hdrlen(&flen);
- if (hdrlen > buflen)
- {
- /* Too little space for headers. */
-
- return 0;
- }
-
- /* OK, now we have field lengths. Time to actually construct the outgoing
- * frame, and store it in the provided buffer
- */
-
- buf[0] = ((finfo->fcf.frame_type & 7) << FRAME802154_FRAMETYPE_SHIFT) |
- ((finfo->fcf.security_enabled & 1) << FRAME802154_SECENABLED_SHIFT) |
- ((finfo->fcf.frame_pending & 1) << FRAME802154_FRAMEPENDING_SHIFT) |
- ((finfo->fcf.ack_required & 1) << FRAME802154_ACKREQUEST_SHIFT) |
- ((finfo->fcf.panid_compression & 1) << FRAME802154_PANIDCOMP_SHIFT);
- buf[1] = ((finfo->fcf.dest_addr_mode & 3) << FRAME802154_DSTADDR_SHIFT) |
- ((finfo->fcf.frame_version & 3) << FRAME802154_VERSION_SHIFT) |
- ((finfo->fcf.src_addr_mode & 3) << FRAME802154_SRCADDR_SHIFT);
-
- /* Sequence number */
-
- buf[2] = finfo->seq;
- pos = 3;
-
- /* Destination PAN ID */
-
- if (flen.dest_pid_len == 2)
- {
- buf[pos++] = finfo->dest_pid & 0xff;
- buf[pos++] = (finfo->dest_pid >> 8) & 0xff;
- }
-
- /* Destination address */
-
- for (i = flen.dest_addr_len; i > 0; i--)
- {
- buf[pos++] = finfo->dest_addr[i - 1];
- }
-
- /* Source PAN ID */
-
- if (flen.src_pid_len == 2)
- {
- buf[pos++] = finfo->src_pid & 0xff;
- buf[pos++] = (finfo->src_pid >> 8) & 0xff;
- }
-
- /* Source address */
-
- for (i = flen.src_addr_len; i > 0; i--)
- {
- buf[pos++] = finfo->src_addr[i - 1];
- }
-
- /* Aux header */
-
-#if 0 /* TODO Aux security header not yet implemented */
- if (flen.aux_sec_len)
- {
- pos += flen.aux_sec_len;
- }
-#endif
-
- DEBUGASSERT(pos == hdrlen);
- return (int)pos;
-}
-
-/****************************************************************************
- * Name: sixlowpan_framecreate
+ * Name: sixlowpan_frame_submit
*
* Description:
* This function is called after eiether (1) the IEEE802.15.4 MAC driver
- * polls for TX data or (2) after the IEEE802.15.4 MAC driver provides an
- * in frame and the network responds with an outgoing packet. It creates
- * the IEEE802.15.4 header in the frame buffer.
+ * polls for TX data or (2) after the IEEE802.15.4 MAC driver provides a
+ * new incoming frame and the network responds with an outgoing packet. It
+ * submits any new outgoing frame to the MAC.
*
* Input parameters:
- * ieee - A reference IEEE802.15.4 MAC network device structure.
- * iob - The IOB in which to create the frame.
- * dest_panid - PAN ID of the destination. May be 0xffff if the destination
- * is not associated.
+ * ieee - A reference IEEE802.15.4 MAC network device structure.
+ * meta - Meta data that describes the MAC header
+ * frame - The IOB containing the frame to be submitted.
*
* Returned Value:
- * The frame header length is returnd on success; otherwise, a negated
- * errno value is return on failure.
+ * Zero (OK) is returned on success; otherwise, a negated errno value is
+ * return on any failure.
*
****************************************************************************/
-int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
- FAR struct iob_s *iob, uint16_t dest_panid)
+int sixlowpan_frame_submit(FAR struct ieee802154_driver_s *ieee,
+ FAR const struct ieee802154_frame_meta_s *meta,
+ FAR struct iob_s *frame)
{
- struct frame802154_s params;
- int hdrlen;
-
- /* Set up the frame parameters */
-
- sixlowpan_setup_params(ieee, dest_panid, ¶ms);
-
- /* Get the length of the header */
-
- hdrlen = sixlowpan_802154_hdrlen(¶ms);
-
- /* Then create the frame */
-
- sixlowpan_802154_framecreate(¶ms, iob->io_data, hdrlen);
-
- wlinfo("Frame type: %02x hdrlen: %d\n",
- params.fcf.frame_type, hdrlen);
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
- wlinfo("Dest address: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
- params.dest_addr[0], params.dest_addr[1], params.dest_addr[2],
- params.dest_addr[3], params.dest_addr[4], params.dest_addr[5],
- params.dest_addr[6], params.dest_addr[7]);
-#else
- wlinfo("Dest address: %02x:%02x\n",
- params.dest_addr[0], params.dest_addr[1]);
-#endif
-
- return hdrlen;
+ return ieee->i_req_data(ieee, meta, frame);
}
#endif /* CONFIG_NET_6LOWPAN */
diff --git a/net/sixlowpan/sixlowpan_globals.c b/net/sixlowpan/sixlowpan_globals.c
index aac17f7eb9c..6d52082df18 100644
--- a/net/sixlowpan/sixlowpan_globals.c
+++ b/net/sixlowpan/sixlowpan_globals.c
@@ -67,9 +67,4 @@ uint8_t g_uncomp_hdrlen;
uint8_t g_frame_hdrlen;
-/* Packet buffer metadata: Attributes and addresses */
-
-uint16_t g_pktattrs[PACKETBUF_NUM_ATTRS];
-struct rimeaddr_s g_pktaddrs[PACKETBUF_NUM_ADDRS];
-
#endif /* CONFIG_NET_6LOWPAN */
diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c
index a2ceb53cb65..4de177e0a83 100644
--- a/net/sixlowpan/sixlowpan_hc06.c
+++ b/net/sixlowpan/sixlowpan_hc06.c
@@ -220,7 +220,7 @@ static FAR struct sixlowpan_addrcontext_s *
}
/****************************************************************************
- * Name: compress_addr_64
+ * Name: comporess_ipaddr, compress_tagaddr, and compress_laddr
*
* Description:
* Uncompress addresses based on a prefix and a postfix with zeroes in
@@ -230,20 +230,16 @@ static FAR struct sixlowpan_addrcontext_s *
* prefpost takes a byte where the first nibble specify prefix count
* and the second postfix count (NOTE: 15/0xf => 16 bytes copy).
*
+ * compress_tagaddr() accepts a remote, variable length, taged MAC address;
+ * compress_laddr() accepts a local, fixed length MAC address.
+ * compress_ipaddr() is simply the common logic that does not depend on
+ * the size of the MAC address.
+ *
****************************************************************************/
-static uint8_t compress_addr_64(FAR const net_ipv6addr_t ipaddr,
- FAR const struct rimeaddr_s *macaddr,
- uint8_t bitpos)
+static uint8_t compress_ipaddr(FAR const net_ipv6addr_t ipaddr, uint8_t bitpos)
{
- ninfo("ipaddr=%p macaddr=%p bitpos=%u g_hc06ptr=%p\n",
- ipaddr, macaddr, bitpos, g_hc06ptr);
-
- if (sixlowpan_ismacbased(ipaddr, macaddr))
- {
- return 3 << bitpos; /* 0-bits */
- }
- else if (SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(ipaddr))
+ if (SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(ipaddr))
{
/* Compress IID to 16 bits: xxxx:xxxx:xxxx:xxxx:0000:00ff:fe00:XXXX */
@@ -261,6 +257,40 @@ static uint8_t compress_addr_64(FAR const net_ipv6addr_t ipaddr,
}
}
+static uint8_t compress_tagaddr(FAR const net_ipv6addr_t ipaddr,
+ FAR const struct sixlowpan_tagaddr_s *macaddr,
+ uint8_t bitpos)
+{
+ ninfo("ipaddr=%p macaddr=%p extended=%u bitpos=%u g_hc06ptr=%p\n",
+ ipaddr, macaddr, macaddr->extended, bitpos, g_hc06ptr);
+
+ if (sixlowpan_ismacbased(ipaddr, macaddr))
+ {
+ return 3 << bitpos; /* 0-bits */
+ }
+ else
+ {
+ return compress_ipaddr(ipaddr, bitpos);
+ }
+}
+
+static uint8_t compress_laddr(FAR const net_ipv6addr_t ipaddr,
+ FAR const struct sixlowpan_addr_s *macaddr,
+ uint8_t bitpos)
+{
+ ninfo("ipaddr=%p macaddr=%p bitpos=%u g_hc06ptr=%p\n",
+ ipaddr, macaddr, bitpos, g_hc06ptr);
+
+ if (sixlowpan_isaddrbased(ipaddr, macaddr))
+ {
+ return 3 << bitpos; /* 0-bits */
+ }
+ else
+ {
+ return compress_ipaddr(ipaddr, bitpos);
+ }
+}
+
/****************************************************************************
* Name: uncompress_addr
*
@@ -275,7 +305,7 @@ static uint8_t compress_addr_64(FAR const net_ipv6addr_t ipaddr,
****************************************************************************/
static void uncompress_addr(FAR net_ipv6addr_t ipaddr, uint8_t const prefix[],
- uint8_t prefpost, FAR struct rimeaddr_s *macaddr)
+ uint8_t prefpost)
{
uint8_t prefcount = prefpost >> 4;
uint8_t postcount = prefpost & 0x0f;
@@ -316,7 +346,7 @@ static void uncompress_addr(FAR net_ipv6addr_t ipaddr, uint8_t const prefix[],
{
/* No IID based configuration if no prefix and no data => unspec */
- sixlowpan_ipfromrime(macaddr, ipaddr);
+ nwarn("WARNING: No IID based configuration\n");
}
ninfo("Uncompressing %d + %d => %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
@@ -446,7 +476,7 @@ void sixlowpan_hc06_initialize(void)
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6,
- FAR const struct rimeaddr_s *destmac,
+ FAR const struct sixlowpan_tagaddr_s *destmac,
FAR uint8_t *fptr)
{
FAR uint8_t *iphc = fptr + g_frame_hdrlen;
@@ -614,9 +644,9 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
/* Compression compare with this nodes address (source) */
- iphc1 |= compress_addr_64(ipv6->srcipaddr,
- &ieee->i_dev.d_mac.ieee802154,
- SIXLOWPAN_IPHC_SAM_BIT);
+ iphc1 |= compress_laddr(ipv6->srcipaddr,
+ &ieee->i_dev.d_mac.ieee802154,
+ SIXLOWPAN_IPHC_SAM_BIT);
}
/* No address context found for this address */
@@ -625,7 +655,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
ipv6->destipaddr[1] == 0 && ipv6->destipaddr[2] == 0 &&
ipv6->destipaddr[3] == 0)
{
- iphc1 |= compress_addr_64(ipv6->srcipaddr,
+ iphc1 |= compress_laddr(ipv6->srcipaddr,
&ieee->i_dev.d_mac.ieee802154,
SIXLOWPAN_IPHC_SAM_BIT);
}
@@ -701,7 +731,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
/* Compession compare with link adress (destination) */
- iphc1 |= compress_addr_64(ipv6->destipaddr, destmac,
+ iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac,
SIXLOWPAN_IPHC_DAM_BIT);
/* No address context found for this address */
@@ -710,7 +740,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
ipv6->destipaddr[1] == 0 && ipv6->destipaddr[2] == 0 &&
ipv6->destipaddr[3] == 0)
{
- iphc1 |= compress_addr_64(ipv6->destipaddr, destmac,
+ iphc1 |= compress_tagaddr(ipv6->destipaddr, destmac,
SIXLOWPAN_IPHC_DAM_BIT);
}
else
@@ -828,8 +858,8 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
* sixlowpan_buf
*
* This function is called by the input function when the dispatch is HC06.
- * We process the packet in the rime buffer, uncompress the header fields,
- * and copy the result in the sixlowpan buffer. At the end of the
+ * We process the frame in the IOB buffer, uncompress the header fields,
+ * and copy the result into the driver packet buffer. At the end of the
* decompression, g_frame_hdrlen and g_uncompressed_hdrlen are set to the
* appropriate values
*
@@ -983,18 +1013,22 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
}
}
- /* If tmp == 0 we do not have a Address context and therefore no prefix */
+ /* If tmp == 0 we do not have a address context and therefore no prefix */
+ /* REVISIT: Source address may not be the same size as the destination
+ * address.
+ */
uncompress_addr(ipv6->srcipaddr,
- tmp != 0 ? addrcontext->prefix : NULL, g_unc_ctxconf[tmp],
- (FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_SENDER]);
+ tmp != 0 ? addrcontext->prefix : NULL, g_unc_ctxconf[tmp]);
}
else
{
/* No compression and link local */
+ /* REVISIT: Source address may not be the same size as the destination
+ * address.
+ */
- uncompress_addr(ipv6->srcipaddr, g_llprefix, g_unc_llconf[tmp],
- (FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_SENDER]);
+ uncompress_addr(ipv6->srcipaddr, g_llprefix, g_unc_llconf[tmp]);
}
/* Destination address */
@@ -1029,7 +1063,7 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
g_hc06ptr++;
}
- uncompress_addr(ipv6->destipaddr, prefix, g_unc_mxconf[tmp], NULL);
+ uncompress_addr(ipv6->destipaddr, prefix, g_unc_mxconf[tmp]);
}
}
else
@@ -1052,15 +1086,13 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
return;
}
- uncompress_addr(ipv6->destipaddr, addrcontext->prefix, g_unc_ctxconf[tmp],
- (FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_RECEIVER]);
+ uncompress_addr(ipv6->destipaddr, addrcontext->prefix, g_unc_ctxconf[tmp]);
}
else
{
/* Not address context based => link local M = 0, DAC = 0 - same as SAC */
- uncompress_addr(ipv6->destipaddr, g_llprefix, g_unc_llconf[tmp],
- (FAR struct rimeaddr_s *)&g_pktaddrs[PACKETBUF_ADDR_RECEIVER]);
+ uncompress_addr(ipv6->destipaddr, g_llprefix, g_unc_llconf[tmp]);
}
}
diff --git a/net/sixlowpan/sixlowpan_hc1.c b/net/sixlowpan/sixlowpan_hc1.c
index 3696c4a34f7..c6b2f4a1379 100644
--- a/net/sixlowpan/sixlowpan_hc1.c
+++ b/net/sixlowpan/sixlowpan_hc1.c
@@ -120,7 +120,7 @@
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6,
- FAR const struct rimeaddr_s *destmac,
+ FAR const struct sixlowpan_tagaddr_s *destmac,
FAR uint8_t *fptr)
{
FAR uint8_t *hc1 = fptr + g_frame_hdrlen;
@@ -129,7 +129,7 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
if (ipv6->vtc != 0x60 || ipv6->tcf != 0 || ipv6->flow != 0 ||
!sixlowpan_islinklocal(ipv6->srcipaddr) ||
- !sixlowpan_ismacbased(ipv6->srcipaddr, &ieee->i_dev.d_mac.ieee802154) ||
+ !sixlowpan_isaddrbased(ipv6->srcipaddr, &ieee->i_dev.d_mac.ieee802154) ||
!sixlowpan_islinklocal(ipv6->destipaddr) ||
!sixlowpan_ismacbased(ipv6->destipaddr, destmac) ||
(ipv6->proto != IP_PROTO_ICMP6 && ipv6->proto != IP_PROTO_UDP &&
@@ -137,12 +137,12 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
{
/* IPV6 DISPATCH
* Something cannot be compressed, use IPV6 DISPATCH, compress
- * nothing, copy IPv6 header in rime buffer
+ * nothing, copy IPv6 header into the frame buffer
*/
/* IPv6 dispatch header (1 byte) */
- hc1[RIME_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_IPV6;
+ hc1[SIXLOWPAN_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_IPV6;
g_frame_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
memcpy(fptr + g_frame_hdrlen, ipv6, IPv6_HDRLEN);
@@ -156,15 +156,15 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
* header is UDP, we compress UDP header using HC2
*/
- hc1[RIME_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_HC1;
+ hc1[SIXLOWPAN_HC1_DISPATCH] = SIXLOWPAN_DISPATCH_HC1;
g_uncomp_hdrlen += IPv6_HDRLEN;
switch (ipv6->proto)
{
case IP_PROTO_ICMP6:
/* HC1 encoding and ttl */
- hc1[RIME_HC1_ENCODING] = 0xfc;
- hc1[RIME_HC1_TTL] = ipv6->ttl;
+ hc1[SIXLOWPAN_HC1_ENCODING] = 0xfc;
+ hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl;
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
@@ -172,8 +172,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
case IP_PROTO_TCP:
/* HC1 encoding and ttl */
- hc1[RIME_HC1_ENCODING] = 0xfe;
- hc1[RIME_HC1_TTL] = ipv6->ttl;
+ hc1[SIXLOWPAN_HC1_ENCODING] = 0xfe;
+ hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl;
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#endif /* CONFIG_NET_TCP */
@@ -201,17 +201,17 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
/* HC1 encoding */
- hcudp[RIME_HC1_HC_UDP_HC1_ENCODING] = 0xfb;
+ hcudp[SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING] = 0xfb;
/* HC_UDP encoding, ttl, src and dest ports, checksum */
- hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] = 0xe0;
- hcudp[RIME_HC1_HC_UDP_TTL] = ipv6->ttl;
- hcudp[RIME_HC1_HC_UDP_PORTS] =
+ hcudp[SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING] = 0xe0;
+ hcudp[SIXLOWPAN_HC1_HC_UDP_TTL] = ipv6->ttl;
+ hcudp[SIXLOWPAN_HC1_HC_UDP_PORTS] =
(uint8_t)((ntohs(udp->srcport) - CONFIG_NET_6LOWPAN_MINPORT) << 4) +
(uint8_t)((ntohs(udp->destport) - CONFIG_NET_6LOWPAN_MINPORT));
- memcpy(&hcudp[RIME_HC1_HC_UDP_CHKSUM], &udp->udpchksum, 2);
+ memcpy(&hcudp[SIXLOWPAN_HC1_HC_UDP_CHKSUM], &udp->udpchksum, 2);
g_frame_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
g_uncomp_hdrlen += UDP_HDRLEN;
@@ -220,8 +220,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
{
/* HC1 encoding and ttl */
- hc1[RIME_HC1_ENCODING] = 0xfa;
- hc1[RIME_HC1_TTL] = ipv6->ttl;
+ hc1[SIXLOWPAN_HC1_ENCODING] = 0xfa;
+ hc1[SIXLOWPAN_HC1_TTL] = ipv6->ttl;
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
}
}
@@ -238,8 +238,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
* Uncompress HC1 (and HC_UDP) headers and put them in sixlowpan_buf
*
* This function is called by the input function when the dispatch is
- * HC1. It processes the packet in the rime buffer, uncompresses the
- * header fields, and copies the result in the sixlowpan buffer. At the
+ * HC1. It processes the frame in the IOB buffer, uncompresses the
+ * header fields, and copies the result in the packet buffer. At the
* end of the decompression, g_frame_hdrlen and uncompressed_hdr_len
* are set to the appropriate values
*
@@ -271,30 +271,22 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
ipv6->tcf = 0; /* Bits 0-3: traffic class (LS), 4-bits: flow label (MS) */
ipv6->flow = 0; /* 16-bit flow label (LS) */
- /* Use stateless auto-configuration to set source and destination IP
- * addresses.
- */
-
- sixlowpan_ipfromrime(&g_pktaddrs[PACKETBUF_ADDR_SENDER],
- ipv6->srcipaddr);
- sixlowpan_ipfromrime(&g_pktaddrs[PACKETBUF_ADDR_RECEIVER],
- ipv6->destipaddr);
g_uncomp_hdrlen += IPv6_HDRLEN;
/* len[], proto, and ttl depend on the encoding */
- switch (hc1[RIME_HC1_ENCODING] & 0x06)
+ switch (hc1[SIXLOWPAN_HC1_ENCODING] & 0x06)
{
case SIXLOWPAN_HC1_NH_ICMP6:
ipv6->proto = IP_PROTO_ICMP6;
- ipv6->ttl = hc1[RIME_HC1_TTL];
+ ipv6->ttl = hc1[SIXLOWPAN_HC1_TTL];
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#if CONFIG_NET_TCP
case SIXLOWPAN_HC1_NH_TCP:
ipv6->proto = IP_PROTO_TCP;
- ipv6->ttl = hc1[RIME_HC1_TTL];
+ ipv6->ttl = hc1[SIXLOWPAN_HC1_TTL];
g_frame_hdrlen += SIXLOWPAN_HC1_HDR_LEN;
break;
#endif /* CONFIG_NET_TCP */
@@ -306,11 +298,11 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
FAR uint8_t *hcudp = fptr + g_frame_hdrlen;
ipv6->proto = IP_PROTO_UDP;
- if ((hcudp[RIME_HC1_HC_UDP_HC1_ENCODING] & 0x01) != 0)
+ if ((hcudp[SIXLOWPAN_HC1_HC_UDP_HC1_ENCODING] & 0x01) != 0)
{
/* UDP header is compressed with HC_UDP */
- if (hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] !=
+ if (hcudp[SIXLOWPAN_HC1_HC_UDP_UDP_ENCODING] !=
SIXLOWPAN_HC_UDP_ALL_C)
{
nwarn("WARNING: sixlowpan (uncompress_hdr), packet not supported");
@@ -319,16 +311,16 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
/* IP TTL */
- ipv6->ttl = hcudp[RIME_HC1_HC_UDP_TTL];
+ ipv6->ttl = hcudp[SIXLOWPAN_HC1_HC_UDP_TTL];
/* UDP ports, len, checksum */
udp->srcport =
- htons(CONFIG_NET_6LOWPAN_MINPORT + (hcudp[RIME_HC1_HC_UDP_PORTS] >> 4));
+ htons(CONFIG_NET_6LOWPAN_MINPORT + (hcudp[SIXLOWPAN_HC1_HC_UDP_PORTS] >> 4));
udp->destport =
- htons(CONFIG_NET_6LOWPAN_MINPORT + (hcudp[RIME_HC1_HC_UDP_PORTS] & 0x0F));
+ htons(CONFIG_NET_6LOWPAN_MINPORT + (hcudp[SIXLOWPAN_HC1_HC_UDP_PORTS] & 0x0F));
- memcpy(&udp->udpchksum, &hcudp[RIME_HC1_HC_UDP_CHKSUM], 2);
+ memcpy(&udp->udpchksum, &hcudp[SIXLOWPAN_HC1_HC_UDP_CHKSUM], 2);
g_uncomp_hdrlen += UDP_HDRLEN;
g_frame_hdrlen += SIXLOWPAN_HC1_HC_UDP_HDR_LEN;
diff --git a/net/sixlowpan/sixlowpan_input.c b/net/sixlowpan/sixlowpan_input.c
index bccd97677b7..9739ab7f610 100644
--- a/net/sixlowpan/sixlowpan_input.c
+++ b/net/sixlowpan/sixlowpan_input.c
@@ -61,6 +61,7 @@
#include "nuttx/net/netdev.h"
#include "nuttx/net/ip.h"
#include "nuttx/net/sixlowpan.h"
+#include "nuttx/wireless/ieee802154/ieee802154_mac.h"
#ifdef CONFIG_NET_PKT
# include "pkt/pkt.h"
@@ -130,89 +131,52 @@ static uint8_t g_bitbucket[UNCOMP_MAXHDR];
****************************************************************************/
/****************************************************************************
- * Name: sixlowpan_recv_hdrlen
+ * Name: sixlowpan_compare_fragsrc
*
* Description:
- * Get the length of the IEEE802.15.4 FCF header on the received frame.
+ * Check if the fragment that we just received is from the same source as
+ * the previosly received fragements.
*
* Input Parameters:
- * ieee - The IEEE802.15.4 MAC network driver interface.
- * iob - The IOB containing the frame.
+ * ieee - IEEE 802.15.4 MAC driver state reference
+ * ind - Characteristics of the newly received frame
*
* Returned Value:
- * Ok is returned on success; Othewise a negated errno value is returned.
- *
- * Assumptions:
- * Network is locked
+ * true if the sources are the same.
*
****************************************************************************/
-int sixlowpan_recv_hdrlen(FAR const uint8_t *fptr)
+static bool sixlowpan_compare_fragsrc(FAR struct ieee802154_driver_s *ieee,
+ FAR const struct ieee802154_data_ind_s *ind)
{
- uint16_t hdrlen;
- uint8_t addrmode;
+ /* Check for an extended source address */
- /* Minimum header: 2 byte FCF + 1 byte sequence number */
-
- hdrlen = 3;
-
- /* Account for destination address size */
-
- addrmode = (fptr[1] & FRAME802154_DSTADDR_MASK) >> FRAME802154_DSTADDR_SHIFT;
- if (addrmode == FRAME802154_SHORTADDRMODE)
+ if (ind->src.mode == IEEE802154_ADDRMODE_EXTENDED)
{
- /* 2 byte dest PAN + 2 byte dest short address */
+ /* Was the first source address also extended? */
- hdrlen += 4;
- }
- else if (addrmode == FRAME802154_LONGADDRMODE)
- {
- /* 2 byte dest PAN + 8 byte dest long address */
+ if (ieee->i_fragsrc.extended)
+ {
+ /* Yes.. perform the extended address comparison */
- hdrlen += 10;
- }
- else if (addrmode != FRAME802154_NOADDR)
- {
- nwarn("WARNING: Unrecognized address mode\n");
-
- return -ENOSYS;
- }
- else if ((fptr[0] & (1 << FRAME802154_PANIDCOMP_SHIFT)) != 0)
- {
- nwarn("WARNING: PAN compression, but no destination address\n");
-
- return -EINVAL;
- }
-
- /* Account for source address size */
-
- addrmode = (fptr[1] & FRAME802154_SRCADDR_MASK) >> FRAME802154_SRCADDR_SHIFT;
- if (addrmode == FRAME802154_NOADDR)
- {
- return hdrlen;
+ return sixlowpan_eaddrcmp(ieee->i_fragsrc.u.eaddr.u8, ind->src.eaddr);
+ }
}
else
{
- /* Add source PANID if PANIDs are not compressed */
+ /* Short source address. Was the first source address also short? */
- if ((fptr[0] & (1 << FRAME802154_PANIDCOMP_SHIFT)) == 0)
+ if (!ieee->i_fragsrc.extended)
{
- hdrlen += 2;
- }
+ /* Yes.. perform the extended short comparison */
- /* Add the length of the source address */
-
- if (addrmode == FRAME802154_SHORTADDRMODE)
- {
- return hdrlen + 2;
- }
- else if (addrmode == FRAME802154_LONGADDRMODE)
- {
- return hdrlen + 8;
+ return sixlowpan_saddrcmp(ieee->i_fragsrc.u.saddr.u8, &ind->src.saddr);
}
}
- return 0;
+ /* Address are different size and, hence, cannot match */
+
+ return false;
}
/****************************************************************************
@@ -245,7 +209,7 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr, FAR uint8_t *bptr)
{
FAR struct ipv6_hdr_s *ipv6 = (FAR struct ipv6_hdr_s *)bptr;
uint16_t protosize;
-
+
/* Put uncompressed IPv6 header in d_buf. */
g_frame_hdrlen += SIXLOWPAN_IPV6_HDR_LEN;
@@ -321,6 +285,7 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr, FAR uint8_t *bptr)
*
* Input Parameters:
* ieee - The IEEE802.15.4 MAC network driver interface.
+ * ind - Meta data characterizing the received frame.
* iob - The IOB containing the frame.
*
* Returned Value:
@@ -332,6 +297,7 @@ static void sixlowpan_uncompress_ipv6hdr(FAR uint8_t *fptr, FAR uint8_t *bptr)
****************************************************************************/
static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
+ FAR const struct ieee802154_data_ind_s *ind,
FAR struct iob_s *iob)
{
FAR uint8_t *fptr; /* Convenience pointer to beginning of the frame */
@@ -355,8 +321,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
* This size includes both fragmentation and FCF headers.
*/
- fptr = iob->io_data;
- hdrsize = sixlowpan_recv_hdrlen(fptr);
+ fptr = iob->io_data; /* Frame data is in I/O buffer */
+ hdrsize = iob->io_offset; /* Offset past the MAC header */
if (hdrsize < 0)
{
nwarn("Invalid IEEE802.15.2 header: %d\n", hdrsize);
@@ -377,7 +343,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
*/
fragptr = fptr + hdrsize;
- switch ((GETINT16(fragptr, RIME_FRAG_DISPATCH_SIZE) & 0xf800) >> 8)
+ switch ((GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0xf800) >> 8)
{
/* First fragment of new reassembly */
@@ -385,8 +351,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
{
/* Set up for the reassembly */
- fragsize = GETINT16(fragptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
- fragtag = GETINT16(fragptr, RIME_FRAG_TAG);
+ fragsize = GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff;
+ fragtag = GETHOST16(fragptr, SIXLOWPAN_FRAG_TAG);
g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN;
ninfo("FRAG1: fragsize=%d fragtag=%d fragoffset=%d\n",
@@ -403,9 +369,9 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
{
/* Set offset, tag, size. Offset is in units of 8 bytes. */
- fragoffset = fragptr[RIME_FRAG_OFFSET];
- fragtag = GETINT16(fragptr, RIME_FRAG_TAG);
- fragsize = GETINT16(fragptr, RIME_FRAG_DISPATCH_SIZE) & 0x07ff;
+ fragoffset = fragptr[SIXLOWPAN_FRAG_OFFSET];
+ fragtag = GETHOST16(fragptr, SIXLOWPAN_FRAG_TAG);
+ fragsize = GETHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE) & 0x07ff;
g_frame_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN;
ninfo("FRAGN: fragsize=%d fragtag=%d fragoffset=%d\n",
@@ -487,8 +453,8 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
/* Verify that this fragment is part of that reassembly sequence */
- else if (fragsize != ieee->i_pktlen || ieee->i_reasstag != fragtag ||
- !rimeaddr_cmp(&ieee->i_fragsrc, &g_pktaddrs[PACKETBUF_ADDR_SENDER]))
+ else if (fragsize != ieee->i_pktlen || ieee->i_reasstag != fragtag ||
+ !sixlowpan_compare_fragsrc(ieee, ind))
{
/* The packet is a fragment that does not belong to the packet
* being reassembled or the packet is not a fragment.
@@ -540,7 +506,21 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
ninfo("Starting reassembly: i_pktlen %u, i_reasstag %d\n",
ieee->i_pktlen, ieee->i_reasstag);
- rimeaddr_copy(&ieee->i_fragsrc, &g_pktaddrs[PACKETBUF_ADDR_SENDER]);
+ /* Extract the source address from the 'ind' meta data. NOTE that the
+ * size of the source address may be different that our local, destination
+ * address.
+ */
+
+ if (ind->src.mode == IEEE802154_ADDRMODE_EXTENDED)
+ {
+ ieee->i_fragsrc.extended = true;
+ sixlowpan_eaddrcopy(ieee->i_fragsrc.u.eaddr.u8, ind->src.eaddr);
+ }
+ else
+ {
+ memset(&ieee->i_fragsrc, 0, sizeof(struct sixlowpan_tagaddr_s));
+ sixlowpan_saddrcopy(ieee->i_fragsrc.u.saddr.u8, &ind->src.saddr);
+ }
}
#endif /* CONFIG_NET_6LOWPAN_FRAG */
@@ -549,7 +529,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
hc1 = fptr + g_frame_hdrlen;
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
- if ((hc1[RIME_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC)
+ if ((hc1[SIXLOWPAN_HC1_DISPATCH] & SIXLOWPAN_DISPATCH_IPHC_MASK) == SIXLOWPAN_DISPATCH_IPHC)
{
ninfo("IPHC Dispatch\n");
sixlowpan_uncompresshdr_hc06(fragsize, iob, fptr, bptr);
@@ -558,7 +538,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC06 */
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
- if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_HC1)
+ if (hc1[SIXLOWPAN_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_HC1)
{
ninfo("HC1 Dispatch\n");
sixlowpan_uncompresshdr_hc1(fragsize, iob, fptr, bptr);
@@ -566,7 +546,7 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
else
#endif /* CONFIG_NET_6LOWPAN_COMPRESSION_HC1 */
- if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_IPV6)
+ if (hc1[SIXLOWPAN_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_IPV6)
{
ninfo("IPv6 Dispatch\n");
sixlowpan_uncompress_ipv6hdr(fptr, bptr);
@@ -575,14 +555,13 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
{
/* Unknown or unsupported header */
- nwarn("WARNING: Unknown dispatch: %u\n", hc1[RIME_HC1_DISPATCH]);
+ nwarn("WARNING: Unknown dispatch: %u\n", hc1[SIXLOWPAN_HC1_DISPATCH]);
return OK;
}
#ifdef CONFIG_NET_6LOWPAN_FRAG
/* Is this the first fragment is a sequence? */
-
if (isfirstfrag)
{
/* Yes.. Remember the offset from the beginning of d_buf where we
@@ -603,12 +582,14 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee,
g_uncomp_hdrlen = ieee->i_boffset;
}
+
+
#endif /* CONFIG_NET_6LOWPAN_FRAG */
- /* Copy "payload" from the rime buffer to the IEEE802.15.4 MAC driver's
- * d_buf. If this frame is a first fragment or not part of a fragmented
- * packet, we have already copied the compressed headers, g_uncomp_hdrlen
- * and g_frame_hdrlen are non-zerio, fragoffset is.
+ /* Copy "payload" from the frame buffer to the IEEE802.15.4 MAC driver's
+ * packet buffer, d_buf. If this frame is a first fragment or not part of
+ * a fragmented packet, we have already copied the compressed headers,
+ * g_uncomp_hdrlen and g_frame_hdrlen are non-zerio, fragoffset is.
*/
paysize = iob->io_len - g_frame_hdrlen;
@@ -729,25 +710,32 @@ static int sixlowpan_dispatch(FAR struct ieee802154_driver_s *ieee)
* Description:
* Process an incoming 6loWPAN frame.
*
- * This function is called when the device driver has received a 6loWPAN
- * frame from the network. The frame from the device driver must be
- * provided in a IOB present in the i_framelist: The frame data is in the
- * IOB io_data[] buffer and the length of the frame is in the IOB io_len
- * field. Only a single IOB is expected in the i_framelist. This incoming
- * data will be processed one frame at a time.
+ * This function is called when the device driver has received an
+ * IEEE802.15.4 frame from the network. The frame from the device
+ * driver must be provided in by the IOB frame argument of the
+ * function call:
*
- * An non-NULL d_buf of size CONFIG_NET_6LOWPAN_MTU must also be provided.
- * The frame will be decompressed and placed in the d_buf. Fragmented
- * packets will also be reassembled in the d_buf as they are received
- * (meaning for the driver, that two packet buffers are required: One for
- * reassembly of RX packets and one used for TX polling).
+ * - The frame data is in the IOB io_data[] buffer,
+ * - The length of the frame is in the IOB io_len field, and
+ * - The offset past the IEEE802.15.4 MAC header is provided in the
+ * io_offset field.
*
- * After each frame is processed into d_buf, the IOB is removed and
- * deallocated. i_framelist will be nullified. If reassembly is
- * incomplete, this function will return to called with i_framelist
- * equal to NULL. The partially reassembled packet must be preserved by
- * the IEEE802.15.4 MAC and provided again when the next frame is
- * received.
+ * The frame argument may refer to a single frame (a list of length one)
+ * or may it be the head of a list of multiple frames.
+ *
+ * - The io_flink field points to the next frame in the list (if enable)
+ * - The last frame in the list will have io_flink == NULL.
+ *
+ * An non-NULL d_buf of size CONFIG_NET_6LOWPAN_MTU + CONFIG_NET_GUARDSIZE
+ * must also be provided. The frame will be decompressed and placed in
+ * the d_buf. Fragmented packets will also be reassembled in the d_buf as
+ * they are received (meaning for the driver, that two packet buffers are
+ * required: One for reassembly of RX packets and one used for TX polling).
+ *
+ * After each frame is processed into d_buf, the IOB is deallocated. If
+ * reassembly is incomplete, the partially reassembled packet must be
+ * preserved by the IEEE802.15.4 MAC network drvier sand provided again
+ * when the next frame is received.
*
* When the packet in the d_buf is fully reassembled, it will be provided
* to the network as with any other received packet. d_len will be set
@@ -755,49 +743,52 @@ static int sixlowpan_dispatch(FAR struct ieee802154_driver_s *ieee)
*
* After the network processes the packet, d_len will be set to zero.
* Network logic may also decide to send a response to the packet. In
- * that case, the outgoing network packet will be placed in d_buf the
- * d_buf and d_len will be set to a non-zero value. That case is handled
- * by this function.
+ * that case, the outgoing network packet will be placed in d_buf and
+ * d_len will be set to a non-zero value. That case is handled by this
+ * function.
*
* If that case occurs, the packet will be converted to a list of
- * compressed and possibly fragmented frames in i_framelist as with other
- * TX operations.
- *
- * So from the standpoint of the IEEE802.15.4 MAC driver, there are two
- * possible results: (1) i_framelist is NULL meaning that the frame
- * was fully processed and freed, or (2) i_framelist is non-NULL meaning
- * that there are outgoing frame(s) to be sent.
+ * compressed and possibly fragmented frames and provided to the MAC
+ * network driver via the req_data() method as with other TX operations.
*
* Input Parameters:
- * ieee - The IEEE802.15.4 MAC network driver interface.
+ * ieee - The IEEE802.15.4 MAC network driver interface.
+ * framelist - The head of an incoming list of frames. Normally this
+ * would be a single frame. A list may be provided if
+ * appropriate, however.
+ * ind - Meta data characterizing the received frame. If there are
+ * multilple frames in the list, this meta data must apply to
+ * all of the frames!
*
* Returned Value:
* Ok is returned on success; Othewise a negated errno value is returned.
*
****************************************************************************/
-int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
+int sixlowpan_input(FAR struct ieee802154_driver_s *ieee,
+ FAR struct iob_s *framelist,
+ FAR const struct ieee802154_data_ind_s *ind)
{
int ret = -EINVAL;
- DEBUGASSERT(ieee != NULL && !FRAME_IOB_EMPTY(ieee));
+ DEBUGASSERT(ieee != NULL && framelist != NULL);
- /* Verify that an IOB is provided in the device structure */
+ /* Verify that an frame has been provided. */
- while (!FRAME_IOB_EMPTY(ieee))
+ while (framelist != NULL)
{
FAR struct iob_s *iob;
/* Remove the IOB containing the frame from the device structure */
- FRAME_IOB_REMOVE(ieee, iob);
- DEBUGASSERT(iob != NULL);
+ iob = framelist;
+ framelist = iob->io_flink;
sixlowpan_dumpbuffer("Incoming frame", iob->io_data, iob->io_len);
/* Process the frame, decompressing it into the packet buffer */
- ret = sixlowpan_frame_process(ieee, iob);
+ ret = sixlowpan_frame_process(ieee, ind, iob);
/* Free the IOB the held the consumed frame */
@@ -822,7 +813,7 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
{
FAR struct ipv6_hdr_s *ipv6hdr;
FAR uint8_t *buffer;
- struct rimeaddr_s destmac;
+ struct sixlowpan_tagaddr_s destmac;
size_t hdrlen;
size_t buflen;
@@ -833,12 +824,12 @@ int sixlowpan_input(FAR struct ieee802154_driver_s *ieee)
ipv6hdr = IPv6BUF(&ieee->i_dev);
- /* Get the Rime MAC address of the destination. This
- * assumes an encoding of the MAC address in the IPv6
+ /* Get the IEEE 802.15.4 MAC address of the destination.
+ * This assumes an encoding of the MAC address in the IPv6
* address.
*/
- sixlowpan_rimefromip(ipv6hdr->destipaddr, &destmac);
+ sixlowpan_addrfromip(ipv6hdr->destipaddr, &destmac);
/* The data payload should follow the IPv6 header plus
* the protocol header.
diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h
index a56678c27f9..a4dd9b21d0b 100644
--- a/net/sixlowpan/sixlowpan_internal.h
+++ b/net/sixlowpan/sixlowpan_internal.h
@@ -71,79 +71,50 @@
* Pre-processor Definitions
****************************************************************************/
-/* Rime addres macros */
-/* Copy a Rime address */
+/* IEEE 802.15.4 addres macros */
+/* Copy a an IEEE 802.15.4 address */
-#define rimeaddr_copy(dest,src) \
- memcpy(dest, src, NET_6LOWPAN_RIMEADDR_SIZE)
+#define sixlowpan_anyaddrcopy(dest,src,len) \
+ memcpy(dest, src, len)
-/* Compare two Rime addresses */
+#define sixlowpan_saddrcopy(dest,src) \
+ sixlowpan_anyaddrcopy(dest,src,NET_6LOWPAN_SADDRSIZE)
-#define rimeaddr_cmp(addr1,addr2) \
- (memcmp(addr1, addr2, NET_6LOWPAN_RIMEADDR_SIZE) == 0)
+#define sixlowpan_eaddrcopy(dest,src) \
+ sixlowpan_anyaddrcopy(dest,src,NET_6LOWPAN_EADDRSIZE)
-/* Pointers in the Rime buffer */
+#define sixlowpan_addrcopy(dest,src) \
+ sixlowpan_anyaddrcopy(dest,src,NET_6LOWPAN_ADDRSIZE)
-/* Packet buffer Definitions */
+/* Compare two IEEE 802.15.4 addresses */
-#define PACKETBUF_ATTR_PACKET_TYPE_DATA 0
-#define PACKETBUF_ATTR_PACKET_TYPE_ACK 1
-#define PACKETBUF_ATTR_PACKET_TYPE_STREAM 2
-#define PACKETBUF_ATTR_PACKET_TYPE_STREAM_END 3
-#define PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP 4
+#define sixlowpan_anyaddrcmp(addr1,addr2,len) \
+ (memcmp(addr1, addr2, len) == 0)
-/* Packet buffer attributes (indices into g_pktattrs) */
+#define sixlowpan_saddrcmp(addr1,addr2) \
+ sixlowpan_anyaddrcmp(addr1,addr2,NET_6LOWPAN_SADDRSIZE)
-#define PACKETBUF_ATTR_NONE 0
+#define sixlowpan_eaddrcmp(addr1,addr2) \
+ sixlowpan_anyaddrcmp(addr1,addr2,NET_6LOWPAN_EADDRSIZE)
-/* Scope 0 attributes: used only on the local node. */
-
-#define PACKETBUF_ATTR_CHANNEL 1
-#define PACKETBUF_ATTR_NETWORK_ID 2
-#define PACKETBUF_ATTR_LINK_QUALITY 3
-#define PACKETBUF_ATTR_RSSI 4
-#define PACKETBUF_ATTR_TIMESTAMP 5
-#define PACKETBUF_ATTR_RADIO_TXPOWER 6
-#define PACKETBUF_ATTR_LISTEN_TIME 7
-#define PACKETBUF_ATTR_TRANSMIT_TIME 8
-#define PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS 9
-#define PACKETBUF_ATTR_MAC_SEQNO 10
-#define PACKETBUF_ATTR_MAC_ACK 11
-
-/* Scope 1 attributes: used between two neighbors only. */
-
-#define PACKETBUF_ATTR_RELIABLE 12
-#define PACKETBUF_ATTR_PACKET_ID 13
-#define PACKETBUF_ATTR_PACKET_TYPE 14
-#define PACKETBUF_ATTR_REXMIT 15
-#define PACKETBUF_ATTR_MAX_REXMIT 16
-#define PACKETBUF_ATTR_NUM_REXMIT 17
-#define PACKETBUF_ATTR_PENDING 18
-
-/* Scope 2 attributes: used between end-to-end nodes. */
-
-#define PACKETBUF_ATTR_HOPS 11
-#define PACKETBUF_ATTR_TTL 20
-#define PACKETBUF_ATTR_EPACKET_ID 21
-#define PACKETBUF_ATTR_EPACKET_TYPE 22
-#define PACKETBUF_ATTR_ERELIABLE 23
-
-#define PACKETBUF_NUM_ATTRS 24
-
-/* Addresses (indices into g_pktaddrs) */
-
-#define PACKETBUF_ADDR_SENDER 0
-#define PACKETBUF_ADDR_RECEIVER 1
-#define PACKETBUF_ADDR_ESENDER 2
-#define PACKETBUF_ADDR_ERECEIVER 3
-
-#define PACKETBUF_NUM_ADDRS 4
+#define sixlowpan_addrcmp(addr1,addr2) \
+ sixlowpan_anyaddrcmp(addr1,addr2,NET_6LOWPAN_ADDRSIZE)
/* General helper macros ****************************************************/
-#define GETINT16(ptr,index) \
+/* GET 16-bit data: source in network order, result in host order */
+
+#define GETHOST16(ptr,index) \
((((uint16_t)((ptr)[index])) << 8) | ((uint16_t)(((ptr)[(index) + 1]))))
-#define PUTINT16(ptr,index,value) \
+
+/* GET 16-bit data: source in network order, result in network order */
+
+#define GETNET16(ptr,index) \
+ ((((uint16_t)((ptr)[(index) + 1])) << 8) | ((uint16_t)(((ptr)[index]))))
+
+/* PUT 16-bit data: source in host order, result in newtwork order */
+
+#define PUTHOST16(ptr,index,value) \
do \
{ \
(ptr)[index] = ((uint16_t)(value) >> 8) & 0xff; \
@@ -163,7 +134,9 @@
* Public Types
****************************************************************************/
-/* IPv^ TCP/UDP Definitions *************************************************/
+/* IPv6 TCP/UDP/ICMPv6 Definitions ******************************************/
+
+#ifdef CONFIG_NET_TCP
/* IPv6 + TCP header. Cast compatible based on IPv6 protocol field. */
struct ipv6tcp_hdr_s
@@ -171,7 +144,9 @@ struct ipv6tcp_hdr_s
struct ipv6_hdr_s ipv6;
struct tcp_hdr_s tcp;
};
+#endif
+#ifdef CONFIG_NET_UDP
/* IPv6 + UDP header */
struct ipv6udp_hdr_s
@@ -179,7 +154,9 @@ struct ipv6udp_hdr_s
struct ipv6_hdr_s ipv6;
struct udp_hdr_s udp;
};
+#endif
+#ifdef CONFIG_NET_ICMPv6
/* IPv6 + ICMPv6 header */
struct ipv6icmp_hdr_s
@@ -187,68 +164,28 @@ struct ipv6icmp_hdr_s
struct ipv6_hdr_s ipv6;
struct icmpv6_iphdr_s icmp;
};
+#endif
-/* IEEE802.15.4 Frame Definitions *******************************************/
-/* The IEEE 802.15.4 frame has a number of constant/fixed fields that can be
- * counted to make frame construction and max payload calculations easier.
- * These include:
+/* In order to provide a customizable IEEE 802.15.4 MAC header, a structure
+ * of meta data is passed to the MAC network driver, struct
+ * ieee802154_frame_meta_s. Many of the settings in this meta data are
+ * fixed, deterimined by the 6loWPAN configuration. Other settings depend
+ * on the protocol used in the current packet or on chacteristics of the
+ * destination node.
*
- * 1. FCF - 2 bytes - Fixed
- * 2. Sequence number - 1 byte - Fixed
- * 3. Addressing fields - 4 - 20 bytes - Variable
- * 4. Aux security header - 0 - 14 bytes - Variable
- * 5. CRC - 2 bytes - Fixed
-*/
-
-/* Defines the bitfields of the frame control field (FCF). */
-
-struct frame802154_fcf_s
-{
- uint8_t frame_type; /* 3 bit. Frame type field, see 802.15.4 */
- uint8_t security_enabled; /* 1 bit. True if security is used in this frame */
- uint8_t frame_pending; /* 1 bit. True if sender has more data to send */
- uint8_t ack_required; /* 1 bit. Is an ack frame required? */
- uint8_t panid_compression; /* 1 bit. Is this a compressed header? */
- /* 3 bit. Unused bits */
- uint8_t dest_addr_mode; /* 2 bit. Destination address mode, see 802.15.4 */
- uint8_t frame_version; /* 2 bit. 802.15.4 frame version */
- uint8_t src_addr_mode; /* 2 bit. Source address mode, see 802.15.4 */
-};
-
-/* 802.15.4 security control bitfield. See section 7.6.2.2.1 in 802.15.4
- * specification.
+ * The following structure is used to summarize those per-packet
+ * customizations and, along, with the fixed configuratin settings,
+ * determines the full form of that meta data.
*/
-struct frame802154_scf_s
+struct packet_metadata_s
{
- uint8_t security_level; /* 3 bit. security level */
- uint8_t key_id_mode; /* 2 bit. Key identifier mode */
- uint8_t reserved; /* 3 bit. Reserved bits */
-};
-
-/* 802.15.4 Aux security header */
-
-struct frame802154_aux_hdr_s
-{
- struct frame802154_scf_s security_control; /* Security control bitfield */
- uint32_t frame_counter; /* Frame counter, used for security */
- uint8_t key[9]; /* The key itself, or an index to the key */
-};
-
-/* Parameters used by the frame802154_create() function. These parameters
- * are used in the 802.15.4 frame header. See the 802.15.4 specification
- * for details.
- */
-
-struct frame802154_s
-{
- struct frame802154_fcf_s fcf; /* Frame control field */
- uint8_t seq; /* Sequence number */
- uint16_t dest_pid; /* Destination PAN ID */
- uint8_t dest_addr[8]; /* Destination address */
- uint16_t src_pid; /* Source PAN ID */
- uint8_t src_addr[8]; /* Source address */
- struct frame802154_aux_hdr_s aux_hdr; /* Aux security header */
+ uint8_t sextended : 1; /* Extended source address */
+ uint8_t dextended : 1; /* Extended destination address */
+ uint8_t xmits; /* Max MAC transmisstion */
+ uint16_t dpanid; /* Destination PAN ID */
+ union sixlowpan_anyaddr_u source; /* Source IEEE 802.15.4 address */
+ union sixlowpan_anyaddr_u dest; /* Destination IEEE 802.15.4 address */
};
/****************************************************************************
@@ -262,14 +199,6 @@ struct frame802154_s
* during that processing
*/
-/* A pointer to the rime buffer.
- *
- * We initialize it to the beginning of the rime buffer, then access
- * different fields by updating the offset ieee->g_frame_hdrlen.
- */
-
-extern FAR uint8_t *g_rimeptr;
-
/* g_uncomp_hdrlen is the length of the headers before compression (if HC2
* is used this includes the UDP header in addition to the IP header).
*/
@@ -283,11 +212,6 @@ extern uint8_t g_uncomp_hdrlen;
extern uint8_t g_frame_hdrlen;
-/* Packet buffer metadata: Attributes and addresses */
-
-extern uint16_t g_pktattrs[PACKETBUF_NUM_ATTRS];
-extern struct rimeaddr_s g_pktaddrs[PACKETBUF_NUM_ADDRS];
-
/****************************************************************************
* Public Types
****************************************************************************/
@@ -300,7 +224,7 @@ struct net_driver_s; /* Forward reference */
struct ieee802154_driver_s; /* Forward reference */
struct devif_callback_s; /* Forward reference */
struct ipv6_hdr_s; /* Forward reference */
-struct rimeaddr_s; /* Forward reference */
+struct sixlowpan_addr_s; /* Forward reference */
struct iob_s; /* Forward reference */
/****************************************************************************
@@ -313,16 +237,15 @@ struct iob_s; /* Forward reference */
*
* The payload data is in the caller 'buf' and is of length 'buflen'.
* Compressed headers will be added and if necessary the packet is
- * fragmented. The resulting packet/fragments are put in ieee->i_framelist
- * and the entire list of frames will be delivered to the 802.15.4 MAC via
- * ieee->i_framelist.
+ * fragmented. The resulting packet/fragments are submitted to the MAC
+ * via the network driver i_req_data method.
*
* Input Parameters:
* dev - The IEEE802.15.4 MAC network driver interface.
* list - Head of callback list for send interrupt
* ipv6hdr - IPv6 plus TCP or UDP headers.
* buf - Data to send
- * buflen - Length of data to send
+ * len - Length of data to send
* raddr - The MAC address of the destination
* timeout - Send timeout in deciseconds
*
@@ -340,11 +263,37 @@ struct iob_s; /* Forward reference */
int sixlowpan_send(FAR struct net_driver_s *dev,
FAR struct devif_callback_s **list,
FAR const struct ipv6_hdr_s *ipv6hdr, FAR const void *buf,
- size_t buflen, FAR const struct rimeaddr_s *raddr,
+ size_t len, FAR const struct sixlowpan_tagaddr_s *destmac,
uint16_t timeout);
/****************************************************************************
- * Name: sixlowpan_send_hdrlen
+ * Name: sixlowpan_meta_data
+ *
+ * Description:
+ * Based on the collected attributes and addresses, construct the MAC meta
+ * data structure that we need to interface with the IEEE802.15.4 MAC.
+ *
+ * Input Parameters:
+ * ieee - IEEE 802.15.4 MAC driver state reference.
+ * pktmeta - Meta-data specific to the current outgoing frame
+ * meta - Location to return the corresponding meta data.
+ * paylen - The size of the data payload to be sent.
+ *
+ * Returned Value:
+ * Ok is returned on success; Othewise a negated errno value is returned.
+ *
+ * Assumptions:
+ * Called with the network locked.
+ *
+ ****************************************************************************/
+
+int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee,
+ FAR const struct packet_metadata_s *pktmeta,
+ FAR struct ieee802154_frame_meta_s *meta,
+ uint16_t paylen);
+
+/****************************************************************************
+ * Name: sixlowpan_frame_hdrlen
*
* Description:
* This function is before the first frame has been sent in order to
@@ -352,9 +301,8 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
* buffer is required to make this determination.
*
* Input parameters:
- * ieee - A reference IEEE802.15.4 MAC network device structure.
- * dest_panid - PAN ID of the destination. May be 0xffff if the destination
- * is not associated.
+ * ieee - A reference IEEE802.15.4 MAC network device structure.
+ * meta - Meta data that describes the MAC header
*
* Returned Value:
* The frame header length is returnd on success; otherwise, a negated
@@ -362,30 +310,32 @@ int sixlowpan_send(FAR struct net_driver_s *dev,
*
****************************************************************************/
-int sixlowpan_send_hdrlen(FAR struct ieee802154_driver_s *ieee,
- uint16_t dest_panid);
+int sixlowpan_frame_hdrlen(FAR struct ieee802154_driver_s *ieee,
+ FAR const struct ieee802154_frame_meta_s *meta);
/****************************************************************************
- * Name: sixlowpan_framecreate
+ * Name: sixlowpan_frame_submit
*
* Description:
- * This function is called after the IEEE802.15.4 MAC driver polls for
- * TX data. It creates the IEEE802.15.4 header in the frame buffer.
+ * This function is called after eiether (1) the IEEE802.15.4 MAC driver
+ * polls for TX data or (2) after the IEEE802.15.4 MAC driver provides a
+ * new incoming frame and the network responds with an outgoing packet. It
+ * submits any new outgoing frame to the MAC.
*
* Input parameters:
- * ieee - A reference IEEE802.15.4 MAC network device structure.
- * iob - The IOB in which to create the frame.
- * dest_panid - PAN ID of the destination. May be 0xffff if the destination
- * is not associated.
+ * ieee - A reference IEEE802.15.4 MAC network device structure.
+ * meta - Meta data that describes the MAC header
+ * frame - The IOB containing the frame to be submitted.
*
* Returned Value:
- * The frame header length is returnd on success; otherwise, a negated
- * errno value is return on failure.
+ * Zero (OK) is returned on success; otherwise, a negated errno value is
+ * return on any failure.
*
****************************************************************************/
-int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
- FAR struct iob_s *iob, uint16_t dest_panid);
+int sixlowpan_frame_submit(FAR struct ieee802154_driver_s *ieee,
+ FAR const struct ieee802154_frame_meta_s *meta,
+ FAR struct iob_s *frame);
/****************************************************************************
* Name: sixlowpan_queue_frames
@@ -397,9 +347,8 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
*
* The payload data is in the caller 'buf' and is of length 'buflen'.
* Compressed headers will be added and if necessary the packet is
- * fragmented. The resulting packet/fragments are put in ieee->i_framelist
- * and the entire list of frames will be delivered to the 802.15.4 MAC via
- * ieee->i_framelist.
+ * fragmented. The resulting packet/fragments are submitted to the MAC
+ * via the network driver i_req_data method.
*
* Input Parameters:
* ieee - The IEEE802.15.4 MAC driver instance
@@ -423,7 +372,7 @@ int sixlowpan_framecreate(FAR struct ieee802154_driver_s *ieee,
int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6hdr,
FAR const void *buf, size_t buflen,
- FAR const struct rimeaddr_s *destmac);
+ FAR const struct sixlowpan_tagaddr_s *destmac);
/****************************************************************************
* Name: sixlowpan_hc06_initialize
@@ -479,7 +428,7 @@ void sixlowpan_hc06_initialize(void);
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06
void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6,
- FAR const struct rimeaddr_s *destmac,
+ FAR const struct sixlowpan_tagaddr_s *destmac,
FAR uint8_t *fptr);
#endif
@@ -491,8 +440,8 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee,
* sixlowpan_buf
*
* This function is called by the input function when the dispatch is HC06.
- * We process the packet in the rime buffer, uncompress the header fields,
- * and copy the result in the sixlowpan buffer. At the end of the
+ * We process the frame in the IOB buffer, uncompress the header fields,
+ * and copy the result into the driver packet buffer. At the end of the
* decompression, g_frame_hdrlen and g_uncompressed_hdrlen are set to the
* appropriate values
*
@@ -540,7 +489,7 @@ void sixlowpan_uncompresshdr_hc06(uint16_t iplen, FAR struct iob_s *iob,
#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC1
void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
FAR const struct ipv6_hdr_s *ipv6,
- FAR const struct rimeaddr_s *destmac,
+ FAR const struct sixlowpan_tagaddr_s *destmac,
FAR uint8_t *fptr);
#endif
@@ -551,8 +500,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee,
* Uncompress HC1 (and HC_UDP) headers and put them in sixlowpan_buf
*
* This function is called by the input function when the dispatch is
- * HC1. It processes the packet in the rime buffer, uncompresses the
- * header fields, and copies the result in the sixlowpan buffer. At the
+ * HC1. It processes the frame in the IOB buffer, uncompresses the
+ * header fields, and copies the result in the packet buffer. At the
* end of the decompression, g_frame_hdrlen and uncompressed_hdr_len
* are set to the appropriate values
*
@@ -577,34 +526,72 @@ int sixlowpan_uncompresshdr_hc1(uint16_t iplen, FAR struct iob_s *iob,
#endif
/****************************************************************************
- * Name: sixlowpan_islinklocal, sixlowpan_ipfromrime, sixlowpan_rimefromip,
- * and sixlowpan_ismacbased
+ * Name: sixlowpan_islinklocal, sixlowpan_addrfromip, and
+ * sixlowpan_ismacbased
*
* Description:
- * sixlowpan_ipfromrime: Create a link local IPv6 address from a rime
- * address.
+ * sixlowpan_addrfromip(): Extract the IEEE 802.15.14 address from a MAC
+ * based IPv6 address. sixlowpan_addrfromip() is intended to handle a
+ * tagged address or any size; sixlowpan_saddrfromip() and
+ * sixlowpan_eaddrfromip() specifically handle short and extended
+ * addresses.
*
- * sixlowpan_rimefromip: Extract the rime address from a link local IPv6
- * address.
- *
- * sixlowpan_islinklocal and sixlowpan_ismacbased will return true for
- * address created in this fashion.
+ * sixlowpan_islinklocal() and sixlowpan_ismacbased() will return true for
+ * address created in this fashion. sixlowpan_addrfromip() is intended to
+ * handle a tagged address or any size; sixlowpan_issaddrbased() and
+ * sixlowpan_iseaddrbased() specifically handle short and extended
+ * addresses. Local addresses are of a fixed but configurable size and
+ * sixlowpan_isaddrbased() is for use with such local addresses.
*
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
- * fe80 0000 0000 0000 xxxx 0000 0000 0000 2-byte Rime address (VALID?)
- * fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address
+ * fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC
+ * fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64
*
****************************************************************************/
#define sixlowpan_islinklocal(ipaddr) ((ipaddr)[0] == NTOHS(0xfe80))
-void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
- net_ipv6addr_t ipaddr);
-void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
- FAR struct rimeaddr_s *rime);
-bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
- FAR const struct rimeaddr_s *rime);
+void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr,
+ FAR struct sixlowpan_saddr_s *saddr);
+void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr,
+ FAR struct sixlowpan_eaddr_s *eaddr);
+void sixlowpan_addrfromip(const net_ipv6addr_t ipaddr,
+ FAR struct sixlowpan_tagaddr_s *addr);
+bool sixlowpan_issaddrbased(const net_ipv6addr_t ipaddr,
+ FAR const struct sixlowpan_saddr_s *saddr);
+bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr,
+ FAR const struct sixlowpan_eaddr_s *eaddr);
+
+#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR
+# define sixlowpan_isaddrbased(ipaddr,addr) \
+ sixlowpan_iseaddrbased(ipaddr,(FAR struct sixlowpan_eaddr_s *)addr)
+#else
+# define sixlowpan_isaddrbased(ipaddr,addr) \
+ sixlowpan_issaddrbased(ipaddr,(FAR struct sixlowpan_saddr_s *)addr)
+#endif
+
+bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
+ FAR const struct sixlowpan_tagaddr_s *addr);
+
+/****************************************************************************
+ * Name: sixlowpan_src_panid
+ *
+ * Description:
+ * Get the source PAN ID from the IEEE802.15.4 radio.
+ *
+ * Input parameters:
+ * ieee - A reference IEEE802.15.4 MAC network device structure.
+ * panid - The location in which to return the PAN ID. 0xfff may be
+ * returned if the device is not associated.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int sixlowpan_src_panid(FAR struct ieee802154_driver_s *ieee,
+ FAR uint16_t *panid);
#endif /* CONFIG_NET_6LOWPAN */
#endif /* _NET_SIXLOWPAN_SIXLOWPAN_INTERNAL_H */
diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c
index 3ad68554aec..db8337834cc 100644
--- a/net/sixlowpan/sixlowpan_send.c
+++ b/net/sixlowpan/sixlowpan_send.c
@@ -83,7 +83,7 @@ struct sixlowpan_send_s
uint16_t s_timeout; /* Send timeout in deciseconds */
systime_t s_time; /* Last send time for determining timeout */
FAR const struct ipv6_hdr_s *s_ipv6hdr; /* IPv6 header, followed by UDP or TCP header. */
- FAR const struct rimeaddr_s *s_destmac; /* Destination MAC address */
+ FAR const struct sixlowpan_tagaddr_s *s_destmac; /* Destination MAC address */
FAR const void *s_buf; /* Data to send */
size_t s_len; /* Length of data in buf */
};
@@ -246,11 +246,10 @@ end_wait:
* it to be sent on an 802.15.4 network using 6lowpan. Called from common
* UDP/TCP send logic.
*
- * The payload data is in the caller 'buf' and is of length 'len'.
+ * The payload data is in the caller 'buf' and is of length 'buflen'.
* Compressed headers will be added and if necessary the packet is
- * fragmented. The resulting packet/fragments are put in ieee->i_framelist
- * and the entire list of frames will be delivered to the 802.15.4 MAC via
- * ieee->i_framelist.
+ * fragmented. The resulting packet/fragments are submitted to the MAC
+ * via the network driver i_req_data method.
*
* Input Parameters:
* dev - The IEEE802.15.4 MAC network driver interface.
@@ -275,7 +274,7 @@ end_wait:
int sixlowpan_send(FAR struct net_driver_s *dev,
FAR struct devif_callback_s **list,
FAR const struct ipv6_hdr_s *ipv6hdr, FAR const void *buf,
- size_t len, FAR const struct rimeaddr_s *destmac,
+ size_t len, FAR const struct sixlowpan_tagaddr_s *destmac,
uint16_t timeout)
{
struct sixlowpan_send_s sinfo;
diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c
index 2bb6c49130c..5ae5de0b81c 100644
--- a/net/sixlowpan/sixlowpan_tcpsend.c
+++ b/net/sixlowpan/sixlowpan_tcpsend.c
@@ -164,7 +164,7 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
FAR struct tcp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6tcp_hdr_s ipv6tcp;
- struct rimeaddr_s destmac;
+ struct sixlowpan_tagaddr_s destmac;
uint16_t timeout;
uint16_t iplen;
int ret;
@@ -317,11 +317,11 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf,
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
- /* Get the Rime MAC address of the destination This assumes an encoding
- * of the MAC address in the IPv6 address.
+ /* Get the IEEE 802.15.4 MAC address of the destination. This assumes
+ * an encoding of the MAC address in the IPv6 address.
*/
- sixlowpan_rimefromip(conn->u.ipv6.raddr, &destmac);
+ sixlowpan_addrfromip(conn->u.ipv6.raddr, &destmac);
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
* packet.
@@ -409,16 +409,16 @@ void sixlowpan_tcp_send(FAR struct net_driver_s *dev)
}
else
{
- struct rimeaddr_s destmac;
+ struct sixlowpan_tagaddr_s destmac;
FAR uint8_t *buf;
uint16_t hdrlen;
uint16_t buflen;
- /* Get the Rime MAC address of the destination. This assumes an
- * encoding of the MAC address in the IPv6 address.
+ /* Get the IEEE 802.15.4 MAC address of the destination. This
+ * assumes an encoding of the MAC address in the IPv6 address.
*/
- sixlowpan_rimefromip(ipv6hdr->ipv6.destipaddr, &destmac);
+ sixlowpan_addrfromip(ipv6hdr->ipv6.destipaddr, &destmac);
/* Get the IPv6 + TCP combined header length. The size of the TCP
* header is encoded in the top 4 bits of the tcpoffset field (in
diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c
index a29197eec70..7036589e097 100644
--- a/net/sixlowpan/sixlowpan_udpsend.c
+++ b/net/sixlowpan/sixlowpan_udpsend.c
@@ -162,7 +162,7 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
FAR struct udp_conn_s *conn;
FAR struct net_driver_s *dev;
struct ipv6udp_hdr_s ipv6udp;
- struct rimeaddr_s destmac;
+ struct sixlowpan_tagaddr_s destmac;
uint16_t iplen;
uint16_t timeout;
int ret;
@@ -292,11 +292,11 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock,
psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);
- /* Get the Rime MAC address of the destination This assumes an encoding
- * of the MAC address in the IPv6 address.
+ /* Get the IEEE 802.15.4 MAC address of the destination This assumes an
+ * encoding of the MAC address in the IPv6 address.
*/
- sixlowpan_rimefromip(to6->sin6_addr.in6_u.u6_addr16, &destmac);
+ sixlowpan_addrfromip(to6->sin6_addr.in6_u.u6_addr16, &destmac);
/* If routable, then call sixlowpan_send() to format and send the 6loWPAN
* packet.
diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c
index dcda6be652d..d04ce878c75 100644
--- a/net/sixlowpan/sixlowpan_utils.c
+++ b/net/sixlowpan/sixlowpan_utils.c
@@ -54,8 +54,10 @@
#include
#include
#include
+#include
#include
+#include
#include "sixlowpan/sixlowpan_internal.h"
@@ -66,94 +68,144 @@
****************************************************************************/
/****************************************************************************
- * Name: sixlowpan_ipfromrime
+ * Name: sixlowpan_addrfromip
*
* Description:
- * Create a link local IPv6 address from a rime address:
+ * sixlowpan_addrfromip(): Extract the IEEE 802.15.14 address from a MAC
+ * based IPv6 address. sixlowpan_addrfromip() is intended to handle a
+ * tagged address or and size; sixlowpan_saddrfromip() and
+ * sixlowpan_eaddrfromip() specifically handler short and extended
+ * addresses.
*
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
- * fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte Rime address IEEE 48-bit MAC
- * fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address IEEE EUI-64
+ * xxxx 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC
+ * xxxx 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64
*
****************************************************************************/
-void sixlowpan_ipfromrime(FAR const struct rimeaddr_s *rime,
- net_ipv6addr_t ipaddr)
+void sixlowpan_saddrfromip(const net_ipv6addr_t ipaddr,
+ FAR struct sixlowpan_saddr_s *saddr)
{
- /* We consider only links with IEEE EUI-64 identifier or IEEE 48-bit MAC
- * addresses.
- */
-
- memset(ipaddr, 0, sizeof(net_ipv6addr_t));
- ipaddr[0] = HTONS(0xfe80);
-
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
- memcpy(&ipaddr[4], rime, NET_6LOWPAN_RIMEADDR_SIZE);
- ipaddr[4] ^= HTONS(0x0200);
-#else
- ipaddr[5] = HTONS(0x00ff);
- ipaddr[6] = HTONS(0xfe00);
- memcpy(&ipaddr[7], rime, NET_6LOWPAN_RIMEADDR_SIZE);
- ipaddr[7] ^= HTONS(0x0200);
-#endif
-}
-
-/****************************************************************************
- * Name: sixlowpan_rimefromip
- *
- * Description:
- * Extract the rime address from a link local IPv6 address:
- *
- * 128 112 96 80 64 48 32 16
- * ---- ---- ---- ---- ---- ---- ---- ----
- * fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte Rime address IEEE 48-bit MAC
- * fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address IEEE EUI-64
- *
- ****************************************************************************/
-
-void sixlowpan_rimefromip(const net_ipv6addr_t ipaddr,
- FAR struct rimeaddr_s *rime)
-{
- /* REVISIT: See notes about 2 byte addresses in sixlowpan_ipfromrime() */
-
DEBUGASSERT(ipaddr[0] == HTONS(0xfe80));
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
- memcpy(rime, &ipaddr[4], NET_6LOWPAN_RIMEADDR_SIZE);
-#else
- memcpy(rime, &ipaddr[7], NET_6LOWPAN_RIMEADDR_SIZE);
-#endif
- rime->u8[0] ^= 0x02;
+ memcpy(saddr, &ipaddr[7], NET_6LOWPAN_SADDRSIZE);
+ saddr->u8[0] ^= 0x02;
+}
+
+void sixlowpan_eaddrfromip(const net_ipv6addr_t ipaddr,
+ FAR struct sixlowpan_eaddr_s *eaddr)
+{
+ DEBUGASSERT(ipaddr[0] == HTONS(0xfe80));
+
+ memcpy(eaddr, &ipaddr[4], NET_6LOWPAN_EADDRSIZE);
+ eaddr->u8[0] ^= 0x02;
+}
+
+void sixlowpan_addrfromip(const net_ipv6addr_t ipaddr,
+ FAR struct sixlowpan_tagaddr_s *addr)
+{
+ DEBUGASSERT(ipaddr[0] == HTONS(0xfe80));
+
+ if (SIXLOWPAN_IS_IID_16BIT_COMPRESSABLE(ipaddr))
+ {
+ memset(addr, 0, sizeof(struct sixlowpan_tagaddr_s));
+ sixlowpan_saddrfromip(ipaddr, &addr->u.saddr);
+ }
+ else
+ {
+ sixlowpan_eaddrfromip(ipaddr, &addr->u.eaddr);
+ addr->extended = true;
+ }
}
/****************************************************************************
* Name: sixlowpan_ismacbased
*
* Description:
- * Check if the MAC address is encoded in the IP address:
+ * sixlowpan_ismacbased() will return true for IP addresses formed from
+ * IEEE802.15.4 MAC addresses. sixlowpan_addrfromip() is intended to
+ * handle a tagged address or any size; sixlowpan_issaddrbased() and
+ * sixlowpan_iseaddrbased() specifically handle short and extended
+ * addresses. Local addresses are of a fixed but configurable size and
+ * sixlowpan_isaddrbased() is for use with such local addresses.
+ *
*
* 128 112 96 80 64 48 32 16
* ---- ---- ---- ---- ---- ---- ---- ----
- * fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte Rime address IEEE 48-bit MAC
- * fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte Rime address IEEE EUI-64
+ * fe80 0000 0000 0000 0000 00ff fe00 xxxx 2-byte short address IEEE 48-bit MAC
+ * fe80 0000 0000 0000 xxxx xxxx xxxx xxxx 8-byte extended address IEEE EUI-64
*
****************************************************************************/
-bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
- FAR const struct rimeaddr_s *rime)
+bool sixlowpan_issaddrbased(const net_ipv6addr_t ipaddr,
+ FAR const struct sixlowpan_saddr_s *saddr)
{
- FAR const uint8_t *rimeptr = rime->u8;
+ FAR const uint8_t *byteptr = saddr->u8;
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
- return (ipaddr[4] == htons((GETINT16(rimeptr, 0) ^ 0x0200)) &&
- ipaddr[5] == GETINT16(rimeptr, 2) &&
- ipaddr[6] == GETINT16(rimeptr, 4) &&
- ipaddr[7] == GETINT16(rimeptr, 6));
-#else
return (ipaddr[5] == HTONS(0x00ff) && ipaddr[6] == HTONS(0xfe00) &&
- ipaddr[7] == htons((GETINT16(rimeptr, 0) ^ 0x0200)));
-#endif
+ ipaddr[7] == (GETNET16(byteptr, 0) ^ HTONS(0x0200)));
+}
+
+bool sixlowpan_iseaddrbased(const net_ipv6addr_t ipaddr,
+ FAR const struct sixlowpan_eaddr_s *eaddr)
+{
+ FAR const uint8_t *byteptr = eaddr->u8;
+
+ return (ipaddr[4] == (GETNET16(byteptr, 0) ^ HTONS(0x0200)) &&
+ ipaddr[5] == GETNET16(byteptr, 2) &&
+ ipaddr[6] == GETNET16(byteptr, 4) &&
+ ipaddr[7] == GETNET16(byteptr, 6));
+}
+
+bool sixlowpan_ismacbased(const net_ipv6addr_t ipaddr,
+ FAR const struct sixlowpan_tagaddr_s *addr)
+{
+ if (addr->extended)
+ {
+ return sixlowpan_iseaddrbased(ipaddr, &addr->u.eaddr);
+ }
+ else
+ {
+ return sixlowpan_issaddrbased(ipaddr, &addr->u.saddr);
+ }
+}
+
+/****************************************************************************
+ * Name: sixlowpan_src_panid
+ *
+ * Description:
+ * Get the source PAN ID from the IEEE802.15.4 MAC layer.
+ *
+ * Input parameters:
+ * ieee - A reference IEEE802.15.4 MAC network device structure.
+ * panid - The location in which to return the PAN ID. 0xfff may be
+ * returned if the device is not associated.
+ *
+ * Returned Value:
+ * Zero (OK) on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int sixlowpan_src_panid(FAR struct ieee802154_driver_s *ieee,
+ FAR uint16_t *panid)
+{
+ FAR struct net_driver_s *dev = &ieee->i_dev;
+ struct ieee802154_netmac_s arg;
+ int ret;
+
+ memcpy(arg.ifr_name, ieee->i_dev.d_ifname, IFNAMSIZ);
+ arg.u.getreq.pib_attr = IEEE802154_PIB_MAC_PAN_ID;
+ ret = dev->d_ioctl(dev, MAC802154IOC_MLME_GET_REQUEST,
+ (unsigned long)((uintptr_t)&arg));
+ if (ret < 0)
+ {
+ wlerr("ERROR: MAC802154IOC_MLME_GET_REQUEST failed: %d\n", ret);
+ return ret;
+ }
+
+ *panid = arg.u.getreq.attr_value.mac.panid;
+ return OK;
}
#endif /* CONFIG_NET_6LOWPAN */
diff --git a/wireless/Kconfig b/wireless/Kconfig
index 440e30a665c..75f4ae12891 100644
--- a/wireless/Kconfig
+++ b/wireless/Kconfig
@@ -6,7 +6,6 @@
config WIRELESS
bool "Wireless Support"
default n
- depends on EXPERIMENTAL
---help---
Enables overall support for Wireless library.
diff --git a/wireless/Makefile b/wireless/Makefile
index 008d23ff1c8..f05d957943d 100644
--- a/wireless/Makefile
+++ b/wireless/Makefile
@@ -52,14 +52,6 @@ VPATH = .
include ieee802154$(DELIM)Make.defs
-# Include support for various drivers. Each Make.defs file will add its
-# files to the source file list, add its DEPPATH info, and will add
-# the appropriate paths to the VPATH variable
-
-ifeq ($(CONFIG_WIRELESS_FORMAT_PCM),y)
- CSRCS += pcm_decode.c
-endif
-
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
diff --git a/wireless/ieee802154/Kconfig b/wireless/ieee802154/Kconfig
index 228779a5d44..ff64c06d843 100644
--- a/wireless/ieee802154/Kconfig
+++ b/wireless/ieee802154/Kconfig
@@ -6,19 +6,128 @@
config WIRELESS_IEEE802154
bool "IEEE 802.15.4 Wireless Support"
default n
- depends on EXPERIMENTAL
+ select DRIVERS_IOB
---help---
Enables support for the IEEE 802.14.5 Wireless library.
if WIRELESS_IEEE802154
+menuconfig IEEE802154_MAC
+ bool "Generic Media Access Control (MAC) layer for 802.15.4 radios"
+ default n
+ depends on WIRELESS_IEEE802154
+ ---help---
+ Enables a Media Access Controller for any IEEE802.15.4 radio
+ device. This in turn can be used by higher layer entities
+ such as 6lowpan. It is not required to use 802.15.4 radios,
+ but is strongly suggested to ensure exchange of valid frames.
+
+if IEEE802154_MAC
+
+config IEEE802154_MAC_DEV
+ bool "Character driver for IEEE 802.15.4 MAC layer"
+ default n
+ depends on IEEE802154_MAC
+ ---help---
+ Enable the device driver to expose the IEEE 802.15.4 MAC layer
+ access to user space as IOCTLs
+
+choice
+ prompt "IEEE 802.15.4 work queue"
+ default MAC802154_LPWORK if SCHED_LPWORK
+ default MAC802154_HPWORK if !SCHED_LPWORK && SCHED_HPWORK
+ depends on SCHED_WORKQUEUE
+ ---help---
+ Work queue support is required to use the IEEE 802.15.4 MAC layer.
+ If the low priority work queue is available, then it should be used by
+ the driver.
+
+config MAC802154_HPWORK
+ bool "High priority"
+ depends on SCHED_HPWORK
+
+config MAC802154_LPWORK
+ bool "Low priority"
+ depends on SCHED_LPWORK
+
+endchoice # Work queue
+
+config IEEE802154_NTXDESC
+ int "Number or TX descriptors"
+ default 3
+ ---help---
+ Configured number of Tx descriptors. Default: 3
+
+endif # IEEE802154_MAC
+
+config IEEE802154_IND_PREALLOC
+ int "Number of pre-allocated meta-data structures"
+ default 20
+ ---help---
+ This specifies the total number of preallocated meta data structures
+ must be allocated with each incoming packet. These may be allocated
+ from either from tasking logic or from interrupt level logic.
+
+config IEEE802154_IND_IRQRESERVE
+ int "Rserved pre-allocated meta-data structures"
+ default 10
+ ---help---
+ If meta-data structures can be allocated from interrupt handlers,
+ then this specifies the number of pre-allocatd meta-data structures
+ that are reserved for for use only by interrupt handlers. This may
+ be zero to reserve no meta-data structures for interrupt handlers.
+ In that case, the allocation will fail if tasking logic has
+ allocated them all.
+
+ Interrupt logic will first attempt to allocate from the general,
+ pre-allocated structure pool that will contain up to (size
+ CONFIG_IEEE802154_IND_PREALLOC - CONFIG_IEEE802154_IND_IRQRESERVE)
+ entries. If that fails, then it will try to take a structure from
+ the reserve (size CONFIG_IEEE802154_IND_IRQRESERVE).
+
+ Non-interrupt logic will also first attempt to allocate from the
+ general, pre-allocated structure pool. If that fails, it will
+ dynamically allocate the meta data structure with an additional cost in performance.
+
+config IEEE802154_NETDEV
+ bool "IEEE802154 6loWPAN Network Device"
+ default n
+ depends on NET_6LOWPAN && NET_IPv6
+ select ARCH_HAVE_NETDEV_STATISTICS
+ ---help---
+ Add support for the IEEE802.15.4 6loWPAN network device built on
+ the common IEEE802.15.4 MAC.
+
+if IEEE802154_NETDEV
+
+choice
+ prompt "Work queue"
+ default IEEE802154_NETDEV_LPWORK if SCHED_LPWORK
+ default IEEE802154_NETDEV_HPWORK if !SCHED_LPWORK && SCHED_HPWORK
+ depends on SCHED_WORKQUEUE
+ ---help---
+ Work queue support is required to use the IEEE802.15.4 network
+ driver. If the low priority work queue is available, then it shoul
+ be used by the loopback driver.
+
+config IEEE802154_NETDEV_HPWORK
+ bool "High priority"
+ depends on SCHED_HPWORK
+
+config IEEE802154_NETDEV_LPWORK
+ bool "Low priority"
+ depends on SCHED_LPWORK
+
+endchoice # Work queue
+endif # IEEE802154_NETDEV
+
config IEEE802154_LOOPBACK
bool "IEEE802154 6loWPAN Loopback"
default n
depends on NET_6LOWPAN && NET_IPv6
select ARCH_HAVE_NETDEV_STATISTICS
---help---
- Add support for the IEEE802154 6loWPAN Loopback test device.
+ Add support for the IEEE802.15.4 6loWPAN Loopback test device.
if IEEE802154_LOOPBACK
diff --git a/wireless/ieee802154/Make.defs b/wireless/ieee802154/Make.defs
index 2f5f19967f4..73354b2609b 100644
--- a/wireless/ieee802154/Make.defs
+++ b/wireless/ieee802154/Make.defs
@@ -1,7 +1,7 @@
############################################################################
# wireless/ieee802145/Make.defs
#
-# Copyright (C) 2016 Gregory Nutt. All rights reserved.
+# Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt
#
# Redistribution and use in source and binary forms, with or without
@@ -37,8 +37,26 @@ ifeq ($(CONFIG_WIRELESS_IEEE802154),y)
# Include IEEE 802.15.4 support
+CSRCS += mac802154_indalloc.c
+
# Include wireless devices build support
+ifeq ($(CONFIG_IEEE802154_MAC),y)
+CSRCS += mac802154.c
+endif
+
+ifeq ($(CONFIG_IEEE802154_MAC_DEV),y)
+CSRCS += mac802154_device.c
+endif
+
+ifeq ($(CONFIG_IEEE802154_DEV),y)
+CSRCS += radio802154_device.c
+endif
+
+ifeq ($(CONFIG_IEEE802154_NETDEV),y)
+CSRCS += mac802154_netdev.c
+endif
+
ifeq ($(CONFIG_IEEE802154_LOOPBACK),y)
CSRCS += mac802154_loopback.c
endif
diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c
new file mode 100644
index 00000000000..1da758082c6
--- /dev/null
+++ b/wireless/ieee802154/mac802154.c
@@ -0,0 +1,1824 @@
+/****************************************************************************
+ * wireless/ieee802154/mac802154.c
+ *
+ * Copyright (C) 2016 Sebastien Lorquet. All rights reserved.
+ * Copyright (C) 2017 Verge Inc. All rights reserved.
+ * Author: Sebastien Lorquet
+ * Author: Anthony Merlino
+ *
+ * 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 "mac802154.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+/* If processing is not done at the interrupt level, then work queue support
+ * is required.
+ */
+
+#if !defined(CONFIG_SCHED_WORKQUEUE)
+# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE)
+#else
+
+ /* Use the low priority work queue if possible */
+
+# if defined(CONFIG_MAC802154_HPWORK)
+# define MAC802154_WORK HPWORK
+# elif defined(CONFIG_MAC802154_LPWORK)
+# define MAC802154_WORK LPWORK
+# else
+# error Neither CONFIG_MAC802154_HPWORK nor CONFIG_MAC802154_LPWORK defined
+# endif
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct mac802154_txframe_s
+{
+ /* Supports a singly linked list */
+
+ FAR struct mac802154_txframe_s *flink;
+ FAR struct iob_s *frame;
+ uint8_t msdu_handle;
+ sem_t sem;
+};
+
+struct mac802154_unsec_mhr_s
+{
+ uint8_t length;
+ union
+ {
+ uint16_t frame_control;
+ uint8_t data[IEEE802154_MAX_UNSEC_MHR_OVERHEAD];
+ } u;
+};
+
+struct mac802154_radiocb_s
+{
+ struct ieee802154_radiocb_s cb;
+ FAR struct ieee802154_privmac_s *priv;
+};
+
+/* The privmac structure holds the internal state of the MAC and is the
+ * underlying represention of the opaque MACHANDLE. It contains storage for
+ * the IEEE802.15.4 MIB attributes.
+ */
+
+struct ieee802154_privmac_s
+{
+ FAR struct ieee802154_radio_s *radio; /* Contained IEEE802.15.4 radio dev */
+ FAR const struct ieee802154_maccb_s *cb; /* Contained MAC callbacks */
+ FAR struct mac802154_radiocb_s radiocb; /* Interface to bind to radio */
+
+ sem_t exclsem; /* Support exclusive access */
+
+ struct work_s tx_work;
+ struct work_s rx_work;
+
+ /* Support a singly linked list of transactions that will be sent using the
+ * CSMA algorithm. On a non-beacon enabled PAN, these transactions will be
+ * sent whenever. On a beacon-enabled PAN, these transactions will be sent
+ * during the CAP of the Coordinator's superframe.
+ */
+
+ FAR struct mac802154_txframe_s *csma_head;
+ FAR struct mac802154_txframe_s *csma_tail;
+
+ /* Support a singly linked list of transactions that will be sent indirectly.
+ * This list should only be used by a MAC acting as a coordinator. These
+ * transactions will stay here until the data is extracted by the destination
+ * device sending a Data Request MAC command or if too much time passes. This
+ * list should also be used to populate the address list of the outgoing
+ * beacon frame.
+ */
+
+ FAR struct mac802154_txframe_s *indirect_head;
+ FAR struct mac802154_txframe_s *indirect_tail;
+
+ uint8_t txdesc_count;
+ struct ieee802154_txdesc_s txdesc[CONFIG_IEEE802154_NTXDESC];
+
+ /* Support a singly linked list of frames received */
+ FAR struct ieee802154_data_ind_s *dataind_head;
+ FAR struct ieee802154_data_ind_s *dataind_tail;
+
+ /* MAC PIB attributes, grouped to save memory */
+
+ /* Holds all address information (Extended, Short, and PAN ID) for the MAC. */
+
+ struct ieee802154_addr_s addr;
+
+ /* Holds all address information (Extended, Short) for Coordinator */
+
+ struct ieee802154_addr_s coord_addr;
+
+ /* The maximum number of symbols to wait for an acknowledgement frame to
+ * arrive following a transmitted data frame. [1] pg. 126
+ *
+ * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't
+ * sure at the time what the range of reasonable values was.
+ */
+
+ uint32_t ack_wait_dur;
+
+ /* The maximum time to wait either for a frame intended as a response to a
+ * data request frame or for a broadcast frame following a beacon with the
+ * Frame Pending field set to one. [1] pg. 127
+ *
+ * NOTE: This may be able to be a 16-bit or even an 8-bit number. I wasn't
+ * sure at the time what the range of reasonable values was.
+ */
+
+ uint32_t max_frame_wait_time;
+
+ /* The maximum time (in unit periods) that a transaction is stored by a
+ * coordinator and indicated in its beacon.
+ */
+
+ uint16_t trans_persist_time;
+
+ /* Contents of beacon payload */
+
+ uint8_t beacon_payload[IEEE802154_MAX_BEACON_PAYLOAD_LEN];
+ uint8_t beacon_payload_len; /* Length of beacon payload */
+
+ uint8_t batt_life_ext_periods; /* # of backoff periods during which rx is
+ * enabled after the IFS following beacon */
+
+ uint8_t bsn; /* Seq. num added to tx beacon frame */
+ uint8_t dsn; /* Seq. num added to tx data or MAC frame */
+ uint8_t max_retries; /* Max # of retries alloed after tx failure */
+
+ /* The maximum time, in multiples of aBaseSuperframeDuration, a device shall
+ * wait for a response command frame to be available following a request
+ * command frame. [1] 128.
+ */
+
+ uint8_t resp_wait_time;
+
+ /* The total transmit duration (including PHY header and FCS) specified in
+ * symbols. [1] pg. 129.
+ */
+
+ uint32_t tx_total_dur;
+
+ /* Start of 32-bit bitfield */
+
+ uint32_t is_assoc : 1; /* Are we associated to the PAN */
+ uint32_t assoc_permit : 1; /* Are we allowing assoc. as a coord. */
+ uint32_t auto_req : 1; /* Automatically send data req. if addr
+ * addr is in the beacon frame */
+
+ uint32_t batt_life_ext : 1; /* Is BLE enabled */
+ uint32_t gts_permit : 1; /* Is PAN Coord. accepting GTS reqs. */
+ uint32_t promisc_mode : 1; /* Is promiscuous mode on? */
+ uint32_t rng_support : 1; /* Does MAC sublayer support ranging */
+ uint32_t rx_when_idle : 1; /* Recvr. on during idle periods */
+ uint32_t sec_enabled : 1; /* Does MAC sublayer have security en. */
+
+ uint32_t max_csma_backoffs : 3; /* Max num backoffs for CSMA algorithm
+ * before declaring ch access failure */
+
+ uint32_t beacon_order : 4; /* Freq. that beacon is transmitted */
+
+ uint32_t superframe_order : 4; /* Length of active portion of outgoing
+ * superframe, including the beacon */
+
+ /* The offset, measured is symbols, between the symbol boundary at which the
+ * MLME captures the timestamp of each transmitted and received frame, and
+ * the onset of the first symbol past the SFD, namely the first symbol of
+ * the frames [1] pg. 129.
+ */
+
+ uint32_t sync_symb_offset : 12;
+
+ /* End of 32-bit bitfield */
+
+ /* Start of 32-bit bitfield */
+
+ uint32_t beacon_tx_time : 24; /* Time of last beacon transmit */
+ uint32_t min_be : 4; /* Min value of backoff exponent (BE) */
+ uint32_t max_be : 4; /* Max value of backoff exponent (BE) */
+
+ /* End of 32-bit bitfield */
+
+ /* Start of 32-bit bitfield */
+
+ uint32_t tx_ctrl_active_dur : 17; /* Duration for which tx is permitted to
+ * be active */
+ uint32_t tx_ctrl_pause_dur : 1; /* Duration after tx before another tx is
+ * permitted. 0=2000, 1= 10000 */
+ uint32_t timestamp_support : 1; /* Does MAC layer supports timestamping */
+ uint32_t is_coord : 1; /* Is this device acting as coordinator */
+ /* 12-bits remaining */
+
+ /* End of 32-bit bitfield. */
+
+ /* TODO: Add Security-related MAC PIB attributes */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static inline int mac802154_takesem(sem_t *sem);
+#define mac802154_givesem(s) sem_post(s);
+
+static void mac802154_txdone_worker(FAR void *arg);
+static void mac802154_rxframe_worker(FAR void *arg);
+
+/* Internal Functions */
+
+static int mac802154_defaultmib(FAR struct ieee802154_privmac_s *priv);
+static int mac802154_applymib(FAR struct ieee802154_privmac_s *priv);
+
+/* IEEE 802.15.4 PHY Interface OPs */
+
+static int mac802154_poll_csma(FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR struct ieee802154_txdesc_s *tx_desc,
+ FAR struct iob_s **frame);
+
+static int mac802154_poll_gts(FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR struct ieee802154_txdesc_s *tx_desc,
+ FAR struct iob_s **frame);
+
+static void mac802154_txdone(FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR const struct ieee802154_txdesc_s *tx_desc);
+
+static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR struct ieee802154_data_ind_s *ind);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Map between ieee802154_addr_mode_e enum and actual address length */
+
+static const uint8_t mac802154_addr_length[4] = {0, 0, 2, 8};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mac802154_semtake
+ *
+ * Description:
+ * Acquire the semaphore used for access serialization.
+ *
+ ****************************************************************************/
+
+static inline int mac802154_takesem(sem_t *sem)
+{
+ /* Take a count from the semaphore, possibly waiting */
+
+ if (sem_wait(sem) < 0)
+ {
+ /* EINTR is the only error that we expect */
+
+ int errcode = get_errno();
+ DEBUGASSERT(errcode == EINTR);
+ return -errcode;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: mac802154_push_csma
+ *
+ * Description:
+ * Push a CSMA transaction onto the list
+ *
+ ****************************************************************************/
+
+static void mac802154_push_csma(FAR struct ieee802154_privmac_s *priv,
+ FAR struct mac802154_txframe_s *trans)
+{
+ /* Ensure the transactions forward link is NULL */
+
+ trans->flink = NULL;
+
+ /* If the tail is not empty, make the transaction pointed to by the tail,
+ * point to the new transaction */
+
+ if (priv->csma_tail != NULL)
+ {
+ priv->csma_tail->flink = trans;
+ }
+
+ /* Point the tail at the new transaction */
+
+ priv->csma_tail = trans;
+
+ /* If the head is NULL, we need to point it at the transaction since there
+ * is only one transaction in the list at this point */
+
+ if (priv->csma_head == NULL)
+ {
+ priv->csma_head = trans;
+ }
+}
+
+/****************************************************************************
+ * Name: mac802154_pop_csma
+ *
+ * Description:
+ * Pop a CSMA transaction from the list
+ *
+ ****************************************************************************/
+
+static FAR struct mac802154_txframe_s *
+ mac802154_pop_csma(FAR struct ieee802154_privmac_s *priv)
+{
+ FAR struct mac802154_txframe_s *trans;
+
+ if (priv->csma_head == NULL)
+ {
+ return NULL;
+ }
+
+ /* Get the transaction from the head of the list */
+
+ trans = priv->csma_head;
+ trans->flink = NULL;
+
+ /* Move the head pointer to the next transaction */
+
+ priv->csma_head = trans->flink;
+
+ /* If the head is now NULL, the list is empty, so clear the tail too */
+
+ if (priv->csma_head == NULL)
+ {
+ priv->csma_tail = NULL;
+ }
+
+ return trans;
+}
+
+/****************************************************************************
+ * Name: mac802154_push_dataind
+ *
+ * Description:
+ * Push a data indication onto the list to be processed
+ *
+ ****************************************************************************/
+
+static void mac802154_push_dataind(FAR struct ieee802154_privmac_s *priv,
+ FAR struct ieee802154_data_ind_s *ind)
+{
+ /* Ensure the forward link is NULL */
+
+ ind->flink = NULL;
+
+ /* If the tail is not empty, make the frame pointed to by the tail,
+ * point to the new data indication */
+
+ if (priv->dataind_tail != NULL)
+ {
+ priv->dataind_tail->flink = ind;
+ }
+
+ /* Point the tail at the new frame */
+
+ priv->dataind_tail = ind;
+
+ /* If the head is NULL, we need to point it at the data indication since there
+ * is only one indication in the list at this point */
+
+ if (priv->dataind_head == NULL)
+ {
+ priv->dataind_head = ind;
+ }
+}
+
+/****************************************************************************
+ * Name: mac802154_pop_dataind
+ *
+ * Description:
+ * Pop a data indication from the list
+ *
+ ****************************************************************************/
+
+static FAR struct ieee802154_data_ind_s *
+ mac802154_pop_dataind(FAR struct ieee802154_privmac_s *priv)
+{
+ FAR struct ieee802154_data_ind_s *ind;
+
+ if (priv->dataind_head == NULL)
+ {
+ return NULL;
+ }
+
+ /* Get the data indication from the head of the list */
+
+ ind = priv->dataind_head;
+ ind->flink = NULL;
+
+ /* Move the head pointer to the next data indication */
+
+ priv->dataind_head = ind->flink;
+
+ /* If the head is now NULL, the list is empty, so clear the tail too */
+
+ if (priv->dataind_head == NULL)
+ {
+ priv->dataind_tail = NULL;
+ }
+
+ return ind;
+}
+
+/****************************************************************************
+ * Name: mac802154_defaultmib
+ *
+ * Description:
+ * Set the MIB to its default values.
+ *
+ ****************************************************************************/
+
+static int mac802154_defaultmib(FAR struct ieee802154_privmac_s *priv)
+{
+ priv->is_assoc = false; /* Not associated with a PAN */
+ priv->assoc_permit = false; /* Device (if coord) not accepting association */
+ priv->auto_req = true; /* Auto send data req if addr. in beacon */
+ priv->batt_life_ext = false; /* BLE disabled */
+ priv->beacon_payload_len = 0; /* Beacon payload NULL */
+ priv->beacon_order = 15; /* Non-beacon enabled network */
+ priv->superframe_order = 15; /* Length of active portion of outgoing SF */
+ priv->beacon_tx_time = 0; /* Device never sent a beacon */
+#warning Set BSN and DSN to random values!
+ priv->bsn = 0;
+ priv->dsn = 0;
+ priv->gts_permit = true; /* PAN Coord accepting GTS requests */
+ priv->min_be = 3; /* Min value of backoff exponent (BE) */
+ priv->max_be = 5; /* Max value of backoff exponent (BE) */
+ priv->max_csma_backoffs = 4; /* Max # of backoffs before failure */
+ priv->max_retries = 3; /* Max # of retries allowed after failure */
+ priv->promisc_mode = false; /* Device not in promiscuous mode */
+ priv->rng_support = false; /* Ranging not yet supported */
+ priv->resp_wait_time = 32; /* 32 SF durations */
+ priv->rx_when_idle = false; /* Don't receive while idle */
+ priv->sec_enabled = false; /* Security disabled by default */
+ priv->tx_total_dur = 0; /* 0 transmit duration */
+
+ priv->trans_persist_time = 0x01F4;
+
+
+ /* Reset the Coordinator address */
+
+ priv->coord_addr.mode = IEEE802154_ADDRMODE_NONE;
+ priv->coord_addr.saddr = IEEE802154_SADDR_UNSPEC;
+ memcpy(&priv->coord_addr.eaddr[0], IEEE802154_EADDR_UNSPEC,
+ IEEE802154_EADDR_LEN);
+
+ /* Reset the device's address */
+
+ priv->addr.mode = IEEE802154_ADDRMODE_NONE;
+ priv->addr.panid = IEEE802154_PAN_UNSPEC;
+ priv->addr.saddr = IEEE802154_SADDR_UNSPEC;
+ memcpy(&priv->addr.eaddr[0], IEEE802154_EADDR_UNSPEC, IEEE802154_EADDR_LEN);
+
+
+ /* These attributes are effected and determined based on the PHY. Need to
+ * figure out how to "share" attributes between the radio driver and this
+ * MAC layer
+ *
+ * macAckWaitDuration
+ * macBattLifeExtPeriods
+ * macMaxFrameTotalWaitTime
+ * macLIFSPeriod
+ * macSIFSPeriod
+ * macSyncSymbolOffset
+ * macTimestampSupported
+ * macTxControlActiveDuration
+ * macTxControlPauseDuration
+ */
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: mac802154_applymib
+ *
+ * Description:
+ * Some parts of the MIB must be sent to the radio device. This routine
+ * calls the radio device routines to store the related parameters in the
+ * radio driver. It must be called each time a MIB parameter is changed.
+ *
+ ****************************************************************************/
+
+static int mac802154_applymib(FAR struct ieee802154_privmac_s *priv)
+{
+ return OK;
+}
+
+/****************************************************************************
+ * Name: mac802154_poll_csma
+ *
+ * Description:
+ * Called from the radio driver through the callback struct. This function is
+ * called when the radio has room for another CSMA transaction. If the MAC
+ * layer has a CSMA transaction, it copies it into the supplied buffer and
+ * returns the length. A descriptor is also populated with the transaction.
+ *
+ ****************************************************************************/
+
+static int mac802154_poll_csma(FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR struct ieee802154_txdesc_s *tx_desc,
+ FAR struct iob_s **frame)
+{
+ FAR struct mac802154_radiocb_s *cb =
+ (FAR struct mac802154_radiocb_s *)radiocb;
+ FAR struct ieee802154_privmac_s *priv;
+ FAR struct mac802154_txframe_s *trans;
+
+ DEBUGASSERT(cb != NULL && cb->priv != NULL);
+ priv = cb->priv;
+
+ /* Get exclusive access to the driver structure. We don't care about any
+ * signals so if we see one, just go back to trying to get access again.
+ */
+
+ while (mac802154_takesem(&priv->exclsem) != 0);
+
+ /* Check to see if there are any CSMA transactions waiting */
+
+ trans = mac802154_pop_csma(priv);
+ mac802154_givesem(&priv->exclsem);
+
+ if (trans != NULL)
+ {
+ /* Setup the transmit descriptor */
+
+ tx_desc->handle = trans->msdu_handle;
+
+ *frame = trans->frame;
+
+ /* Now that we've passed off the data, notify the waiting thread.
+ * NOTE: The transaction was allocated on the waiting thread's stack so
+ * it will be automatically deallocated when that thread awakens and
+ * returns. */
+
+ sem_post(&trans->sem);
+ return (trans->frame->io_len);
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: mac802154_poll_gts
+ *
+ * Description:
+ * Called from the radio driver through the callback struct. This function is
+ * called when the radio has room for another GTS transaction. If the MAC
+ * layer has a GTS transaction, it copies it into the supplied buffer and
+ * returns the length. A descriptor is also populated with the transaction.
+ *
+ ****************************************************************************/
+
+static int mac802154_poll_gts(FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR struct ieee802154_txdesc_s *tx_desc,
+ FAR struct iob_s **frame)
+{
+ FAR struct mac802154_radiocb_s *cb =
+ (FAR struct mac802154_radiocb_s *)radiocb;
+ FAR struct ieee802154_privmac_s *priv;
+ FAR struct mac802154_txframe_s *trans;
+ int ret = 0;
+
+ DEBUGASSERT(cb != NULL && cb->priv != NULL);
+ priv = cb->priv;
+
+ /* Get exclusive access to the driver structure. We don't care about any
+ * signals so if we see one, just go back to trying to get access again.
+ */
+
+ while (mac802154_takesem(&priv->exclsem) != 0);
+
+#warning Missing logic.
+
+ mac802154_givesem(&priv->exclsem);
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: mac802154_txdone
+ *
+ * Description:
+ * Called from the radio driver through the callback struct. This function is
+ * called when the radio has completed a transaction. The txdesc passed gives
+ * provides information about the completed transaction including the original
+ * handle provided when the transaction was created and the status of the
+ * transaction. This function copies the descriptor and schedules work to
+ * handle the transaction without blocking the radio.
+ *
+ ****************************************************************************/
+
+static void mac802154_txdone(FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR const struct ieee802154_txdesc_s *tx_desc)
+{
+ FAR struct mac802154_radiocb_s *cb =
+ (FAR struct mac802154_radiocb_s *)radiocb;
+ FAR struct ieee802154_privmac_s *priv;
+
+ DEBUGASSERT(cb != NULL && cb->priv != NULL);
+ priv = cb->priv;
+
+ /* Get exclusive access to the driver structure. We don't care about any
+ * signals so if we see one, just go back to trying to get access again.
+ */
+
+ while (mac802154_takesem(&priv->exclsem) != 0);
+
+ /* Check to see if there is an available tx descriptor slot. If there is
+ * not we simply drop the notification */
+
+ if (priv->txdesc_count < CONFIG_IEEE802154_NTXDESC)
+ {
+ /* Copy the txdesc over and link it into our list */
+
+ memcpy(&priv->txdesc[priv->txdesc_count++], tx_desc,
+ sizeof(struct ieee802154_txdesc_s));
+ }
+ else
+ {
+ wlinfo("MAC802154: No room for TX Desc.\n");
+ }
+
+ mac802154_givesem(&priv->exclsem);
+
+ /* Schedule work with the work queue to process the completion further */
+
+ if (work_available(&priv->tx_work))
+ {
+ work_queue(MAC802154_WORK, &priv->tx_work, mac802154_txdone_worker,
+ (FAR void *)priv, 0);
+ }
+}
+
+/****************************************************************************
+ * Name: mac802154_txdone_worker
+ *
+ * Description:
+ * Worker function scheduled from mac802154_txdone. This function pops any
+ * TX descriptors off of the list and calls the next highest layers callback
+ * to inform the layer of the completed transaction and the status of it.
+ *
+ ****************************************************************************/
+
+static void mac802154_txdone_worker(FAR void *arg)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)arg;
+ int i = 0;
+
+ /* Get exclusive access to the driver structure. We don't care about any
+ * signals so if we see one, just go back to trying to get access again.
+ */
+
+ while (mac802154_takesem(&priv->exclsem) != 0);
+
+ /* For each pending TX descriptor, send an application callback */
+
+ for (i = 0; i < priv->txdesc_count; i++)
+ {
+ priv->cb->mcps_notify(priv->cb, IEEE802154_NOTIFY_CONF_DATA,
+ (FAR const union ieee802154_mcps_notify_u *) &priv->txdesc[i]);
+ }
+
+ /* We've handled all the descriptors and no further desc could have been added
+ * since we have the struct locked */
+
+ priv->txdesc_count = 0;
+
+ mac802154_givesem(&priv->exclsem);
+}
+
+/****************************************************************************
+ * Name: mac802154_rxframe
+ *
+ * Description:
+ * Called from the radio driver through the callback struct. This function is
+ * called when the radio has received a frame. The frame is passed in an iob,
+ * so that we can free it when we are done processing. A pointer to the RX
+ * descriptor is passed along with the iob, but it must be copied here as it
+ * is allocated directly on the caller's stack. We simply link the frame,
+ * copy the RX descriptor, and schedule a worker to process the frame later so
+ * that we do not hold up the radio.
+ *
+ ****************************************************************************/
+
+static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb,
+ FAR struct ieee802154_data_ind_s *ind)
+{
+ FAR struct mac802154_radiocb_s *cb =
+ (FAR struct mac802154_radiocb_s *)radiocb;
+ FAR struct ieee802154_privmac_s *priv;
+
+ DEBUGASSERT(cb != NULL && cb->priv != NULL);
+ priv = cb->priv;
+
+ /* Get exclusive access to the driver structure. We don't care about any
+ * signals so if we see one, just go back to trying to get access again.
+ */
+
+ while (mac802154_takesem(&priv->exclsem) != 0);
+
+ /* Push the iob onto the tail of the frame list for processing */
+
+ mac802154_push_dataind(priv, ind);
+
+ mac802154_givesem(&priv->exclsem);
+
+ /* Schedule work with the work queue to process the completion further */
+
+ if (work_available(&priv->rx_work))
+ {
+ work_queue(MAC802154_WORK, &priv->rx_work, mac802154_rxframe_worker,
+ (FAR void *)priv, 0);
+ }
+}
+
+/****************************************************************************
+ * Name: mac802154_rxframe_worker
+ *
+ * Description:
+ * Worker function scheduled from mac802154_rxframe. This function processes
+ * any frames in the list. Frames intended to be consumed by the MAC layer
+ * will not produce any callbacks to the next highest layer. Frames intended
+ * for the application layer will be forwarded to them.
+ *
+ ****************************************************************************/
+
+static void mac802154_rxframe_worker(FAR void *arg)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)arg;
+ FAR struct ieee802154_data_ind_s *ind;
+ union ieee802154_mcps_notify_u mcps_notify;
+ FAR struct iob_s *frame;
+ uint16_t *frame_ctrl;
+ bool panid_comp;
+ uint8_t ftype;
+
+ while(1)
+ {
+ /* Get exclusive access to the driver structure. We don't care about any
+ * signals so if we see one, just go back to trying to get access again.
+ */
+
+ while (mac802154_takesem(&priv->exclsem) != 0);
+
+ /* Push the iob onto the tail of the frame list for processing */
+
+ ind = mac802154_pop_dataind(priv);
+
+ if (ind == NULL)
+ {
+ mac802154_givesem(&priv->exclsem);
+ break;
+ }
+
+ /* Once we pop off the indication, we don't need to keep the mac locked */
+
+ mac802154_givesem(&priv->exclsem);
+
+ /* Get a local copy of the frame to make it easier to access */
+
+ frame = ind->frame;
+
+ /* Set a local pointer to the frame control then move the offset past
+ * the frame control field
+ */
+
+ frame_ctrl = (uint16_t *)&frame->io_data[frame->io_offset];
+ frame->io_offset += 2;
+
+ /* We use the data_ind_s as a container for the frame information even if
+ * this isn't a data frame
+ */
+
+ ind->src.mode = (*frame_ctrl & IEEE802154_FRAMECTRL_SADDR) >>
+ IEEE802154_FRAMECTRL_SHIFT_SADDR;
+
+ ind->dest.mode = (*frame_ctrl & IEEE802154_FRAMECTRL_DADDR) >>
+ IEEE802154_FRAMECTRL_SHIFT_DADDR;
+
+ panid_comp = (*frame_ctrl & IEEE802154_FRAMECTRL_PANIDCOMP) >>
+ IEEE802154_FRAMECTRL_SHIFT_PANIDCOMP;
+
+ ind->dsn = frame->io_data[frame->io_offset++];
+
+ /* If the destination address is included */
+
+ if (ind->dest.mode != IEEE802154_ADDRMODE_NONE)
+ {
+ /* Get the destination PAN ID */
+
+ ind->dest.panid = frame->io_data[frame->io_offset];
+ frame->io_offset += 2;
+
+ if (ind->dest.mode == IEEE802154_ADDRMODE_SHORT)
+ {
+ ind->dest.saddr = frame->io_data[frame->io_offset];
+ frame->io_offset += 2;
+ }
+ else if (ind->dest.mode == IEEE802154_ADDRMODE_EXTENDED)
+ {
+ memcpy(&ind->dest.eaddr[0], &frame->io_data[frame->io_offset],
+ IEEE802154_EADDR_LEN);
+ frame->io_offset += 8;
+ }
+ }
+
+ if (ind->src.mode != IEEE802154_ADDRMODE_NONE)
+ {
+ /* If the source address is included, and the PAN ID compression field
+ * is set, get the PAN ID from the header.
+ */
+
+ if (!panid_comp)
+ {
+ ind->src.panid = frame->io_data[frame->io_offset];
+ frame->io_offset += 2;
+ }
+
+ /* If the source address is included, and the PAN ID compression field
+ * is set, the source PAN ID is the same as the destination PAN ID
+ */
+
+ else
+ {
+ ind->src.panid = ind->dest.panid;
+ }
+
+ if (ind->src.mode == IEEE802154_ADDRMODE_SHORT)
+ {
+ ind->src.saddr = frame->io_data[frame->io_offset];
+ frame->io_offset += 2;
+ }
+ else if (ind->src.mode == IEEE802154_ADDRMODE_EXTENDED)
+ {
+ memcpy(&ind->src.eaddr[0], &frame->io_data[frame->io_offset],
+ IEEE802154_EADDR_LEN);
+ frame->io_offset += 8;
+ }
+ }
+
+ ftype = (*frame_ctrl & IEEE802154_FRAMECTRL_FTYPE) >>
+ IEEE802154_FRAMECTRL_SHIFT_FTYPE;
+
+ if (ftype == IEEE802154_FRAME_DATA)
+ {
+ /* If there is a registered MCPS callback receiver registered, send
+ * the frame, otherwise, throw it out.
+ */
+
+ if (priv->cb->mcps_notify != NULL)
+ {
+ mcps_notify.dataind = ind;
+ priv->cb->mcps_notify(priv->cb, IEEE802154_NOTIFY_IND_DATA,
+ &mcps_notify);
+ }
+ else
+ {
+ /* Free the data indication struct from the pool */
+
+ ieee802154_ind_free(ind);
+ }
+ }
+ else if (ftype == IEEE802154_FRAME_COMMAND)
+ {
+
+ }
+ else if (ftype == IEEE802154_FRAME_BEACON)
+ {
+
+ }
+ else
+ {
+ /* The radio layer is responsible for handling all ACKs and retries. If for
+ * some reason an ACK gets here, just throw it out.
+ */
+ }
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mac802154_create
+ *
+ * Description:
+ * Create a 802.15.4 MAC device from a 802.15.4 compatible radio device.
+ *
+ * The returned MAC structure should be passed to either the next highest
+ * layer in the network stack, or registered with a mac802154dev character
+ * or network drivers. In any of these scenarios, the next highest layer
+ * should register a set of callbacks with the MAC layer by setting the
+ * mac->cbs member.
+ *
+ * NOTE: This API does not create any device accessible to userspace. If
+ * you want to call these APIs from userspace, you have to wrap your mac
+ * in a character device via mac802154_device.c.
+ *
+ * Input Parameters:
+ * radiodev - an instance of an IEEE 802.15.4 radio
+ *
+ * Returned Value:
+ * An opaque reference to the MAC state data.
+ *
+ ****************************************************************************/
+
+MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
+{
+ FAR struct ieee802154_privmac_s *mac;
+ FAR struct ieee802154_radiocb_s *radiocb;
+
+ /* Allocate object */
+
+ mac = (FAR struct ieee802154_privmac_s *)
+ kmm_zalloc(sizeof(struct ieee802154_privmac_s));
+
+ if (mac == NULL)
+ {
+ return NULL;
+ }
+
+ /* Allow exclusive access to the privmac struct */
+
+ sem_init(&mac->exclsem, 0, 1);
+
+ /* Initialize fields */
+
+ mac->radio = radiodev;
+
+ mac802154_defaultmib(mac);
+ mac802154_applymib(mac);
+
+ /* Initialize the Radio callbacks */
+
+ mac->radiocb.priv = mac;
+
+ radiocb = &mac->radiocb.cb;
+ radiocb->poll_csma = mac802154_poll_csma;
+ radiocb->poll_gts = mac802154_poll_gts;
+ radiocb->txdone = mac802154_txdone;
+ radiocb->rxframe = mac802154_rxframe;
+
+ /* Bind our callback structure */
+
+ radiodev->ops->bind(radiodev, &mac->radiocb.cb);
+
+ /* Initialize our data indication pool */
+
+ ieee802154_indpool_initialize();
+
+ return (MACHANDLE)mac;
+}
+
+/****************************************************************************
+ * Name: mac802154_bind
+ *
+ * Description:
+ * Bind the MAC callback table to the MAC state.
+ *
+ * Parameters:
+ * mac - Reference to the MAC driver state structure
+ * cb - MAC callback operations
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ ****************************************************************************/
+
+int mac802154_bind(MACHANDLE mac, FAR const struct ieee802154_maccb_s *cb)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+
+ priv->cb = cb;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: mac802154_ioctl
+ *
+ * Description:
+ * Handle MAC and radio IOCTL commands directed to the MAC.
+ *
+ * Parameters:
+ * mac - Reference to the MAC driver state structure
+ * cmd - The IOCTL command
+ * arg - The argument for the IOCTL command
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ ****************************************************************************/
+
+int mac802154_ioctl(MACHANDLE mac, int cmd, unsigned long arg)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ int ret = -EINVAL;
+
+ FAR union ieee802154_macarg_u *macarg =
+ (FAR union ieee802154_macarg_u *)((uintptr_t)arg);
+
+ DEBUGASSERT(priv != NULL);
+
+ /* Check for IOCTLs aimed at the IEEE802.15.4 MAC layer */
+
+ if (_MAC802154IOCVALID(cmd))
+ {
+ /* Handle the MAC IOCTL command */
+
+ switch (cmd)
+ {
+ case MAC802154IOC_MLME_ASSOC_REQUEST:
+ {
+ ret = mac802154_req_associate(mac, &macarg->assocreq);
+ }
+ break;
+ case MAC802154IOC_MLME_ASSOC_RESPONSE:
+ {
+ ret = mac802154_resp_associate(mac, &macarg->assocresp);
+ }
+ break;
+ case MAC802154IOC_MLME_DISASSOC_REQUEST:
+ {
+ ret = mac802154_req_disassociate(mac, &macarg->disassocreq);
+ }
+ break;
+ case MAC802154IOC_MLME_GET_REQUEST:
+ {
+ ret = mac802154_req_get(mac, macarg->getreq.pib_attr,
+ &macarg->getreq.attr_value);
+ }
+ break;
+ case MAC802154IOC_MLME_GTS_REQUEST:
+ {
+ ret = mac802154_req_gts(mac, &macarg->gtsreq);
+ }
+ break;
+ case MAC802154IOC_MLME_ORPHAN_RESPONSE:
+ {
+ ret = mac802154_resp_orphan(mac, &macarg->orphanresp);
+ }
+ break;
+ case MAC802154IOC_MLME_RESET_REQUEST:
+ {
+ ret = mac802154_req_reset(mac, macarg->resetreq.rst_pibattr);
+ }
+ break;
+ case MAC802154IOC_MLME_RXENABLE_REQUEST:
+ {
+ ret = mac802154_req_rxenable(mac, &macarg->rxenabreq);
+ }
+ break;
+ case MAC802154IOC_MLME_SCAN_REQUEST:
+ {
+ ret = mac802154_req_scan(mac, &macarg->scanreq);
+ }
+ break;
+ case MAC802154IOC_MLME_SET_REQUEST:
+ {
+ ret = mac802154_req_set(mac, macarg->setreq.pib_attr,
+ &macarg->setreq.attr_value);
+ }
+ break;
+ case MAC802154IOC_MLME_START_REQUEST:
+ {
+ ret = mac802154_req_start(mac, &macarg->startreq);
+ }
+ break;
+ case MAC802154IOC_MLME_SYNC_REQUEST:
+ {
+ ret = mac802154_req_sync(mac, &macarg->syncreq);
+ }
+ break;
+ case MAC802154IOC_MLME_POLL_REQUEST:
+ {
+ ret = mac802154_req_poll(mac, &macarg->pollreq);
+ }
+ break;
+ default:
+ wlerr("ERROR: Unrecognized cmd: %d\n", cmd);
+ ret = -ENOTTY;
+ break;
+ }
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * MAC Interface Operations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mac802154_get_mhrlen
+ *
+ * Description:
+ * Calculate the MAC header length given the frame meta-data.
+ *
+ ****************************************************************************/
+
+int mac802154_get_mhrlen(MACHANDLE mac,
+ FAR const struct ieee802154_frame_meta_s *meta)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ int ret = 3; /* Always frame control (2 bytes) and seq. num (1 byte) */
+
+ /* Check to make sure both the dest address and the source address are not set
+ * to NONE */
+
+ if (meta->dest_addr.mode == IEEE802154_ADDRMODE_NONE &&
+ meta->src_addr_mode == IEEE802154_ADDRMODE_NONE)
+ {
+ return -EINVAL;
+ }
+
+ /* The source address can only be set to NONE if the device is the PAN coord */
+
+ if (meta->src_addr_mode == IEEE802154_ADDRMODE_NONE && !priv->is_coord)
+ {
+ return -EINVAL;
+ }
+
+ /* Add the destination address length */
+
+ ret += mac802154_addr_length[meta->dest_addr.mode];
+
+ /* Add the source address length */
+
+ ret += mac802154_addr_length[ meta->src_addr_mode];
+
+ /* If both destination and source addressing information is present, the MAC
+ * sublayer shall compare the destination and source PAN identifiers.
+ * [1] pg. 41.
+ */
+
+ if (meta->src_addr_mode != IEEE802154_ADDRMODE_NONE &&
+ meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE)
+ {
+ /* If the PAN identifiers are identical, the PAN ID Compression field
+ * shall be set to one, and the source PAN identifier shall be omitted
+ * from the transmitted frame. [1] pg. 41.
+ */
+
+ if (meta->dest_addr.panid == priv->addr.panid)
+ {
+ ret += 2; /* 2 bytes for destination PAN ID */
+ return ret;
+ }
+ }
+
+ /* If we are here, PAN ID compression is off, so include the dest and source
+ * PAN ID if the respective address is included
+ */
+
+ if (meta->src_addr_mode != IEEE802154_ADDRMODE_NONE)
+ {
+ ret += 2; /* 2 bytes for source PAN ID */
+ }
+
+ if (meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE)
+ {
+ ret += 2; /* 2 bytes for destination PAN ID */
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_data
+ *
+ * Description:
+ * The MCPS-DATA.request primitive requests the transfer of a data SPDU
+ * (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_data callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_data(MACHANDLE mac,
+ FAR const struct ieee802154_frame_meta_s *meta,
+ FAR struct iob_s *frame)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ FAR struct mac802154_txframe_s trans;
+ uint16_t *frame_ctrl;
+ uint8_t mhr_len = 3; /* Start assuming frame control and seq. num */
+ int ret;
+
+ /* Check the required frame size */
+
+ if (frame->io_len > IEEE802154_MAX_PHY_PACKET_SIZE)
+ {
+ return -E2BIG;
+ }
+
+ /* Cast the first two bytes of the IOB to a uint16_t frame control field */
+
+ frame_ctrl = (uint16_t *)&frame->io_data[0];
+
+ /* Ensure we start with a clear frame control field */
+
+ *frame_ctrl = 0;
+
+ /* Set the frame type to Data */
+
+ *frame_ctrl |= IEEE802154_FRAME_DATA << IEEE802154_FRAMECTRL_SHIFT_FTYPE;
+
+ /* If the msduLength is greater than aMaxMACSafePayloadSize, the MAC
+ * sublayer will set the Frame Version to one. [1] pg. 118.
+ */
+
+ if ((frame->io_len - frame->io_offset) > IEEE802154_MAX_SAFE_MAC_PAYLOAD_SIZE)
+ {
+ *frame_ctrl |= IEEE802154_FRAMECTRL_VERSION;
+ }
+
+ /* If the TXOptions parameter specifies that an acknowledged transmission
+ * is required, the AR field will be set appropriately, as described in
+ * 5.1.6.4 [1] pg. 118.
+ */
+
+ *frame_ctrl |= (meta->msdu_flags.ack_tx << IEEE802154_FRAMECTRL_SHIFT_ACKREQ);
+
+ /* If the destination address is present, copy the PAN ID and one of the
+ * addresses, depending on mode, into the MHR.
+ */
+
+ if (meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE)
+ {
+ memcpy(&frame->io_data[mhr_len], &meta->dest_addr.panid, 2);
+ mhr_len += 2;
+
+ if (meta->dest_addr.mode == IEEE802154_ADDRMODE_SHORT)
+ {
+ memcpy(&frame->io_data[mhr_len], &meta->dest_addr.saddr, 2);
+ mhr_len += 2;
+ }
+ else if (meta->dest_addr.mode == IEEE802154_ADDRMODE_EXTENDED)
+ {
+ memcpy(&frame->io_data[mhr_len], &meta->dest_addr.eaddr,
+ IEEE802154_EADDR_LEN);
+
+ mhr_len += IEEE802154_EADDR_LEN;
+ }
+ }
+
+ /* Set the destination addr mode inside the frame control field */
+
+ *frame_ctrl |= (meta->dest_addr.mode << IEEE802154_FRAMECTRL_SHIFT_DADDR);
+
+ /* From this point on, we need exclusive access to the privmac struct */
+
+ ret = mac802154_takesem(&priv->exclsem);
+ if (ret < 0)
+ {
+ wlerr("ERROR: mac802154_takesem failed: %d\n", ret);
+ return ret;
+ }
+
+ /* If both destination and source addressing information is present, the MAC
+ * sublayer shall compare the destination and source PAN identifiers.
+ * [1] pg. 41.
+ */
+
+ if (meta->src_addr_mode != IEEE802154_ADDRMODE_NONE &&
+ meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE)
+ {
+ /* If the PAN identifiers are identical, the PAN ID Compression field
+ * shall be set to one, and the source PAN identifier shall be omitted
+ * from the transmitted frame. [1] pg. 41.
+ */
+
+ if (meta->dest_addr.panid == priv->addr.panid)
+ {
+ *frame_ctrl |= IEEE802154_FRAMECTRL_PANIDCOMP;
+ }
+ }
+
+ if (meta->src_addr_mode != IEEE802154_ADDRMODE_NONE)
+ {
+ /* If the destination address is not included, or if PAN ID Compression
+ * is off, we need to include the Source PAN ID.
+ */
+
+ if ((meta->dest_addr.mode == IEEE802154_ADDRMODE_NONE) ||
+ (!(*frame_ctrl & IEEE802154_FRAMECTRL_PANIDCOMP)))
+ {
+ memcpy(&frame->io_data[mhr_len], &priv->addr.panid, 2);
+ mhr_len += 2;
+ }
+
+ if (meta->src_addr_mode == IEEE802154_ADDRMODE_SHORT)
+ {
+ memcpy(&frame->io_data[mhr_len], &priv->addr.saddr, 2);
+ mhr_len += 2;
+ }
+ else if (meta->src_addr_mode == IEEE802154_ADDRMODE_EXTENDED)
+ {
+ memcpy(&frame->io_data[mhr_len], &priv->addr.eaddr,
+ IEEE802154_EADDR_LEN);
+
+ mhr_len += IEEE802154_EADDR_LEN;
+ }
+ }
+
+ /* Set the source addr mode inside the frame control field */
+
+ *frame_ctrl |= (meta->src_addr_mode << IEEE802154_FRAMECTRL_SHIFT_SADDR);
+
+ /* Each time a data or a MAC command frame is generated, the MAC sublayer
+ * shall copy the value of macDSN into the Sequence Number field of the MHR
+ * of the outgoing frame and then increment it by one. [1] pg. 40.
+ */
+
+ frame->io_data[2] = priv->dsn++;
+
+ /* The MAC header we just created must never have exceeded where the app
+ * data starts. This should never happen since the offset should have
+ * been set via the same logic to calculate the header length as the logic
+ * here that created the header
+ */
+
+ DEBUGASSERT(mhr_len == frame->io_offset);
+
+ frame->io_offset = 0; /* Set the offset to 0 to include the header */
+
+ /* Setup our transaction */
+
+ trans.msdu_handle = meta->msdu_handle;
+ trans.frame = frame;
+ sem_init(&trans.sem, 0, 1);
+
+ /* If the TxOptions parameter specifies that a GTS transmission is required,
+ * the MAC sublayer will determine whether it has a valid GTS as described
+ * 5.1.7.3. If a valid GTS could not be found, the MAC sublayer will discard
+ * the MSDU. If a valid GTS was found, the MAC sublayer will defer, if
+ * necessary, until the GTS. If the TxOptions parameter specifies that a GTS
+ * transmission is not required, the MAC sublayer will transmit the MSDU using
+ * either slotted CSMA-CA in the CAP for a beacon-enabled PAN or unslotted
+ * CSMA-CA for a nonbeacon-enabled PAN. Specifying a GTS transmission in the
+ * TxOptions parameter overrides an indirect transmission request.
+ * [1] pg. 118.
+ */
+
+ if (meta->msdu_flags.gts_tx)
+ {
+ /* TODO: Support GTS transmission. This should just change where we link
+ * the transaction. Instead of going in the CSMA transaction list, it
+ * should be linked to the GTS' transaction list. We'll need to check if
+ * the GTS is valid, and then find the GTS, before linking. Note, we also
+ * don't have to try and kick-off any transmission here.
+ */
+
+ return -ENOTSUP;
+ }
+ else
+ {
+ /* If the TxOptions parameter specifies that an indirect transmission is
+ * required and this primitive is received by the MAC sublayer of a
+ * coordinator, the data frame is sent using indirect transmission, as
+ * described in 5.1.5 and 5.1.6.3. [1]
+ */
+
+ if (meta->msdu_flags.indirect_tx)
+ {
+ /* If the TxOptions parameter specifies that an indirect transmission
+ * is required and if the device receiving this primitive is not a
+ * coordinator, the destination address is not present, or the
+ * TxOptions parameter also specifies a GTS transmission, the indirect
+ * transmission option will be ignored. [1]
+ *
+ * NOTE: We don't just ignore the parameter. Instead, we throw an
+ * error, since this really shouldn't be happening.
+ */
+
+ if (priv->is_coord && meta->dest_addr.mode != IEEE802154_ADDRMODE_NONE)
+ {
+ /* Link the transaction into the indirect_trans list */
+
+ }
+ else
+ {
+ return -EINVAL;
+ }
+ }
+ else
+ {
+ /* Link the transaction into the CSMA transaction list */
+
+ mac802154_push_csma(priv, &trans);
+
+ /* We no longer need to have the MAC layer locked. */
+
+ mac802154_givesem(&priv->exclsem);
+
+ /* Notify the radio driver that there is data available */
+
+ priv->radio->ops->txnotify_csma(priv->radio);
+
+ sem_wait(&trans.sem);
+ }
+ }
+
+ sem_destroy(&trans.sem);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_purge
+ *
+ * Description:
+ * The MCPS-PURGE.request primitive allows the next higher layer to purge
+ * an MSDU from the transaction queue. Confirmation is returned via
+ * the struct ieee802154_maccb_s->conf_purge callback.
+ *
+ * NOTE: The standard specifies that confirmation should be indicated via
+ * the asynchronous MLME-PURGE.confirm primitve. However, in our
+ * implementation we synchronously return the status from the request.
+ * Therefore, we merge the functionality of the MLME-PURGE.request and
+ * MLME-PURGE.confirm primitives together.
+ *
+ ****************************************************************************/
+
+int mac802154_req_purge(MACHANDLE mac, uint8_t msdu_handle)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_associate
+ *
+ * Description:
+ * The MLME-ASSOCIATE.request primitive allows a device to request an
+ * association with a coordinator. Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_associate callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_associate(MACHANDLE mac,
+ FAR struct ieee802154_assoc_req_s *req)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+
+ /* Set the channel of the PHY layer */
+
+ /* Set the channel page of the PHY layer */
+
+ /* Set the macPANId */
+
+ /* Set either the macCoordExtendedAddress and macCoordShortAddress
+ * depending on the CoordAddrMode in the primitive.
+ */
+
+ if (req->coord_addr.mode == IEEE802154_ADDRMODE_EXTENDED)
+ {
+
+ }
+ else if (req->coord_addr.mode == IEEE802154_ADDRMODE_EXTENDED)
+ {
+
+ }
+ else
+ {
+ return -EINVAL;
+ }
+
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_disassociate
+ *
+ * Description:
+ * The MLME-DISASSOCIATE.request primitive is used by an associated device to
+ * notify the coordinator of its intent to leave the PAN. It is also used by
+ * the coordinator to instruct an associated device to leave the PAN.
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_disassociate callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_disassociate(MACHANDLE mac,
+ FAR struct ieee802154_disassoc_req_s *req)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+
+/****************************************************************************
+ * Name: mac802154_req_gts
+ *
+ * Description:
+ * The MLME-GTS.request primitive allows a device to send a request to the PAN
+ * coordinator to allocate a new GTS or to deallocate an existing GTS.
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_gts callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_reset
+ *
+ * Description:
+ * The MLME-RESET.request primitive allows the next higher layer to request
+ * that the MLME performs a reset operation.
+ *
+ * NOTE: The standard specifies that confirmation should be provided via
+ * via the asynchronous MLME-RESET.confirm primitve. However, in our
+ * implementation we synchronously return the value immediately. Therefore,
+ * we merge the functionality of the MLME-RESET.request and MLME-RESET.confirm
+ * primitives together.
+ *
+ * Input Parameters:
+ * mac - Handle to the MAC layer instance
+ * rst_pibattr - Whether or not to reset the MAC PIB attributes to defaults
+ *
+ ****************************************************************************/
+
+int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr)
+{
+ FAR struct ieee802154_privmac_s * priv =
+ (FAR struct ieee802154_privmac_s *) mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_rxenable
+ *
+ * Description:
+ * The MLME-RX-ENABLE.request primitive allows the next higher layer to
+ * request that the receiver is enable for a finite period of time.
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_rxenable callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_rxenable(MACHANDLE mac,
+ FAR struct ieee802154_rxenable_req_s *req)
+{
+ FAR struct ieee802154_privmac_s * priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_scan
+ *
+ * Description:
+ * The MLME-SCAN.request primitive is used to initiate a channel scan over a
+ * given list of channels. A device can use a channel scan to measure the
+ * energy on the channel, search for the coordinator with which it associated,
+ * or search for all coordinators transmitting beacon frames within the POS of
+ * the scanning device. Scan results are returned
+ * via MULTIPLE calls to the struct ieee802154_maccb_s->conf_scan callback.
+ * This is a difference with the official 802.15.4 specification, implemented
+ * here to save memory.
+ *
+ ****************************************************************************/
+
+int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_get
+ *
+ * Description:
+ * The MLME-GET.request primitive requests information about a given PIB
+ * attribute.
+ *
+ * NOTE: The standard specifies that the attribute value should be returned
+ * via the asynchronous MLME-GET.confirm primitve. However, in our
+ * implementation, we synchronously return the value immediately.Therefore, we
+ * merge the functionality of the MLME-GET.request and MLME-GET.confirm
+ * primitives together.
+ *
+ ****************************************************************************/
+
+int mac802154_req_get(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr,
+ FAR union ieee802154_attr_val_u *attr_value)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_set
+ *
+ * Description:
+ * The MLME-SET.request primitive attempts to write the given value to the
+ * indicated MAC PIB attribute.
+ *
+ * NOTE: The standard specifies that confirmation should be indicated via
+ * the asynchronous MLME-SET.confirm primitve. However, in our implementation
+ * we synchronously return the status from the request. Therefore, we do merge
+ * the functionality of the MLME-SET.request and MLME-SET.confirm primitives
+ * together.
+ *
+ ****************************************************************************/
+
+int mac802154_req_set(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr,
+ FAR const union ieee802154_attr_val_u *attr_value)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ int ret;
+
+ switch (pib_attr)
+ {
+ case IEEE802154_PIB_MAC_EXTENDED_ADDR:
+ {
+ /* Set the MAC copy of the address in the table */
+
+ memcpy(&priv->addr.eaddr[0], &attr_value->mac.eaddr[0],
+ IEEE802154_EADDR_LEN);
+
+ /* Tell the radio about the attribute */
+
+ priv->radio->ops->set_attr(priv->radio, pib_attr, attr_value);
+
+ ret = IEEE802154_STATUS_SUCCESS;
+ }
+ break;
+ default:
+ {
+ /* The attribute may be handled soley in the radio driver, so pass
+ * it along.
+ */
+
+ ret = priv->radio->ops->set_attr(priv->radio, pib_attr, attr_value);
+ }
+ break;
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_start
+ *
+ * Description:
+ * The MLME-START.request primitive makes a request for the device to start
+ * using a new superframe configuration. Confirmation is returned
+ * via the struct ieee802154_maccb_s->conf_start callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_sync
+ *
+ * Description:
+ * The MLME-SYNC.request primitive requests to synchronize with the
+ * coordinator by acquiring and, if specified, tracking its beacons.
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->int_commstatus callback. TOCHECK.
+ *
+ ****************************************************************************/
+
+int mac802154_req_sync(MACHANDLE mac, FAR struct ieee802154_sync_req_s *req)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_req_poll
+ *
+ * Description:
+ * The MLME-POLL.request primitive prompts the device to request data from
+ * the coordinator. Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_poll callback, followed by a
+ * struct ieee802154_maccb_s->ind_data callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_resp_associate
+ *
+ * Description:
+ * The MLME-ASSOCIATE.response primitive is used to initiate a response to
+ * an MLME-ASSOCIATE.indication primitive.
+ *
+ ****************************************************************************/
+
+int mac802154_resp_associate(MACHANDLE mac,
+ FAR struct ieee802154_assoc_resp_s *resp)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: mac802154_resp_orphan
+ *
+ * Description:
+ * The MLME-ORPHAN.response primitive allows the next higher layer of a
+ * coordinator to respond to the MLME-ORPHAN.indication primitive.
+ *
+ ****************************************************************************/
+
+int mac802154_resp_orphan(MACHANDLE mac,
+ FAR struct ieee802154_orphan_resp_s *resp)
+{
+ FAR struct ieee802154_privmac_s *priv =
+ (FAR struct ieee802154_privmac_s *)mac;
+ return -ENOTTY;
+}
+
diff --git a/wireless/ieee802154/mac802154.h b/wireless/ieee802154/mac802154.h
new file mode 100644
index 00000000000..66fa5495cab
--- /dev/null
+++ b/wireless/ieee802154/mac802154.h
@@ -0,0 +1,345 @@
+/****************************************************************************
+ * wireless/ieee802154/mac802154.h
+ *
+ * Copyright (C) 2016 Sebastien Lorquet. All rights reserved.
+ * Copyright (C) 2017 Verge Inc. All rights reserved.
+ * Copyright (C) 2017 Gregory Nutt. All rights reserved.
+ *
+ * Author: Sebastien Lorquet
+ * Author: Anthony Merlino
+ *
+ * The naming and comments for various fields are taken directly
+ * from the IEEE 802.15.4 2011 standard.
+ *
+ * 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 __WIRELESS_IEEE802154__MAC802154_H
+#define __WIRELESS_IEEE802154__MAC802154_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+
+#include
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+struct iob_s; /* Forward reference */
+
+ /****************************************************************************
+ * Name: mac802154_bind
+ *
+ * Description:
+ * Bind the MAC callback table to the MAC state.
+ *
+ * Parameters:
+ * mac - Reference to the MAC driver state structure
+ * cb - MAC callback operations
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ ****************************************************************************/
+
+int mac802154_bind(MACHANDLE mac, FAR const struct ieee802154_maccb_s *cb);
+
+/****************************************************************************
+ * Name: mac802154_ioctl
+ *
+ * Description:
+ * Handle MAC and radio IOCTL commands directed to the MAC.
+ *
+ * Parameters:
+ * mac - Reference to the MAC driver state structure
+ * cmd - The IOCTL command
+ * arg - The argument for the IOCTL command
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ ****************************************************************************/
+
+int mac802154_ioctl(MACHANDLE mac, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * MAC Interface Operations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: mac802154_get_mhrlen
+ *
+ * Description:
+ * Calculate the MAC header length given the frame meta-data.
+ *
+ ****************************************************************************/
+
+int mac802154_get_mhrlen(MACHANDLE mac,
+ FAR const struct ieee802154_frame_meta_s *meta);
+
+/****************************************************************************
+ * Name: mac802154_req_data
+ *
+ * Description:
+ * The MCPS-DATA.request primitive requests the transfer of a data SPDU
+ * (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_data callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_data(MACHANDLE mac,
+ FAR const struct ieee802154_frame_meta_s *meta,
+ FAR struct iob_s *frame);
+
+/****************************************************************************
+ * Name: mac802154_req_purge
+ *
+ * Description:
+ * The MCPS-PURGE.request primitive allows the next higher layer to purge
+ * an MSDU from the transaction queue. Confirmation is returned via
+ * the struct ieee802154_maccb_s->conf_purge callback.
+ *
+ * NOTE: The standard specifies that confirmation should be indicated via
+ * the asynchronous MLME-PURGE.confirm primitve. However, in our
+ * implementation we synchronously return the status from the request.
+ * Therefore, we merge the functionality of the MLME-PURGE.request and
+ * MLME-PURGE.confirm primitives together.
+ *
+ ****************************************************************************/
+
+int mac802154_req_purge(MACHANDLE mac, uint8_t msdu_handle);
+
+/****************************************************************************
+ * Name: mac802154_req_associate
+ *
+ * Description:
+ * The MLME-ASSOCIATE.request primitive allows a device to request an
+ * association with a coordinator. Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_associate callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_associate(MACHANDLE mac,
+ FAR struct ieee802154_assoc_req_s *req);
+
+/****************************************************************************
+ * Name: mac802154_req_disassociate
+ *
+ * Description:
+ * The MLME-DISASSOCIATE.request primitive is used by an associated device
+ * to notify the coordinator of its intent to leave the PAN. It is also
+ * used by the coordinator to instruct an associated device to leave the
+ * PAN.
+ *
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_disassociate callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_disassociate(MACHANDLE mac,
+ FAR struct ieee802154_disassoc_req_s *req);
+
+/****************************************************************************
+ * Name: mac802154_req_gts
+ *
+ * Description:
+ * The MLME-GTS.request primitive allows a device to send a request to the
+ * PAN coordinator to allocate a new GTS or to deallocate an existing GTS.
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_gts callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_gts(MACHANDLE mac, FAR struct ieee802154_gts_req_s *req);
+
+/****************************************************************************
+ * Name: mac802154_req_reset
+ *
+ * Description:
+ * The MLME-RESET.request primitive allows the next higher layer to request
+ * that the MLME performs a reset operation.
+ *
+ * NOTE: The standard specifies that confirmation should be provided via
+ * via the asynchronous MLME-RESET.confirm primitve. However, in our
+ * implementation we synchronously return the value immediately. Therefore,
+ * we merge the functionality of the MLME-RESET.request and MLME-RESET.confirm
+ * primitives together.
+ *
+ * Input Parameters:
+ * mac - Handle to the MAC layer instance
+ * rst_pibattr - Whether or not to reset the MAC PIB attributes to defaults
+ *
+ ****************************************************************************/
+
+int mac802154_req_reset(MACHANDLE mac, bool rst_pibattr);
+
+/****************************************************************************
+ * Name: mac802154_req_rxenable
+ *
+ * Description:
+ * The MLME-RX-ENABLE.request primitive allows the next higher layer to
+ * request that the receiver is enable for a finite period of time.
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_rxenable callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_rxenable(MACHANDLE mac,
+ FAR struct ieee802154_rxenable_req_s *req);
+
+/****************************************************************************
+ * Name: mac802154_req_scan
+ *
+ * Description:
+ * The MLME-SCAN.request primitive is used to initiate a channel scan over
+ * a given list of channels. A device can use a channel scan to measure
+ * the energy on the channel, search for the coordinator with which it
+ * associated, or search for all coordinators transmitting beacon frames
+ * within the POS of the scanning device. Scan results are returned
+ * via MULTIPLE calls to the struct ieee802154_maccb_s->conf_scan
+ * callback. This is a difference with the official 802.15.4
+ * specification, implemented here to save memory.
+ *
+ ****************************************************************************/
+
+int mac802154_req_scan(MACHANDLE mac, FAR struct ieee802154_scan_req_s *req);
+
+/****************************************************************************
+ * Name: mac802154_req_get
+ *
+ * Description:
+ * The MLME-GET.request primitive requests information about a given PIB
+ * attribute.
+ *
+ * NOTE: The standard specifies that the attribute value should be returned
+ * via the asynchronous MLME-GET.confirm primitve. However, in our
+ * implementation, we synchronously return the value immediately.Therefore, we
+ * merge the functionality of the MLME-GET.request and MLME-GET.confirm
+ * primitives together.
+ *
+ ****************************************************************************/
+
+int mac802154_req_get(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr,
+ FAR union ieee802154_attr_val_u *attr_value);
+
+/****************************************************************************
+ * Name: mac802154_req_set
+ *
+ * Description:
+ * The MLME-SET.request primitive attempts to write the given value to the
+ * indicated MAC PIB attribute.
+ *
+ * NOTE: The standard specifies that confirmation should be indicated via
+ * the asynchronous MLME-SET.confirm primitve. However, in our implementation
+ * we synchronously return the status from the request. Therefore, we do merge
+ * the functionality of the MLME-SET.request and MLME-SET.confirm primitives
+ * together.
+ *
+ ****************************************************************************/
+
+int mac802154_req_set(MACHANDLE mac, enum ieee802154_pib_attr_e pib_attr,
+ FAR const union ieee802154_attr_val_u *attr_value);
+
+/****************************************************************************
+ * Name: mac802154_req_start
+ *
+ * Description:
+ * The MLME-START.request primitive makes a request for the device to
+ * start using a new superframe configuration. Confirmation is returned
+ * via the struct ieee802154_maccb_s->conf_start callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_start(MACHANDLE mac, FAR struct ieee802154_start_req_s *req);
+
+/****************************************************************************
+ * Name: mac802154_req_sync
+ *
+ * Description:
+ * The MLME-SYNC.request primitive requests to synchronize with the
+ * coordinator by acquiring and, if specified, tracking its beacons.
+ * Confirmation is returned via the
+ * struct ieee802154_maccb_s->int_commstatus callback. TOCHECK.
+ *
+ ****************************************************************************/
+
+int mac802154_req_sync(MACHANDLE mac, FAR struct ieee802154_sync_req_s *req);
+
+/****************************************************************************
+ * Name: mac802154_req_poll
+ *
+ * Description:
+ * The MLME-POLL.request primitive prompts the device to request data from
+ * the coordinator. Confirmation is returned via the
+ * struct ieee802154_maccb_s->conf_poll callback, followed by a
+ * struct ieee802154_maccb_s->ind_data callback.
+ *
+ ****************************************************************************/
+
+int mac802154_req_poll(MACHANDLE mac, FAR struct ieee802154_poll_req_s *req);
+
+/****************************************************************************
+ * Name: mac802154_resp_associate
+ *
+ * Description:
+ * The MLME-ASSOCIATE.response primitive is used to initiate a response to
+ * an MLME-ASSOCIATE.indication primitive.
+ *
+ ****************************************************************************/
+
+int mac802154_resp_associate(MACHANDLE mac,
+ FAR struct ieee802154_assoc_resp_s *resp);
+
+/****************************************************************************
+ * Name: mac802154_resp_orphan
+ *
+ * Description:
+ * The MLME-ORPHAN.response primitive allows the next higher layer of a
+ * coordinator to respond to the MLME-ORPHAN.indication primitive.
+ *
+ ****************************************************************************/
+
+int mac802154_resp_orphan(MACHANDLE mac,
+ FAR struct ieee802154_orphan_resp_s *resp);
+
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WIRELESS_IEEE802154__MAC802154_H */
diff --git a/wireless/ieee802154/mac802154_device.c b/wireless/ieee802154/mac802154_device.c
new file mode 100644
index 00000000000..a4eb93b6563
--- /dev/null
+++ b/wireless/ieee802154/mac802154_device.c
@@ -0,0 +1,1017 @@
+/****************************************************************************
+ * wireless/ieee802154/mac802154_device.c
+ *
+ * Copyright (C) 2017 Verge Inc. All rights reserved.
+ * Author: Anthony Merlino