From f5b6ae627dbefa85457e9adcf5f9c19ab19301eb Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Thu, 6 Apr 2017 17:12:13 +0900 Subject: [PATCH 01/16] EFM32 I2C: Fix timeout calculation --- arch/arm/src/efm32/efm32_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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; From 1fa300f01159382c078ead269028278a7a2e024c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 6 Apr 2017 08:32:18 -0600 Subject: [PATCH 02/16] 6loWPAN: Fix uncompressing of IPv6 encoded packet. --- net/sixlowpan/sixlowpan_input.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) 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. */ From 95941b49084e5e30194a6debdac9c60bbf3e596e Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Thu, 6 Apr 2017 08:35:33 -0600 Subject: [PATCH 03/16] STM32: Fix SYSCFG_CFGR1_I2C_PBXFMP_SHIFT value --- arch/arm/src/stm32/chip/stm32f30xxx_syscfg.h | 2 +- arch/arm/src/stm32/chip/stm32f33xxx_syscfg.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 */ From e180522854970106801c93135aa4d4742df4fc7d Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 6 Apr 2017 08:41:41 -0600 Subject: [PATCH 04/16] stm32f7: serial: add interface to get uart_dev_t by USART number, stm32_serial_get_uart --- arch/arm/src/stm32f7/stm32_serial.c | 38 +++++++++++++++++++++++++++++ arch/arm/src/stm32f7/stm32_uart.h | 11 +++++++++ 2 files changed, 49 insertions(+) diff --git a/arch/arm/src/stm32f7/stm32_serial.c b/arch/arm/src/stm32f7/stm32_serial.c index b839aad8f44..eb554c314e9 100644 --- a/arch/arm/src/stm32f7/stm32_serial.c +++ b/arch/arm/src/stm32f7/stm32_serial.c @@ -228,6 +228,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. */ @@ -1460,6 +1464,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 +1548,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 +2542,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 * From dabf45f10077cc40496a0d8f58cede2047ec1544 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 6 Apr 2017 08:44:53 -0600 Subject: [PATCH 05/16] STM32F7: default CONFIG_STM32F7_DMACAPABLE to 'n'. STM32F7 does not have CCM RAM but DTCM, so this option does not need to enabled. DTCM RAM is DMA-able through CPU AHBS bus. --- arch/arm/src/stm32f7/Kconfig | 3 +-- arch/arm/src/stm32f7/stm32_ethernet.c | 4 ++-- arch/arm/src/stm32f7/stm32_serial.c | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index e727aef24aa..f5815f4d91b 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -1884,8 +1884,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_serial.c b/arch/arm/src/stm32f7/stm32_serial.c index eb554c314e9..18f56600df1 100644 --- a/arch/arm/src/stm32f7/stm32_serial.c +++ b/arch/arm/src/stm32f7/stm32_serial.c @@ -383,8 +383,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. From e2702cbe4eacfe2d94f7d704cd954ce4684af5c2 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 6 Apr 2017 08:46:24 -0600 Subject: [PATCH 06/16] STM32F7: fix UART7 and UART8 IFLOWCONTROL options --- arch/arm/src/stm32f7/stm32_serial.c | 8 ++++---- drivers/serial/Kconfig | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_serial.c b/arch/arm/src/stm32f7/stm32_serial.c index 18f56600df1..1ea4bce7dc7 100644 --- a/arch/arm/src/stm32f7/stm32_serial.c +++ b/arch/arm/src/stm32f7/stm32_serial.c @@ -882,11 +882,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 @@ -943,11 +943,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 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--- From 0aa52d98a2dbc4601f217d77e74c0cae2a69d770 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 6 Apr 2017 08:47:45 -0600 Subject: [PATCH 07/16] STM32F7: add warning for RXDMA + IFLOWCONTROL combination 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. Data loss can be demonstrated by doing long up_mdelay inside irq critical section and feeding data to RXDMA+IFLOWCONTROL UART. --- arch/arm/src/stm32f7/stm32_serial.c | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/arch/arm/src/stm32f7/stm32_serial.c b/arch/arm/src/stm32f7/stm32_serial.c index 1ea4bce7dc7..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 ****************************************************************************/ From 869e3b5b73391d8a6359f54de97635dbe212f88b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 6 Apr 2017 09:36:57 -0600 Subject: [PATCH 08/16] sim/sixlowpan: Now support apps/examples/udpblaster too. --- configs/sim/README.txt | 6 ++++++ configs/sim/sixlowpan/defconfig | 36 ++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) 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 From 571f3d952e5d3944830ac37a427f4a4ff13ff702 Mon Sep 17 00:00:00 2001 From: Frank Benkert Date: Thu, 6 Apr 2017 09:43:07 -0600 Subject: [PATCH 09/16] SAMV7: Watchdog: fix Forbidden Window Value According the Datasheet the WDD Value is the lower bound of a so called Forbidden Window and to disable this we have to set the WDD Value greater than or equal to the WDV Value. This seems to be a bug in the datasheet. It looks like we have to set it to a greater value than the WDV to realy disable this Thing. When triggering the Watchdog faster than the (very slow) clock source of the Watchdog fires, this Forbidden Window Feature resets the System if WDD equals to WDV. This Changeset disables the Forbidden Window by setting the WDD Value to the Maximum (0xfff) Value possible. --- arch/arm/src/samv7/sam_wdt.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/samv7/sam_wdt.c b/arch/arm/src/samv7/sam_wdt.c index e662146077e..c3921df2fdf 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 + * 0xfff to truly disable this Forbidden Window Feature. */ - regval = WDT_MR_WDV(reload) | WDT_MR_WDD(reload); + regval = WDT_MR_WDV(reload) | WDT_MR_WDD(0xfff); #ifdef CONFIG_SAMV7_WDT_INTERRUPT /* Generate an interrupt whent he watchdog timer expires */ From ac8ddf4eb1bd91b6f87aeabd3cd1e8b252e5add9 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 6 Apr 2017 09:46:04 -0600 Subject: [PATCH 10/16] SAMv7: In review of last patch, change literal 0xfff to WDT_MR_WDD_MAX for portability. --- arch/arm/src/samv7/sam_wdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/samv7/sam_wdt.c b/arch/arm/src/samv7/sam_wdt.c index c3921df2fdf..4ce21303c33 100644 --- a/arch/arm/src/samv7/sam_wdt.c +++ b/arch/arm/src/samv7/sam_wdt.c @@ -507,10 +507,10 @@ static int sam_settimeout(FAR struct watchdog_lowerhalf_s *lower, * * 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 - * 0xfff to truly disable this Forbidden Window Feature. + * WDT_MR_WDD_MAX to truly disable this Forbidden Window Feature. */ - regval = WDT_MR_WDV(reload) | WDT_MR_WDD(0xfff); + 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 */ From e3b3e57e560ef39c26ce498ab29181288816ffaf Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Thu, 6 Apr 2017 09:53:11 -0600 Subject: [PATCH 11/16] RTC: add interface for check if RTC time has been set New interface allows checking if RTC time has been set. This allows to application to detect if RTC has valid time (after reset) or should application attempt to get real time by other means (for example, by launching ntpclient or GPS). --- arch/arm/src/kinetis/kinetis_rtc_lowerhalf.c | 1 + arch/arm/src/stm32/Kconfig | 7 ++- arch/arm/src/stm32/stm32_rcc.c | 2 +- arch/arm/src/stm32/stm32_rtc.h | 5 ++ arch/arm/src/stm32/stm32_rtc_lowerhalf.c | 23 +++++++++ arch/arm/src/stm32/stm32_rtcc.c | 13 ++++- arch/arm/src/stm32/stm32f40xxx_rtcc.c | 15 ++++-- arch/arm/src/stm32f7/Kconfig | 7 ++- arch/arm/src/stm32f7/stm32_rtc.c | 25 ++++++---- arch/arm/src/stm32f7/stm32_rtc.h | 5 ++ arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c | 23 +++++++++ arch/arm/src/stm32l4/stm32l4_rtc.h | 13 +++++ arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c | 25 +++++++++- arch/arm/src/stm32l4/stm32l4_rtcc.c | 51 +++++++++++++++----- drivers/timers/rtc.c | 20 +++++++- include/nuttx/timers/rtc.h | 21 ++++++-- 16 files changed, 220 insertions(+), 36 deletions(-) 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/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/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 f5815f4d91b..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 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/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/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. */ From 50170a6108541ce5d868382fccf4e7a8653fca6c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 6 Apr 2017 11:57:43 -0600 Subject: [PATCH 12/16] 6loWPAN: Fixes for UDP packet transfers. --- net/sixlowpan/sixlowpan_internal.h | 7 +++++-- net/sixlowpan/sixlowpan_send.c | 6 ++++-- net/sixlowpan/sixlowpan_tcpsend.c | 3 ++- net/sixlowpan/sixlowpan_udpsend.c | 20 +++++++------------- 4 files changed, 18 insertions(+), 18 deletions(-) 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..d078a8534e8 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -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) { From 27c65c3f229cf3bbeec83180d32e6df16fccc54d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 6 Apr 2017 15:58:00 -0600 Subject: [PATCH 13/16] 6loWPAN: Add network IOCTL support to set the node address --- net/netdev/netdev_ioctl.c | 82 +++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 8 deletions(-) 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; From 494d9968266373bc5749179527e2eb253e90abae Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 6 Apr 2017 17:56:22 -0600 Subject: [PATCH 14/16] 6loWPAN: Fix a few UDP-related issues. --- net/sixlowpan/sixlowpan_framelist.c | 2 +- net/sixlowpan/sixlowpan_hc1.c | 18 +++++---- net/sixlowpan/sixlowpan_internal.h | 16 ++++++++ net/sixlowpan/sixlowpan_send.c | 62 ++++++++++++++++++++++++++--- 4 files changed, 84 insertions(+), 14 deletions(-) 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_internal.h b/net/sixlowpan/sixlowpan_internal.h index d6a795c5540..23bff8ad98d 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -327,6 +327,22 @@ struct ipv6icmp_hdr_s struct icmpv6_iphdr_s icmp; }; +/* IPv6 + TCP or UDP or ICMPv6 header */ + +union ipv6_hdr_u +{ + struct ipv6_hdr_s ipv6; +#ifdef CONFIG_NET_TCP + struct ipv6tcp_hdr_s ipv6tcp; +#endif +#ifdef CONFIG_NET_UDP + struct ipv6udp_hdr_s ipv6udp; +#endif +#ifdef CONFIG_NET_ICMPv6 + struct ipv6icmp_hdr_s ipv6icmp +#endif +}; + /* IEEE802.15.4 Frame Definitions *******************************************/ /* The IEEE 802.15.4 frame has a number of constant/fixed fields that can be * counted to make frame construction and max payload calculations easier. diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index d078a8534e8..cf15cac28b5 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -39,6 +39,7 @@ #include +#include #include #include #include @@ -82,10 +83,10 @@ struct sixlowpan_send_s int s_result; /* The result of the transfer */ uint16_t s_timeout; /* Send timeout in deciseconds */ systime_t s_time; /* Last send time for determining timeout */ - FAR const struct ipv6_hdr_s *s_ipv6hdr; /* IPv6 header, followed by UDP or TCP header. */ FAR const struct rimeaddr_s *s_destmac; /* Destination MAC address */ FAR const void *s_buf; /* Data to send */ size_t s_len; /* Length of data in buf */ + FAR const union ipv6_hdr_u s_ipv6hdr; /* IPv6 header, followed by UDP, TCP, or ICMPv6 header. */ }; /**************************************************************************** @@ -176,12 +177,12 @@ 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, - sinfo->s_ipv6hdr, sinfo->s_buf, sinfo->s_len, - sinfo->s_destmac); + &sinfo->s_ipv6hdr.ipv6, sinfo->s_buf, + sinfo->s_len, sinfo->s_destmac); flags &= ~WPAN_POLL; neighbor_reachable(dev); @@ -217,6 +218,56 @@ end_wait: return flags; } +/**************************************************************************** + * Name: sixlowpan_ipv6_copy + * + * Description: + * Make a copy of the IPv6 + {TCP, UDP, ICMPv6} header structure. + * + * Input Parameters: + * ipv6hdr - IPv6 header followed by TCP or UDP header. + * sinfo - Send state structure reference + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void sixlowpan_ipv6_copy(FAR const struct ipv6_hdr_s *ipv6hdr, + FAR struct sixlowpan_send_s *sinfo) +{ + size_t structsize; + + switch (ipv6hdr->proto) + { +#ifdef CONFIG_NET_TCP + case IP_PROTO_TCP: + structsize = sizeof(struct ipv6tcp_hdr_s); + break; +#endif + +#ifdef CONFIG_NET_UDP + case IP_PROTO_UDP: + structsize = sizeof(struct ipv6udp_hdr_s); + break; +#endif + +#ifdef CONFIG_NET_ICMPv6 + case IP_PROTO_ICMP6: + structsize = sizeof(struct ipv6icmp_hdr_s); + break; +#endif + + default: + nwarn("WARNING: Unrecognized proto: %u\n", ipv6hdr->proto); + structsize = sizeof(struct ipv6_hdr_s); + break; + } + + memcpy((FAR void *)&sinfo->s_ipv6hdr, (FAR const void *)ipv6hdr, + structsize); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -271,11 +322,12 @@ int sixlowpan_send(FAR struct net_driver_s *dev, sinfo.s_result = -EBUSY; sinfo.s_timeout = timeout; sinfo.s_time = clock_systimer(); - sinfo.s_ipv6hdr = ipv6hdr; sinfo.s_destmac = destmac; sinfo.s_buf = buf; sinfo.s_len = len; + sixlowpan_ipv6_copy(ipv6hdr, &sinfo); + net_lock(); if (len > 0) { From 58d0c1f22851cb8196e4de3f12f9302c0a969487 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 6 Apr 2017 18:11:04 -0600 Subject: [PATCH 15/16] 6loWPAN: Back out part of the last commit. That included two fixes for a problem. One that didn't work and is unnecessary and one that is necessary. The commit removes the former. --- net/sixlowpan/sixlowpan_internal.h | 16 -------- net/sixlowpan/sixlowpan_send.c | 60 ++---------------------------- 2 files changed, 4 insertions(+), 72 deletions(-) diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index 23bff8ad98d..d6a795c5540 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -327,22 +327,6 @@ struct ipv6icmp_hdr_s struct icmpv6_iphdr_s icmp; }; -/* IPv6 + TCP or UDP or ICMPv6 header */ - -union ipv6_hdr_u -{ - struct ipv6_hdr_s ipv6; -#ifdef CONFIG_NET_TCP - struct ipv6tcp_hdr_s ipv6tcp; -#endif -#ifdef CONFIG_NET_UDP - struct ipv6udp_hdr_s ipv6udp; -#endif -#ifdef CONFIG_NET_ICMPv6 - struct ipv6icmp_hdr_s ipv6icmp -#endif -}; - /* IEEE802.15.4 Frame Definitions *******************************************/ /* The IEEE 802.15.4 frame has a number of constant/fixed fields that can be * counted to make frame construction and max payload calculations easier. diff --git a/net/sixlowpan/sixlowpan_send.c b/net/sixlowpan/sixlowpan_send.c index cf15cac28b5..8338a413473 100644 --- a/net/sixlowpan/sixlowpan_send.c +++ b/net/sixlowpan/sixlowpan_send.c @@ -39,7 +39,6 @@ #include -#include #include #include #include @@ -83,10 +82,10 @@ struct sixlowpan_send_s int s_result; /* The result of the transfer */ uint16_t s_timeout; /* Send timeout in deciseconds */ systime_t s_time; /* Last send time for determining timeout */ + FAR const struct ipv6_hdr_s *s_ipv6hdr; /* IPv6 header, followed by UDP or TCP header. */ FAR const struct rimeaddr_s *s_destmac; /* Destination MAC address */ FAR const void *s_buf; /* Data to send */ size_t s_len; /* Length of data in buf */ - FAR const union ipv6_hdr_u s_ipv6hdr; /* IPv6 header, followed by UDP, TCP, or ICMPv6 header. */ }; /**************************************************************************** @@ -181,8 +180,8 @@ static uint16_t send_interrupt(FAR struct net_driver_s *dev, sinfo->s_result = sixlowpan_queue_frames((FAR struct ieee802154_driver_s *)dev, - &sinfo->s_ipv6hdr.ipv6, sinfo->s_buf, - sinfo->s_len, sinfo->s_destmac); + sinfo->s_ipv6hdr, sinfo->s_buf, sinfo->s_len, + sinfo->s_destmac); flags &= ~WPAN_POLL; neighbor_reachable(dev); @@ -218,56 +217,6 @@ end_wait: return flags; } -/**************************************************************************** - * Name: sixlowpan_ipv6_copy - * - * Description: - * Make a copy of the IPv6 + {TCP, UDP, ICMPv6} header structure. - * - * Input Parameters: - * ipv6hdr - IPv6 header followed by TCP or UDP header. - * sinfo - Send state structure reference - * - * Returned Value: - * None - * - ****************************************************************************/ - -static void sixlowpan_ipv6_copy(FAR const struct ipv6_hdr_s *ipv6hdr, - FAR struct sixlowpan_send_s *sinfo) -{ - size_t structsize; - - switch (ipv6hdr->proto) - { -#ifdef CONFIG_NET_TCP - case IP_PROTO_TCP: - structsize = sizeof(struct ipv6tcp_hdr_s); - break; -#endif - -#ifdef CONFIG_NET_UDP - case IP_PROTO_UDP: - structsize = sizeof(struct ipv6udp_hdr_s); - break; -#endif - -#ifdef CONFIG_NET_ICMPv6 - case IP_PROTO_ICMP6: - structsize = sizeof(struct ipv6icmp_hdr_s); - break; -#endif - - default: - nwarn("WARNING: Unrecognized proto: %u\n", ipv6hdr->proto); - structsize = sizeof(struct ipv6_hdr_s); - break; - } - - memcpy((FAR void *)&sinfo->s_ipv6hdr, (FAR const void *)ipv6hdr, - structsize); -} - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -322,12 +271,11 @@ int sixlowpan_send(FAR struct net_driver_s *dev, sinfo.s_result = -EBUSY; sinfo.s_timeout = timeout; sinfo.s_time = clock_systimer(); + sinfo.s_ipv6hdr = ipv6hdr; sinfo.s_destmac = destmac; sinfo.s_buf = buf; sinfo.s_len = len; - sixlowpan_ipv6_copy(ipv6hdr, &sinfo); - net_lock(); if (len > 0) { From 3465f6be535cdc5517bf049ad3b7cfe7c915d282 Mon Sep 17 00:00:00 2001 From: Bob Ryan Date: Thu, 6 Apr 2017 17:41:07 -0700 Subject: [PATCH 16/16] Disable serial console on stm32f103-minimum usbnsh example project config. Devices enumerate after this change. --- configs/stm32f103-minimum/usbnsh/defconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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