1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
19397: drivers/usbdev_synopsys_dwc2: fix and reenable DMA mode r=benpicco a=gschorcht

### Contribution description

This PR fixes the DMA mode for all STM32 USB OTG HS cores (including that for STM32F4xx CID 1.xxx) and reenables it. It fixes remaining problems in issue #19359.

This PR includes also includes some changes that are needed to use the DMA mode:
- EP number is used as defined in CMSIS (if defined) for STM32
- `periph_usbdev_hs` feature is added in Kconfig
- `periph_usbdev_hs` feature is added in board definition of `stm32f429i-disc1`
- largest number of available EPs is used for STM32 instead of the smallest number (to be able to use all EPs of HS peripheral)
- `stm32f429i-disco` is removed from blacklist in `tests/usbus_cdc_ecm` since it uses the HS peripheral

### Testing procedure

The following tests should work
```python
USEMODULE=stdio_cdc_acm BOARD=stm32f429i-disc1 make -j8 -C tests/usbus_cdc_ecm flash
```
<details>
<summary>Test results</summary>

```python
[526755.875691] usb 1-2.2: new full-speed USB device number 106 using xhci_hcd
[526755.977853] usb 1-2.2: config 1 interface 3 altsetting 1 endpoint 0x84 has invalid maxpacket 512, setting to 64
[526755.977856] usb 1-2.2: config 1 interface 3 altsetting 1 endpoint 0x2 has invalid maxpacket 512, setting to 64
[526755.978762] usb 1-2.2: New USB device found, idVendor=1209, idProduct=7d01, bcdDevice= 1.00
[526755.978764] usb 1-2.2: New USB device strings: Mfr=3, Product=2, SerialNumber=4
[526755.978766] usb 1-2.2: Product: stm32f429i-disc1
[526755.978768] usb 1-2.2: Manufacturer: RIOT-os.org
[526755.978769] usb 1-2.2: SerialNumber: 7C156425A950A8EB
[526755.991190] cdc_acm 1-2.2:1.0: ttyACM1: USB ACM device
[526755.998131] cdc_ether 1-2.2:1.2 usb0: register 'cdc_ether' at usb-0000:00:14.0-2.2, CDC Ethernet Device, a6:f6:4a:85:1d:c9
[526756.044150] cdc_ether 1-2.2:1.2 enp0s20f0u2u2i2: renamed from usb0
```

</details>

```python
USEMODULE='stdio_cdc_acm periph_usbdev_hs_utmi' BOARD=stm32f723e-disco make -j8 -C tests/usbus_cdc_ecm flash
```
<details>
<summary>Test results</summary>

```python
[528733.480207] usb 1-4.3.4: reset high-speed USB device number 32 using xhci_hcd
[528733.707800] usb 1-4.4: new high-speed USB device number 111 using xhci_hcd
[528733.808257] usb 1-4.4: config 1 interface 0 altsetting 0 endpoint 0x81 has an invalid bInterval 255, changing to 11
[528733.808260] usb 1-4.4: config 1 interface 1 altsetting 0 bulk endpoint 0x1 has invalid maxpacket 64
[528733.808263] usb 1-4.4: config 1 interface 1 altsetting 0 bulk endpoint 0x82 has invalid maxpacket 64
[528733.808642] usb 1-4.4: New USB device found, idVendor=1209, idProduct=7d01, bcdDevice= 1.00
[528733.808645] usb 1-4.4: New USB device strings: Mfr=3, Product=2, SerialNumber=4
[528733.808647] usb 1-4.4: Product: stm32f723e-disco
[528733.808649] usb 1-4.4: Manufacturer: RIOT-os.org
[528733.808651] usb 1-4.4: SerialNumber: A6BAC4E1B1E0806B
[528733.811988] cdc_acm 1-4.4:1.0: ttyACM1: USB ACM device
[528733.814456] cdc_ether 1-4.4:1.2 usb0: register 'cdc_ether' at usb-0000:00:14.0-4.4, CDC Ethernet Device, e6:75:97:3a:74:ba
[528733.854371] cdc_ether 1-4.4:1.2 enp0s20f0u4u4i2: renamed from usb0
```

</details>

```python
USEMODULE='stdio_cdc_acm periph_usbdev_hs_ulpi' BOARD=stm32f746g-disco make -j8 -C tests/usbus_cdc_ecm flash
```
<details>
<summary>Test results</summary>

