1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
19055: shell/gnrc_icmpv6_echo: acquire ZTIMER_USEC clock for time measurement r=benpicco a=jue89



19188: cpu/gd32v: add periph_adc support r=benpicco a=gschorcht

### Contribution description

This PR provides the `periph_adc` support and is one of a bunch of follow up PRs that complete the peripheral drivers for GD32VF103.

This PR depends on PR #19170 and includes this PR to be compilable since includes the ADC configuration also for Sipeed Longan Nano board.

### Testing procedure

`tests/periph_adc` should work on any GD32VF103 board.

### Issues/PRs references

Depends on PR #19170 

19225: sys/net/dhcpv6: include IA Prefix Option in SOLICIT r=benpicco a=benpicco





Co-authored-by: Jue <me@jue.yt>
Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
Co-authored-by: Benjamin Valentin <benjamin.valentin@ml-pa.com>
This commit is contained in:
bors[bot] 2023-02-02 00:04:14 +00:00 committed by GitHub
commit a9dbf8bc36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 387 additions and 20 deletions

View File

@ -14,6 +14,7 @@ config BOARD_SEEEDSTUDIO_GD32
select CPU_MODEL_GD32VF103VBT6
select BOARD_HAS_HXTAL
select BOARD_HAS_LXTAL
select HAS_PERIPH_ADC
select HAS_PERIPH_I2C
select HAS_PERIPH_PWM
select HAS_PERIPH_SPI

View File

@ -1,6 +1,7 @@
CPU_MODEL = gd32vf103vbt6
# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_adc
FEATURES_PROVIDED += periph_i2c
FEATURES_PROVIDED += periph_pwm
FEATURES_PROVIDED += periph_spi

View File

