From d3ec8d276ccc5b7b8641e2bcccc1ab7fb9090073 Mon Sep 17 00:00:00 2001 From: Yonatan Schachter Date: Sat, 26 Feb 2022 19:25:03 +0200 Subject: [PATCH 1/4] soc: rpi_pico: Added panic handler Some pico-sdk drivers call a panic function, originally implemented as part of the Pico's C runtime. This commit adds a Zephyr compatible implementation of panic, so that those drivers could be compiled with Zephyr. Signed-off-by: Yonatan Schachter --- soc/arm/rpi_pico/rp2/soc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/soc/arm/rpi_pico/rp2/soc.c b/soc/arm/rpi_pico/rp2/soc.c index 3df9b983723e8..69681016b384d 100644 --- a/soc/arm/rpi_pico/rp2/soc.c +++ b/soc/arm/rpi_pico/rp2/soc.c @@ -13,9 +13,12 @@ * for the Raspberry Pi RP2040 family processor. */ +#include + #include #include #include +#include #include #include @@ -61,4 +64,18 @@ static int rp2040_init(const struct device *arg) return 0; } +/* + * Some pico-sdk drivers call panic on fatal error. + * This alternative implementation of panic handles the panic + * through Zephyr. + */ +void __attribute__((noreturn)) panic(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vprintf(fmt, args); + k_fatal_halt(K_ERR_CPU_EXCEPTION); +} + SYS_INIT(rp2040_init, PRE_KERNEL_1, 0); From 0999771dc0ac5279f90302d3c72492ea1a9d07c7 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 18 Jan 2023 08:57:14 +0900 Subject: [PATCH 2/4] modules: hal_rpi_pico: Enable DMA driver Enable DMA driver. Add the path of the DMA driver header into include paths. `hardware_claim` is depends by DMA driver, also enable it. Signed-off-by: TOKITA Hiroshi --- modules/hal_rpi_pico/CMakeLists.txt | 10 ++++++++++ modules/hal_rpi_pico/Kconfig | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/modules/hal_rpi_pico/CMakeLists.txt b/modules/hal_rpi_pico/CMakeLists.txt index 880af90a594b6..9db2b66e4d94f 100644 --- a/modules/hal_rpi_pico/CMakeLists.txt +++ b/modules/hal_rpi_pico/CMakeLists.txt @@ -100,6 +100,16 @@ if(CONFIG_HAS_RPI_PICO) zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_ADC ${rp2_common_dir}/hardware_adc/include) + zephyr_library_sources_ifdef(CONFIG_PICOSDK_USE_DMA + ${rp2_common_dir}/hardware_dma/dma.c) + zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_DMA + ${rp2_common_dir}/hardware_dma/include) + + zephyr_library_sources_ifdef(CONFIG_PICOSDK_USE_CLAIM + ${rp2_common_dir}/hardware_claim/claim.c) + zephyr_include_directories_ifdef(CONFIG_PICOSDK_USE_CLAIM + ${rp2_common_dir}/hardware_claim/include) + # Some flash driver functions must be executed from the RAM. # Originally pico-sdk places them in the RW data section, so this # implementation does the same. diff --git a/modules/hal_rpi_pico/Kconfig b/modules/hal_rpi_pico/Kconfig index 9bb327b8735ba..ecb4c4993c6af 100644 --- a/modules/hal_rpi_pico/Kconfig +++ b/modules/hal_rpi_pico/Kconfig @@ -28,3 +28,13 @@ config PICOSDK_USE_ADC bool help Use the ADC driver from pico-sdk + +config PICOSDK_USE_DMA + bool + help + Use the DMA driver from pico-sdk + +config PICOSDK_USE_CLAIM + bool + help + Use the "claim" driver from pico-sdk From 28fc9aa9d30945464c48a0c3c76a5b7fa25e1e63 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 18 Jan 2023 08:13:54 +0900 Subject: [PATCH 3/4] drivers: dma: rpi_pico: add support for RaspberryPi Pico DMA Adding RaspberryPi Pico DMA driver. Signed-off-by: TOKITA Hiroshi --- boards/arm/rpi_pico/rpi_pico.yaml | 1 + drivers/dma/CMakeLists.txt | 1 + drivers/dma/Kconfig | 2 + drivers/dma/Kconfig.rpi_pico | 12 + drivers/dma/dma_rpi_pico.c | 384 ++++++++++++++++++ dts/arm/rpi_pico/rp2040.dtsi | 13 + dts/bindings/dma/raspberrypi,pico-dma.yaml | 42 ++ include/zephyr/dt-bindings/dma/rpi_pico_dma.h | 64 +++ 8 files changed, 519 insertions(+) create mode 100644 drivers/dma/Kconfig.rpi_pico create mode 100644 drivers/dma/dma_rpi_pico.c create mode 100644 dts/bindings/dma/raspberrypi,pico-dma.yaml create mode 100644 include/zephyr/dt-bindings/dma/rpi_pico_dma.h diff --git a/boards/arm/rpi_pico/rpi_pico.yaml b/boards/arm/rpi_pico/rpi_pico.yaml index 96aa12649e644..d3baa1f1822f5 100644 --- a/boards/arm/rpi_pico/rpi_pico.yaml +++ b/boards/arm/rpi_pico/rpi_pico.yaml @@ -18,3 +18,4 @@ supported: - watchdog - pwm - flash + - dma diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt index d5f76cbccabf4..d73d0a87e08c7 100644 --- a/drivers/dma/CMakeLists.txt +++ b/drivers/dma/CMakeLists.txt @@ -27,3 +27,4 @@ zephyr_library_sources_ifdef(CONFIG_DMA_GD32 dma_gd32.c) zephyr_library_sources_ifdef(CONFIG_DMA_ESP32 dma_esp32_gdma.c) zephyr_library_sources_ifdef(CONFIG_DMA_MCHP_XEC dma_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_DMA_XMC4XXX dma_xmc4xxx.c) +zephyr_library_sources_ifdef(CONFIG_DMA_RPI_PICO dma_rpi_pico.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 4e20a43224e20..76daa4cabee42 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -56,4 +56,6 @@ source "drivers/dma/Kconfig.xec" source "drivers/dma/Kconfig.xmc4xxx" +source "drivers/dma/Kconfig.rpi_pico" + endif # DMA diff --git a/drivers/dma/Kconfig.rpi_pico b/drivers/dma/Kconfig.rpi_pico new file mode 100644 index 0000000000000..434ac9fdf14c5 --- /dev/null +++ b/drivers/dma/Kconfig.rpi_pico @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Tokita, Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +config DMA_RPI_PICO + bool "Raspberry Pi Pico DMA driver" + default y + depends on DT_HAS_RASPBERRYPI_PICO_DMA_ENABLED + select PICOSDK_USE_DMA + select PICOSDK_USE_CLAIM + depends on RESET + help + DMA driver for RaspberryPi Pico. diff --git a/drivers/dma/dma_rpi_pico.c b/drivers/dma/dma_rpi_pico.c new file mode 100644 index 0000000000000..57c23ced657f1 --- /dev/null +++ b/drivers/dma/dma_rpi_pico.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DT_DRV_COMPAT raspberrypi_pico_dma + +#define DMA_INT_ERROR_FLAGS \ + (DMA_CH0_CTRL_TRIG_AHB_ERROR_BITS | DMA_CH0_CTRL_TRIG_READ_ERROR_BITS | \ + DMA_CH0_CTRL_TRIG_WRITE_ERROR_BITS) + +LOG_MODULE_REGISTER(dma_rpi_pico, CONFIG_DMA_LOG_LEVEL); + +struct dma_rpi_pico_config { + uint32_t reg; + uint32_t channels; + struct reset_dt_spec reset; + void (*irq_configure)(void); + uint32_t *irq0_channels; + size_t irq0_channels_size; +}; + +struct dma_rpi_pico_channel { + dma_callback_t callback; + void *user_data; + uint32_t direction; + dma_channel_config config; + void *source_address; + void *dest_address; + size_t block_size; +}; + +struct dma_rpi_pico_data { + struct dma_context ctx; + struct dma_rpi_pico_channel *channels; +}; + +/* + * Register access functions + */ + +static inline void rpi_pico_dma_channel_clear_error_flags(const struct device *dev, + uint32_t channel) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + + ((dma_hw_t *)cfg->reg)->ch[channel].al1_ctrl &= ~DMA_INT_ERROR_FLAGS; +} + +static inline uint32_t rpi_pico_dma_channel_get_error_flags(const struct device *dev, + uint32_t channel) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + + return ((dma_hw_t *)cfg->reg)->ch[channel].al1_ctrl & DMA_INT_ERROR_FLAGS; +} + +static inline void rpi_pico_dma_channel_abort(const struct device *dev, uint32_t channel) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + + ((dma_hw_t *)cfg->reg)->abort = BIT(channel); +} + +/* + * Utility functions + */ + +static inline uint32_t dma_rpi_pico_transfer_size(uint32_t width) +{ + switch (width) { + case 4: + return DMA_SIZE_32; + case 2: + return DMA_SIZE_16; + default: + return DMA_SIZE_8; + } +} + +static inline uint32_t dma_rpi_pico_channel_irq(const struct device *dev, uint32_t channel) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + + for (size_t i = 0; i < cfg->irq0_channels_size; i++) { + if (cfg->irq0_channels[i] == channel) { + return 0; + } + } + + return 1; +} + +/* + * API functions + */ + +static int dma_rpi_pico_config(const struct device *dev, uint32_t channel, + struct dma_config *dma_cfg) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + struct dma_rpi_pico_data *data = dev->data; + + if (channel >= cfg->channels) { + LOG_ERR("channel must be < %" PRIu32 " (%" PRIu32 ")", cfg->channels, channel); + return -EINVAL; + } + + if (dma_cfg->block_count != 1) { + LOG_ERR("chained block transfer not supported."); + return -ENOTSUP; + } + + if (dma_cfg->channel_priority > 3) { + LOG_ERR("channel_priority must be < 4 (%" PRIu32 ")", dma_cfg->channel_priority); + return -EINVAL; + } + + if (dma_cfg->head_block->source_addr_adj == DMA_ADDR_ADJ_DECREMENT) { + LOG_ERR("source_addr_adj not supported DMA_ADDR_ADJ_DECREMENT"); + return -ENOTSUP; + } + + if (dma_cfg->head_block->dest_addr_adj == DMA_ADDR_ADJ_DECREMENT) { + LOG_ERR("dest_addr_adj not supported DMA_ADDR_ADJ_DECREMENT"); + return -ENOTSUP; + } + + if (dma_cfg->head_block->source_addr_adj != DMA_ADDR_ADJ_INCREMENT && + dma_cfg->head_block->source_addr_adj != DMA_ADDR_ADJ_NO_CHANGE) { + LOG_ERR("invalid source_addr_adj %" PRIu16, dma_cfg->head_block->source_addr_adj); + return -ENOTSUP; + } + if (dma_cfg->head_block->dest_addr_adj != DMA_ADDR_ADJ_INCREMENT && + dma_cfg->head_block->dest_addr_adj != DMA_ADDR_ADJ_NO_CHANGE) { + LOG_ERR("invalid dest_addr_adj %" PRIu16, dma_cfg->head_block->dest_addr_adj); + return -ENOTSUP; + } + + if (dma_cfg->source_data_size != 1 && dma_cfg->source_data_size != 2 && + dma_cfg->source_data_size != 4) { + LOG_ERR("source_data_size must be 1, 2, or 4 (%" PRIu32 ")", + dma_cfg->source_data_size); + return -EINVAL; + } + + if (dma_cfg->source_data_size != dma_cfg->dest_data_size) { + return -EINVAL; + } + + if (dma_cfg->dest_data_size != 1 && dma_cfg->dest_data_size != 2 && + dma_cfg->dest_data_size != 4) { + LOG_ERR("dest_data_size must be 1, 2, or 4 (%" PRIu32 ")", dma_cfg->dest_data_size); + return -EINVAL; + } + + if (dma_cfg->channel_direction > PERIPHERAL_TO_MEMORY) { + LOG_ERR("channel_direction must be MEMORY_TO_MEMORY, " + "MEMORY_TO_PERIPHERAL or PERIPHERAL_TO_MEMORY (%" PRIu32 ")", + dma_cfg->channel_direction); + return -ENOTSUP; + } + + data->channels[channel].config = dma_channel_get_default_config(channel); + + data->channels[channel].source_address = (void *)dma_cfg->head_block->source_address; + data->channels[channel].dest_address = (void *)dma_cfg->head_block->dest_address; + data->channels[channel].block_size = dma_cfg->head_block->block_size; + channel_config_set_read_increment(&data->channels[channel].config, + dma_cfg->head_block->source_addr_adj == + DMA_ADDR_ADJ_INCREMENT); + channel_config_set_write_increment(&data->channels[channel].config, + dma_cfg->head_block->dest_addr_adj == + DMA_ADDR_ADJ_INCREMENT); + channel_config_set_transfer_data_size( + &data->channels[channel].config, + dma_rpi_pico_transfer_size(dma_cfg->source_data_size)); + channel_config_set_dreq(&data->channels[channel].config, + RPI_PICO_DMA_SLOT_TO_DREQ(dma_cfg->dma_slot)); + channel_config_set_high_priority(&data->channels[channel].config, + !!(dma_cfg->channel_priority)); + + data->channels[channel].callback = dma_cfg->dma_callback; + data->channels[channel].user_data = dma_cfg->user_data; + data->channels[channel].direction = dma_cfg->channel_direction; + + return 0; +} + +static int dma_rpi_pico_reload(const struct device *dev, uint32_t ch, uint32_t src, uint32_t dst, + size_t size) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + struct dma_rpi_pico_data *data = dev->data; + + if (ch >= cfg->channels) { + LOG_ERR("reload channel must be < %" PRIu32 " (%" PRIu32 ")", cfg->channels, ch); + return -EINVAL; + } + + if (dma_channel_is_busy(ch)) { + return -EBUSY; + } + + data->channels[ch].source_address = (void *)src; + data->channels[ch].dest_address = (void *)dst; + data->channels[ch].block_size = size; + dma_channel_configure(ch, &data->channels[ch].config, data->channels[ch].dest_address, + data->channels[ch].source_address, data->channels[ch].block_size, + true); + + return 0; +} + +static int dma_rpi_pico_start(const struct device *dev, uint32_t ch) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + struct dma_rpi_pico_data *data = dev->data; + + if (ch >= cfg->channels) { + LOG_ERR("start channel must be < %" PRIu32 " (%" PRIu32 ")", cfg->channels, ch); + return -EINVAL; + } + + dma_irqn_acknowledge_channel(dma_rpi_pico_channel_irq(dev, ch), ch); + dma_irqn_set_channel_enabled(dma_rpi_pico_channel_irq(dev, ch), ch, true); + + dma_channel_configure(ch, &data->channels[ch].config, data->channels[ch].dest_address, + data->channels[ch].source_address, data->channels[ch].block_size, + true); + + return 0; +} + +static int dma_rpi_pico_stop(const struct device *dev, uint32_t ch) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + + if (ch >= cfg->channels) { + LOG_ERR("stop channel must be < %" PRIu32 " (%" PRIu32 ")", cfg->channels, ch); + return -EINVAL; + } + + dma_irqn_set_channel_enabled(dma_rpi_pico_channel_irq(dev, ch), ch, false); + rpi_pico_dma_channel_clear_error_flags(dev, ch); + + /* + * Considering the possibility of being called in an interrupt context, + * it does not wait until the abort bit becomes clear. + * Ensure the busy status is canceled with dma_get_status + * before the next transfer starts. + */ + rpi_pico_dma_channel_abort(dev, ch); + + return 0; +} + +static int dma_rpi_pico_get_status(const struct device *dev, uint32_t ch, struct dma_status *stat) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + struct dma_rpi_pico_data *data = dev->data; + + if (ch >= cfg->channels) { + LOG_ERR("channel must be < %" PRIu32 " (%" PRIu32 ")", cfg->channels, ch); + return -EINVAL; + } + + stat->pending_length = 0; + stat->dir = data->channels[ch].direction; + stat->busy = dma_channel_is_busy(ch); + + return 0; +} + +static bool dma_rpi_pico_api_chan_filter(const struct device *dev, int ch, void *filter_param) +{ + uint32_t filter; + + if (!filter_param) { + LOG_ERR("filter_param must not be NULL"); + return false; + } + + filter = *((uint32_t *)filter_param); + + return (filter & BIT(ch)); +} + +static int dma_rpi_pico_init(const struct device *dev) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + + (void)reset_line_toggle_dt(&cfg->reset); + + cfg->irq_configure(); + + return 0; +} + +static void dma_rpi_pico_isr(const struct device *dev) +{ + const struct dma_rpi_pico_config *cfg = dev->config; + struct dma_rpi_pico_data *data = dev->data; + int err = 0; + + for (uint32_t i = 0; i < cfg->channels; i++) { + if (!dma_irqn_get_channel_status(dma_rpi_pico_channel_irq(dev, i), i)) { + continue; + } + + if (rpi_pico_dma_channel_get_error_flags(dev, i)) { + err = -EIO; + } + + dma_irqn_acknowledge_channel(dma_rpi_pico_channel_irq(dev, i), i); + dma_irqn_set_channel_enabled(dma_rpi_pico_channel_irq(dev, i), i, false); + rpi_pico_dma_channel_clear_error_flags(dev, i); + + if (data->channels[i].callback) { + data->channels[i].callback(dev, data->channels[i].user_data, i, err); + } + } +} + +static const struct dma_driver_api dma_rpi_pico_driver_api = { + .config = dma_rpi_pico_config, + .reload = dma_rpi_pico_reload, + .start = dma_rpi_pico_start, + .stop = dma_rpi_pico_stop, + .get_status = dma_rpi_pico_get_status, + .chan_filter = dma_rpi_pico_api_chan_filter, +}; + +#define IRQ_CONFIGURE(n, inst) \ + IRQ_CONNECT(DT_INST_IRQ_BY_IDX(inst, n, irq), DT_INST_IRQ_BY_IDX(inst, n, priority), \ + dma_rpi_pico_isr, DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQ_BY_IDX(inst, n, irq)); + +#define CONFIGURE_ALL_IRQS(inst, n) LISTIFY(n, IRQ_CONFIGURE, (), inst) + +#define RPI_PICO_DMA_INIT(inst) \ + static void dma_rpi_pico##inst##_irq_configure(void) \ + { \ + CONFIGURE_ALL_IRQS(inst, DT_NUM_IRQS(DT_DRV_INST(inst))); \ + } \ + static uint32_t dma_rpi_pico##inst##_irq0_channels[] = \ + DT_INST_PROP_OR(inst, irq0_channels, {0}); \ + static const struct dma_rpi_pico_config dma_rpi_pico##inst##_config = { \ + .reg = DT_INST_REG_ADDR(inst), \ + .channels = DT_INST_PROP(inst, dma_channels), \ + .reset = RESET_DT_SPEC_INST_GET(inst), \ + .irq_configure = dma_rpi_pico##inst##_irq_configure, \ + .irq0_channels = dma_rpi_pico##inst##_irq0_channels, \ + .irq0_channels_size = ARRAY_SIZE(dma_rpi_pico##inst##_irq0_channels), \ + }; \ + static struct dma_rpi_pico_channel \ + dma_rpi_pico##inst##_channels[DT_INST_PROP(inst, dma_channels)]; \ + ATOMIC_DEFINE(dma_rpi_pico_atomic##inst, DT_INST_PROP(inst, dma_channels)); \ + static struct dma_rpi_pico_data dma_rpi_pico##inst##_data = { \ + .ctx = \ + { \ + .magic = DMA_MAGIC, \ + .atomic = dma_rpi_pico_atomic##inst, \ + .dma_channels = DT_INST_PROP(inst, dma_channels), \ + }, \ + .channels = dma_rpi_pico##inst##_channels, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(inst, &dma_rpi_pico_init, NULL, &dma_rpi_pico##inst##_data, \ + &dma_rpi_pico##inst##_config, POST_KERNEL, CONFIG_DMA_INIT_PRIORITY, \ + &dma_rpi_pico_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RPI_PICO_DMA_INIT) diff --git a/dts/arm/rpi_pico/rp2040.dtsi b/dts/arm/rpi_pico/rp2040.dtsi index 591041136b683..eebb68a61d40e 100644 --- a/dts/arm/rpi_pico/rp2040.dtsi +++ b/dts/arm/rpi_pico/rp2040.dtsi @@ -186,6 +186,19 @@ #pwm-cells = <3>; }; + dma: dma@50000000 { + compatible = "raspberrypi,pico-dma"; + reg = <0x50000000 DT_SIZE_K(64)>; + resets = <&reset RPI_PICO_RESETS_RESET_DMA>; + clocks = <&system_clk>; + interrupts = <11 RPI_PICO_DEFAULT_IRQ_PRIORITY>, + <12 RPI_PICO_DEFAULT_IRQ_PRIORITY>; + interrupt-names = "dma0", "dma1"; + dma-channels = <12>; + status = "disabled"; + #dma-cells = <3>; + }; + vreg: vreg@40064000 { compatible = "raspberrypi,core-supply-regulator"; reg = <0x40064000 1>; diff --git a/dts/bindings/dma/raspberrypi,pico-dma.yaml b/dts/bindings/dma/raspberrypi,pico-dma.yaml new file mode 100644 index 0000000000000..35960fbca7fe9 --- /dev/null +++ b/dts/bindings/dma/raspberrypi,pico-dma.yaml @@ -0,0 +1,42 @@ +# Copyright (c) 2023 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +description: | + Raspberry Pi Pico GPIO + + channel: Select channel for data transmitting + + slot: Select peripheral data request + Use the definitions defined in `zephyr/dt-bindings/dma/rpi_pico_dma.h`. + + channel-config: A 32bit mask specifying the DMA channel configuration + - bit 3: Enable Quiet IRQ + - bit 1: Enable Byte Swap + - bit 0: Enable High Priority + +compatible: "raspberrypi,pico-dma" + +include: [dma-controller.yaml, reset-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + dma-channels: + required: true + + irq0-channels: + type: uint8-array + default: [0, 2, 4, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30] + description: Channels list that uses the irq0 + + "#dma-cells": + const: 3 + +dma-cells: + - channel + - slot + - channel-config diff --git a/include/zephyr/dt-bindings/dma/rpi_pico_dma.h b/include/zephyr/dt-bindings/dma/rpi_pico_dma.h new file mode 100644 index 0000000000000..f181a31beba90 --- /dev/null +++ b/include/zephyr/dt-bindings/dma/rpi_pico_dma.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 TOKITA Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_H_ + +/* + * Use lower 6-bit of inverted DREQ value for `slot` cell. + * Need to be able to work for memory-to-memory transfer + * with zero, which is the default value. + */ +#define RPI_PICO_DMA_SLOT_TO_DREQ(s) (~(s)&0x3F) +#define RPI_PICO_DMA_DREQ_TO_SLOT RPI_PICO_DMA_SLOT_TO_DREQ + +#define RPI_PICO_DMA_SLOT_PIO0_TX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x00) +#define RPI_PICO_DMA_SLOT_PIO0_TX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x01) +#define RPI_PICO_DMA_SLOT_PIO0_TX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x02) +#define RPI_PICO_DMA_SLOT_PIO0_TX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x03) +#define RPI_PICO_DMA_SLOT_PIO0_RX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x04) +#define RPI_PICO_DMA_SLOT_PIO0_RX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x05) +#define RPI_PICO_DMA_SLOT_PIO0_RX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x06) +#define RPI_PICO_DMA_SLOT_PIO0_RX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x07) +#define RPI_PICO_DMA_SLOT_PIO1_TX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x08) +#define RPI_PICO_DMA_SLOT_PIO1_TX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x09) +#define RPI_PICO_DMA_SLOT_PIO1_TX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x0A) +#define RPI_PICO_DMA_SLOT_PIO1_TX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x0B) +#define RPI_PICO_DMA_SLOT_PIO1_RX0 RPI_PICO_DMA_DREQ_TO_SLOT(0x0C) +#define RPI_PICO_DMA_SLOT_PIO1_RX1 RPI_PICO_DMA_DREQ_TO_SLOT(0x0D) +#define RPI_PICO_DMA_SLOT_PIO1_RX2 RPI_PICO_DMA_DREQ_TO_SLOT(0x0E) +#define RPI_PICO_DMA_SLOT_PIO1_RX3 RPI_PICO_DMA_DREQ_TO_SLOT(0x0F) +#define RPI_PICO_DMA_SLOT_SPI0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x10) +#define RPI_PICO_DMA_SLOT_SPI0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x11) +#define RPI_PICO_DMA_SLOT_SPI1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x12) +#define RPI_PICO_DMA_SLOT_SPI1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x13) +#define RPI_PICO_DMA_SLOT_UART0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x14) +#define RPI_PICO_DMA_SLOT_UART0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x15) +#define RPI_PICO_DMA_SLOT_UART1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x16) +#define RPI_PICO_DMA_SLOT_UART1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x17) +#define RPI_PICO_DMA_SLOT_PWM_WRAP0 RPI_PICO_DMA_DREQ_TO_SLOT(0x18) +#define RPI_PICO_DMA_SLOT_PWM_WRAP1 RPI_PICO_DMA_DREQ_TO_SLOT(0x19) +#define RPI_PICO_DMA_SLOT_PWM_WRAP2 RPI_PICO_DMA_DREQ_TO_SLOT(0x1A) +#define RPI_PICO_DMA_SLOT_PWM_WRAP3 RPI_PICO_DMA_DREQ_TO_SLOT(0x1B) +#define RPI_PICO_DMA_SLOT_PWM_WRAP4 RPI_PICO_DMA_DREQ_TO_SLOT(0x1C) +#define RPI_PICO_DMA_SLOT_PWM_WRAP5 RPI_PICO_DMA_DREQ_TO_SLOT(0x1D) +#define RPI_PICO_DMA_SLOT_PWM_WRAP6 RPI_PICO_DMA_DREQ_TO_SLOT(0x1E) +#define RPI_PICO_DMA_SLOT_PWM_WRAP7 RPI_PICO_DMA_DREQ_TO_SLOT(0x1F) +#define RPI_PICO_DMA_SLOT_I2C0_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x30) +#define RPI_PICO_DMA_SLOT_I2C0_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x31) +#define RPI_PICO_DMA_SLOT_I2C1_TX RPI_PICO_DMA_DREQ_TO_SLOT(0x32) +#define RPI_PICO_DMA_SLOT_I2C1_RX RPI_PICO_DMA_DREQ_TO_SLOT(0x33) +#define RPI_PICO_DMA_SLOT_ADC RPI_PICO_DMA_DREQ_TO_SLOT(0x34) +#define RPI_PICO_DMA_SLOT_XIP_STREAM RPI_PICO_DMA_DREQ_TO_SLOT(0x35) +#define RPI_PICO_DMA_SLOT_XIP_SSITX RPI_PICO_DMA_DREQ_TO_SLOT(0x36) +#define RPI_PICO_DMA_SLOT_XIP_SSIRX RPI_PICO_DMA_DREQ_TO_SLOT(0x37) +#define RPI_PICO_DMA_SLOT_DMA_TIMER0 RPI_PICO_DMA_DREQ_TO_SLOT(0x3B) +#define RPI_PICO_DMA_SLOT_DMA_TIMER1 RPI_PICO_DMA_DREQ_TO_SLOT(0x3C) +#define RPI_PICO_DMA_SLOT_DMA_TIMER2 RPI_PICO_DMA_DREQ_TO_SLOT(0x3D) +#define RPI_PICO_DMA_SLOT_DMA_TIMER3 RPI_PICO_DMA_DREQ_TO_SLOT(0x3E) +#define RPI_PICO_DMA_SLOT_FORCE RPI_PICO_DMA_DREQ_TO_SLOT(0x3F) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_RPI_PICO_DMA_H_ */ From 3e530c6e775e1ff7213c00f046a13f1dda8874c2 Mon Sep 17 00:00:00 2001 From: TOKITA Hiroshi Date: Wed, 18 Jan 2023 08:56:33 +0900 Subject: [PATCH 4/4] tests: dma: loop_transfer: add overlay for RaspberryPi Pico Add overlay file for rpi_pico target. Signed-off-by: TOKITA Hiroshi --- tests/drivers/dma/loop_transfer/boards/rpi_pico.overlay | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/drivers/dma/loop_transfer/boards/rpi_pico.overlay diff --git a/tests/drivers/dma/loop_transfer/boards/rpi_pico.overlay b/tests/drivers/dma/loop_transfer/boards/rpi_pico.overlay new file mode 100644 index 0000000000000..b70c452e4250a --- /dev/null +++ b/tests/drivers/dma/loop_transfer/boards/rpi_pico.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Tokita, Hiroshi + * + * SPDX-License-Identifier: Apache-2.0 + */ + +test_dma: &dma { + status = "okay"; +};