```python
[529000.944482] usb 1-4.3.4: reset high-speed USB device number 32 using xhci_hcd
[529003.728260] usb 1-4.4: new high-speed USB device number 114 using xhci_hcd
[529003.833107] usb 1-4.4: config 1 interface 0 altsetting 0 endpoint 0x81 has an invalid bInterval 255, changing to 11
[529003.833111] usb 1-4.4: config 1 interface 1 altsetting 0 bulk endpoint 0x1 has invalid maxpacket 64
[529003.833113] usb 1-4.4: config 1 interface 1 altsetting 0 bulk endpoint 0x82 has invalid maxpacket 64
[529003.833743] usb 1-4.4: New USB device found, idVendor=1209, idProduct=7d00, bcdDevice= 1.00
[529003.833747] usb 1-4.4: New USB device strings: Mfr=3, Product=2, SerialNumber=4
[529003.833749] usb 1-4.4: Product: stm32f746g-disco
[529003.833751] usb 1-4.4: Manufacturer: RIOT-os.org
[529003.833753] usb 1-4.4: SerialNumber: 66FE8934D1A363E0
[529003.837143] cdc_acm 1-4.4:1.0: ttyACM1: USB ACM device
[529003.839755] cdc_ether 1-4.4:1.2 usb0: register 'cdc_ether' at usb-0000:00:14.0-4.4, CDC Ethernet Device, 6a:88:1f:1f:b1:f0
[529003.879025] cdc_ether 1-4.4:1.2 enp0s20f0u4u4i2: renamed from usb0```
```
</details>

### Issues/PRs references

Fixes #19359


19416: cpu/rpx0xx/cmsis: Update vendor header files r=benpicco a=maribu

### Contribution description

Generated new vendor header files from upstream SVD files using:

    ./SVDConv "$PICO_SDK_DIR"/src/rp2040/hardware_regs/rp2040.svd \
        --generate=header --fields=macro --fields=enum

Note: The missing `--fields=struct` flag resulted in the header no longer containing bit-fields to represent different fields within registers. While this would generally ease writing code, the RP2040 has the unpleasant feature of corrupting the remaining bits of the register when a write access that is not word-sized occurs in the memory mapped I/O area. This could happen e.g. when a bit field is byte-sized and byte-aligned.
### Testing procedure

No binary changes (hopefully).

### Issues/PRs references

This adds a few additional vendor defines, notably for USB. If anyone were to implement USB, this would be a requirement.

19418: cpu/gd32v: fix gpio_read in periph_gpio r=benpicco a=gschorcht

### Contribution description

This PR fixes a bug in `gpio_read` which made `gpio_read` completely unusable!

A small bug with big consequences. In `gpio_read` the combined port | pin_num parameter `pin` was used instead of the pin number `pin_num` for the call of `_pin_is_input`. This caused the problem that for example instead of accessing GPIOA->CTL0 with address 0x40010800, address 0x60018c00 was accessed. As a result, a pin was randomly detected as input or output and thus a result was arbitrarily returned. Approx. 50% of all inputs always returned LOW.

I found this error by coincidence when I tried to find out why the BOOT0 button on a Sipeed Longan Nano is not usable as a button in RIOT.

### Testing procedure

Flash `tests/periph_gpio`
```
BOARD=sipeed-longan-nano make -j8 -C tests/periph_gpio flash
```
and use commands
```
init_in 0 8
read 0 8
```
Without this PR, the pin is always LOW. With the PR, the pin should be HIGH when the BOOT button is pressed.

### Issues/PRs references

19419: boards/sipeed-longan-nano: add BOOT as user button r=benpicco a=gschorcht

### Contribution description

This PR makes the BOOT button usable as a user button.

### Testing procedure

The test requires PR #19418 to work.

Flash and test:
```
BOARD=sipeed-longan-nano make -j8 -C tests/saul flash term
```
The output
```
Dev: BOOT	Type: SENSE_BTN
Data:	              0 
```
should change to
```
Dev: BOOT	Type: SENSE_BTN
Data:	              1 
```
when the BOOT button is pressed.

### Issues/PRs references

Depends on PR #19418 


Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
Co-authored-by: Marian Buschsieweke <marian.buschsieweke@ovgu.de>
This commit is contained in:
bors[bot] 2023-03-24 08:38:06 +00:00 committed by GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 3553 additions and 13261 deletions

View File

@ -34,9 +34,9 @@ extern "C" {
* @{ * @{
*/ */
#define LED0_PIN GPIO_PIN(0, 25) #define LED0_PIN GPIO_PIN(0, 25)
#define LED0_ON do {SIO->GPIO_OUT_SET.reg = 1UL << 25;} while (0) #define LED0_ON do {SIO->GPIO_OUT_SET = 1UL << 25;} while (0)
#define LED0_OFF do {SIO->GPIO_OUT_CLR.reg = 1UL << 25;} while (0) #define LED0_OFF do {SIO->GPIO_OUT_CLR = 1UL << 25;} while (0)
#define LED0_TOGGLE do {SIO->GPIO_OUT_XOR.reg = 1UL << 25;} while (0) #define LED0_TOGGLE do {SIO->GPIO_OUT_XOR = 1UL << 25;} while (0)
#define LED0_NAME "LED(Green)" #define LED0_NAME "LED(Green)"
/** @} */ /** @} */

View File

@ -67,9 +67,9 @@ by pins.
| ADC_LINE(5) | PB1 | ADC01_IN9 | TFT RST | N/A if TFT is used | | ADC_LINE(5) | PB1 | ADC01_IN9 | TFT RST | N/A if TFT is used |
| ADC_LINE(6) | PA6 | ADC01_IN6 | | N/A if TFT is used | | ADC_LINE(6) | PA6 | ADC01_IN6 | | N/A if TFT is used |
| ADC_LINE(7) | PA7 | ADC01_IN7 | | N/A if TFT is used | | ADC_LINE(7) | PA7 | ADC01_IN7 | | N/A if TFT is used |
| ADC_LINE(8) | PA8 | ADC01_IN4 | | N/A if TFT is used | | ADC_LINE(8) | PA4 | ADC01_IN4 | | N/A if TFT is used |
| ADC_LINE(9) | PA9 | ADC01_IN5 | | N/A if TFT is used | | ADC_LINE(9) | PA5 | ADC01_IN5 | | N/A if TFT is used |
| BTN0 | PA0 | BOOT0 | BOOT | | | BTN0 | PA8 | BOOT0 | BOOT | |
| DAC_LINE(0) | PA4 | DAC0 | | N/A if TFT is used | | DAC_LINE(0) | PA4 | DAC0 | | N/A if TFT is used |
| DAC_LINE(1) | PA5 | DAC1 | | N/A if TFT is used | | DAC_LINE(1) | PA5 | DAC1 | | N/A if TFT is used |
| GPIO_PIN(1, 2) | PB2 | | TFT CS | | | GPIO_PIN(1, 2) | PB2 | | TFT CS | |
@ -105,7 +105,7 @@ by pins.
| PA5 | TFT SCL | SPI_DEV(1) SCLK | ADC_LINE(9)* | DAC_LINE(1)* | | PA5 | TFT SCL | SPI_DEV(1) SCLK | ADC_LINE(9)* | DAC_LINE(1)* |
| PA6 | | SPI_DEV(1) MISO | ADC_LINE(6)* | | | PA6 | | SPI_DEV(1) MISO | ADC_LINE(6)* | |
| PA7 | TFT SDA | SPI_DEV(1) MOSI | ADC_LINE(7)* | | | PA7 | TFT SDA | SPI_DEV(1) MOSI | ADC_LINE(7)* | |
| PA8 | | | | | | PA8 | BOOT | | | BTN0 |
| PA9 | | UART_DEV(0) TX | | | | PA9 | | UART_DEV(0) TX | | |
| PA10 | | UART_DEV(0) RX | | | | PA10 | | UART_DEV(0) RX | | |
| PA11 | USB D- | | | | | PA11 | USB D- | | | |

View File

@ -26,6 +26,15 @@
extern "C" { extern "C" {
#endif #endif
/**
* @name Button pin definitions
* @{
*/
#define BTN0_PIN GPIO_PIN(PORT_A, 8)
#define BTN0_MODE GPIO_IN
#define BTN0_INT_FLANK GPIO_RISING
/** @} */
/** /**
* @name LED (on-board) configuration * @name LED (on-board) configuration
* @{ * @{

View File

@ -31,6 +31,11 @@ extern "C" {
*/ */
static const saul_gpio_params_t saul_gpio_params[] = static const saul_gpio_params_t saul_gpio_params[] =
{ {
{
.name = "BOOT",
.pin = BTN0_PIN,
.mode = BTN0_MODE,
},
{ {
.name = "LED RED", .name = "LED RED",
.pin = LED0_PIN, .pin = LED0_PIN,

View File

@ -20,6 +20,7 @@ config BOARD_STM32F429I_DISC1
select HAS_PERIPH_TIMER select HAS_PERIPH_TIMER
select HAS_PERIPH_UART select HAS_PERIPH_UART
select HAS_PERIPH_USBDEV select HAS_PERIPH_USBDEV
select HAS_PERIPH_USBDEV_HS
# Put other features for this board (in alphabetical order) # Put other features for this board (in alphabetical order)
select HAS_RIOTBOOT select HAS_RIOTBOOT
@ -38,4 +39,6 @@ config BOARD_STM32F429I_DISC1
select HAVE_I3G4250D select HAVE_I3G4250D
select HAVE_L3GD20 select HAVE_L3GD20
select MODULE_PERIPH_USBDEV_HS if MODULE_PERIPH_USBDEV
source "$(RIOTBOARD)/common/stm32/Kconfig" source "$(RIOTBOARD)/common/stm32/Kconfig"

View File

@ -1,3 +1,7 @@
ifneq (,$(filter periph_usbdev,$(USEMODULE)))
USEMODULE += periph_usbdev_hs
endif
ifneq (,$(filter saul_default,$(USEMODULE))) ifneq (,$(filter saul_default,$(USEMODULE)))
USEMODULE += saul_gpio USEMODULE += saul_gpio
USEMODULE += l3gxxxx USEMODULE += l3gxxxx

View File

@ -8,6 +8,7 @@ FEATURES_PROVIDED += periph_spi
FEATURES_PROVIDED += periph_timer FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart FEATURES_PROVIDED += periph_uart
FEATURES_PROVIDED += periph_usbdev FEATURES_PROVIDED += periph_usbdev
FEATURES_PROVIDED += periph_usbdev_hs
# Put other features for this board (in alphabetical order) # Put other features for this board (in alphabetical order)
FEATURES_PROVIDED += riotboot FEATURES_PROVIDED += riotboot

View File

@ -165,7 +165,7 @@ int gpio_read(gpio_t pin)
GPIO_Type *port = _port(pin); GPIO_Type *port = _port(pin);
unsigned pin_num = _pin_num(pin); unsigned pin_num = _pin_num(pin);
if (_pin_is_output(port, pin)) { if (_pin_is_output(port, pin_num)) {
/* pin is output */ /* pin is output */
return (port->OCTL & (1 << pin_num)); return (port->OCTL & (1 << pin_num));
} }

View File

@ -29,25 +29,25 @@
static void _clk_sys_set_source(CLOCKS_CLK_SYS_CTRL_SRC_Enum source) static void _clk_sys_set_source(CLOCKS_CLK_SYS_CTRL_SRC_Enum source)
{ {
io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL.reg, source << CLOCKS_CLK_SYS_CTRL_SRC_Pos, io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL, source << CLOCKS_CLK_SYS_CTRL_SRC_Pos,
CLOCKS_CLK_SYS_CTRL_SRC_Msk); CLOCKS_CLK_SYS_CTRL_SRC_Msk);
} }
static void _clk_sys_set_aux_source(CLOCKS_CLK_SYS_CTRL_AUXSRC_Enum source) static void _clk_sys_set_aux_source(CLOCKS_CLK_SYS_CTRL_AUXSRC_Enum source)
{ {
io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL.reg, source << CLOCKS_CLK_SYS_CTRL_AUXSRC_Pos, io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL, source << CLOCKS_CLK_SYS_CTRL_AUXSRC_Pos,
CLOCKS_CLK_SYS_CTRL_AUXSRC_Msk); CLOCKS_CLK_SYS_CTRL_AUXSRC_Msk);
} }
static void _clk_ref_set_source(CLOCKS_CLK_REF_CTRL_SRC_Enum source) static void _clk_ref_set_source(CLOCKS_CLK_REF_CTRL_SRC_Enum source)
{ {
io_reg_write_dont_corrupt(&CLOCKS->CLK_REF_CTRL.reg, source << CLOCKS_CLK_REF_CTRL_SRC_Pos, io_reg_write_dont_corrupt(&CLOCKS->CLK_REF_CTRL, source << CLOCKS_CLK_REF_CTRL_SRC_Pos,
CLOCKS_CLK_REF_CTRL_SRC_Msk); CLOCKS_CLK_REF_CTRL_SRC_Msk);
} }
static void _clk_ref_set_aux_source(CLOCKS_CLK_REF_CTRL_AUXSRC_Enum source) static void _clk_ref_set_aux_source(CLOCKS_CLK_REF_CTRL_AUXSRC_Enum source)
{ {
io_reg_write_dont_corrupt(&CLOCKS->CLK_REF_CTRL.reg, source << CLOCKS_CLK_REF_CTRL_AUXSRC_Pos, io_reg_write_dont_corrupt(&CLOCKS->CLK_REF_CTRL, source << CLOCKS_CLK_REF_CTRL_AUXSRC_Pos,
CLOCKS_CLK_REF_CTRL_AUXSRC_Msk); CLOCKS_CLK_REF_CTRL_AUXSRC_Msk);
} }
@ -66,7 +66,7 @@ void clock_sys_configure_source(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_SYS_CT
/* switch the glitchless mux to clk_ref */ /* switch the glitchless mux to clk_ref */
_clk_sys_set_source(source); _clk_sys_set_source(source);
/* apply divider */ /* apply divider */
CLOCKS->CLK_SYS_DIV.reg = div; CLOCKS->CLK_SYS_DIV = div;
/* poll SELECTED until the switch is completed */ /* poll SELECTED until the switch is completed */
while (!(CLOCKS->CLK_SYS_SELECTED & (1U << source))) { } while (!(CLOCKS->CLK_SYS_SELECTED & (1U << source))) { }
} }
@ -83,7 +83,7 @@ void clock_sys_configure_aux_source(uint32_t f_in, uint32_t f_out,
/* change the auxiliary mux */ /* change the auxiliary mux */
_clk_sys_set_aux_source(aux); _clk_sys_set_aux_source(aux);
/* apply divider */ /* apply divider */
CLOCKS->CLK_SYS_DIV.reg = div; CLOCKS->CLK_SYS_DIV = div;
/* switch the glitchless mux to clk_sys_aux */ /* switch the glitchless mux to clk_sys_aux */
_clk_sys_set_source(CLOCKS_CLK_SYS_CTRL_SRC_clksrc_clk_sys_aux); _clk_sys_set_source(CLOCKS_CLK_SYS_CTRL_SRC_clksrc_clk_sys_aux);
/* poll SELECTED until the switch is completed */ /* poll SELECTED until the switch is completed */
@ -98,7 +98,7 @@ void clock_ref_configure_source(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_REF_CT
/* switch the glitchless mux to clock source */ /* switch the glitchless mux to clock source */
_clk_ref_set_source(source); _clk_ref_set_source(source);
/* apply divider */ /* apply divider */
CLOCKS->CLK_REF_DIV.reg = div & CLOCKS_CLK_REF_DIV_INT_Msk; CLOCKS->CLK_REF_DIV = div & CLOCKS_CLK_REF_DIV_INT_Msk;
/* poll SELECTED until the switch is completed */ /* poll SELECTED until the switch is completed */
while (!(CLOCKS->CLK_REF_SELECTED & (1U << source))) { } while (!(CLOCKS->CLK_REF_SELECTED & (1U << source))) { }
} }
@ -115,7 +115,7 @@ void clock_ref_configure_aux_source(uint32_t f_in, uint32_t f_out,
/* change the auxiliary mux */ /* change the auxiliary mux */
_clk_ref_set_aux_source(aux); _clk_ref_set_aux_source(aux);
/* apply divider */ /* apply divider */
CLOCKS->CLK_REF_DIV.reg = div & CLOCKS_CLK_REF_DIV_INT_Msk; CLOCKS->CLK_REF_DIV = div & CLOCKS_CLK_REF_DIV_INT_Msk;
/* switch the glitchless mux to clk_ref_aux */ /* switch the glitchless mux to clk_ref_aux */
_clk_ref_set_source(CLOCKS_CLK_REF_CTRL_SRC_clksrc_clk_ref_aux); _clk_ref_set_source(CLOCKS_CLK_REF_CTRL_SRC_clksrc_clk_ref_aux);
/* poll SELECTED until the switch is completed */ /* poll SELECTED until the switch is completed */
@ -124,21 +124,21 @@ void clock_ref_configure_aux_source(uint32_t f_in, uint32_t f_out,
void clock_periph_configure(CLOCKS_CLK_PERI_CTRL_AUXSRC_Enum aux) void clock_periph_configure(CLOCKS_CLK_PERI_CTRL_AUXSRC_Enum aux)
{ {
io_reg_atomic_clear(&CLOCKS->CLK_PERI_CTRL.reg, (1u << CLOCKS_CLK_PERI_CTRL_ENABLE_Pos)); io_reg_atomic_clear(&CLOCKS->CLK_PERI_CTRL, (1u << CLOCKS_CLK_PERI_CTRL_ENABLE_Pos));
io_reg_write_dont_corrupt(&CLOCKS->CLK_PERI_CTRL.reg, aux << CLOCKS_CLK_PERI_CTRL_AUXSRC_Pos, io_reg_write_dont_corrupt(&CLOCKS->CLK_PERI_CTRL, aux << CLOCKS_CLK_PERI_CTRL_AUXSRC_Pos,
CLOCKS_CLK_PERI_CTRL_AUXSRC_Msk); CLOCKS_CLK_PERI_CTRL_AUXSRC_Msk);
io_reg_atomic_set(&CLOCKS->CLK_PERI_CTRL.reg, (1u << CLOCKS_CLK_PERI_CTRL_ENABLE_Pos)); io_reg_atomic_set(&CLOCKS->CLK_PERI_CTRL, (1u << CLOCKS_CLK_PERI_CTRL_ENABLE_Pos));
} }
void clock_gpout0_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_Enum aux) void clock_gpout0_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_Enum aux)
{ {
assert(f_out <= f_in); assert(f_out <= f_in);
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out; uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
io_reg_atomic_clear(&CLOCKS->CLK_GPOUT0_CTRL.reg, 1U << CLOCKS_CLK_GPOUT0_CTRL_ENABLE_Pos); io_reg_atomic_clear(&CLOCKS->CLK_GPOUT0_CTRL, 1U << CLOCKS_CLK_GPOUT0_CTRL_ENABLE_Pos);
_gpout_set_aux_source(&CLOCKS->CLK_GPOUT0_CTRL.reg, aux); _gpout_set_aux_source(&CLOCKS->CLK_GPOUT0_CTRL, aux);
CLOCKS->CLK_GPOUT0_DIV.reg = div; CLOCKS->CLK_GPOUT0_DIV = div;
io_reg_atomic_set(&CLOCKS->CLK_GPOUT0_CTRL.reg, 1U << CLOCKS_CLK_GPOUT0_CTRL_ENABLE_Pos); io_reg_atomic_set(&CLOCKS->CLK_GPOUT0_CTRL, 1U << CLOCKS_CLK_GPOUT0_CTRL_ENABLE_Pos);
io_reg_atomic_set(&PADS_BANK0->GPIO21.reg, 1U << PADS_BANK0_GPIO21_IE_Pos); io_reg_atomic_set(&PADS_BANK0->GPIO21, 1U << PADS_BANK0_GPIO21_IE_Pos);
gpio_set_function_select(21, FUNCTION_SELECT_CLOCK); gpio_set_function_select(21, FUNCTION_SELECT_CLOCK);
} }
@ -146,11 +146,11 @@ void clock_gpout1_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT1_CTR
{ {
assert(f_out <= f_in); assert(f_out <= f_in);
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out; uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
io_reg_atomic_clear(&CLOCKS->CLK_GPOUT1_CTRL.reg, 1U << CLOCKS_CLK_GPOUT1_CTRL_ENABLE_Pos); io_reg_atomic_clear(&CLOCKS->CLK_GPOUT1_CTRL, 1U << CLOCKS_CLK_GPOUT1_CTRL_ENABLE_Pos);
_gpout_set_aux_source(&CLOCKS->CLK_GPOUT1_CTRL.reg, aux); _gpout_set_aux_source(&CLOCKS->CLK_GPOUT1_CTRL, aux);
CLOCKS->CLK_GPOUT1_DIV.reg = div; CLOCKS->CLK_GPOUT1_DIV = div;
io_reg_atomic_set(&CLOCKS->CLK_GPOUT1_CTRL.reg, 1U << CLOCKS_CLK_GPOUT1_CTRL_ENABLE_Pos); io_reg_atomic_set(&CLOCKS->CLK_GPOUT1_CTRL, 1U << CLOCKS_CLK_GPOUT1_CTRL_ENABLE_Pos);
io_reg_atomic_set(&PADS_BANK0->GPIO23.reg, 1U << PADS_BANK0_GPIO23_IE_Pos); io_reg_atomic_set(&PADS_BANK0->GPIO23, 1U << PADS_BANK0_GPIO23_IE_Pos);
gpio_set_function_select(23, FUNCTION_SELECT_CLOCK); gpio_set_function_select(23, FUNCTION_SELECT_CLOCK);
} }
@ -158,11 +158,11 @@ void clock_gpout2_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT2_CTR
{ {
assert(f_out <= f_in); assert(f_out <= f_in);
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out; uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
io_reg_atomic_clear(&CLOCKS->CLK_GPOUT2_CTRL.reg, 1U << CLOCKS_CLK_GPOUT2_CTRL_ENABLE_Pos); io_reg_atomic_clear(&CLOCKS->CLK_GPOUT2_CTRL, 1U << CLOCKS_CLK_GPOUT2_CTRL_ENABLE_Pos);
_gpout_set_aux_source(&CLOCKS->CLK_GPOUT2_CTRL.reg, aux); _gpout_set_aux_source(&CLOCKS->CLK_GPOUT2_CTRL, aux);
CLOCKS->CLK_GPOUT2_DIV.reg = div; CLOCKS->CLK_GPOUT2_DIV = div;
io_reg_atomic_set(&CLOCKS->CLK_GPOUT2_CTRL.reg, 1U << CLOCKS_CLK_GPOUT2_CTRL_ENABLE_Pos); io_reg_atomic_set(&CLOCKS->CLK_GPOUT2_CTRL, 1U << CLOCKS_CLK_GPOUT2_CTRL_ENABLE_Pos);
io_reg_atomic_set(&PADS_BANK0->GPIO24.reg, 1U << PADS_BANK0_GPIO24_IE_Pos); io_reg_atomic_set(&PADS_BANK0->GPIO24, 1U << PADS_BANK0_GPIO24_IE_Pos);
gpio_set_function_select(24, FUNCTION_SELECT_CLOCK); gpio_set_function_select(24, FUNCTION_SELECT_CLOCK);
} }
@ -170,10 +170,10 @@ void clock_gpout3_configure(uint32_t f_in, uint32_t f_out, CLOCKS_CLK_GPOUT3_CTR
{ {
assert(f_out <= f_in); assert(f_out <= f_in);
uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out; uint32_t div = (((uint64_t)f_in) << CLOCKS_CLK_REF_DIV_INT_Pos) / f_out;
io_reg_atomic_clear(&CLOCKS->CLK_GPOUT3_CTRL.reg, 1U << CLOCKS_CLK_GPOUT3_CTRL_ENABLE_Pos); io_reg_atomic_clear(&CLOCKS->CLK_GPOUT3_CTRL, 1U << CLOCKS_CLK_GPOUT3_CTRL_ENABLE_Pos);
_gpout_set_aux_source(&CLOCKS->CLK_GPOUT3_CTRL.reg, aux); _gpout_set_aux_source(&CLOCKS->CLK_GPOUT3_CTRL, aux);
CLOCKS->CLK_GPOUT3_DIV.reg = div; CLOCKS->CLK_GPOUT3_DIV = div;
io_reg_atomic_set(&CLOCKS->CLK_GPOUT3_CTRL.reg, 1U << CLOCKS_CLK_GPOUT3_CTRL_ENABLE_Pos); io_reg_atomic_set(&CLOCKS->CLK_GPOUT3_CTRL, 1U << CLOCKS_CLK_GPOUT3_CTRL_ENABLE_Pos);
io_reg_atomic_set(&PADS_BANK0->GPIO25.reg, 1U << PADS_BANK0_GPIO25_IE_Pos); io_reg_atomic_set(&PADS_BANK0->GPIO25, 1U << PADS_BANK0_GPIO25_IE_Pos);
gpio_set_function_select(25, FUNCTION_SELECT_CLOCK); gpio_set_function_select(25, FUNCTION_SELECT_CLOCK);
} }

View File

@ -121,7 +121,7 @@ static inline void io_reg_atomic_clear(volatile uint32_t *reg, uint32_t mask)
* *
* Example use: * Example use:
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
* io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL.reg, source << CLOCKS_CLK_SYS_CTRL_SRC_Pos, * io_reg_write_dont_corrupt(&CLOCKS->CLK_SYS_CTRL, source << CLOCKS_CLK_SYS_CTRL_SRC_Pos,
* CLOCKS_CLK_SYS_CTRL_SRC_Msk); * CLOCKS_CLK_SYS_CTRL_SRC_Msk);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/ */

View File

@ -487,7 +487,7 @@ static inline void gpio_reset_all_config(uint8_t pin)
*/ */
static inline void periph_reset(uint32_t components) static inline void periph_reset(uint32_t components)
{ {
io_reg_atomic_set(&RESETS->RESET.reg, components); io_reg_atomic_set(&RESETS->RESET, components);
} }
/** /**
@ -498,8 +498,8 @@ static inline void periph_reset(uint32_t components)
*/ */
static inline void periph_reset_done(uint32_t components) static inline void periph_reset_done(uint32_t components)
{ {
io_reg_atomic_clear(&RESETS->RESET.reg, components); io_reg_atomic_clear(&RESETS->RESET, components);
while ((~RESETS->RESET_DONE.reg) & components) { } while ((~RESETS->RESET_DONE) & components) { }
} }
/** /**

File diff suppressed because it is too large Load Diff

View File

@ -42,8 +42,8 @@ static void *_args[GPIO_PIN_NUMOF];
int gpio_init(gpio_t pin, gpio_mode_t mode) int gpio_init(gpio_t pin, gpio_mode_t mode)
{ {
assert(pin < GPIO_PIN_NUMOF); assert(pin < GPIO_PIN_NUMOF);
SIO->GPIO_OE_CLR.reg = 1LU << pin; SIO->GPIO_OE_CLR = 1LU << pin;
SIO->GPIO_OUT_CLR.reg = 1LU << pin; SIO->GPIO_OUT_CLR = 1LU << pin;
switch (mode) { switch (mode) {
case GPIO_IN: case GPIO_IN:
@ -98,7 +98,7 @@ int gpio_init(gpio_t pin, gpio_mode_t mode)
gpio_set_pad_config(pin, pad_config); gpio_set_pad_config(pin, pad_config);
gpio_set_io_config(pin, io_config); gpio_set_io_config(pin, io_config);
} }
SIO->GPIO_OE_SET.reg = 1LU << pin; SIO->GPIO_OE_SET = 1LU << pin;
break; break;
default: default:
return -ENOTSUP; return -ENOTSUP;
@ -108,27 +108,27 @@ int gpio_init(gpio_t pin, gpio_mode_t mode)
int gpio_read(gpio_t pin) int gpio_read(gpio_t pin)
{ {
if (SIO->GPIO_OE.reg & (1LU << pin)) { if (SIO->GPIO_OE & (1LU << pin)) {
/* pin is output: */ /* pin is output: */
return SIO->GPIO_OUT.reg & (1LU << pin); return SIO->GPIO_OUT & (1LU << pin);
} }
/* pin is input: */ /* pin is input: */
return SIO->GPIO_IN.reg & (1LU << pin); return SIO->GPIO_IN & (1LU << pin);
} }
void gpio_set(gpio_t pin) void gpio_set(gpio_t pin)
{ {
SIO->GPIO_OUT_SET.reg = 1LU << pin; SIO->GPIO_OUT_SET = 1LU << pin;
} }
void gpio_clear(gpio_t pin) void gpio_clear(gpio_t pin)
{ {
SIO->GPIO_OUT_CLR.reg = 1LU << pin; SIO->GPIO_OUT_CLR = 1LU << pin;
} }
void gpio_toggle(gpio_t pin) void gpio_toggle(gpio_t pin)
{ {
SIO->GPIO_OUT_XOR.reg = 1LU << pin; SIO->GPIO_OUT_XOR = 1LU << pin;
} }
void gpio_write(gpio_t pin, int value) void gpio_write(gpio_t pin, int value)
@ -144,8 +144,8 @@ void gpio_write(gpio_t pin, int value)
#ifdef MODULE_PERIPH_GPIO_IRQ #ifdef MODULE_PERIPH_GPIO_IRQ
static void _irq_enable(gpio_t pin, unsigned flank) static void _irq_enable(gpio_t pin, unsigned flank)
{ {
volatile uint32_t *irq_enable_regs = &IO_BANK0->PROC0_INTE0.reg; volatile uint32_t *irq_enable_regs = &IO_BANK0->PROC0_INTE0;
volatile uint32_t *irq_ack_regs = &IO_BANK0->INTR0.reg; volatile uint32_t *irq_ack_regs = &IO_BANK0->INTR0;
/* There are 4 bits to control IRQs per pin, hence the configuration is split across multiple /* There are 4 bits to control IRQs per pin, hence the configuration is split across multiple
* I/O registers. The following calculates the position the four bits matching the given pin, * I/O registers. The following calculates the position the four bits matching the given pin,
* where idx refers to the I/O register and shift_amount to the position in the I/O register. * where idx refers to the I/O register and shift_amount to the position in the I/O register.
@ -201,15 +201,15 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, gpio_cb_t cb
void isr_io_bank0(void) void isr_io_bank0(void)
{ {
unsigned offset = 0; unsigned offset = 0;
volatile uint32_t *irq_status_regs = &IO_BANK0->PROC0_INTS0.reg; volatile uint32_t *irq_status_regs = &IO_BANK0->PROC0_INTS0;
volatile uint32_t *irq_ack_regs = &IO_BANK0->INTR0.reg; volatile uint32_t *irq_ack_regs = &IO_BANK0->INTR0;
DEBUG("[rp0x00] GPIO IRQ mask: %08x, %08x, %08x, %08x\n", DEBUG("[rp0x00] GPIO IRQ mask: %08x, %08x, %08x, %08x\n",
(unsigned)IO_BANK0->PROC0_INTE0.reg, (unsigned)IO_BANK0->PROC0_INTE1.reg, (unsigned)IO_BANK0->PROC0_INTE0, (unsigned)IO_BANK0->PROC0_INTE1,
(unsigned)IO_BANK0->PROC0_INTE2.reg, (unsigned)IO_BANK0->PROC0_INTE3.reg); (unsigned)IO_BANK0->PROC0_INTE2, (unsigned)IO_BANK0->PROC0_INTE3);
DEBUG("[rp0x00] GPIO IRQ status: %08x, %08x, %08x, %08x\n", DEBUG("[rp0x00] GPIO IRQ status: %08x, %08x, %08x, %08x\n",
(unsigned)IO_BANK0->PROC0_INTS0.reg, (unsigned)IO_BANK0->PROC0_INTS1.reg, (unsigned)IO_BANK0->PROC0_INTS0, (unsigned)IO_BANK0->PROC0_INTS1,
(unsigned)IO_BANK0->PROC0_INTS2.reg, (unsigned)IO_BANK0->PROC0_INTS3.reg); (unsigned)IO_BANK0->PROC0_INTS2, (unsigned)IO_BANK0->PROC0_INTS3);
/* There are four IRQ status bits per pin, so there is info for 8 pins per I/O register. /* There are four IRQ status bits per pin, so there is info for 8 pins per I/O register.
* We will iterate over all IRQ status I/O registers in the outer loop, and over all 8 pins * We will iterate over all IRQ status I/O registers in the outer loop, and over all 8 pins

View File

@ -88,14 +88,14 @@ static inline void _irq_enable(tim_t dev)
{ {
for (uint8_t i = 0; i < timer_config[dev].ch_numof; i++) { for (uint8_t i = 0; i < timer_config[dev].ch_numof; i++) {
NVIC_EnableIRQ(timer_config[dev].ch[i].irqn); NVIC_EnableIRQ(timer_config[dev].ch[i].irqn);
io_reg_atomic_set(&DEV(dev)->INTE.reg, (1U << i)); io_reg_atomic_set(&DEV(dev)->INTE, (1U << i));
} }
} }
static void _isr(tim_t dev, int channel) static void _isr(tim_t dev, int channel)
{ {
/* clear latched interrupt */ /* clear latched interrupt */
io_reg_atomic_clear(&DEV(dev)->INTR.reg, 1U << channel); io_reg_atomic_clear(&DEV(dev)->INTR, 1U << channel);
if (_timer_is_periodic(dev, channel)) { if (_timer_is_periodic(dev, channel)) {
if (_timer_reset_on_match(dev, channel)) { if (_timer_reset_on_match(dev, channel)) {
@ -118,7 +118,8 @@ int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg)
} }
/* The timer must run at 1000000 Hz (µs precision) /* The timer must run at 1000000 Hz (µs precision)
because the number of cycles per µs is shared with the watchdog. because the number of cycles per µs is shared with the watchdog.
The reference clock (clk_ref) is divided by WATCHDOG->TICK.bits.CYCLES The reference clock (clk_ref) is divided by
(WATCHDOG->TICK & WATCHDOC_TICK_CYCLES_Mask)
to generate µs ticks. to generate µs ticks.
*/ */
assert(freq == US_PER_SEC); (void)freq; assert(freq == US_PER_SEC); (void)freq;
@ -126,7 +127,7 @@ int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg)
_timer_ctx_arg[dev] = arg; _timer_ctx_arg[dev] = arg;
periph_reset(RESETS_RESET_timer_Msk); periph_reset(RESETS_RESET_timer_Msk);
periph_reset_done(RESETS_RESET_timer_Msk); periph_reset_done(RESETS_RESET_timer_Msk);
io_reg_write_dont_corrupt(&WATCHDOG->TICK.reg, io_reg_write_dont_corrupt(&WATCHDOG->TICK,
(CLOCK_XOSC / MHZ(1)) << WATCHDOG_TICK_CYCLES_Pos, (CLOCK_XOSC / MHZ(1)) << WATCHDOG_TICK_CYCLES_Pos,
WATCHDOG_TICK_CYCLES_Msk); WATCHDOG_TICK_CYCLES_Msk);
_irq_enable(dev); _irq_enable(dev);
@ -205,7 +206,7 @@ int timer_clear(tim_t dev, int channel)
return -EINVAL; return -EINVAL;
} }
/* ARMED bits are write clear */ /* ARMED bits are write clear */
io_reg_atomic_set(&DEV(dev)->ARMED.reg, (1 << channel)); io_reg_atomic_set(&DEV(dev)->ARMED, (1 << channel));
unsigned state = irq_disable(); unsigned state = irq_disable();
_timer_disable_periodic(dev, channel); _timer_disable_periodic(dev, channel);
irq_restore(state); irq_restore(state);
@ -223,13 +224,13 @@ unsigned int timer_read(tim_t dev)
void timer_start(tim_t dev) void timer_start(tim_t dev)
{ {
assert(dev < TIMER_NUMOF); assert(dev < TIMER_NUMOF);
io_reg_atomic_clear(&DEV(dev)->PAUSE.reg, (1 << TIMER_PAUSE_PAUSE_Pos)); io_reg_atomic_clear(&DEV(dev)->PAUSE, (1 << TIMER_PAUSE_PAUSE_Pos));
} }
void timer_stop(tim_t dev) void timer_stop(tim_t dev)
{ {
assert(dev < TIMER_NUMOF); assert(dev < TIMER_NUMOF);
io_reg_atomic_set(&DEV(dev)->PAUSE.reg, (1 << TIMER_PAUSE_PAUSE_Pos)); io_reg_atomic_set(&DEV(dev)->PAUSE, (1 << TIMER_PAUSE_PAUSE_Pos));
} }
/* timer 0 IRQ0 */ /* timer 0 IRQ0 */

View File

@ -48,7 +48,7 @@ static uint32_t uartcr;
void _irq_enable(uart_t uart) void _irq_enable(uart_t uart)
{ {
UART0_Type *dev = uart_config[uart].dev; UART0_Type *dev = uart_config[uart].dev;
dev->UARTIMSC.reg = UART0_UARTIMSC_RXIM_Msk; dev->UARTIMSC = UART0_UARTIMSC_RXIM_Msk;
NVIC_EnableIRQ(uart_config[uart].irqn); NVIC_EnableIRQ(uart_config[uart].irqn);
} }
@ -72,8 +72,8 @@ void _set_symbolrate(uart_t uart, uint32_t baud)
baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2; baud_fbrd = ((baud_rate_div & 0x7f) + 1) / 2;
} }
dev->UARTIBRD.reg = baud_ibrd; dev->UARTIBRD = baud_ibrd;
dev->UARTFBRD.reg = baud_fbrd; dev->UARTFBRD = baud_fbrd;
} }
int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t uart_parity, int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t uart_parity,
@ -82,7 +82,7 @@ int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t uart_parity
assert((unsigned)uart < UART_NUMOF); assert((unsigned)uart < UART_NUMOF);
UART0_Type *dev = uart_config[uart].dev; UART0_Type *dev = uart_config[uart].dev;
io_reg_atomic_clear(&dev->UARTCR.reg, io_reg_atomic_clear(&dev->UARTCR,
UART0_UARTCR_UARTEN_Msk | UART0_UARTCR_TXE_Msk | UART0_UARTCR_RXE_Msk); UART0_UARTCR_UARTEN_Msk | UART0_UARTCR_TXE_Msk | UART0_UARTCR_RXE_Msk);
/* Beware of strange hardware bug: If the configuration bitmask is prepared in register and /* Beware of strange hardware bug: If the configuration bitmask is prepared in register and
@ -91,26 +91,26 @@ int uart_mode(uart_t uart, uart_data_bits_t data_bits, uart_parity_t uart_parity
* next char send out. If the configuration is updated in multiple bus accesses, it will apply * next char send out. If the configuration is updated in multiple bus accesses, it will apply
* directly to the next char. So: Double check e.g. with tests/periph_uart_mode after touching * directly to the next char. So: Double check e.g. with tests/periph_uart_mode after touching
* the initialization code here */ * the initialization code here */
dev->UARTLCR_H.reg = (uint32_t)data_bits << UART0_UARTLCR_H_WLEN_Pos; dev->UARTLCR_H = (uint32_t)data_bits << UART0_UARTLCR_H_WLEN_Pos;
if (stop_bits == UART_STOP_BITS_2) { if (stop_bits == UART_STOP_BITS_2) {
io_reg_atomic_set(&dev->UARTLCR_H.reg, UART0_UARTLCR_H_STP2_Msk); io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_STP2_Msk);
} }
switch (uart_parity) { switch (uart_parity) {
case UART_PARITY_NONE: case UART_PARITY_NONE:
break; break;
case UART_PARITY_EVEN: case UART_PARITY_EVEN:
io_reg_atomic_set(&dev->UARTLCR_H.reg, UART0_UARTLCR_H_EPS_Msk | UART0_UARTLCR_H_PEN_Msk); io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_EPS_Msk | UART0_UARTLCR_H_PEN_Msk);
break; break;
case UART_PARITY_ODD: case UART_PARITY_ODD:
io_reg_atomic_set(&dev->UARTLCR_H.reg, UART0_UARTLCR_H_PEN_Msk); io_reg_atomic_set(&dev->UARTLCR_H, UART0_UARTLCR_H_PEN_Msk);
break; break;
default: default:
return UART_NOMODE; return UART_NOMODE;
} }
io_reg_atomic_set(&dev->UARTCR.reg, io_reg_atomic_set(&dev->UARTCR,
UART0_UARTCR_UARTEN_Msk | UART0_UARTCR_TXE_Msk | UART0_UARTCR_RXE_Msk); UART0_UARTCR_UARTEN_Msk | UART0_UARTCR_TXE_Msk | UART0_UARTCR_RXE_Msk);
return UART_OK; return UART_OK;
@ -148,7 +148,7 @@ void uart_deinit_pins(uart_t uart)
{ {
assert((unsigned)uart < UART_NUMOF); assert((unsigned)uart < UART_NUMOF);
gpio_reset_all_config(uart_config[uart].tx_pin); gpio_reset_all_config(uart_config[uart].tx_pin);
SIO->GPIO_OE_CLR.reg = 1LU << uart_config[uart].tx_pin; SIO->GPIO_OE_CLR = 1LU << uart_config[uart].tx_pin;
if (ctx[uart].rx_cb) { if (ctx[uart].rx_cb) {
gpio_reset_all_config(uart_config[uart].rx_pin); gpio_reset_all_config(uart_config[uart].rx_pin);
} }
@ -167,10 +167,10 @@ void uart_poweron(uart_t uart)
_poweron(uart); _poweron(uart);
UART0_Type *dev = uart_config[uart].dev; UART0_Type *dev = uart_config[uart].dev;
/* restore configuration registers */ /* restore configuration registers */
dev->UARTIBRD.reg = uartibrd; dev->UARTIBRD = uartibrd;
dev->UARTFBRD.reg = uartfbrd; dev->UARTFBRD = uartfbrd;
dev->UARTLCR_H.reg = uartlcr_h; dev->UARTLCR_H = uartlcr_h;
dev->UARTCR.reg = uartcr; dev->UARTCR = uartcr;
/* restore IRQs, if needed */ /* restore IRQs, if needed */
if (ctx[uart].rx_cb != NULL) { if (ctx[uart].rx_cb != NULL) {
_irq_enable(uart); _irq_enable(uart);
@ -183,10 +183,10 @@ void uart_poweroff(uart_t uart)
assert((unsigned)uart < UART_NUMOF); assert((unsigned)uart < UART_NUMOF);
UART0_Type *dev = uart_config[uart].dev; UART0_Type *dev = uart_config[uart].dev;
/* backup configuration registers */ /* backup configuration registers */
uartibrd = dev->UARTIBRD.reg; uartibrd = dev->UARTIBRD;
uartfbrd = dev->UARTFBRD.reg; uartfbrd = dev->UARTFBRD;
uartlcr_h = dev->UARTLCR_H.reg; uartlcr_h = dev->UARTLCR_H;
uartcr = dev->UARTCR.reg; uartcr = dev->UARTCR;
/* disconnect GPIOs and power off peripheral */ /* disconnect GPIOs and power off peripheral */
uart_deinit_pins(uart); uart_deinit_pins(uart);
periph_reset((uart) ? RESETS_RESET_uart1_Msk : RESETS_RESET_uart0_Msk); periph_reset((uart) ? RESETS_RESET_uart1_Msk : RESETS_RESET_uart0_Msk);
@ -217,10 +217,10 @@ int uart_init(uart_t uart, uint32_t baud, uart_rx_cb_t rx_cb, void *arg)
if (rx_cb != NULL) { if (rx_cb != NULL) {
_irq_enable(uart); _irq_enable(uart);
/* clear any pending data and IRQ to avoid receiving a garbage char */ /* clear any pending data and IRQ to avoid receiving a garbage char */
uint32_t status = dev->UARTRIS.reg; uint32_t status = dev->UARTRIS;
dev->UARTICR.reg = status; dev->UARTICR = status;
(void)dev->UARTDR.reg; (void)dev->UARTDR;
io_reg_atomic_set(&dev->UARTCR.reg, UART0_UARTCR_RXE_Msk); io_reg_atomic_set(&dev->UARTCR, UART0_UARTCR_RXE_Msk);
} }
return UART_OK; return UART_OK;
@ -232,8 +232,8 @@ void uart_write(uart_t uart, const uint8_t *data, size_t len)
UART0_Type *dev = uart_config[uart].dev; UART0_Type *dev = uart_config[uart].dev;
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
dev->UARTDR.reg = data[i]; dev->UARTDR = data[i];
while (!(dev->UARTRIS.reg & UART0_UARTRIS_TXRIS_Msk)) { } while (!(dev->UARTRIS & UART0_UARTRIS_TXRIS_Msk)) { }
} }
} }
@ -253,11 +253,11 @@ void isr_handler(uint8_t num)
{ {
UART0_Type *dev = uart_config[num].dev; UART0_Type *dev = uart_config[num].dev;
uint32_t status = dev->UARTMIS.reg; uint32_t status = dev->UARTMIS;
dev->UARTICR.reg = status; dev->UARTICR = status;
if (status & UART0_UARTMIS_RXMIS_Msk) { if (status & UART0_UARTMIS_RXMIS_Msk) {
uint32_t data = dev->UARTDR.reg; uint32_t data = dev->UARTDR;
if (data & (UART0_UARTDR_BE_Msk | UART0_UARTDR_PE_Msk | UART0_UARTDR_FE_Msk)) { if (data & (UART0_UARTDR_BE_Msk | UART0_UARTDR_PE_Msk | UART0_UARTDR_FE_Msk)) {
DEBUG_PUTS("[rpx0xx] uart RX error (parity, break, or framing error"); DEBUG_PUTS("[rpx0xx] uart RX error (parity, break, or framing error");
} }

View File

@ -44,22 +44,22 @@ static void _pll_start(PLL_SYS_Type *pll, uint8_t ref_div,
assert(post_div_2 <= PLL_POSTDIV_MAX); assert(post_div_2 <= PLL_POSTDIV_MAX);
/* program reference clock divider */ /* program reference clock divider */
io_reg_write_dont_corrupt(&pll->CS.reg, ref_div << PLL_SYS_CS_REFDIV_Pos, io_reg_write_dont_corrupt(&pll->CS, ref_div << PLL_SYS_CS_REFDIV_Pos,
PLL_SYS_CS_REFDIV_Msk); PLL_SYS_CS_REFDIV_Msk);
/* program feedback divider */ /* program feedback divider */
io_reg_write_dont_corrupt(&pll->FBDIV_INT.reg, io_reg_write_dont_corrupt(&pll->FBDIV_INT,
vco_feedback_scale << PLL_SYS_FBDIV_INT_FBDIV_INT_Pos, vco_feedback_scale << PLL_SYS_FBDIV_INT_FBDIV_INT_Pos,
PLL_SYS_FBDIV_INT_FBDIV_INT_Msk); PLL_SYS_FBDIV_INT_FBDIV_INT_Msk);
/* turn on the main power */ /* turn on the main power */
io_reg_atomic_clear(&pll->PWR.reg, (1U << PLL_SYS_PWR_VCOPD_Pos) io_reg_atomic_clear(&pll->PWR, (1U << PLL_SYS_PWR_VCOPD_Pos)
| (1U << PLL_SYS_PWR_DSMPD_Pos) | (1U << PLL_SYS_PWR_DSMPD_Pos)
| (1U << PLL_SYS_PWR_PD_Pos)); | (1U << PLL_SYS_PWR_PD_Pos));
/* wait for VCO to lock (i.e. keep its output stable) */ /* wait for VCO to lock (i.e. keep its output stable) */
while (!pll->CS.bit.LOCK) { } while (!(pll->CS & PLL_SYS_CS_LOCK_Msk)) { }
/* set up post divisors and turn them on */ /* set up post divisors and turn them on */
pll->PRIM.reg = (post_div_1 << PLL_SYS_PRIM_POSTDIV1_Pos) pll->PRIM = (post_div_1 << PLL_SYS_PRIM_POSTDIV1_Pos)
| (post_div_2 << PLL_SYS_PRIM_POSTDIV2_Pos); | (post_div_2 << PLL_SYS_PRIM_POSTDIV2_Pos);
io_reg_atomic_clear(&pll->PWR.reg, 1U << PLL_SYS_PWR_POSTDIVPD_Pos); io_reg_atomic_clear(&pll->PWR, 1U << PLL_SYS_PWR_POSTDIVPD_Pos);
} }
/** /**
@ -72,7 +72,7 @@ static void _pll_stop(PLL_SYS_Type *pll)
| (1U << PLL_SYS_PWR_POSTDIVPD_Pos) | (1U << PLL_SYS_PWR_POSTDIVPD_Pos)
| (1U << PLL_SYS_PWR_DSMPD_Pos) | (1U << PLL_SYS_PWR_DSMPD_Pos)
| (1U << PLL_SYS_PWR_PD_Pos); | (1U << PLL_SYS_PWR_PD_Pos);
io_reg_atomic_set(&pll->PWR.reg, reg); io_reg_atomic_set(&pll->PWR, reg);
} }
void pll_start_sys(uint8_t ref_div, void pll_start_sys(uint8_t ref_div,

View File

@ -31,19 +31,19 @@
void rosc_start(void) void rosc_start(void)
{ {
/* set drive strengths to default 0 */ /* set drive strengths to default 0 */
io_reg_atomic_clear(&ROSC->FREQA.reg, ROSC_FREQA_PASSWD_Msk); io_reg_atomic_clear(&ROSC->FREQA, ROSC_FREQA_PASSWD_Msk);
io_reg_atomic_clear(&ROSC->FREQB.reg, ROSC_FREQB_PASSWD_Msk); io_reg_atomic_clear(&ROSC->FREQB, ROSC_FREQB_PASSWD_Msk);
/* apply settings with magic value 0x9696 */ /* apply settings with magic value 0x9696 */
const uint32_t magic = 0x9696U; const uint32_t magic = 0x9696U;
io_reg_write_dont_corrupt(&ROSC->FREQA.reg, magic << ROSC_FREQA_PASSWD_Pos, io_reg_write_dont_corrupt(&ROSC->FREQA, magic << ROSC_FREQA_PASSWD_Pos,
ROSC_FREQA_PASSWD_Msk); ROSC_FREQA_PASSWD_Msk);
io_reg_write_dont_corrupt(&ROSC->FREQB.reg, magic << ROSC_FREQB_PASSWD_Pos, io_reg_write_dont_corrupt(&ROSC->FREQB, magic << ROSC_FREQB_PASSWD_Pos,
ROSC_FREQB_PASSWD_Msk); ROSC_FREQB_PASSWD_Msk);
/* default divider is 16 */ /* default divider is 16 */
io_reg_write_dont_corrupt(&ROSC->DIV.reg, 16 << ROSC_DIV_DIV_Pos, ROSC_DIV_DIV_Msk); io_reg_write_dont_corrupt(&ROSC->DIV, 16 << ROSC_DIV_DIV_Pos, ROSC_DIV_DIV_Msk);
io_reg_atomic_set(&ROSC->CTRL.reg, ROSC_CTRL_ENABLE_ENABLE << ROSC_CTRL_ENABLE_Pos); io_reg_atomic_set(&ROSC->CTRL, ROSC_CTRL_ENABLE_ENABLE << ROSC_CTRL_ENABLE_Pos);
while (!ROSC->STATUS.bit.STABLE) { } while (!(ROSC->STATUS & ROSC_STATUS_STABLE_Msk)) { }
} }
/** /**
@ -53,5 +53,5 @@ void rosc_start(void)
*/ */
void rosc_stop(void) void rosc_stop(void)
{ {
io_reg_atomic_set(&ROSC->CTRL.reg, ROSC_CTRL_ENABLE_DISABLE << ROSC_CTRL_ENABLE_Pos); io_reg_atomic_set(&ROSC->CTRL, ROSC_CTRL_ENABLE_DISABLE << ROSC_CTRL_ENABLE_Pos);
} }

View File

@ -34,15 +34,15 @@ void xosc_start(uint32_t f_ref)
{ {
assert(f_ref == MHZ(12)); assert(f_ref == MHZ(12));
uint32_t delay = _xosc_conf_sartup_delay(f_ref, 1); uint32_t delay = _xosc_conf_sartup_delay(f_ref, 1);
io_reg_write_dont_corrupt(&XOSC->STARTUP.reg, delay << XOSC_STARTUP_DELAY_Pos, io_reg_write_dont_corrupt(&XOSC->STARTUP, delay << XOSC_STARTUP_DELAY_Pos,
XOSC_STARTUP_DELAY_Msk); XOSC_STARTUP_DELAY_Msk);
io_reg_write_dont_corrupt(&XOSC->CTRL.reg, XOSC_CTRL_ENABLE_ENABLE << XOSC_CTRL_ENABLE_Pos, io_reg_write_dont_corrupt(&XOSC->CTRL, XOSC_CTRL_ENABLE_ENABLE << XOSC_CTRL_ENABLE_Pos,
XOSC_CTRL_ENABLE_Msk); XOSC_CTRL_ENABLE_Msk);
while (!XOSC->STATUS.bit.STABLE) { } while (!(XOSC->STATUS & XOSC_STATUS_STABLE_Msk)) { }
} }
void xosc_stop(void) void xosc_stop(void)
{ {
io_reg_write_dont_corrupt(&XOSC->CTRL.reg, XOSC_CTRL_ENABLE_DISABLE << XOSC_CTRL_ENABLE_Pos, io_reg_write_dont_corrupt(&XOSC->CTRL, XOSC_CTRL_ENABLE_DISABLE << XOSC_CTRL_ENABLE_Pos,
XOSC_CTRL_ENABLE_Msk); XOSC_CTRL_ENABLE_Msk);
} }

View File

@ -131,33 +131,40 @@ typedef struct {
* @brief Number of endpoints available with the OTG FS peripheral * @brief Number of endpoints available with the OTG FS peripheral
* including the control endpoint * including the control endpoint
*/ */
#ifdef STM32_USB_OTG_CID_1x #if defined(USB_OTG_FS_MAX_IN_ENDPOINTS)
#define STM32_USB_OTG_FS_NUM_EP (4) /**< OTG FS with 4 endpoints */ #define STM32_USB_OTG_FS_NUM_EP (USB_OTG_FS_MAX_IN_ENDPOINTS)
#elif defined(STM32_USB_OTG_CID_1x)
#define STM32_USB_OTG_FS_NUM_EP (4) /**< OTG FS with 4 endpoints */
#elif defined(STM32_USB_OTG_CID_2x) #elif defined(STM32_USB_OTG_CID_2x)
#define STM32_USB_OTG_FS_NUM_EP (6) /**< OTG FS with 6 endpoints */ #define STM32_USB_OTG_FS_NUM_EP (6) /**< OTG FS with 6 endpoints */
#endif #endif
/** /**
* @brief Number of endpoints available with the OTG HS peripheral * @brief Number of endpoints available with the OTG HS peripheral
* including the control endpoint * including the control endpoint
*/ */
#ifdef STM32_USB_OTG_CID_1x #if defined(USB_OTG_HS_MAX_IN_ENDPOINTS)
#define STM32_USB_OTG_HS_NUM_EP (6) /**< OTG HS with 6 endpoints */ #define STM32_USB_OTG_HS_NUM_EP (USB_OTG_HS_MAX_IN_ENDPOINTS)
#elif defined(STM32_USB_OTG_CID_1x)
#define STM32_USB_OTG_HS_NUM_EP (6) /**< OTG HS with 6 endpoints */
#elif defined(STM32_USB_OTG_CID_2x) #elif defined(STM32_USB_OTG_CID_2x)
#define STM32_USB_OTG_HS_NUM_EP (9) /**< OTG HS with 9 endpoints */ #define STM32_USB_OTG_HS_NUM_EP (9) /**< OTG HS with 9 endpoints */
#endif #endif
/** /**
* @brief Number of IN/OUT endpoints including EP0 as used by USBUS * @brief Number of IN/OUT endpoints including EP0 as used by USBUS
* *
* @note Since only a single number of EPs can be defined for USBUS that is * @note USBUS allows only one definition of the number of available EPs, which
* valid for all devices, the smallest number of EPs must be used for * is then used for all devices. To be able to use all EPs for devices
* multiple USB devices. * with more EPs, the largest possible number of available EPs for
* several USB devices is defined here. The driver has to ensure that the
* number of allocated EPs does not exceed the number of available EPs if
* a device has less EPs.
*/ */
#if defined(STM32_USB_OTG_FS_NUM_EP) #if defined(MODULE_PERIPH_USBDEV_HS) && defined(STM32_USB_OTG_HS_NUM_EP)
#define USBDEV_NUM_ENDPOINTS STM32_USB_OTG_FS_NUM_EP
#elif defined(STM32_USB_OTG_HS_NUM_EP)
#define USBDEV_NUM_ENDPOINTS STM32_USB_OTG_HS_NUM_EP #define USBDEV_NUM_ENDPOINTS STM32_USB_OTG_HS_NUM_EP
#elif defined(STM32_USB_OTG_FS_NUM_EP)
#define USBDEV_NUM_ENDPOINTS STM32_USB_OTG_FS_NUM_EP
#else #else
#define USBDEV_NUM_ENDPOINTS 8 #define USBDEV_NUM_ENDPOINTS 8
#endif #endif

View File

@ -111,19 +111,6 @@ extern "C" {
*/ */
#define DWC2_USB_OTG_HS_TOTAL_FIFO_SIZE USB_OTG_HS_TOTAL_FIFO_SIZE #define DWC2_USB_OTG_HS_TOTAL_FIFO_SIZE USB_OTG_HS_TOTAL_FIFO_SIZE
/**
* @brief Use the built-in DMA controller of the HS peripheral when possible
*/
#ifndef STM32_USB_OTG_HS_USE_DMA
#ifdef STM32_USB_OTG_CID_1x
/* FIXME: It should be possible to use DMA with the 1.x version of the *
* peripheral, but somehow it doesn't work. */
#define STM32_USB_OTG_HS_USE_DMA (0)
#else
#define STM32_USB_OTG_HS_USE_DMA (1)
#endif
#endif
/* periph/usbdev.h is included after the definitions above by intention */ /* periph/usbdev.h is included after the definitions above by intention */
#include "periph/usbdev.h" #include "periph/usbdev.h"

View File

@ -22,6 +22,16 @@ config MODULE_PERIPH_INIT_USBDEV
bool "Auto initialize USBDEV peripheral" bool "Auto initialize USBDEV peripheral"
default y if MODULE_PERIPH_INIT default y if MODULE_PERIPH_INIT
config MODULE_PERIPH_USBDEV_HS
bool "Use USB HS peripheral"
depends on HAS_PERIPH_USBDEV_HS
default y if MODULE_PERIPH_INIT_USBDEV_HS_ULPI || MODULE_PERIPH_USBDEV_HS_UTMI
config MODULE_PERIPH_INIT_USBDEV_HS
bool
depends on MODULE_PERIPH_USBDEV_HS
default y if MODULE_PERIPH_INIT
config MODULE_PERIPH_USBDEV_HS_ULPI config MODULE_PERIPH_USBDEV_HS_ULPI
bool "Use USB HS peripheral with ULPI HS PHY" bool "Use USB HS peripheral with ULPI HS PHY"
depends on HAS_PERIPH_USBDEV_HS_ULPI depends on HAS_PERIPH_USBDEV_HS_ULPI

View File

@ -130,6 +130,9 @@ typedef struct {
usbdev_ep_t *in; /**< In endpoints */ usbdev_ep_t *in; /**< In endpoints */
dwc2_usb_otg_fshs_out_ep_t *out; /**< Out endpoints */ dwc2_usb_otg_fshs_out_ep_t *out; /**< Out endpoints */
bool suspend; /**< Suspend status */ bool suspend; /**< Suspend status */
#ifdef DWC2_USB_OTG_HS_ENABLED
uint8_t *ep0_out_buf; /**< Points to the buffer of EP0 OUT handler */
#endif
} dwc2_usb_otg_fshs_t; } dwc2_usb_otg_fshs_t;
/* List of instantiated USB peripherals */ /* List of instantiated USB peripherals */
@ -219,7 +222,7 @@ static bool _uses_dma(const dwc2_usb_otg_fshs_config_t *config)
* request. In this case the enumeration of further interfaces, for example * request. In this case the enumeration of further interfaces, for example
* CDC ECM is stopped. * CDC ECM is stopped.
* - The Enumeration fails for CDC ECM interface which uses URB support. */ * - The Enumeration fails for CDC ECM interface which uses URB support. */
#if 0 /* defined(DWC2_USB_OTG_HS_ENABLED) && STM32_USB_OTG_HS_USE_DMA */ #ifdef DWC2_USB_OTG_HS_ENABLED
return config->type == DWC2_USB_OTG_HS; return config->type == DWC2_USB_OTG_HS;
#else #else
(void)config; (void)config;
@ -982,7 +985,7 @@ static void _usbdev_init(usbdev_t *dev)
/* Unmask the transfer complete interrupts /* Unmask the transfer complete interrupts
* Only needed when using DMA, otherwise the RX FIFO not empty * Only needed when using DMA, otherwise the RX FIFO not empty
* interrupt is used */ * interrupt is used */
_device_regs(conf)->DOEPMSK |= USB_OTG_DOEPMSK_XFRCM; _device_regs(conf)->DOEPMSK |= USB_OTG_DOEPMSK_XFRCM | USB_OTG_DOEPMSK_STUPM;
_device_regs(conf)->DIEPMSK |= USB_OTG_DIEPMSK_XFRCM; _device_regs(conf)->DIEPMSK |= USB_OTG_DIEPMSK_XFRCM;
} }
@ -1172,6 +1175,22 @@ static void _usbdev_ep0_stall(usbdev_t *usbdev)
/* Stall both directions, cleared automatically on SETUP received */ /* Stall both directions, cleared automatically on SETUP received */
_in_regs(conf, 0)->DIEPCTL |= USB_OTG_DIEPCTL_STALL; _in_regs(conf, 0)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
_out_regs(conf, 0)->DOEPCTL |= USB_OTG_DOEPCTL_STALL; _out_regs(conf, 0)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
#ifdef DWC2_USB_OTG_HS_ENABLED
if (_uses_dma(conf) && st_usbdev->ep0_out_buf) {
/* The STALL condition is automatically cleared by the hardware as
* specified in the API documentation. However, in DMA mode the
* reception of the next SETUP must be prepared by setting the SETUP
* packet counter (STUPCNT) and enabling the OUT endpoint. Otherwise
* the USB OTG HS core will not generate an interrupt and the USB stack
* cannot respond correctly to the next SETUP received. In addition,
* the DMA address must be reset to the buffer address of the EP0
* OUT handler. */
_out_regs(conf, 0)->DOEPDMA = (uint32_t)(intptr_t)(st_usbdev->ep0_out_buf);
_out_regs(conf, 0)->DOEPTSIZ |= 1 << USB_OTG_DOEPTSIZ_STUPCNT_Pos;
_out_regs(conf, 0)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA;
}
#endif
} }
static void _ep_set_stall(usbdev_ep_t *ep, bool enable) static void _ep_set_stall(usbdev_ep_t *ep, bool enable)
@ -1313,6 +1332,13 @@ static int _usbdev_ep_xmit(usbdev_ep_t *ep, uint8_t *buf, size_t len)
if (_uses_dma(conf)) { if (_uses_dma(conf)) {
_out_regs(conf, ep->num)->DOEPDMA = (uint32_t)(intptr_t)buf; _out_regs(conf, ep->num)->DOEPDMA = (uint32_t)(intptr_t)buf;
/* store the buffer address of the EP0 OUT handler to use it in
* _usbdev_ep0_stall */
#ifdef DWC2_USB_OTG_HS_ENABLED
if (ep->num == 0) {
usbdev->ep0_out_buf = buf;
}
#endif
} }
else { else {
container_of(ep, dwc2_usb_otg_fshs_out_ep_t, ep)->out_buf = buf; container_of(ep, dwc2_usb_otg_fshs_out_ep_t, ep)->out_buf = buf;
@ -1361,11 +1387,6 @@ static void _read_packet(dwc2_usb_otg_fshs_out_ep_t *st_ep)
* complete status */ * complete status */
if (pkt_status == DWC2_PKTSTS_DATA_UPDT || if (pkt_status == DWC2_PKTSTS_DATA_UPDT ||
pkt_status == DWC2_PKTSTS_SETUP_UPDT) { pkt_status == DWC2_PKTSTS_SETUP_UPDT) {
#if defined(MCU_EFM32)
/* TODO For some reason a short delay is required here on EFM32. It has
* to be investigated further. A delay of 1 msec is inserted for now. */
ztimer_sleep(ZTIMER_MSEC, 1);
#endif
_copy_rxfifo(usbdev, st_ep->out_buf, len); _copy_rxfifo(usbdev, st_ep->out_buf, len);
#if !defined(STM32_USB_OTG_CID_1x) #if !defined(STM32_USB_OTG_CID_1x)
/* CID 2x doesn't signal SETUP_COMP on non-zero length packets, signal /* CID 2x doesn't signal SETUP_COMP on non-zero length packets, signal
@ -1416,6 +1437,15 @@ static void _usbdev_ep_esr(usbdev_ep_t *ep)
!_uses_dma(conf)) { !_uses_dma(conf)) {
_read_packet(container_of(ep, dwc2_usb_otg_fshs_out_ep_t, ep)); _read_packet(container_of(ep, dwc2_usb_otg_fshs_out_ep_t, ep));
} }
#ifdef DWC2_USB_OTG_HS_ENABLED
else if (_out_regs(conf, ep->num)->DOEPINT & USB_OTG_DOEPINT_STUP) {
_out_regs(conf, ep->num)->DOEPINT = USB_OTG_DOEPINT_STUP;
_out_regs(conf, ep->num)->DOEPINT = USB_OTG_DOEPINT_XFRC;
if (_uses_dma(conf)) {
usbdev->usbdev.epcb(ep, USBDEV_EVENT_TR_COMPLETE);
}
}
#endif
/* Transfer complete seems only reliable when used with DMA */ /* Transfer complete seems only reliable when used with DMA */
else if (_out_regs(conf, ep->num)->DOEPINT & USB_OTG_DOEPINT_XFRC) { else if (_out_regs(conf, ep->num)->DOEPINT & USB_OTG_DOEPINT_XFRC) {
_out_regs(conf, ep->num)->DOEPINT = USB_OTG_DOEPINT_XFRC; _out_regs(conf, ep->num)->DOEPINT = USB_OTG_DOEPINT_XFRC;

View File

@ -12,7 +12,6 @@ USEMODULE += ps
# Boards that don't have enough endpoints to use CDC ACM together with CDC ECM # Boards that don't have enough endpoints to use CDC ACM together with CDC ECM
ifeq (,$(filter stdio_%,$(filter-out stdio_cdc_acm,$(USEMODULE)))) ifeq (,$(filter stdio_%,$(filter-out stdio_cdc_acm,$(USEMODULE))))
BOARD_BLACKLIST += \ BOARD_BLACKLIST += \
stm32f429i-disco \
stm32f4discovery \ stm32f4discovery \
weact-f401cc \ weact-f401cc \
weact-f401ce \ weact-f401ce \