@ -37,7 +37,7 @@ on-board components:
| Timers | 5 x 16-bit timer | yes |
| RTC | 1 x 32-bit counter, 20-bit prescaler | yes |
| WDT | 2 x 12-bit counter, 3-bit prescaler | yes |
| ADC | 2 x 12-bit units, 16 channels, 1 Msps | no |
| ADC | 2 x 12-bit units, 16 channels @ 1 Msps | yes |
| DAC | 2 x 12-bit channel | no |
| UART | 2 | yes |
| USART | 3 | yes |
@ -65,6 +65,9 @@ MCU pins and their configuration in RIOT.
| MCU Pin | MCU Peripheral | RIOT Peripheral | Board Function | Remark |
|:--------|:---------------|:-----------------|:---------------|:-----------------------------|
| PA0 | BOOT0 | BTN0 | KEY1 | |
| PA1 | ADC01_IN1 | ADC_LINE(0) | | |
| PA2 | ADC01_IN2 | ADC_LINE(1) | | |
| PA3 | ADC01_IN3 | ADC_LINE(2) | | |
| PA9 | USART0 TX | UART_DEV(0) TX | UART TX | |
| PA10 | USART0 RX | UART_DEV(0) RX | UART RX | |
| PA4 | SPI1 CS | SPI_DEV(1) CS | | |
@ -84,7 +87,15 @@ MCU pins and their configuration in RIOT.
| PB13 | SPI0 SCLK | SPI_DEV(0) SCLK | | |
| PB14 | SPI0 MISO | SPI_DEV(0) MISO | | |
| PB15 | SPI0 MOSI | SPI_DEV(0) MOSI | | |
| PC0 | ADC01_IN10 | ADC_LINE(3) | | |
| PC1 | ADC01_IN11 | ADC_LINE(4) | | |
| PC2 | ADC01_IN12 | ADC_LINE(5) | | |
| PC3 | ADC01_IN13 | ADC_LINE(6) | | |
| PC4 | ADC01_IN14 | ADC_LINE(7) | | |
| PC5 | ADC01_IN15 | ADC_LINE(8) | | |
| PC13 | | BTN1 | KEY2 | |
| - | ADC01_IN16 | ADC_LINE(9) | | internal Temperature channel |
| - | ADC01_IN17 | ADC_LINE(10) | | internal VFEF channel |
## Flashing the Device

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2020 Koen Zandberg <koen@bergzand.net>
* 2023 Gunar Schorcht <gunar@schorcht.net>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -14,6 +15,7 @@
* @brief Board specific definitions for the SeeedStudio GD32 RISC-V board
*
* @author Koen Zandberg <koen@bergzand.net>
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#ifndef PERIPH_CONF_H
@ -45,6 +47,29 @@
extern "C" {
#endif
/**
* @name ADC configuration
* @{
*/
static const adc_conf_t adc_config[] = {
{ .pin = GPIO_PIN(PORT_A, 1), .dev = 0, .chan = 1 },
{ .pin = GPIO_PIN(PORT_A, 2), .dev = 0, .chan = 2 },
{ .pin = GPIO_PIN(PORT_A, 3), .dev = 0, .chan = 3 },
{ .pin = GPIO_PIN(PORT_C, 0), .dev = 0, .chan = 10 },
{ .pin = GPIO_PIN(PORT_C, 1), .dev = 0, .chan = 11 },
{ .pin = GPIO_PIN(PORT_C, 2), .dev = 0, .chan = 12 },
{ .pin = GPIO_PIN(PORT_C, 3), .dev = 0, .chan = 13 },
{ .pin = GPIO_PIN(PORT_C, 4), .dev = 0, .chan = 14 },
{ .pin = GPIO_PIN(PORT_C, 5), .dev = 0, .chan = 15 },
/* ADC Temperature channel */
{ .pin = GPIO_UNDEF, .dev = 0, .chan = 16 },
/* ADC VREF channel */
{ .pin = GPIO_UNDEF, .dev = 0, .chan = 17 },
};
#define ADC_NUMOF ARRAY_SIZE(adc_config)
/** @} */
/**
* @name PWM configuration
* @{

View File

@ -14,6 +14,7 @@ config BOARD_SIPEED_LONGAN_NANO
select CPU_MODEL_GD32VF103CBT6
select BOARD_HAS_HXTAL
select BOARD_HAS_LXTAL
select HAS_PERIPH_ADC
select HAS_PERIPH_I2C
select HAS_PERIPH_PWM
select HAS_PERIPH_SPI
@ -21,4 +22,9 @@ config BOARD_SIPEED_LONGAN_NANO
select HAS_PERIPH_UART
select HAVE_SAUL_GPIO
config SIPEED_LONGAN_NANO_WITH_TFT
bool "Board with TFT display"
help
Indicates that a Sipeed Longan Nano board with TFT display is used.
source "$(RIOTBOARD)/common/gd32v/Kconfig"

View File

@ -1,6 +1,7 @@
CPU_MODEL = gd32vf103cbt6
# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_adc
FEATURES_PROVIDED += periph_i2c
FEATURES_PROVIDED += periph_pwm
FEATURES_PROVIDED += periph_spi

View File

@ -31,7 +31,7 @@ on-board components:
| Timers | 5 x 16-bit timer | yes |
| RTC | 1 x 32-bit counter, 20-bit prescaler | yes |
| WDT | 2 x 12-bit counter, 3-bit prescaler | yes |
| ADC | 2 x 12-bit units, 16 channels, 1 Msps | no |
| ADC | 2 x 12-bit units, 16 channels @ 1 Msps | yes |
| DAC | 2 x 12-bit channel | no |
| UART | - | yes |
| USART | 3 | yes |
@ -61,12 +61,19 @@ MCU pins and their configuration in RIOT.
| PA0 | BOOT0 | BTN0 | BOOT | |
| PA1 | | PWM_DEV(0) CH0 | LED1 green | |
| PA2 | | PWM_DEV(0) CH1 | LED2 blue | |
| PA4 | SPI1 CS | SPI_DEV(1) CS | | |
| PA5 | SPI1 SCLK | SPI_DEV(1) SCLK | | |
| PA6 | SPI1 MISO | SPI_DEV(1) MISO | | |
| PA7 | SPI1 MOSI | SPI_DEV(1) MOSI | | |
| PA3 | ADC01_IN3 | ADC_LINE(1) | | |
| PA4 | ADC01_IN4 | ADC_LINE(6) | | N/A if SPI is used |
| PA5 | ADC01_IN5 | ADC_LINE(7) | | N/A if SPI or TFT is used |
| PA6 | ADC01_IN6 | ADC_LINE(8) | | N/A if SPI is used |
| PA7 | ADC01_IN7 | ADC_LINE(9) | | N/A if SPI or TFT is used |
| PA4 | SPI1 CS | SPI_DEV(1) CS | | N/A if ADC_LINE(6) is used |
| PA5 | SPI1 SCLK | SPI_DEV(1) SCLK | | N/A if ADC_LINE(7) is used |
| PA6 | SPI1 MISO | SPI_DEV(1) MISO | | N/A if ADC_LINE(8) is used |
| PA7 | SPI1 MOSI | SPI_DEV(1) MOSI | | N/A if ADC_LINE(9) is used |
| PA9 | USART0 TX | UART_DEV(0) TX | UART TX | |
| PA10 | USART0 RX | UART_DEV(0) RX | UART RX | |
| PB0 | ADC01_IN8 | ADC_LINE(4) | | N/A if TFT is used |
| PB1 | ADC01_IN8 | ADC_LINE(5) | | N/A if TFT is used |
| PB6 | I2C0 SCL | I2C_DEV(0) SCL | | |
| PB7 | I2C0 SDA | I2C_DEV(0) SDA | | |
| PB8 | | PWM_DEV(1) CH0 | | N/A if CAN is used |
@ -78,6 +85,11 @@ MCU pins and their configuration in RIOT.
| PB14 | SPI0 MISO | SPI_DEV(0) MISO | | |
| PB15 | SPI0 MOSI | SPI_DEV(0) MOSI | | |
| PC13 | | | LED0 red | |
| - | ADC01_IN16 | ADC_LINE(2) | | internal Temperature channel |
| - | ADC01_IN17 | ADC_LINE(3) | | internal VFEF channel |
@note Since the availability of `ADC_LINE(4)` to `ADC_LINE(9)` depends on other
peripheral configurations, their index may vary.
## Flashing the Device

View File

@ -45,6 +45,38 @@
extern "C" {
#endif
/**
* @name ADC configuration
* @{
*/
static const adc_conf_t adc_config[] = {
{ .pin = GPIO_PIN(PORT_A, 0), .dev = 0, .chan = 0 },
{ .pin = GPIO_PIN(PORT_A, 3), .dev = 0, .chan = 3 },
/* ADC Temperature channel */
{ .pin = GPIO_UNDEF, .dev = 0, .chan = 16 },
/* ADC VREF channel */
{ .pin = GPIO_UNDEF, .dev = 0, .chan = 17 },
#if !defined(CONFIG_SIPEED_LONGAN_NANO_WITH_TFT)
/* This conflicts with TFT pins if connected. */
{ .pin = GPIO_PIN(PORT_B, 0), .dev = 0, .chan = 8 },
{ .pin = GPIO_PIN(PORT_B, 1), .dev = 0, .chan = 9 },
#endif
#if !defined(MODULE_PERIPH_SPI)
/* This conflicts with the SPI0 controller which is used for TFT if connected */
{ .pin = GPIO_PIN(PORT_A, 4), .dev = 0, .chan = 4 },
#if !defined(CONFIG_SIPEED_LONGAN_NANO_WITH_TFT)
{ .pin = GPIO_PIN(PORT_A, 5), .dev = 0, .chan = 5 },
#endif /* !defined(CONFIG_SIPEED_LONGAN_NANO_WITH_TFT) */
{ .pin = GPIO_PIN(PORT_A, 6), .dev = 0, .chan = 6 },
#if !defined(CONFIG_SIPEED_LONGAN_NANO_WITH_TFT)
{ .pin = GPIO_PIN(PORT_A, 7), .dev = 0, .chan = 7 },
#endif /* !defined(CONFIG_SIPEED_LONGAN_NANO_WITH_TFT) */
#endif
};
#define ADC_NUMOF ARRAY_SIZE(adc_config)
/** @} */
/**
* @name PWM configuration
* @{

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2020 Koen Zandberg <koen@bergzand.net>
* 2023 Gunar Schorcht <gunar@schorcht.net>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
@ -14,6 +15,7 @@
* @brief CPU specific definitions for internal peripheral handling
*
* @author Koen Zandberg <koen@bergzand.net>
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#ifndef PERIPH_CPU_H
@ -166,6 +168,35 @@ typedef enum {
GPIO_AF_OUT_OD = 0xf, /**< alternate function output - open-drain */
} gpio_af_t;
/**
* @brief Configure the alternate function for the given pin
*
* @param[in] pin pin to configure
* @param[in] af alternate function to use
*/
void gpio_init_af(gpio_t pin, gpio_af_t af);
/**
* @brief Configure the given pin to be used as ADC input
*
* @param[in] pin pin to configure
*/
void gpio_init_analog(gpio_t pin);
/**
* @brief Available number of ADC devices
*/
#define ADC_DEVS (2U)
/**
* @brief ADC channel configuration data
*/
typedef struct {
gpio_t pin; /**< pin connected to the channel */
uint8_t dev; /**< ADCx - 1 device used for the channel */
uint8_t chan; /**< CPU ADC channel connected to the pin */
} adc_conf_t;
/**
* @brief GD32V timers have 4 capture-compare channels
*/

