diff --git a/arch/arm/src/efm32/efm32_i2c.c b/arch/arm/src/efm32/efm32_i2c.c index 59ad3aa2f84..a52cd05ead5 100644 --- a/arch/arm/src/efm32/efm32_i2c.c +++ b/arch/arm/src/efm32/efm32_i2c.c @@ -553,7 +553,7 @@ static inline int efm32_i2c_sem_waitdone(FAR struct efm32_i2c_priv_s *priv) #ifdef CONFIG_EFM32_I2C_DYNTIMEO abstime.tv_nsec += 1000 * efm32_i2c_tousecs(priv->msgc, priv->msgv); - if (abstime.tv_nsec > 1000 * 1000 * 1000) + if (abstime.tv_nsec >= 1000 * 1000 * 1000) { abstime.tv_sec++; abstime.tv_nsec -= 1000 * 1000 * 1000; @@ -561,7 +561,7 @@ static inline int efm32_i2c_sem_waitdone(FAR struct efm32_i2c_priv_s *priv) #elif CONFIG_EFM32_I2CTIMEOMS > 0 abstime.tv_nsec += CONFIG_EFM32_I2CTIMEOMS * 1000 * 1000; - if (abstime.tv_nsec > 1000 * 1000 * 1000) + if (abstime.tv_nsec >= 1000 * 1000 * 1000) { abstime.tv_sec++; abstime.tv_nsec -= 1000 * 1000 * 1000; 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/configs/stm32f103-minimum/usbnsh/defconfig b/configs/stm32f103-minimum/usbnsh/defconfig index e5319a27eb3..312a2e8505d 100644 --- a/configs/stm32f103-minimum/usbnsh/defconfig +++ b/configs/stm32f103-minimum/usbnsh/defconfig @@ -744,7 +744,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_SENSORS is not set CONFIG_SERIAL=y CONFIG_SERIAL_REMOVABLE=y -CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_CONSOLE is not set # CONFIG_16550_UART is not set # CONFIG_UART_SERIALDRIVER is not set # CONFIG_UART0_SERIALDRIVER is not set @@ -774,9 +774,9 @@ CONFIG_STANDARD_SERIAL=y # CONFIG_SERIAL_OFLOWCONTROL is not set # CONFIG_SERIAL_DMA is not set CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y -CONFIG_USART1_SERIAL_CONSOLE=y +# CONFIG_USART1_SERIAL_CONSOLE is not set # CONFIG_OTHER_SERIAL_CONSOLE is not set -# CONFIG_NO_SERIAL_CONSOLE is not set +CONFIG_NO_SERIAL_CONSOLE=y # # USART1 Configuration 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/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/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index a9a70191fdb..413a5d10fc8 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -59,6 +59,10 @@ #include #include +#ifdef CONFIG_NET_6LOWPAN +# include +#endif + #ifdef CONFIG_NET_IGMP # include # include @@ -702,16 +706,47 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, /* MAC address operations only make sense if Ethernet is supported */ -#ifdef CONFIG_NET_ETHERNET +#if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_NET_6LOWPAN) case SIOCGIFHWADDR: /* Get hardware address */ { dev = netdev_ifrdev(req); if (dev) { - req->ifr_hwaddr.sa_family = AF_INETX; - memcpy(req->ifr_hwaddr.sa_data, - dev->d_mac.ether_addr_octet, IFHWADDRLEN); - ret = OK; +#ifdef CONFIG_NET_ETHERNET +#ifdef CONFIG_NET_MULTILINK + if (dev->d_lltype == NET_LL_ETHERNET) +#else + if (true) +#endif + { + req->ifr_hwaddr.sa_family = AF_INETX; + memcpy(req->ifr_hwaddr.sa_data, + dev->d_mac.ether_addr_octet, IFHWADDRLEN); + ret = OK; + } + else +#endif + +#ifdef CONFIG_NET_6LOWPAN +#ifdef CONFIG_NET_MULTILINK + if (dev->d_lltype == NET_LL_IEEE802154) +#else + if (true) +#endif + { + FAR struct ieee802154_driver_s *ieee = + (FAR struct ieee802154_driver_s *)dev; + + req->ifr_hwaddr.sa_family = AF_INETX; + memcpy(req->ifr_hwaddr.sa_data, ieee->i_nodeaddr.u8, + CONFIG_NET_6LOWPAN_RIMEADDR_SIZE); + ret = OK; + } + else +#endif + { + nerr("Unsupported link layer\n"); + } } } break; @@ -721,9 +756,40 @@ static int netdev_ifrioctl(FAR struct socket *psock, int cmd, dev = netdev_ifrdev(req); if (dev) { - memcpy(dev->d_mac.ether_addr_octet, - req->ifr_hwaddr.sa_data, IFHWADDRLEN); - ret = OK; +#ifdef CONFIG_NET_ETHERNET +#ifdef CONFIG_NET_MULTILINK + if (dev->d_lltype == NET_LL_ETHERNET) +#else + if (true) +#endif + { + memcpy(dev->d_mac.ether_addr_octet, + req->ifr_hwaddr.sa_data, IFHWADDRLEN); + ret = OK; + } + else +#endif + +#ifdef CONFIG_NET_6LOWPAN +#ifdef CONFIG_NET_MULTILINK + if (dev->d_lltype == NET_LL_IEEE802154) +#else + if (true) +#endif + { + FAR struct ieee802154_driver_s *ieee = + (FAR struct ieee802154_driver_s *)dev; + + req->ifr_hwaddr.sa_family = AF_INETX; + memcpy(ieee->i_nodeaddr.u8, req->ifr_hwaddr.sa_data, + CONFIG_NET_6LOWPAN_RIMEADDR_SIZE); + ret = OK; + } + else +#endif + { + nerr("Unsupported link layer\n"); + } } } break; diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index bd4dd2e8eb6..8995048b007 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -146,7 +146,7 @@ static void sixlowpan_compress_ipv6hdr(FAR struct ieee802154_driver_s *ieee, * * Input Parameters: * ieee - The IEEE802.15.4 MAC driver instance - * ipv6hdr - IPv6 header followed by TCP or UDP header. + * ipv6hdr - IPv6 header followed by TCP, UDP, or ICMPv6 header. * buf - Beginning of the packet packet to send (with IPv6 + protocol * headers) * buflen - Length of data to send (include IPv6 and protocol headers) diff --git a/net/sixlowpan/sixlowpan_hc1.c b/net/sixlowpan/sixlowpan_hc1.c index a7040d5bcb3..6626501363c 100644 --- a/net/sixlowpan/sixlowpan_hc1.c +++ b/net/sixlowpan/sixlowpan_hc1.c @@ -116,7 +116,8 @@ * * Input Parmeters: * ieee - A reference to the IEE802.15.4 network device state - * ipv6 - The IPv6 header to be compressed + * ipv6 - The IPv6 header followd by TCP, UDP, or ICMPv6 header to be + * compressed * destmac - L2 destination address, needed to compress the IP * destination field * fptr - Pointer to frame to be compressed. @@ -189,7 +190,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, #if CONFIG_NET_UDP case IP_PROTO_UDP: { - FAR struct udp_hdr_s *udp = UDPIPv6BUF(&ieee->i_dev); + FAR struct udp_hdr_s *udp = + &(((FAR struct ipv6udp_hdr_s *)ipv6)->udp); /* Try to compress UDP header (we do only full compression). * This is feasible if both src and dest ports are between @@ -199,10 +201,10 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, ninfo("local/remote port %u/%u\n", udp->srcport, udp->destport); - if (htons(udp->srcport) >= CONFIG_NET_6LOWPAN_MINPORT && - htons(udp->srcport) < (CONFIG_NET_6LOWPAN_MINPORT + 16) && - htons(udp->destport) >= CONFIG_NET_6LOWPAN_MINPORT && - htons(udp->destport) < (CONFIG_NET_6LOWPAN_MINPORT + 16)) + if (ntohs(udp->srcport) >= CONFIG_NET_6LOWPAN_MINPORT && + ntohs(udp->srcport) < (CONFIG_NET_6LOWPAN_MINPORT + 16) && + ntohs(udp->destport) >= CONFIG_NET_6LOWPAN_MINPORT && + ntohs(udp->destport) < (CONFIG_NET_6LOWPAN_MINPORT + 16)) { FAR uint8_t *hcudp = fptr + g_frame_hdrlen; @@ -215,8 +217,8 @@ void sixlowpan_compresshdr_hc1(FAR struct ieee802154_driver_s *ieee, hcudp[RIME_HC1_HC_UDP_UDP_ENCODING] = 0xe0; hcudp[RIME_HC1_HC_UDP_TTL] = ipv6->ttl; hcudp[RIME_HC1_HC_UDP_PORTS] = - (uint8_t)((htons(udp->srcport) - CONFIG_NET_6LOWPAN_MINPORT) << 4) + - (uint8_t)((htons(udp->destport) - CONFIG_NET_6LOWPAN_MINPORT)); + (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); 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. */ diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index 8f3e52dfd39..d6a795c5540 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -446,6 +446,7 @@ extern struct rimeaddr_s g_pktaddrs[PACKETBUF_NUM_ADDRS]; 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 iob_s; /* Forward reference */ @@ -466,7 +467,8 @@ struct iob_s; /* Forward reference */ * * Input Parameters: * dev - The IEEE802.15.4 MAC network driver interface. - * destip - IPv6 plus TCP or UDP headers. + * 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 * raddr - The MAC address of the destination @@ -484,7 +486,8 @@ struct iob_s; /* Forward reference */ ****************************************************************************/ int sixlowpan_send(FAR struct net_driver_s *dev, - FAR const struct ipv6_hdr_s *destip, FAR const void *buf, + 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, uint16_t timeout); diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index 98cc577f5f5..8338a413473 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -176,7 +176,7 @@ static uint16_t send_interrupt(FAR struct net_driver_s *dev, { DEBUGASSERT((flags & WPAN_POLL) != 0); - /* Transfer the frame listto the IEEE802.15.4 MAC device */ + /* Transfer the frame list to the IEEE802.15.4 MAC device */ sinfo->s_result = sixlowpan_queue_frames((FAR struct ieee802154_driver_s *)dev, @@ -237,6 +237,7 @@ end_wait: * * Input Parameters: * dev - The IEEE802.15.4 MAC network driver interface. + * list - Head of callback list for send interrupt * ipv6hdr - IPv6 header followed by TCP or UDP header. * buf - Data to send * len - Length of data to send @@ -255,6 +256,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, uint16_t timeout) @@ -283,7 +285,7 @@ int sixlowpan_send(FAR struct net_driver_s *dev, * device related events, no connect-related events. */ - sinfo.s_cb = devif_callback_alloc(dev, NULL); + sinfo.s_cb = devif_callback_alloc(dev, list); if (sinfo.s_cb != NULL) { int ret; @@ -312,7 +314,7 @@ int sixlowpan_send(FAR struct net_driver_s *dev, /* Make sure that no further interrupts are processed */ - devif_dev_callback_free(dev, sinfo.s_cb); + devif_conn_callback_free(dev, sinfo.s_cb, list); } } diff --git a/net/sixlowpan/sixlowpan_tcpsend.c b/net/sixlowpan/sixlowpan_tcpsend.c index 1ad8068a317..a34bfe0666e 100644 --- a/net/sixlowpan/sixlowpan_tcpsend.c +++ b/net/sixlowpan/sixlowpan_tcpsend.c @@ -327,7 +327,8 @@ ssize_t psock_6lowpan_tcp_send(FAR struct socket *psock, FAR const void *buf, timeout = 0; #endif - ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6tcp, + ret = sixlowpan_send(dev, &conn->list, + (FAR const struct ipv6_hdr_s *)&ipv6tcp, buf, buflen, &destmac, timeout); if (ret < 0) { diff --git a/net/sixlowpan/sixlowpan_udpsend.c b/net/sixlowpan/sixlowpan_udpsend.c index 717df424a27..f8f62e528b1 100644 --- a/net/sixlowpan/sixlowpan_udpsend.c +++ b/net/sixlowpan/sixlowpan_udpsend.c @@ -191,8 +191,9 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, if (to6->sin6_family != AF_INET6 || tolen < sizeof(struct sockaddr_in6)) { - nerr("ERROR: Invalid destination address\n"); - return (ssize_t)-EAFNOSUPPORT; + nerr("ERROR: Invalid destination address: sin6_family=%u tolen = %u\n", + to6->sin6_family, tolen); + return (ssize_t)-EPROTOTYPE; } /* Get the underlying UDP "connection" structure */ @@ -200,14 +201,6 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, conn = (FAR struct udp_conn_s *)psock->s_conn; DEBUGASSERT(conn != NULL); - /* Ignore if not IPv6 domain */ - - if (conn->domain != PF_INET6) - { - nwarn("WARNING: Not IPv6\n"); - return (ssize_t)-EPROTOTYPE; - } - /* Route outgoing message to the correct device */ #ifdef CONFIG_NETDEV_MULTINIC @@ -264,8 +257,8 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, /* Copy the source and destination addresses */ - net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr, to6->sin6_addr.in6_u.u6_addr16); - net_ipv6addr_hdrcopy(ipv6udp.ipv6.destipaddr, conn->u.ipv6.raddr); + net_ipv6addr_hdrcopy(ipv6udp.ipv6.destipaddr, to6->sin6_addr.in6_u.u6_addr16); + net_ipv6addr_hdrcopy(ipv6udp.ipv6.srcipaddr, conn->u.ipv6.laddr); ninfo("IPv6 length: %d\n", ((int)ipv6udp.ipv6.len[0] << 8) + ipv6udp.ipv6.len[1]); @@ -315,7 +308,8 @@ ssize_t psock_6lowpan_udp_sendto(FAR struct socket *psock, timeout = 0; #endif - ret = sixlowpan_send(dev, (FAR const struct ipv6_hdr_s *)&ipv6udp, + ret = sixlowpan_send(dev, &conn->list, + (FAR const struct ipv6_hdr_s *)&ipv6udp, buf, buflen, &destmac, timeout); if (ret < 0) {