Added PWM support for rp2040

This commit is contained in:
curuvar 2022-06-22 20:23:07 -04:00 committed by Alan Carvalho de Assis
parent 77557d8d9f
commit 75facdee72
11 changed files with 1219 additions and 0 deletions

4
.gitignore vendored
View file

@ -30,6 +30,7 @@
.depend
/.config
/.config.old
/.config\ *
/.cproject
/.gdbinit
/.project
@ -50,5 +51,8 @@ uImage
/external
# $(TOPDIR)/Makefile.[unix|win]::$(CONTEXTDIRS_DEPS)
.context
.context\ *
# $(TOPDIR)/Makefile.[unix|win]::$(DIRLINKS_EXTERNAL_DIRS)
.dirlinks
.vscode
.DS_Store

View file

@ -235,6 +235,7 @@ config ARCH_CHIP_RP2040
select ARCH_HAVE_I2CRESET
select ARM_HAVE_WFE_SEV
select LIBC_ARCH_ATOMIC
select ARCH_HAVE_PWM_MULTICHAN
---help---
Raspberry Pi RP2040 architectures (ARM dual Cortex-M0+).

View file

@ -141,6 +141,82 @@ config RP2040_I2C_DRIVER
endif
config RP2040_PWM
bool "PWM"
select PWM
---help---
After enabling PWM support here, configure the GPIO pins to use
under the Board Selection menu.
if RP2040_PWM
config PWM_MULTICHAN
bool "Support Multi-Channel PWM"
default y
---help---
If support for multi-channel PWM is disabled, the generated code
will only support the A channel of the PWM slices.
if PWM_MULTICHAN
config PWM_NCHANNELS
int "Number of channels"
default 2
---help---
If the number of channels is set to 1, the generated code will
only support the A channel of the PWM slices. This is functionally
identical to disabling multi-channel PWM support.
endif
config RP2040_PWM0
bool "PWM0"
---help---
Drives GPIO pin 0 or 16 with the A channel, and
drives GPIO pin 1 or 17 with the B channel.
config RP2040_PWM1
bool "PWM1"
---help---
Drives GPIO pin 2 or 18 with the A channel, and
drives GPIO pin 3 or 19 with the B channel.
config RP2040_PWM2
bool "PWM2"
---help---
Drives GPIO pin 4 or 20 with the A channel, and
drives GPIO pin 5 or 21 with the B channel.
config RP2040_PWM3
bool "PWM3"
---help---
Drives GPIO pin 6 or 22 with the A channel, and
drives GPIO pin 7 or 23 with the B channel.
config RP2040_PWM4
bool "PWM4"
---help---
Drives GPIO pin 8 or 24 with the A channel, and
drives GPIO pin 9 or 25 with the B channel.
config RP2040_PWM5
bool "PWM5"
---help---
Drives GPIO pin 10 or 26 with the A channel, and
drives GPIO pin 11 or 27 with the B channel.
config RP2040_PWM6
bool "PWM6"
---help---
Drives GPIO pin 12 or 28 with the A channel, and
drives GPIO pin 13 or 29 with the B channel.
config RP2040_PWM7
bool "PWM7 (Pin 14 and 15)"
---help---
Drives GPIO pin 14 with the A channel, and
drives GPIO pin 15 with the B channel.
endif
config RP2040_I2S
bool "I2S"
select I2S

View file

@ -49,6 +49,10 @@ ifeq ($(CONFIG_RP2040_SPI),y)
CHIP_CSRCS += rp2040_spi.c
endif
ifeq ($(CONFIG_RP2040_PWM),y)
CHIP_CSRCS += rp2040_pwm.c
endif
ifeq ($(CONFIG_RP2040_I2C),y)
CHIP_CSRCS += rp2040_i2c.c
endif

View file

@ -24,6 +24,10 @@ ifeq ($(CONFIG_RP2040_I2C_DRIVER),y)
CSRCS += rp2040_i2cdev.c
endif
ifeq ($(CONFIG_RP2040_PWM),y)
CSRCS += rp2040_pwmdev.c
endif
ifeq ($(CONFIG_RP2040_SPI_DRIVER),y)
CSRCS += rp2040_spidev.c
endif

