diff --git a/Documentation/NuttShell.html b/Documentation/NuttShell.html index 987f8a71779..af8eeba20b0 100644 --- a/Documentation/NuttShell.html +++ b/Documentation/NuttShell.html @@ -8,7 +8,7 @@

NuttShell (NSH)

-

Last Updated: February 5, 2017

+

Last Updated: April 5, 2017

@@ -2708,11 +2708,13 @@ nsh>

Command Syntax:

Synopsis. - Set the environment variable <name> to the string <value>. + Set the environment variable <name> to the string <value> and or set NSH + parser control options. For example, + For example,

+

+ Set the 'exit on error control' and/or 'print a trace' of commands when parsing + scripts in NSH. The settinngs are in effect from the point of exection, until + they are changed again, or in the case of the init script, the settings are + returned to the default settings when it exits. Included child scripts will run + with the parents settings and changes made in the child script will effect the + parent on return. +

+

+ Use 'set -e' to enable and 'set +e' to disable (ignore) the exit condition on commands. + The default is -e. Errors cause script to exit. +

+

+ Use 'set -x' to enable and 'set +x' to disable (silence) printing a trace of the script + commands as they are ececuted. + The default is +x. No printing of a trace of script commands as they are executed. + +

+ + Example 1 - no exit on command not found + + + Example 2 - will exit on command not found + + + Example 3 - will exit on command not found, and print a trace of the script commmands + + + Example 4 - will exit on command not found, and print a trace of the script commmands + and set foobar to foovalue. + + +
diff --git a/arch/arm/src/kinetis/kinetis_rtc_lowerhalf.c b/arch/arm/src/kinetis/kinetis_rtc_lowerhalf.c index 961a212b6a8..b56fc5d44ac 100644 --- a/arch/arm/src/kinetis/kinetis_rtc_lowerhalf.c +++ b/arch/arm/src/kinetis/kinetis_rtc_lowerhalf.c @@ -121,6 +121,7 @@ static const struct rtc_ops_s g_rtc_ops = { .rdtime = kinetis_rdtime, .settime = kinetis_settime, + .havesettime = NULL, #ifdef CONFIG_RTC_ALARM .setalarm = kinetis_setalarm, .setrelative = kinetis_setrelative, diff --git a/arch/arm/src/samv7/sam_wdt.c b/arch/arm/src/samv7/sam_wdt.c index e662146077e..4ce21303c33 100644 --- a/arch/arm/src/samv7/sam_wdt.c +++ b/arch/arm/src/samv7/sam_wdt.c @@ -495,9 +495,22 @@ static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower, * NOTE: The Watchdog Mode Register (WDT_MR) can be written only once. Only * a processor reset resets it. Writing the WDT_MR register reloads the * timer with the newly programmed mode parameters. + * + * NOTE: The WDD Value is the lower bound of a so called Forbidden Window + * (see Datasheet for further Informations). To disable this Forbidden + * Window we have to set the WDD Value greater than or equal to WDV + * (according the Datasheet). + * + * When setting the WDD Value equal to WDV we have to wait at least one clock + * pulse of the (very slow) watchdog clock source between two resets (or the + * configuration and the first reset) of the watchdog. + * + * On fast systems this can lead to a direct hit of the WDD boundary and + * thus to a reset of the system. This is why we program the WDD Value toi + * WDT_MR_WDD_MAX to truly disable this Forbidden Window Feature. */ - regval = WDT_MR_WDV(reload) | WDT_MR_WDD(reload); + regval = WDT_MR_WDV(reload) | WDT_MR_WDD(WDT_MR_WDD_MAX); #ifdef CONFIG_SAMV7_WDT_INTERRUPT /* Generate an interrupt whent he watchdog timer expires */ diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index 6927a3c0544..86b5b714351 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -6334,10 +6334,15 @@ config RTC_MAGIC_REG depends on RTC && !STM32_HAVE_RTC_COUNTER config RTC_MAGIC - hex "Value used as Magic to determine if RTC is set already" + hex "Value used as Magic to determine if RTC is already setup" default 0xfacefeee depends on RTC && !STM32_HAVE_RTC_COUNTER +config RTC_MAGIC_TIME_SET + hex "Value used as Magic to determine if RTC is setup and have time set" + default 0xfacefeef + depends on RTC && !STM32_HAVE_RTC_COUNTER + choice prompt "RTC clock source" default RTC_LSECLOCK diff --git a/arch/arm/src/stm32/chip/stm32f30xxx_syscfg.h b/arch/arm/src/stm32/chip/stm32f30xxx_syscfg.h index 1f19e74dcc8..a4bf5d184ca 100644 --- a/arch/arm/src/stm32/chip/stm32f30xxx_syscfg.h +++ b/arch/arm/src/stm32/chip/stm32f30xxx_syscfg.h @@ -94,7 +94,7 @@ #define SYSCFG_CFGR1_DAC1_DMARMP (1 << 13) /* Bit 13: DAC channel DMA remap */ #define SYSCFG_CFGR1_TIM7_DMARMP (1 << 14) /* Bit 14: TIM7 DMA remap */ #define SYSCFG_CFGR1_DAC2_DMARMP (1 << 14) /* Bit 14: DAC channel2 DMA remap */ -#define SYSCFG_CFGR1_I2C_PBXFMP_SHIFT (0) /* Bits 16-19: Fast Mode Plus (FM+) driving capability */ +#define SYSCFG_CFGR1_I2C_PBXFMP_SHIFT (16) /* Bits 16-19: Fast Mode Plus (FM+) driving capability */ #define SYSCFG_CFGR1_I2C_PBXFMP_MASK (15 << SYSCFG_CFGR1_I2C_PBXFMP_SHIFT) #define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 fast mode Plus driving capability */ #define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C2 fast mode Plus driving capability */ diff --git a/arch/arm/src/stm32/chip/stm32f33xxx_syscfg.h b/arch/arm/src/stm32/chip/stm32f33xxx_syscfg.h index 6e83d0b6111..d675d00f7bf 100644 --- a/arch/arm/src/stm32/chip/stm32f33xxx_syscfg.h +++ b/arch/arm/src/stm32/chip/stm32f33xxx_syscfg.h @@ -96,7 +96,7 @@ #define SYSCFG_CFGR1_TIM7_DMARMP (1 << 14) /* Bit 14: TIM7 DMA remap */ #define SYSCFG_CFGR1_DAC2CH2_DMARMP (1 << 14) /* Bit 14: DAC channel2 DMA remap */ #define SYSCFG_CFGR1_DAC2CH1_DMARMP (1 << 15) /* Bit 14: DAC channel1 DMA remap */ -#define SYSCFG_CFGR1_I2C_PBXFMP_SHIFT (0) /* Bits 16-19: Fast Mode Plus (FM+) driving capability */ +#define SYSCFG_CFGR1_I2C_PBXFMP_SHIFT (16) /* Bits 16-19: Fast Mode Plus (FM+) driving capability */ #define SYSCFG_CFGR1_I2C_PBXFMP_MASK (15 << SYSCFG_CFGR1_I2C_PBXFMP_SHIFT) #define SYSCFG_CFGR1_I2C1_FMP (1 << 20) /* Bit 20: I2C1 fast mode Plus driving capability */ #define SYSCFG_CFGR1_I2C2_FMP (1 << 21) /* Bit 21: I2C2 fast mode Plus driving capability */ diff --git a/arch/arm/src/stm32/stm32_rcc.c b/arch/arm/src/stm32/stm32_rcc.c index 3cb57ae6a0e..be152ff8d85 100644 --- a/arch/arm/src/stm32/stm32_rcc.c +++ b/arch/arm/src/stm32/stm32_rcc.c @@ -131,7 +131,7 @@ static inline void rcc_resetbkp(void) stm32_pwr_initbkp(false); regval = getreg32(RTC_MAGIC_REG); - if (regval != RTC_MAGIC) + if (regval != RTC_MAGIC && regval != RTC_MAGIC_TIME_SET) { stm32_pwr_enablebkp(true); diff --git a/arch/arm/src/stm32/stm32_rtc.h b/arch/arm/src/stm32/stm32_rtc.h index 119e5e54dfc..d228a3c4589 100644 --- a/arch/arm/src/stm32/stm32_rtc.h +++ b/arch/arm/src/stm32/stm32_rtc.h @@ -83,11 +83,16 @@ # define CONFIG_RTC_MAGIC (0xfacefeee) #endif +#if !defined(CONFIG_RTC_MAGIC_TIME_SET) +# define CONFIG_RTC_MAGIC_TIME_SET (CONFIG_RTC_MAGIC + 1) +#endif + #if !defined(CONFIG_RTC_MAGIC_REG) # define CONFIG_RTC_MAGIC_REG (0) #endif #define RTC_MAGIC CONFIG_RTC_MAGIC +#define RTC_MAGIC_TIME_SET CONFIG_RTC_MAGIC_TIME_SET #define RTC_MAGIC_REG STM32_RTC_BKR(CONFIG_RTC_MAGIC_REG) /**************************************************************************** diff --git a/arch/arm/src/stm32/stm32_rtc_lowerhalf.c b/arch/arm/src/stm32/stm32_rtc_lowerhalf.c index feaa3f53951..548b7fa81b0 100644 --- a/arch/arm/src/stm32/stm32_rtc_lowerhalf.c +++ b/arch/arm/src/stm32/stm32_rtc_lowerhalf.c @@ -49,6 +49,8 @@ #include #include +#include "up_arch.h" + #include "chip.h" #include "stm32_rtc.h" @@ -111,6 +113,7 @@ static int stm32_rdtime(FAR struct rtc_lowerhalf_s *lower, FAR struct rtc_time *rtctime); static int stm32_settime(FAR struct rtc_lowerhalf_s *lower, FAR const struct rtc_time *rtctime); +static bool stm32_havesettime(FAR struct rtc_lowerhalf_s *lower); #ifdef CONFIG_RTC_ALARM static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower, @@ -130,6 +133,7 @@ static const struct rtc_ops_s g_rtc_ops = { .rdtime = stm32_rdtime, .settime = stm32_settime, + .havesettime = stm32_havesettime, #ifdef CONFIG_RTC_ALARM .setalarm = stm32_setalarm, .setrelative = stm32_setrelative, @@ -345,6 +349,25 @@ static int stm32_settime(FAR struct rtc_lowerhalf_s *lower, #endif } +/**************************************************************************** + * Name: stm32_havesettime + * + * Description: + * Implements the havesettime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * + * Returned Value: + * Returns true if RTC date-time have been previously set. + * + ****************************************************************************/ + +static bool stm32_havesettime(FAR struct rtc_lowerhalf_s *lower) +{ + return getreg32(RTC_MAGIC_REG) == RTC_MAGIC_TIME_SET; +} + /**************************************************************************** * Name: stm32_setalarm * diff --git a/arch/arm/src/stm32/stm32_rtcc.c b/arch/arm/src/stm32/stm32_rtcc.c index b7155854965..b1347fd9e7c 100644 --- a/arch/arm/src/stm32/stm32_rtcc.c +++ b/arch/arm/src/stm32/stm32_rtcc.c @@ -600,7 +600,7 @@ int up_rtc_initialize(void) stm32_pwr_enablebkp(true); - if (regval != RTC_MAGIC) + if (regval != RTC_MAGIC && regval != RTC_MAGIC_TIME_SET) { /* Some boards do not have the external 32khz oscillator installed, for those * boards we must fallback to the crummy internal RC clock or the external high @@ -712,7 +712,7 @@ int up_rtc_initialize(void) * has been writing to to back-up date register DR0. */ - if (regval != RTC_MAGIC) + if (regval != RTC_MAGIC && regval != RTC_MAGIC_TIME_SET) { rtcinfo("Do setup\n"); @@ -1004,6 +1004,15 @@ int stm32_rtc_setdatetime(FAR const struct tm *tp) ret = rtc_synchwait(); } + /* Remember that the RTC is initialized and had its time set. */ + + if (getreg32(RTC_MAGIC_REG) != RTC_MAGIC_TIME_SET) + { + stm32_pwr_enablebkp(true); + putreg32(RTC_MAGIC_TIME_SET, RTC_MAGIC_REG); + stm32_pwr_enablebkp(false); + } + /* Re-enable the write protection for RTC registers */ rtc_wprlock(); diff --git a/arch/arm/src/stm32/stm32f40xxx_rtcc.c b/arch/arm/src/stm32/stm32f40xxx_rtcc.c index 4e8cfc773be..57029041317 100644 --- a/arch/arm/src/stm32/stm32f40xxx_rtcc.c +++ b/arch/arm/src/stm32/stm32f40xxx_rtcc.c @@ -894,7 +894,7 @@ int up_rtc_initialize(void) stm32_pwr_enablebkp(true); - if (regval != RTC_MAGIC) + if (regval != RTC_MAGIC && regval != RTC_MAGIC_TIME_SET) { /* Some boards do not have the external 32khz oscillator installed, * for those boards we must fallback to the crummy internal RC clock @@ -1011,7 +1011,7 @@ int up_rtc_initialize(void) * has been writing to to back-up date register DR0. */ - if (regval != RTC_MAGIC) + if (regval != RTC_MAGIC && regval != RTC_MAGIC_TIME_SET) { rtcinfo("Do setup\n"); @@ -1287,6 +1287,15 @@ int stm32_rtc_setdatetime(FAR const struct tm *tp) ret = rtc_synchwait(); } + /* Remember that the RTC is initialized and had its time set. */ + + if (getreg32(RTC_MAGIC_REG) != RTC_MAGIC_TIME_SET) + { + stm32_pwr_enablebkp(true); + putreg32(RTC_MAGIC_TIME_SET, RTC_MAGIC_REG); + stm32_pwr_enablebkp(false); + } + /* Re-enable the write protection for RTC registers */ rtc_wprlock(); @@ -1362,7 +1371,7 @@ int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo) (rtc_bin2bcd(alminfo->as_time.tm_min) << RTC_ALRMR_MNU_SHIFT) | (rtc_bin2bcd(alminfo->as_time.tm_hour) << RTC_ALRMR_HU_SHIFT) | (rtc_bin2bcd(alminfo->as_time.tm_mday) << RTC_ALRMR_DU_SHIFT); - + /* Set the alarm in hardware and enable interrupts from the RTC */ switch (alminfo->as_id) diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index e727aef24aa..d8eabdcd4bd 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -1832,10 +1832,15 @@ config RTC_MAGIC_REG depends on RTC && !STM32F7_HAVE_RTC_COUNTER config RTC_MAGIC - hex "Value used as Magic to determine if RTC is set already" + hex "Value used as Magic to determine if RTC is already setup" default 0xfacefeee depends on RTC && !STM32F7_HAVE_RTC_COUNTER +config RTC_MAGIC_TIME_SET + hex "Value used as Magic to determine if RTC is setup and have time set" + default 0xfacefeef + depends on RTC && !STM32F7_HAVE_RTC_COUNTER + choice prompt "RTC clock source" default STM32F7_RTC_LSECLOCK @@ -1884,8 +1889,7 @@ config STM32F7_DTCM_PROCFS config STM32F7_DMACAPABLE bool "Workaround non-DMA capable memory" depends on ARCH_DMA - default y if !STM32F7_CCMEXCLUDE - default n if STM32F7_CCMEXCLUDE + default n ---help--- This option enables the DMA interface stm32_dmacapable that can be used to check if it is possible to do DMA from the selected address. diff --git a/arch/arm/src/stm32f7/stm32_ethernet.c b/arch/arm/src/stm32f7/stm32_ethernet.c index 480c395c79e..961b21bf268 100644 --- a/arch/arm/src/stm32f7/stm32_ethernet.c +++ b/arch/arm/src/stm32f7/stm32_ethernet.c @@ -635,8 +635,8 @@ struct stm32_ethmac_s * 1. Be a multiple of the D-Cache line size. This requirement is assured * by the definition of RXDMA buffer size above. * 2. Be aligned a D-Cache line boundaries, and - * 3. Be positioned in DMA-able memory (*NOT* DTCM memory). This must - * be managed by logic in the linker script file. + * 3. Be positioned in DMA-able memory. This must be managed by logic + * in the linker script file. * * These DMA buffers are defined sequentially here to best assure optimal * packing of the buffers. diff --git a/arch/arm/src/stm32f7/stm32_rtc.c b/arch/arm/src/stm32f7/stm32_rtc.c index 2840fac8a5d..4583dfaf1ef 100644 --- a/arch/arm/src/stm32f7/stm32_rtc.c +++ b/arch/arm/src/stm32f7/stm32_rtc.c @@ -856,9 +856,13 @@ int up_rtc_initialize(void) regval = getreg32(RTC_MAGIC_REG); + /* Enable write access to the backup domain (RTC registers, RTC + * backup data registers and backup SRAM). + */ + stm32_pwr_enablebkp(true); - if (regval != RTC_MAGIC) + if (regval != RTC_MAGIC && regval != RTC_MAGIC_TIME_SET) { /* Issue the Backup domain Reset Per Section 5.3.20 DocID028270 Rev 2 * The LSEON, LSEBYP, RTCSEL and RTCEN bits in the RCC backup domain @@ -949,8 +953,6 @@ int up_rtc_initialize(void) } } - stm32_pwr_enablebkp(false); - /* Loop, attempting to initialize/resume the RTC. This loop is necessary * because it seems that occasionally it takes longer to initialize the * RTC (the actual failure is in rtc_synchwait()). @@ -988,7 +990,7 @@ int up_rtc_initialize(void) * has been writing to to back-up date register DR0. */ - if (regval != RTC_MAGIC) + if (regval != RTC_MAGIC && regval != RTC_MAGIC_TIME_SET) { rtcinfo("Do setup\n"); @@ -996,12 +998,6 @@ int up_rtc_initialize(void) ret = rtc_setup(); - /* Enable write access to the backup domain (RTC registers, RTC - * backup data registers and backup SRAM). - */ - - stm32_pwr_enablebkp(true); - /* Remember that the RTC is initialized */ putreg32(RTC_MAGIC, RTC_MAGIC_REG); @@ -1297,6 +1293,15 @@ int stm32_rtc_setdatetime(FAR const struct tm *tp) ret = rtc_synchwait(); } + /* Remember that the RTC is initialized and had its time set. */ + + if (getreg32(RTC_MAGIC_REG) != RTC_MAGIC_TIME_SET) + { + stm32_pwr_enablebkp(true); + putreg32(RTC_MAGIC_TIME_SET, RTC_MAGIC_REG); + stm32_pwr_enablebkp(false); + } + /* Re-enable the write protection for RTC registers */ rtc_wprlock(); diff --git a/arch/arm/src/stm32f7/stm32_rtc.h b/arch/arm/src/stm32f7/stm32_rtc.h index f784f8acd31..a46361a55db 100644 --- a/arch/arm/src/stm32f7/stm32_rtc.h +++ b/arch/arm/src/stm32f7/stm32_rtc.h @@ -66,11 +66,16 @@ # define CONFIG_RTC_MAGIC (0xfacefeee) #endif +#if !defined(CONFIG_RTC_MAGIC_TIME_SET) +# define CONFIG_RTC_MAGIC_TIME_SET (CONFIG_RTC_MAGIC + 1) +#endif + #if !defined(CONFIG_RTC_MAGIC_REG) # define CONFIG_RTC_MAGIC_REG (0) #endif #define RTC_MAGIC CONFIG_RTC_MAGIC +#define RTC_MAGIC_TIME_SET CONFIG_RTC_MAGIC_TIME_SET #define RTC_MAGIC_REG STM32_RTC_BKR(CONFIG_RTC_MAGIC_REG) /**************************************************************************** diff --git a/arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c b/arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c index 1b20b44edab..25868c58b8d 100644 --- a/arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c +++ b/arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c @@ -50,6 +50,8 @@ #include #include +#include "up_arch.h" + #include "chip.h" #include "stm32_rtc.h" @@ -106,6 +108,7 @@ static int stm32_rdtime(FAR struct rtc_lowerhalf_s *lower, FAR struct rtc_time *rtctime); static int stm32_settime(FAR struct rtc_lowerhalf_s *lower, FAR const struct rtc_time *rtctime); +static bool stm32_havesettime(FAR struct rtc_lowerhalf_s *lower); #ifdef CONFIG_RTC_ALARM static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower, @@ -125,6 +128,7 @@ static const struct rtc_ops_s g_rtc_ops = { .rdtime = stm32_rdtime, .settime = stm32_settime, + .havesettime = stm32_havesettime, #ifdef CONFIG_RTC_ALARM .setalarm = stm32_setalarm, .setrelative = stm32_setrelative, @@ -314,6 +318,25 @@ static int stm32_settime(FAR struct rtc_lowerhalf_s *lower, #endif } +/**************************************************************************** + * Name: stm32_havesettime + * + * Description: + * Implements the havesettime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * + * Returned Value: + * Returns true if RTC date-time have been previously set. + * + ****************************************************************************/ + +static bool stm32_havesettime(FAR struct rtc_lowerhalf_s *lower) +{ + return getreg32(RTC_MAGIC_REG) == RTC_MAGIC_TIME_SET; +} + /**************************************************************************** * Name: stm32_setalarm * diff --git a/arch/arm/src/stm32f7/stm32_serial.c b/arch/arm/src/stm32f7/stm32_serial.c index b839aad8f44..ec97ec7096c 100644 --- a/arch/arm/src/stm32f7/stm32_serial.c +++ b/arch/arm/src/stm32f7/stm32_serial.c @@ -218,6 +218,46 @@ #ifdef USE_SERIALDRIVER #ifdef HAVE_UART +/* Warnings for potentially unsafe configuration combinations. */ + +/* Combination of RXDMA + IFLOWCONTROL does not work as one might expect. + * Since RXDMA uses circular DMA-buffer, DMA will always keep reading new + * data from USART peripheral even if DMA buffer underruns. Thus this + * combination only does following: RTS is asserted on USART setup and + * deasserted on shutdown and does not perform actual RTS flow-control. + */ + +#if defined(CONFIG_USART1_RXDMA) && defined(CONFIG_USART1_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for USART1. \ + This combination can lead to data loss." +#endif + +#if defined(CONFIG_USART2_RXDMA) && defined(CONFIG_USART2_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for USART2. \ + This combination can lead to data loss." +#endif + +#if defined(CONFIG_USART3_RXDMA) && defined(CONFIG_USART3_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for USART3. \ + This combination can lead to data loss." +#endif + +#if defined(CONFIG_USART6_RXDMA) && defined(CONFIG_USART6_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for USART6. \ + This combination can lead to data loss." +#endif + +#if defined(CONFIG_UART7_RXDMA) && defined(CONFIG_UART7_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for UART7. \ + This combination can lead to data loss." +#endif + +#if defined(CONFIG_UART8_RXDMA) && defined(CONFIG_UART8_IFLOWCONTROL) +# warning "RXDMA and IFLOWCONTROL both enabled for UART8. \ + This combination can lead to data loss." +#endif + + /**************************************************************************** * Private Types ****************************************************************************/ @@ -228,6 +268,10 @@ struct up_dev_s uint16_t ie; /* Saved interrupt mask bits value */ uint16_t sr; /* Saved status bits */ + /* Has been initialized and HW is setup. */ + + bool initialized; + /* If termios are supported, then the following fields may vary at * runtime. */ @@ -379,8 +423,7 @@ static const struct uart_ops_s g_uart_dma_ops = * 1. Be a multiple of the D-Cache line size. This requirement is assured * by the definition of RXDMA buffer size above. * 2. Be aligned a D-Cache line boundaries, and - * 3. Be positioned in DMA-able memory (*NOT* DTCM memory). This must - * be managed by logic in the linker script file. + * 3. Be positioned in DMA-able memory. * * These DMA buffers are defined sequentially here to best assure optimal * packing of the buffers. @@ -879,11 +922,11 @@ static struct up_dev_s g_uart7priv = .usartbase = STM32_UART7_BASE, .tx_gpio = GPIO_UART7_TX, .rx_gpio = GPIO_UART7_RX, -#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART7_OFLOWCONTROL) +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART7_OFLOWCONTROL) .oflow = true, .cts_gpio = GPIO_UART7_CTS, #endif -#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART7_IFLOWCONTROL) +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART7_IFLOWCONTROL) .iflow = true, .rts_gpio = GPIO_UART7_RTS, #endif @@ -940,11 +983,11 @@ static struct up_dev_s g_uart8priv = .usartbase = STM32_UART8_BASE, .tx_gpio = GPIO_UART8_TX, .rx_gpio = GPIO_UART8_RX, -#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART8_OFLOWCONTROL) +#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART8_OFLOWCONTROL) .oflow = true, .cts_gpio = GPIO_UART8_CTS, #endif -#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_USART8_IFLOWCONTROL) +#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART8_IFLOWCONTROL) .iflow = true, .rts_gpio = GPIO_UART8_RTS, #endif @@ -1460,6 +1503,11 @@ static int up_setup(struct uart_dev_s *dev) /* Set up the cached interrupt enables value */ priv->ie = 0; + + /* Mark device as initialized. */ + + priv->initialized = true; + return OK; } @@ -1539,6 +1587,10 @@ static void up_shutdown(struct uart_dev_s *dev) struct up_dev_s *priv = (struct up_dev_s *)dev->priv; uint32_t regval; + /* Mark device as uninitialized. */ + + priv->initialized = false; + /* Disable all interrupts */ up_disableusartint(priv, NULL); @@ -2529,6 +2581,31 @@ static int up_pm_prepare(struct pm_callback_s *cb, int domain, #ifdef USE_SERIALDRIVER +/**************************************************************************** + * Name: stm32_serial_get_uart + * + * Description: + * Get serial driver structure for STM32 USART + * + ****************************************************************************/ + +FAR uart_dev_t *stm32_serial_get_uart(int uart_num) +{ + int uart_idx = uart_num - 1; + + if (uart_idx < 0 || uart_idx >= STM32_NSERIAL || !uart_devs[uart_idx]) + { + return NULL; + } + + if (!uart_devs[uart_idx]->initialized) + { + return NULL; + } + + return &uart_devs[uart_idx]->dev; +} + /**************************************************************************** * Name: up_earlyserialinit * diff --git a/arch/arm/src/stm32f7/stm32_uart.h b/arch/arm/src/stm32f7/stm32_uart.h index d250eb77612..496d7e9ea42 100644 --- a/arch/arm/src/stm32f7/stm32_uart.h +++ b/arch/arm/src/stm32f7/stm32_uart.h @@ -41,6 +41,7 @@ ************************************************************************************/ #include +#include #include "chip/stm32_uart.h" @@ -319,6 +320,16 @@ extern "C" * Public Functions ************************************************************************************/ +/************************************************************************************ + * Name: stm32_serial_get_uart + * + * Description: + * Get serial driver structure for STM32 USART + * + ************************************************************************************/ + +FAR uart_dev_t *stm32_serial_get_uart(int uart_num); + /************************************************************************************ * Name: stm32_serial_dma_poll * diff --git a/arch/arm/src/stm32l4/stm32l4_rtc.h b/arch/arm/src/stm32l4/stm32l4_rtc.h index 404f8325ad5..18e7f6031be 100644 --- a/arch/arm/src/stm32l4/stm32l4_rtc.h +++ b/arch/arm/src/stm32l4/stm32l4_rtc.h @@ -171,6 +171,19 @@ struct tm; int stm32l4_rtc_setdatetime(FAR const struct tm *tp); #endif +/**************************************************************************** + * Name: stm32l4_rtc_setdatetime + * + * Description: + * Check if RTC time has been set. + * + * Returned Value: + * Returns true if RTC date-time have been previously set. + * + ****************************************************************************/ + +bool stm32l4_rtc_havesettime(void); + #ifdef CONFIG_RTC_ALARM /**************************************************************************** * Name: stm32l4_rtc_setalarm diff --git a/arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c b/arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c index 437faf54f13..5ab212dd86f 100644 --- a/arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c +++ b/arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c @@ -107,6 +107,7 @@ static int stm32l4_rdtime(FAR struct rtc_lowerhalf_s *lower, FAR struct rtc_time *rtctime); static int stm32l4_settime(FAR struct rtc_lowerhalf_s *lower, FAR const struct rtc_time *rtctime); +static bool stm32l4_havesettime(FAR struct rtc_lowerhalf_s *lower); #ifdef CONFIG_RTC_ALARM static int stm32l4_setalarm(FAR struct rtc_lowerhalf_s *lower, @@ -127,6 +128,7 @@ static const struct rtc_ops_s g_rtc_ops = { .rdtime = stm32l4_rdtime, .settime = stm32l4_settime, + .havesettime = stm32l4_havesettime, #ifdef CONFIG_RTC_ALARM .setalarm = stm32l4_setalarm, .setrelative = stm32l4_setrelative, @@ -235,7 +237,7 @@ static int stm32l4_rdtime(FAR struct rtc_lowerhalf_s *lower, ret = up_rtc_getdatetime((FAR struct tm *)rtctime); sem_post(&priv->devsem); - + return ret; } @@ -273,12 +275,31 @@ static int stm32l4_settime(FAR struct rtc_lowerhalf_s *lower, */ ret = stm32l4_rtc_setdatetime((FAR const struct tm *)rtctime); - + sem_post(&priv->devsem); return ret; } +/**************************************************************************** + * Name: stm32l4_havesettime + * + * Description: + * Implements the havesettime() method of the RTC driver interface + * + * Input Parameters: + * lower - A reference to RTC lower half driver state structure + * + * Returned Value: + * Returns true if RTC date-time have been previously set. + * + ****************************************************************************/ + +static bool stm32l4_havesettime(FAR struct rtc_lowerhalf_s *lower) +{ + return stm32l4_rtc_havesettime(); +} + /**************************************************************************** * Name: stm32l4_setalarm * diff --git a/arch/arm/src/stm32l4/stm32l4_rtcc.c b/arch/arm/src/stm32l4/stm32l4_rtcc.c index a0221240f78..84a1f9eab6e 100644 --- a/arch/arm/src/stm32l4/stm32l4_rtcc.c +++ b/arch/arm/src/stm32l4/stm32l4_rtcc.c @@ -87,6 +87,10 @@ # define CONFIG_RTC_MAGIC (0xfacefeee) #endif +#if !defined(CONFIG_RTC_MAGIC_TIME_SET) +# define CONFIG_RTC_MAGIC_TIME_SET (CONFIG_RTC_MAGIC + 1) +#endif + #if !defined(CONFIG_RTC_MAGIC_REG) # define CONFIG_RTC_MAGIC_REG (0) #endif @@ -185,7 +189,7 @@ static void rtc_dumpregs(FAR const char *msg) rtcinfo(" ISR: %08x\n", getreg32(STM32L4_RTC_ISR)); rtcinfo(" PRER: %08x\n", getreg32(STM32L4_RTC_PRER)); rtcinfo(" WUTR: %08x\n", getreg32(STM32L4_RTC_WUTR)); - + rtcinfo(" ALRMAR: %08x\n", getreg32(STM32L4_RTC_ALRMAR)); rtcinfo(" ALRMBR: %08x\n", getreg32(STM32L4_RTC_ALRMBR)); rtcinfo(" SHIFTR: %08x\n", getreg32(STM32L4_RTC_SHIFTR)); @@ -693,12 +697,12 @@ static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg) modifyreg32(STM32L4_RTC_CR, (RTC_CR_ALRAE | RTC_CR_ALRAIE), 0); /* Ensure Alarm A flag reset; this is edge triggered */ - + isr = getreg32(STM32L4_RTC_ISR) & ~RTC_ISR_ALRAF; putreg32(isr, STM32L4_RTC_ISR); /* Wait for Alarm A to be writable */ - + ret = rtchw_check_alrawf(); if (ret != OK) { @@ -739,12 +743,12 @@ static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg) modifyreg32(STM32L4_RTC_CR, (RTC_CR_ALRBE | RTC_CR_ALRBIE), 0); /* Ensure Alarm B flag reset; this is edge triggered */ - + isr = getreg32(STM32L4_RTC_ISR) & ~RTC_ISR_ALRBF; putreg32(isr, STM32L4_RTC_ISR); /* Wait for Alarm B to be writable */ - + ret = rtchw_check_alrbwf(); if (ret != OK) { @@ -865,7 +869,7 @@ int up_rtc_initialize(void) init_stat = rtc_is_inits(); - if(!init_stat) + if (!init_stat) { /* Enable write access to the backup domain (RTC registers, RTC * backup data registers and backup SRAM). @@ -951,11 +955,11 @@ int up_rtc_initialize(void) (void)ret; /* Exit Initialization mode */ - + rtc_exitinit(); /* Enable the write protection for RTC registers */ - + rtc_wprlock(); /* Disable write access to the backup domain (RTC registers, RTC backup @@ -978,11 +982,11 @@ int up_rtc_initialize(void) //rtc_wprunlock(); rtc_resume(); - + /* Enable the write protection for RTC registers */ - + //rtc_wprlock(); - + /* Disable write access to the backup domain (RTC registers, RTC backup * data registers and backup SRAM). */ @@ -1210,6 +1214,15 @@ int stm32l4_rtc_setdatetime(FAR const struct tm *tp) ret = rtc_synchwait(); } + /* Remember that the RTC is initialized and had its time set. */ + + if (getreg32(CONFIG_RTC_MAGIC_REG) != CONFIG_RTC_MAGIC_TIME_SET) + { + stm32l4_pwr_enablebkp(true); + putreg32(CONFIG_RTC_MAGIC_TIME_SET, CONFIG_RTC_MAGIC_REG); + stm32l4_pwr_enablebkp(false); + } + /* Re-enable the write protection for RTC registers */ rtc_wprlock(); @@ -1217,6 +1230,22 @@ int stm32l4_rtc_setdatetime(FAR const struct tm *tp) return ret; } +/************************************************************************************ + * Name: stm32l4_rtc_setdatetime + * + * Description: + * Check if RTC time has been set. + * + * Returned Value: + * Returns true if RTC date-time have been previously set. + * + ************************************************************************************/ + +bool stm32l4_rtc_havesettime(void) +{ + return getreg32(CONFIG_RTC_MAGIC_REG) == CONFIG_RTC_MAGIC_TIME_SET; +} + /************************************************************************************ * Name: up_rtc_settime * diff --git a/configs/sim/README.txt b/configs/sim/README.txt index 7fa886b5bda..816ed007437 100644 --- a/configs/sim/README.txt +++ b/configs/sim/README.txt @@ -813,6 +813,12 @@ sixlowpan 6loWPAN stack. It enables networking with 6loWPAN support and uses only a IEEE802.15.4 MAC loopback network device to supported testing. + This configuration includes apps/examples/nettest and apps/examples/udpblaster. + Neither are truly functional. The only intent of this configuration + is to verify that the 6loWPAN stack correctly encodes IEEE802.15.4 + packets on output to the loopback device and correct decodes the + returned packet. + touchscreen This configuration uses the simple touchscreen test at diff --git a/configs/sim/sixlowpan/defconfig b/configs/sim/sixlowpan/defconfig index 8a5d9f766d8..ac4d9e35ded 100644 --- a/configs/sim/sixlowpan/defconfig +++ b/configs/sim/sixlowpan/defconfig @@ -525,6 +525,10 @@ CONFIG_NETDEV_PHY_IOCTL=y # CONFIG_NET_IPv4 is not set CONFIG_NET_IPv6=y CONFIG_NET_IPv6_NCONF_ENTRIES=8 + +# +# 6LoWPAN Configuration +# CONFIG_NET_6LOWPAN_FRAG=y CONFIG_NET_6LOWPAN_FRAMELEN=127 # CONFIG_NET_6LOWPAN_COMPRESSION_IPv6 is not set @@ -882,6 +886,7 @@ CONFIG_EXAMPLES_NETTEST_IPv6=y # # Target IPv6 address # + # # Client IPv6 address # @@ -922,7 +927,36 @@ CONFIG_EXAMPLES_NSH=y # CONFIG_EXAMPLES_TIFF is not set # CONFIG_EXAMPLES_TOUCHSCREEN is not set # CONFIG_EXAMPLES_UDP is not set -# CONFIG_EXAMPLES_UDPBLASTER is not set +CONFIG_EXAMPLES_UDPBLASTER=y +CONFIG_EXAMPLES_UDPBLASTER_STACKSIZE=8192 +CONFIG_EXAMPLES_UDPBLASTER_PRIORITY=100 +CONFIG_EXAMPLES_UDPBLASTER_HOSTRATE=800000 +CONFIG_EXAMPLES_UDPBLASTER_IPv6=y +# CONFIG_EXAMPLES_UDPBLASTER_INIT is not set + +# +# Target IPv6 address +# +CONFIG_EXAMPLES_UDPBLASTER_TARGETIPv6_1=0xfe80 +CONFIG_EXAMPLES_UDPBLASTER_TARGETIPv6_2=0x0000 +CONFIG_EXAMPLES_UDPBLASTER_TARGETIPv6_3=0x0000 +CONFIG_EXAMPLES_UDPBLASTER_TARGETIPv6_4=0x0000 +CONFIG_EXAMPLES_UDPBLASTER_TARGETIPv6_5=0x0000 +CONFIG_EXAMPLES_UDPBLASTER_TARGETIPv6_6=0x00ff +CONFIG_EXAMPLES_UDPBLASTER_TARGETIPv6_7=0xfe00 +CONFIG_EXAMPLES_UDPBLASTER_TARGETIPv6_8=0xa9cd + +# +# Router IPv6 address +# +CONFIG_EXAMPLES_UDPBLASTER_HOSTIPv6_1=0xfe80 +CONFIG_EXAMPLES_UDPBLASTER_HOSTIPv6_2=0x0000 +CONFIG_EXAMPLES_UDPBLASTER_HOSTIPv6_3=0x0000 +CONFIG_EXAMPLES_UDPBLASTER_HOSTIPv6_4=0x0000 +CONFIG_EXAMPLES_UDPBLASTER_HOSTIPv6_5=0x0000 +CONFIG_EXAMPLES_UDPBLASTER_HOSTIPv6_6=0x00ff +CONFIG_EXAMPLES_UDPBLASTER_HOSTIPv6_7=0xfe00 +CONFIG_EXAMPLES_UDPBLASTER_HOSTIPv6_8=0x1034 # CONFIG_EXAMPLES_USBSERIAL is not set # CONFIG_EXAMPLES_WATCHDOG is not set # CONFIG_EXAMPLES_WEBSERVER is not set diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 53ef72c3cb5..a6d8c2f1205 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -1577,7 +1577,7 @@ config USART6_2STOP 1=Two stop bits config USART6_IFLOWCONTROL - bool "UART6 RTS flow control" + bool "USART6 RTS flow control" default n select SERIAL_IFLOWCONTROL ---help--- diff --git a/drivers/timers/rtc.c b/drivers/timers/rtc.c index 0b467fde2f7..990cec845fa 100644 --- a/drivers/timers/rtc.c +++ b/drivers/timers/rtc.c @@ -332,7 +332,7 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg) /* RTC_SET_TIME sets the RTC's time * - * Argument: A read-only reference to a struct rtc_time containing the + * Argument: A read-only reference to a struct rtc_time containing * the new time to be set. */ @@ -348,6 +348,24 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg) } break; + /* RTC_HAVE_SET_TIME checks if RTC's time had been set + * + * Argument: A writable reference to a bool to receive true/false return + * value of the check. + */ + + case RTC_HAVE_SET_TIME: + { + FAR bool *have_set_time = (FAR bool *)((uintptr_t)arg); + + if (ops->havesettime) + { + *have_set_time = ops->havesettime(upper->lower); + ret = OK; + } + } + break; + #ifdef CONFIG_RTC_ALARM /* RTC_SET_ALARM sets the alarm time. * diff --git a/include/nuttx/net/sixlowpan.h b/include/nuttx/net/sixlowpan.h index 5f73d9cdb19..0211d17ce6f 100644 --- a/include/nuttx/net/sixlowpan.h +++ b/include/nuttx/net/sixlowpan.h @@ -94,37 +94,40 @@ /* IPHC encoding * - * Values of fields within the IPHC encoding first byte (C stands for - * compressed and I for inline) + * Values of fields within the IPHC encoding first byte + * (Using MS-to-LS bit numbering of the draft RFC) */ - -#define SIXLOWPAN_IPHC_FL_C 0x10 -#define SIXLOWPAN_IPHC_TC_C 0x08 -#define SIXLOWPAN_IPHC_NH_C 0x04 -#define SIXLOWPAN_IPHC_TTL_1 0x01 -#define SIXLOWPAN_IPHC_TTL_64 0x02 -#define SIXLOWPAN_IPHC_TTL_255 0x03 -#define SIXLOWPAN_IPHC_TTL_I 0x00 + /* 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 - -#define SIXLOWPAN_IPHC_SAC 0x40 -#define SIXLOWPAN_IPHC_SAM_00 0x00 -#define SIXLOWPAN_IPHC_SAM_01 0x10 -#define SIXLOWPAN_IPHC_SAM_10 0x20 -#define SIXLOWPAN_IPHC_SAM_11 0x30 +#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_M 0x08 -#define SIXLOWPAN_IPHC_DAC 0x04 -#define SIXLOWPAN_IPHC_DAM_00 0x00 -#define SIXLOWPAN_IPHC_DAM_01 0x01 -#define SIXLOWPAN_IPHC_DAM_10 0x02 -#define SIXLOWPAN_IPHC_DAM_11 0x03 - #define SIXLOWPAN_IPHC_DAM_BIT 0 /* Link local context number */ diff --git a/include/nuttx/timers/rtc.h b/include/nuttx/timers/rtc.h index d2345a4dc16..33b761ed0e4 100644 --- a/include/nuttx/timers/rtc.h +++ b/include/nuttx/timers/rtc.h @@ -145,13 +145,22 @@ #define RTC_SET_TIME _RTCIOC(0x0002) + +/* RTC_HAVE_SET_TIME checks if RTC's time had been set + * + * Argument: A writable reference to a bool to receive true/false return value + * of the check. + */ + +#define RTC_HAVE_SET_TIME _RTCIOC(0x0003) + /* RTC_SET_ALARM sets the alarm time (for RTCs that support alarms). * * Argument: A read-only reference to a struct rtc_setalarm_s containing the * new alarm time to be set. */ -#define RTC_SET_ALARM _RTCIOC(0x0003) +#define RTC_SET_ALARM _RTCIOC(0x0004) /* RTC_SET_RELATIVE sets the alarm time relative to the current time. * @@ -159,14 +168,14 @@ * new relative alarm time to be set. */ -#define RTC_SET_RELATIVE _RTCIOC(0x0004) +#define RTC_SET_RELATIVE _RTCIOC(0x0005) /* RTC_SET_RELATIVE cancel the alarm. * * Argument: An ALARM ID value that indicates which alarm should be canceled. */ -#define RTC_CANCEL_ALARM _RTCIOC(0x0005) +#define RTC_CANCEL_ALARM _RTCIOC(0x0006) /* Architecture-specific RTC IOCTLS should begin at RTC_USER_IOCBASE. For * example: @@ -176,7 +185,7 @@ * etc. */ -#define RTC_USER_IOCBASE 0x0006 +#define RTC_USER_IOCBASE 0x0007 /**************************************************************************** * Public Types @@ -291,6 +300,10 @@ struct rtc_ops_s CODE int (*settime)(FAR struct rtc_lowerhalf_s *lower, FAR const struct rtc_time *rtctime); + /* havesettime checks if RTC time have been set */ + + CODE bool (*havesettime)(FAR struct rtc_lowerhalf_s *lower); + #ifdef CONFIG_RTC_ALARM /* setalarm sets up a new alarm. */ diff --git a/net/sixlowpan/sixlowpan_hc06.c b/net/sixlowpan/sixlowpan_hc06.c index 0b9d5153b07..9e51f88c17b 100644 --- a/net/sixlowpan/sixlowpan_hc06.c +++ b/net/sixlowpan/sixlowpan_hc06.c @@ -458,9 +458,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, uint8_t iphc1; uint8_t tmp; - g_hc06ptr = fptr + 2; - ninfo("fptr=%p g_frame_hdrlen=%u iphc=%p g_hc06ptr=%p\n", - fptr, g_frame_hdrlen, iphc, g_hc06ptr); + ninfo("fptr=%p g_frame_hdrlen=%u iphc=%p\n", fptr, g_frame_hdrlen, iphc); /* As we copy some bit-length fields, in the IPHC encoding bytes, * we sometimes use |= @@ -472,6 +470,10 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, iphc1 = 0; iphc[2] = 0; /* Might not be used - but needs to be cleared */ + /* Point to just after the two IPHC bytes we have committed to */ + + g_hc06ptr = iphc + 2; + /* Address handling needs to be made first since it might cause an extra * byte with [ SCI | DCI ] */ @@ -508,12 +510,12 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, { /* Flow label can be compressed */ - iphc0 |= SIXLOWPAN_IPHC_FL_C; + iphc0 |= SIXLOWPAN_IPHC_TC_10; if (((ipv6->vtc & 0x0f) == 0) && ((ipv6->tcf & 0xf0) == 0)) { /* Compress (elide) all */ - iphc0 |= SIXLOWPAN_IPHC_TC_C; + iphc0 |= SIXLOWPAN_IPHC_TC_01; } else { @@ -527,11 +529,11 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, { /* Flow label cannot be compressed */ - if (((ipv6->vtc & 0x0f) == 0) && ((ipv6->tcf & 0xF0) == 0)) + if (((ipv6->vtc & 0x0f) == 0) && ((ipv6->tcf & 0xf0) == 0)) { /* Compress only traffic class */ - iphc0 |= SIXLOWPAN_IPHC_TC_C; + iphc0 |= SIXLOWPAN_IPHC_TC_01; *g_hc06ptr = (tmp & 0xc0) | (ipv6->tcf & 0x0f); memcpy(g_hc06ptr + 1, &ipv6->flow, 2); g_hc06ptr += 3; @@ -556,11 +558,11 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, #if CONFIG_NET_UDP || UIP_CONF_ROUTER if (ipv6->proto == IP_PROTO_UDP) { - iphc0 |= SIXLOWPAN_IPHC_NH_C; + iphc0 |= SIXLOWPAN_IPHC_NH; } #endif /* CONFIG_NET_UDP */ - if ((iphc0 & SIXLOWPAN_IPHC_NH_C) == 0) + if ((iphc0 & SIXLOWPAN_IPHC_NH) == 0) { *g_hc06ptr = ipv6->proto; g_hc06ptr += 1; @@ -577,15 +579,15 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, switch (ipv6->ttl) { case 1: - iphc0 |= SIXLOWPAN_IPHC_TTL_1; + iphc0 |= SIXLOWPAN_IPHC_HLIM_1; break; case 64: - iphc0 |= SIXLOWPAN_IPHC_TTL_64; + iphc0 |= SIXLOWPAN_IPHC_HLIM_64; break; case 255: - iphc0 |= SIXLOWPAN_IPHC_TTL_255; + iphc0 |= SIXLOWPAN_IPHC_HLIM_255; break; default: @@ -601,7 +603,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, ninfo("Compressing unspecified. Setting SAC\n"); iphc1 |= SIXLOWPAN_IPHC_SAC; - iphc1 |= SIXLOWPAN_IPHC_SAM_00; + iphc1 |= SIXLOWPAN_IPHC_SAM_128; } else if ((addrcontext = find_addrcontext_byprefix(ipv6->srcipaddr)) != NULL) { @@ -613,13 +615,14 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, iphc1 |= SIXLOWPAN_IPHC_CID | SIXLOWPAN_IPHC_SAC; iphc[2] |= addrcontext->number << 4; - /* Compession compare with this nodes address (source) */ + /* Compression compare with this nodes address (source) */ iphc1 |= compress_addr_64(ipv6->srcipaddr, &ieee->i_nodeaddr, SIXLOWPAN_IPHC_SAM_BIT); - - /* No address context found for this address */ } + + /* No address context found for this address */ + else if (net_is_addr_linklocal(ipv6->srcipaddr) && ipv6->destipaddr[1] == 0 && ipv6->destipaddr[2] == 0 && ipv6->destipaddr[3] == 0) @@ -631,7 +634,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, { /* Send the full address => SAC = 0, SAM = 00 */ - iphc1 |= SIXLOWPAN_IPHC_SAM_00; /* 128-bits */ + iphc1 |= SIXLOWPAN_IPHC_SAM_128; /* 128-bits */ memcpy(g_hc06ptr, ipv6->srcipaddr, 16); g_hc06ptr += 16; } @@ -645,7 +648,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, iphc1 |= SIXLOWPAN_IPHC_M; if (SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE8(ipv6->destipaddr)) { - iphc1 |= SIXLOWPAN_IPHC_DAM_11; + iphc1 |= SIXLOWPAN_IPHC_DAM_0; /* Use last byte */ @@ -656,7 +659,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, { FAR uint8_t *iptr = (FAR uint8_t *)ipv6->destipaddr; - iphc1 |= SIXLOWPAN_IPHC_DAM_10; + iphc1 |= SIXLOWPAN_IPHC_DAM_16; /* Second byte + the last three */ @@ -668,7 +671,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, { FAR uint8_t *iptr = (FAR uint8_t *)ipv6->destipaddr; - iphc1 |= SIXLOWPAN_IPHC_DAM_01; + iphc1 |= SIXLOWPAN_IPHC_DAM_64; /* Second byte + the last five */ @@ -678,7 +681,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, } else { - iphc1 |= SIXLOWPAN_IPHC_DAM_00; + iphc1 |= SIXLOWPAN_IPHC_DAM_128; /* Full address */ @@ -715,7 +718,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, { /* Send the full address */ - iphc1 |= SIXLOWPAN_IPHC_DAM_00; /* 128-bits */ + iphc1 |= SIXLOWPAN_IPHC_DAM_128; /* 128-bits */ memcpy(g_hc06ptr, ipv6->destipaddr, 16); g_hc06ptr += 16; } @@ -819,7 +822,7 @@ void sixlowpan_compresshdr_hc06(FAR struct ieee802154_driver_s *ieee, } /**************************************************************************** - * Name: sixlowpan_hc06_initialize + * Name: sixlowpan_uncompresshdr_hc06 * * Description: * Uncompress HC06 (i.e., IPHC and LOWPAN_UDP) headers and put them in @@ -849,36 +852,39 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee, FAR uint8_t *payptr) { FAR struct ipv6_hdr_s *ipv6 = IPv6BUF(ieee); - FAR uint8_t *iphc = payptr + g_frame_hdrlen; + FAR uint8_t *iphc; uint8_t iphc0; uint8_t iphc1; uint8_t tmp; - /* At least two byte will be used for the encoding */ - - g_hc06ptr = payptr + g_frame_hdrlen + 2; + /* payptr points to IPHC. At least two byte will be used for the encoding. */ + iphc = payptr; iphc0 = iphc[0]; iphc1 = iphc[1]; - ninfo("payptr=%p g_frame_hdrlen=%u iphc[%p]=%02x:%02x:%02x g_hc06ptr=%p\n", - payptr, g_frame_hdrlen, iphc, iphc[0], iphc[1], iphc[2], g_hc06ptr); + /* g_hc96ptr points to just after the 2-byte minimum IPHC */ + + g_hc06ptr = payptr + 2; + + ninfo("payptr=%p g_frame_hdrlen=%u iphc=%02x:%02x:%02x g_hc06ptr=%p\n", + payptr, g_frame_hdrlen, iphc[0], iphc[1], iphc[2], g_hc06ptr); /* Another if the CID flag is set */ - if (iphc1 & SIXLOWPAN_IPHC_CID) + if ((iphc1 & SIXLOWPAN_IPHC_CID) != 0) { - ninfo("IPHC: CID flag set. Increase header by one\n"); + ninfo("CID flag set. Increase header by one\n"); g_hc06ptr++; } /* Traffic class and flow label */ - if ((iphc0 & SIXLOWPAN_IPHC_FL_C) == 0) + if ((iphc0 & SIXLOWPAN_IPHC_TC_10) == 0) { /* Flow label are carried inline */ - if ((iphc0 & SIXLOWPAN_IPHC_TC_C) == 0) + if ((iphc0 & SIXLOWPAN_IPHC_TC_01) == 0) { /* Traffic class is carried inline */ @@ -913,7 +919,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee, /* Version is always 6! */ /* Version and flow label are compressed */ - if ((iphc0 & SIXLOWPAN_IPHC_TC_C) == 0) + if ((iphc0 & SIXLOWPAN_IPHC_TC_01) == 0) { /* Traffic class is inline */ @@ -934,7 +940,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee, /* Next Header */ - if ((iphc0 & SIXLOWPAN_IPHC_NH_C) == 0) + if ((iphc0 & SIXLOWPAN_IPHC_NH) == 0) { /* Next header is carried inline */ @@ -945,23 +951,23 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee, /* Hop limit */ - if ((iphc0 & 0x03) != SIXLOWPAN_IPHC_TTL_I) + if ((iphc0 & SIXLOWPAN_IPHC_HLIM_MASK) != SIXLOWPAN_IPHC_HLIM_INLINE) { - ipv6->ttl = g_ttl_values[iphc0 & 0x03]; + ipv6->ttl = g_ttl_values[iphc0 & SIXLOWPAN_IPHC_HLIM_MASK]; } else { - ipv6->ttl = *g_hc06ptr; + ipv6->ttl = *g_hc06ptr; g_hc06ptr += 1; } /* Put the source address compression mode SAM in the tmp var */ - tmp = ((iphc1 & SIXLOWPAN_IPHC_SAM_11) >> SIXLOWPAN_IPHC_SAM_BIT) & 0x03; + tmp = ((iphc1 & SIXLOWPAN_IPHC_SAM_MASK) >> SIXLOWPAN_IPHC_SAM_BIT) & 0x03; /* Address context based compression */ - if (iphc1 & SIXLOWPAN_IPHC_SAC) + if ((iphc1 & SIXLOWPAN_IPHC_SAC) != 0) { FAR struct sixlowpan_addrcontext_s *addrcontext; uint8_t sci = (iphc1 & SIXLOWPAN_IPHC_CID) ? iphc[2] >> 4 : 0; @@ -993,28 +999,28 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee, } /* Destination address */ - /* put the destination address compression mode into tmp */ + /* Put the destination address compression mode into tmp */ - tmp = ((iphc1 & SIXLOWPAN_IPHC_DAM_11) >> SIXLOWPAN_IPHC_DAM_BIT) & 0x03; + tmp = ((iphc1 & SIXLOWPAN_IPHC_DAM_MASK) >> SIXLOWPAN_IPHC_DAM_BIT) & 0x03; /* Multicast compression */ - if (iphc1 & SIXLOWPAN_IPHC_M) + if ((iphc1 & SIXLOWPAN_IPHC_M) != 0) { /* Address context based multicast compression */ - if (iphc1 & SIXLOWPAN_IPHC_DAC) + if ((iphc1 & SIXLOWPAN_IPHC_DAC) != 0) { /* TODO: implement this */ } else { - /* non-address context based multicast compression + /* Non-address context based multicast compression * - * DAM_00: 128 bits - * DAM_01: 48 bits FFXX::00XX:XXXX:XXXX - * DAM_10: 32 bits FFXX::00XX:XXXX - * DAM_11: 8 bits FF02::00XX + * DAM 00: 128 bits + * DAM 01: 48 bits FFXX::00XX:XXXX:XXXX + * DAM 0: 32 bits FFXX::00XX:XXXX + * DAM 11: 8 bits FF02::00XX */ uint8_t prefix[] = { 0xff, 0x02 }; @@ -1032,10 +1038,10 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee, /* no multicast */ /* Context based */ - if (iphc1 & SIXLOWPAN_IPHC_DAC) + if ((iphc1 & SIXLOWPAN_IPHC_DAC) != 0) { FAR struct sixlowpan_addrcontext_s *addrcontext; - uint8_t dci = (iphc1 & SIXLOWPAN_IPHC_CID) ? iphc[2] & 0x0f : 0; + uint8_t dci = ((iphc1 & SIXLOWPAN_IPHC_CID) != 0) ? iphc[2] & 0x0f : 0; addrcontext = find_addrcontext_bynumber(dci); @@ -1063,7 +1069,7 @@ void sixlowpan_uncompresshdr_hc06(FAR struct ieee802154_driver_s *ieee, /* Next header processing - continued */ - if ((iphc0 & SIXLOWPAN_IPHC_NH_C)) + if ((iphc0 & SIXLOWPAN_IPHC_NH) != 0) { FAR struct udp_hdr_s *udp = UDPIPv6BUF(ieee); diff --git a/net/sixlowpan/sixlowpan_input.c b/net/sixlowpan/sixlowpan_input.c index 03a78f3684e..257e7b48c9e 100644 --- a/net/sixlowpan/sixlowpan_input.c +++ b/net/sixlowpan/sixlowpan_input.c @@ -462,12 +462,21 @@ static int sixlowpan_frame_process(FAR struct ieee802154_driver_s *ieee, if (hc1[RIME_HC1_DISPATCH] == SIXLOWPAN_DISPATCH_IPV6) { - ninfo("IPV6 Dispatch\n"); + FAR struct ipv6_hdr_s *ipv6 = IPv6BUF(&ieee->i_dev); + + ninfo("IPv6 Dispatch\n"); g_frame_hdrlen += SIXLOWPAN_IPV6_HDR_LEN; + /* payptr was set up to begin just after the IPHC bytes. However, + * those bytes are not present for the case of IPv6 dispatch. Just + * reset back to the begnning of the buffer. + */ + + payptr = iob->io_data; + /* Put uncompressed IP header in d_buf. */ - memcpy(ieee->i_dev.d_buf, payptr + g_frame_hdrlen, IPv6_HDRLEN); + memcpy(ipv6, payptr + g_frame_hdrlen, IPv6_HDRLEN); /* Update g_uncomp_hdrlen and g_frame_hdrlen. */