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:
commit
a9dbf8bc36
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
* @{
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
* @{
|
||||
|
@ -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
|
||||
*/
|
||||
|
4
cpu/gd32v/include/vendor/gd32vf103_periph.h
vendored
4
cpu/gd32v/include/vendor/gd32vf103_periph.h
vendored
@ -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
212
cpu/gd32v/periph/adc.c
Normal 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;
|
||||
}
|
2
dist/tools/doccheck/generic_exclude_patterns
vendored
2
dist/tools/doccheck/generic_exclude_patterns
vendored
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user