View file

@ -50,6 +50,272 @@ config RP2040_I2C1_GPIO
range -1 29
depends on RP2040_I2C1
if RP2040_PWM0
config RP2040_PWM0A_GPIO
int "PWM0 channel 1 GPIO pin assign (0 or -1:no assign)"
default 0
range -1 16
---help---
This sets the GPIO pin to use for the A channel it must be
either 0, any other value disables the output.
config RP2040_PWM0A_INVERT
bool "PWM0 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM0B_GPIO
int "PWM0 channel 2 GPIO pin assign (1 or -1:no assign)"
default 1
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 1, any other value disables the output.
config RP2040_PWM0B_INVERT
bool "PWM0 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM0_PHASE_CORRECT
bool "PWM0 phase correct"
default n
endif
if RP2040_PWM1
config RP2040_PWM1A_GPIO
int "PWM1 channel 1 GPIO pin assign (2, 18 or -1:no assign)"
default 2
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 2 or 18, any other value disables the output.
config RP2040_PWM1A_INVERT
bool "PWM1 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM1B_GPIO
int "PWM1 channel 2 GPIO pin assign (3, 19 or -1:no assign)"
default 3
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 3 or 19, any other value disables the output.
config RP2040_PWM1B_INVERT
bool "PWM1 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM1_PHASE_CORRECT
bool "PWM1 phase correct"
default n
endif
if RP2040_PWM2
config RP2040_PWM2A_GPIO
int "PWM2 channel 1 GPIO pin assign (4, 20 or -1:no assign)"
default 4
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 4 or 20, any other value disables the output.
config RP2040_PWM2A_INVERT
bool "PWM2 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM2B_GPIO
int "PWM2 channel 2 GPIO pin assign (5, 21 or -1:no assign)"
default 5
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 5 or 21, any other value disables the output.
config RP2040_PWM2B_INVERT
bool "PWM2 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM2_PHASE_CORRECT
bool "PWM2 phase correct"
default n
endif
if RP2040_PWM3
config RP2040_PWM3A_GPIO
int "PWM3 channel 1 GPIO pin assign (6 or -1:no assign)"
default 6
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 6, any other value disables the output.
config RP2040_PWM3A_INVERT
bool "PWM3 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM3B_GPIO
int "PWM3 channel 2 GPIO pin assign (7 or -1:no assign)"
default 7
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 7, any other value disables the output.
config RP2040_PWM3B_INVERT
bool "PWM3 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM3_PHASE_CORRECT
bool "PWM3 phase correct"
default n
endif
if RP2040_PWM5
config RP2040_PWM5A_GPIO
int "PWM5 channel 1 GPIO pin assign (26 or -1:no assign)"
default 26
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 26, any other value disables the output.
config RP2040_PWM5A_INVERT
bool "PWM5 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM5B_GPIO
int "PWM5 channel 2 GPIO pin assign (27 or -1:no assign)"
default 27
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 27, any other value disables the output.
config RP2040_PWM5B_INVERT
bool "PWM5 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM5_PHASE_CORRECT
bool "PWM5 phase correct"
default n
endif
if RP2040_PWM6
config RP2040_PWM6A_GPIO
int "PWM6 channel 1 GPIO pin assign (28 or -1:no assign)"
default 28
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 28, any other value disables the output.
config RP2040_PWM6A_INVERT
bool "PWM6 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM6B_GPIO
int "PWM6 channel 2 GPIO pin assign (29 or -1:no assign)"
default 29
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 29, any other value disables the output.
config RP2040_PWM6B_INVERT
bool "PWM6 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM6_PHASE_CORRECT
bool "PWM6 phase correct"
default n
endif
if RP2040_PWM7
config RP2040_PWM7A_GPIO
int "PWM7 channel 1 GPIO pin assign (14 or -1:no assign)"
default 14
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 14, any other value disables the output.
config RP2040_PWM7A_INVERT
bool "PWM7 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM7B_GPIO
int "PWM7 channel 2 GPIO pin assign (15 or -1:no assign)"
default 15
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 15, any other value disables the output.
config RP2040_PWM7B_INVERT
bool "PWM7 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM7_PHASE_CORRECT
bool "PWM7 phase correct"
default n
endif
config RP2040_SPI0_GPIO
int "SPI0 GPIO pin assign (0,4,16,20 or -1:no assign)"
default -1