View File

@ -11529,8 +11529,8 @@ typedef struct { /*!< (@ 0x40002C00) WWDGT Struct
* @{
*/
//#define ADC0_BASE 0x40012400UL
//#define ADC1_BASE 0x40012800UL
#define ADC0_BASE 0x40012400UL
#define ADC1_BASE 0x40012800UL
//#define AFIO_BASE 0x40010000UL
//#define BKP_BASE 0x40006C00UL
//#define CAN0_BASE 0x40006400UL

212
cpu/gd32v/periph/adc.c Normal file
View File

@ -0,0 +1,212 @@
/*
* Copyright (C) 2016 Engineering-Spirit
* 2023 Gunar Schorcht
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_gd32v
* @ingroup drivers_periph_adc
* @{
*
* @file
* @brief Low-level ADC driver implementation
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Nick van IJzendoorn <nijzendoorn@engineering-spirit.nl>
* @author Gunar Schorcht <gunar@schorcht.net>
*
* @}
*/
#include "cpu.h"
#include "macros/units.h"
#include "mutex.h"
#include "periph/adc.h"
#include "periph_conf.h"
/**
* @brief Maximum allowed ADC clock speed
*/
#define MAX_ADC_SPEED MHZ(14)
/**
* @brief Allocate locks for all three available ADC devices
*/
static mutex_t locks[] = {
#if ADC_DEVS > 1
MUTEX_INIT,
#endif
MUTEX_INIT
};
static inline ADC0_Type *dev(adc_t line)
{
switch (adc_config[line].dev) {
case 0:
return (ADC0_Type *)ADC0_BASE;
#if ADC_DEVS > 1
case 1:
return (ADC0_Type *)ADC1_BASE;
#endif
default:
assert(0);
return NULL;
}
}
static inline void prep(adc_t line, adc_res_t res)
{
mutex_lock(&locks[adc_config[line].dev]);
periph_clk_en(APB2, (RCU_APB2EN_ADC0EN_Msk << adc_config[line].dev));
/* enable the ADC module */
dev(line)->CTL1 |= ADC0_CTL1_ADCON_Msk;
/* configure the resolution */
dev(line)->OVSAMPCTL &= ~ADC0_OVSAMPCTL_DRES_Msk;
switch (res) {
case ADC_RES_12BIT:
dev(line)->OVSAMPCTL |= 0 << ADC0_OVSAMPCTL_DRES_Pos;
break;
case ADC_RES_10BIT:
dev(line)->OVSAMPCTL |= 1 << ADC0_OVSAMPCTL_DRES_Pos;
break;
case ADC_RES_8BIT:
dev(line)->OVSAMPCTL |= 2 << ADC0_OVSAMPCTL_DRES_Pos;
break;
case ADC_RES_6BIT:
dev(line)->OVSAMPCTL |= 3 << ADC0_OVSAMPCTL_DRES_Pos;
break;
default:
break;
}
/* check if this channel is an internal ADC channel, if so
* enable the internal temperature and Vref */
if (adc_config[line].chan == 16 || adc_config[line].chan == 17) {
dev(line)->CTL1 |= ADC0_CTL1_TSVREN_Msk;
}
}
static inline void done(adc_t line)
{
/* disable the internal temperature and Vref */
dev(line)->CTL1 &= ~ADC0_CTL1_TSVREN_Msk;
/* disable the ADC module */
dev(line)->CTL1 &= ~ADC0_CTL1_ADCON_Msk;
periph_clk_dis(APB2, (RCU_APB2EN_ADC0EN_Msk << adc_config[line].dev));
mutex_unlock(&locks[adc_config[line].dev]);
}
int adc_init(adc_t line)
{
uint32_t clk_div = 2;
/* check if the line is valid */
if (line >= ADC_NUMOF) {
return -1;
}
/* lock and power-on the device */
prep(line, ADC_RES_12BIT);
/* configure the pin */
if (adc_config[line].pin != GPIO_UNDEF) {
gpio_init_analog(adc_config[line].pin);
}
/* set clock prescaler to get the maximal possible ADC clock value */
for (clk_div = 2; clk_div < 8; clk_div += 2) {
if ((CLOCK_CORECLOCK / clk_div) <= MAX_ADC_SPEED) {
break;
}
}
RCU->CFG0 &= ~(RCU_CFG0_ADCPSC_2_Msk);
RCU->CFG0 |= ((clk_div / 2) - 1) << RCU_CFG0_ADCPSC_2_Pos;
/* resets the selected ADC calibration registers */
dev(line)->CTL1 |= ADC0_CTL1_RSTCLB_Msk;
/* check the status of RSTCAL bit */
while (dev(line)->CTL1 & ADC0_CTL1_RSTCLB_Msk) {}
/* enable the selected ADC calibration process */
dev(line)->CTL1 |= ADC0_CTL1_CLB_Msk;
/* wait for the calibration to have finished */
while (dev(line)->CTL1 & ADC0_CTL1_CLB_Msk) {}
/* set all channels to maximum (239.5) cycles for best accuracy */
dev(line)->SAMPT0 |= 0x00ffffff;
dev(line)->SAMPT1 |= 0x3fffffff;
/* we want to sample one channel */
dev(line)->RSQ0 = 1 << ADC0_RSQ0_RL_Pos;
/* start sampling from software */
dev(line)->CTL1 |= ADC0_CTL1_ETERC_Msk | ADC0_CTL1_ETSRC_Msk;
/* check if the internal channels are configured to use ADC0 */
if (adc_config[line].chan == 16 || adc_config[line].chan == 17) {
assert (dev(line) == ADC0);
}
/* free the device again */
done(line);
return 0;
}
int32_t adc_sample(adc_t line, adc_res_t res)
{
int sample;
/* check if the linenel is valid */
if (line >= ADC_NUMOF) {
return -1;
}
/* check valid resolution */
dev(line)->OVSAMPCTL &= ~ADC0_OVSAMPCTL_DRES_Msk;
switch (res) {
case ADC_RES_12BIT:
case ADC_RES_10BIT:
case ADC_RES_8BIT:
case ADC_RES_6BIT:
break;
default:
return -1;
}
/* lock and power on the ADC device */
prep(line, res);
/* set conversion channel */
dev(line)->RSQ2 = adc_config[line].chan;
/* start conversion and wait for results */
dev(line)->CTL1 |= ADC0_CTL1_SWRCST_Msk;
while (!(dev(line)->STAT & ADC0_STAT_EOC_Msk)) {}
/* finally read sample and reset the STRT bit in the status register */
sample = (int)dev(line)->RDATA;
/* the sample is 12 bit even if the resolution is less than 12 bit,
* scale down the 12 bit value to the requested resolution */
switch (res) {
case ADC_RES_10BIT:
sample = sample >> 2;
break;
case ADC_RES_8BIT:
sample = sample >> 4;
break;
case ADC_RES_6BIT:
sample = sample >> 6;
break;
default:
break;
}
/* power off and unlock device again */
done(line);
return sample;
}

View File

@ -1,3 +1,5 @@
warning: Member adc_config\[\] \(variable\) of
warning: Member ADC_NUMOF \(macro definition\) of
warning: Member AT86RF2XX_PARAM_CS \(macro definition\) of
warning: Member AT86RF2XX_PARAM_INT \(macro definition\) of
warning: Member AT86RF2XX_PARAM_RESET \(macro definition\) of

View File

@ -5,6 +5,7 @@ ZEP_PORT_MAX := $(shell expr $(ZEP_PORT_BASE) + $(ZEP_DEVICES) - 1)
CFLAGS += -DSOCKET_ZEP_MAX=$(ZEP_DEVICES)
CFLAGS += -DASYNC_READ_NUMOF=$(shell expr $(ZEP_DEVICES) + 1)
CFLAGS += -DCONFIG_DHCPV6_CLIENT_PFX_LEASE_MAX=$(ZEP_DEVICES)
# Set CFLAGS if not being set via Kconfig
CFLAGS += $(if $(CONFIG_KCONFIG_MODULE_DHCPV6),,-DCONFIG_DHCPV6_CLIENT_PFX_LEASE_MAX=$(ZEP_DEVICES))

View File

@ -158,8 +158,12 @@ void dhcpv6_client_start(void);
* @param[in] netif The interface to request the prefix delegation for.
* @param[in] pfx_len The desired length of the prefix (note that the server
* might not consider this request). Must be <= 128
*
* @retval 0 on success
* @retval -ENOMEM when there is no lease entry available anymore
* @retval -ENOTSUP when module `dhcpv6_client_ia_pd` is not being used
*/
void dhcpv6_client_req_ia_pd(unsigned netif, unsigned pfx_len);
int dhcpv6_client_req_ia_pd(unsigned netif, unsigned pfx_len);
/** @} */
/**

View File

@ -257,26 +257,30 @@ void dhcpv6_client_start(void)
}
}
void dhcpv6_client_req_ia_pd(unsigned netif, unsigned pfx_len)
int dhcpv6_client_req_ia_pd(unsigned netif, unsigned pfx_len)
{
pfx_lease_t *lease = NULL;
assert(IS_USED(MODULE_DHCPV6_CLIENT_IA_PD));
assert(pfx_len <= 128);
if (!IS_USED(MODULE_DHCPV6_CLIENT_IA_PD)) {
LOG_WARNING("DHCPv6 client: Unable to request IA_PD as module "
"`dhcpv6_client_ia_pd` is not used\n");
return;
return -ENOTSUP;
}
for (unsigned i = 0; i < CONFIG_DHCPV6_CLIENT_PFX_LEASE_MAX; i++) {
if (pfx_leases[i].parent.ia_id.id == 0) {
lease = &pfx_leases[i];
lease->parent.ia_id.info.netif = netif;
lease->parent.ia_id.info.type = DHCPV6_OPT_IA_PD;
lease->pfx_len = pfx_len;
break;
return 0;
}
}
return -ENOMEM;
}
int dhcpv6_client_req_ia_na(unsigned netif)
@ -423,15 +427,32 @@ static inline size_t _compose_oro_opt(dhcpv6_opt_oro_t *oro, uint16_t *opts,
}
static inline size_t _compose_ia_pd_opt(dhcpv6_opt_ia_pd_t *ia_pd,
uint32_t ia_id, uint16_t opts_len)
const pfx_lease_t *lease)
{
uint16_t len = 12U + opts_len;
uint16_t len = 12;
/* add IA Prefix Option if length was given*/
if (lease->pfx_len != 0) {
dhcpv6_opt_iapfx_t *iapfx = (dhcpv6_opt_iapfx_t *)ia_pd->opts;
uint16_t iapfx_len = 25;
/* set all unused/requested fields to 0 */
memset(iapfx, 0, sizeof(*iapfx));
iapfx->type = byteorder_htons(DHCPV6_OPT_IAPFX);
iapfx->len = byteorder_htons(iapfx_len);
iapfx->pfx_len = lease->pfx_len;
len += iapfx_len + sizeof(dhcpv6_opt_t);
}
/* write Identity Association for Prefix Delegation Option */
ia_pd->type = byteorder_htons(DHCPV6_OPT_IA_PD);
ia_pd->len = byteorder_htons(len);
ia_pd->ia_id = byteorder_htonl(ia_id);
ia_pd->ia_id = byteorder_htonl(lease->parent.ia_id.id);
ia_pd->t1.u32 = 0;
ia_pd->t2.u32 = 0;
return len + sizeof(dhcpv6_opt_t);
}
@ -486,12 +507,15 @@ static inline size_t _add_ia_pd_from_config(uint8_t *buf, size_t len_max)
size_t msg_len = 0;
for (unsigned i = 0; i < CONFIG_DHCPV6_CLIENT_PFX_LEASE_MAX; i++) {
uint32_t ia_id = pfx_leases[i].parent.ia_id.id;
if (ia_id != 0) {
dhcpv6_opt_ia_pd_t *ia_pd = (dhcpv6_opt_ia_pd_t *)(&buf[msg_len]);
pfx_lease_t *lease = &pfx_leases[i];
msg_len += _compose_ia_pd_opt(ia_pd, ia_id, 0U);
if (lease->parent.ia_id.id == 0) {
continue;
}
/* add Identity Association for Prefix Delegation Option */
dhcpv6_opt_ia_pd_t *ia_pd = (dhcpv6_opt_ia_pd_t *)(&buf[msg_len]);
msg_len += _compose_ia_pd_opt(ia_pd, lease);
}
if (msg_len > len_max) {

View File

@ -97,8 +97,10 @@ static int _gnrc_icmpv6_ping(int argc, char **argv)
};
int res;
ztimer_acquire(ZTIMER_USEC);
if ((res = _configure(argc, argv, &data)) != 0) {
return res;
goto ret;
}
gnrc_netreg_register(GNRC_NETTYPE_ICMPV6, &data.netreg);
_pinger(&data);
@ -142,6 +144,8 @@ finish:
msg_send(&msg, thread_getpid());
}
}
ret:
ztimer_release(ZTIMER_USEC);
return res;
}