View file

@ -16,6 +16,7 @@ Currently only the following devices are supported.
- I2C (not tested on Tiny 2040)
- SPI
- DMAC
- PWM
- USB device
- MSC, CDC/ACM serial and these composite device are supported.
- CDC/ACM serial device can be used for the console.

View file

@ -33,6 +33,11 @@
#include "rp2040_tiny2040.h"
#ifdef CONFIG_RP2040_PWM
#include "rp2040_pwm.h"
#include "rp2040_pwmdev.h"
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -119,5 +124,279 @@ int rp2040_bringup(void)
}
#endif
#ifdef CONFIG_RP2040_PWM
# ifdef CONFIG_RP2040_PWM0
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(0,
CONFIG_RP2040_PWM0A_GPIO,
CONFIG_RP2040_PWM0B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM0A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM0B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM0_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(0,
CONFIG_RP2040_PWM0A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM0A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM0_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM0.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM1
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(1,
CONFIG_RP2040_PWM1A_GPIO,
CONFIG_RP2040_PWM1B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM1A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM1B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM1_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(1,
CONFIG_RP2040_PWM1A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM1A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM1_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM1.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM2
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(2,
CONFIG_RP2040_PWM2A_GPIO,
CONFIG_RP2040_PWM2B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM2A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM2B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM2_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(2,
CONFIG_RP2040_PWM2A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM2A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM2_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM2.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM3
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(3,
CONFIG_RP2040_PWM3A_GPIO,
CONFIG_RP2040_PWM3B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM3A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM3B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM3_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(3,
CONFIG_RP2040_PWM3A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM3A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM3_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM3.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM4
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(4,
CONFIG_RP2040_PWM4A_GPIO,
CONFIG_RP2040_PWM4B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM4A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM4B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM4_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(4,
CONFIG_RP2040_PWM4A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM4A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM4_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM4.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM5
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(5,
CONFIG_RP2040_PWM5A_GPIO,
CONFIG_RP2040_PWM5B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM5A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM5B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM5_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(5,
CONFIG_RP2040_PWM5A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM5A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM5_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM5.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM6
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(6,
CONFIG_RP2040_PWM6A_GPIO,
CONFIG_RP2040_PWM6B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM6A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM6B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM6_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(6,
CONFIG_RP2040_PWM6A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM6A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM6_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM6.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM7
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(7,
CONFIG_RP2040_PWM7A_GPIO,
CONFIG_RP2040_PWM7B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM7A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM7B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM7_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(7,
CONFIG_RP2040_PWM7A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM7A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM7_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM7.\n");
}
# endif
#endif
return ret;
}

View file

@ -50,6 +50,310 @@ config RP2040_I2C1_GPIO
range -1 29
depends on RP2040_I2C1
if RP2040_PWM0
config RP2040_PWM0A_GPIO
int "PWM0 channel 1 GPIO pin assign (0, 16 or -1:no assign)"
default 0
range -1 16
---help---
This sets the GPIO pin to use for the A channel it must be
either 0 or 16, any other value disables the output.
config RP2040_PWM0A_INVERT
bool "PWM0 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM0B_GPIO
int "PWM0 channel 2 GPIO pin assign (1, 17 or -1:no assign)"
default 1
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 1 or 17, any other value disables the output.
config RP2040_PWM0B_INVERT
bool "PWM0 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM0_PHASE_CORRECT
bool "PWM0 phase correct"
default n
endif
if RP2040_PWM1
config RP2040_PWM1A_GPIO
int "PWM1 channel 1 GPIO pin assign (2, 18 or -1:no assign)"
default 2
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 2 or 18, any other value disables the output.
config RP2040_PWM1A_INVERT
bool "PWM1 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM1B_GPIO
int "PWM1 channel 2 GPIO pin assign (3, 19 or -1:no assign)"
default 3
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 3 or 19, any other value disables the output.
config RP2040_PWM1B_INVERT
bool "PWM1 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM1_PHASE_CORRECT
bool "PWM1 phase correct"
default n
endif
if RP2040_PWM2
config RP2040_PWM2A_GPIO
int "PWM2 channel 1 GPIO pin assign (4, 20 or -1:no assign)"
default 4
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 4 or 20, any other value disables the output.
config RP2040_PWM2A_INVERT
bool "PWM2 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM2B_GPIO
int "PWM2 channel 2 GPIO pin assign (5, 21 or -1:no assign)"
default 5
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 5 or 21, any other value disables the output.
config RP2040_PWM2B_INVERT
bool "PWM2 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM2_PHASE_CORRECT
bool "PWM2 phase correct"
default n
endif
if RP2040_PWM3
config RP2040_PWM3A_GPIO
int "PWM3 channel 1 GPIO pin assign (6, 22 or -1:no assign)"
default 6
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 6 or 22, any other value disables the output.
config RP2040_PWM3A_INVERT
bool "PWM3 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM3B_GPIO
int "PWM3 channel 2 GPIO pin assign (7, 23 or -1:no assign)"
default 7
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 7 or 23, any other value disables the output.
config RP2040_PWM3B_INVERT
bool "PWM3 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM3_PHASE_CORRECT
bool "PWM3 phase correct"
default n
endif
if RP2040_PWM4
config RP2040_PWM4A_GPIO
int "PWM4 channel 1 GPIO pin assign (8, 24 or -1:no assign)"
default 8
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 8 or 24, any other value disables the output.
config RP2040_PWM4A_INVERT
bool "PWM4 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM4B_GPIO
int "PWM4 channel 2 GPIO pin assign (9, 25 or -1:no assign)"
default 9
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 9 or 25, any other value disables the output.
config RP2040_PWM4B_INVERT
bool "PWM4 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM4_PHASE_CORRECT
bool "PWM4 phase correct"
default n
endif
if RP2040_PWM5
config RP2040_PWM5A_GPIO
int "PWM5 channel 1 GPIO pin assign (10, 26 or -1:no assign)"
default 10
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 10 or 26, any other value disables the output.
config RP2040_PWM5A_INVERT
bool "PWM5 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM5B_GPIO
int "PWM5 channel 2 GPIO pin assign (11, 27 or -1:no assign)"
default 11
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 11 or 27, any other value disables the output.
config RP2040_PWM5B_INVERT
bool "PWM5 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM5_PHASE_CORRECT
bool "PWM5 phase correct"
default n
endif
if RP2040_PWM6
config RP2040_PWM6A_GPIO
int "PWM6 channel 1 GPIO pin assign (12, 28 or -1:no assign)"
default 12
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 12 or 28, any other value disables the output.
config RP2040_PWM6A_INVERT
bool "PWM6 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM6B_GPIO
int "PWM6 channel 2 GPIO pin assign (13, 29 or -1:no assign)"
default 13
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 13 or 29, any other value disables the output.
config RP2040_PWM6B_INVERT
bool "PWM6 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM6_PHASE_CORRECT
bool "PWM6 phase correct"
default n
endif
if RP2040_PWM7
config RP2040_PWM7A_GPIO
int "PWM7 channel 1 GPIO pin assign (14 or -1:no assign)"
default 14
range -1 29
---help---
This sets the GPIO pin to use for the A channel it must be
either 14, any other value disables the output.
config RP2040_PWM7A_INVERT
bool "PWM7 channel 1 invert"
default n
---help---
If invert is enabled, the PWM on the A pin will idle high
with the pulse going low.
if PWM_MULTICHAN && PWM_NCHANNELS > 1
config RP2040_PWM7B_GPIO
int "PWM7 channel 2 GPIO pin assign (15 or -1:no assign)"
default 15
range -1 29
---help---
This sets the GPIO pin to use for the B channel it must be
either 15, any other value disables the output.
config RP2040_PWM7B_INVERT
bool "PWM7 channel 2 invert"
default n
---help---
If invert is enabled, the PWM on the B pin will idle high
with the pulse going low.
endif
config RP2040_PWM7_PHASE_CORRECT
bool "PWM7 phase correct"
default n
endif
config RP2040_SPI0_GPIO
int "SPI0 GPIO pin assign (0,4,16,20 or -1:no assign)"
default -1

View file

@ -13,6 +13,7 @@ Currently only the following devices are supported.
- I2C
- SPI
- DMAC
- PWM
- USB device
- MSC, CDC/ACM serial and these composite device are supported.
- CDC/ACM serial device can be used for the console.

View file

@ -59,6 +59,11 @@
#include "rp2040_bmp180.h"
#endif
#ifdef CONFIG_RP2040_PWM
#include "rp2040_pwm.h"
#include "rp2040_pwmdev.h"
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -107,6 +112,280 @@ int rp2040_bringup(void)
#endif
#endif
#ifdef CONFIG_RP2040_PWM
# ifdef CONFIG_RP2040_PWM0
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(0,
CONFIG_RP2040_PWM0A_GPIO,
CONFIG_RP2040_PWM0B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM0A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM0B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM0_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(0,
CONFIG_RP2040_PWM0A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM0A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM0_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM0.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM1
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(1,
CONFIG_RP2040_PWM1A_GPIO,
CONFIG_RP2040_PWM1B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM1A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM1B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM1_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(1,
CONFIG_RP2040_PWM1A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM1A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM1_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM1.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM2
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(2,
CONFIG_RP2040_PWM2A_GPIO,
CONFIG_RP2040_PWM2B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM2A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM2B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM2_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(2,
CONFIG_RP2040_PWM2A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM2A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM2_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM2.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM3
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(3,
CONFIG_RP2040_PWM3A_GPIO,
CONFIG_RP2040_PWM3B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM3A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM3B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM3_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(3,
CONFIG_RP2040_PWM3A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM3A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM3_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM3.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM4
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(4,
CONFIG_RP2040_PWM4A_GPIO,
CONFIG_RP2040_PWM4B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM4A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM4B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM4_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(4,
CONFIG_RP2040_PWM4A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM4A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM4_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM4.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM5
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(5,
CONFIG_RP2040_PWM5A_GPIO,
CONFIG_RP2040_PWM5B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM5A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM5B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM5_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(5,
CONFIG_RP2040_PWM5A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM5A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM5_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM5.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM6
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(6,
CONFIG_RP2040_PWM6A_GPIO,
CONFIG_RP2040_PWM6B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM6A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM6B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM6_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(6,
CONFIG_RP2040_PWM6A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM6A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM6_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM6.\n");
}
# endif
# ifdef CONFIG_RP2040_PWM7
# if defined(CONFIG_PWM_NCHANNELS) && CONFIG_PWM_NCHANNELS == 2
ret = rp2040_pwmdev_initialize(7,
CONFIG_RP2040_PWM7A_GPIO,
CONFIG_RP2040_PWM7B_GPIO,
(0
# ifdef CONFIG_RP2040_PWM7A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM7B_INVERT
| RP2040_PWM_CSR_B_INV
# endif
# ifdef CONFIG_RP2040_PWM7_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# else
ret = rp2040_pwmdev_initialize(7,
CONFIG_RP2040_PWM7A_GPIO,
(0
# ifdef CONFIG_RP2040_PWM7A_INVERT
| RP2040_PWM_CSR_A_INV
# endif
# ifdef CONFIG_RP2040_PWM7_PHASE_CORRECT
| RP2040_PWM_CSR_PH_CORRECT
# endif
));
# endif
if (ret < 0)
{
_err("ERROR: Failed to initialize PWM7.\n");
}
# endif
#endif
#ifdef CONFIG_RP2040_SPISD
/* Mount the SPI-based MMC/SD block driver */