From c48b378bcc390f2f71bb572e74176bf4bd36c4f5 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:14:01 +0200 Subject: [PATCH 1/6] [top] minor XBUS signal rearrangement --- docs/datasheet/soc.adoc | 2 +- rtl/core/neorv32_package.vhd | 4 ++-- rtl/core/neorv32_top.vhd | 2 +- rtl/system_integration/neorv32_litex_core_complex.vhd | 2 +- sim/neorv32_tb.vhd | 2 +- sim/simple/neorv32_tb.simple.vhd | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/datasheet/soc.adoc b/docs/datasheet/soc.adoc index 8923de021..273ea45e0 100644 --- a/docs/datasheet/soc.adoc +++ b/docs/datasheet/soc.adoc @@ -87,12 +87,12 @@ Some interfaces (like the TWI and the 1-Wire bus) require tri-state drivers in t | `jtag_tms_i` | 1 | in | `'L'` | mode select 5+^| **<<_processor_external_bus_interface_xbus>>** | `xbus_adr_o` | 32 | out | - | destination address -| `xbus_dat_i` | 32 | in | `'L'` | write data | `xbus_dat_o` | 32 | out | - | read data | `xbus_we_o` | 1 | out | - | write enable ('0' = read transfer) | `xbus_sel_o` | 4 | out | - | byte enable | `xbus_stb_o` | 1 | out | - | strobe | `xbus_cyc_o` | 1 | out | - | valid cycle +| `xbus_dat_i` | 32 | in | `'L'` | write data | `xbus_ack_i` | 1 | in | `'L'` | transfer acknowledge | `xbus_err_i` | 1 | in | `'L'` | transfer error 5+^| **<<_stream_link_interface_slink>>** diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index f6ea707a1..0df921cdc 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -29,7 +29,7 @@ package neorv32_package is -- Architecture Constants ----------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090803"; -- hardware version + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090804"; -- hardware version constant archid_c : natural := 19; -- official RISC-V architecture ID constant XLEN : natural := 32; -- native data path width @@ -816,12 +816,12 @@ package neorv32_package is jtag_tms_i : in std_ulogic := 'L'; -- External bus interface (available if XBUS_EN = true) -- xbus_adr_o : out std_ulogic_vector(31 downto 0); - xbus_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); xbus_dat_o : out std_ulogic_vector(31 downto 0); xbus_we_o : out std_ulogic; xbus_sel_o : out std_ulogic_vector(03 downto 0); xbus_stb_o : out std_ulogic; xbus_cyc_o : out std_ulogic; + xbus_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); xbus_ack_i : in std_ulogic := 'L'; xbus_err_i : in std_ulogic := 'L'; -- Stream Link Interface (available if IO_SLINK_EN = true) -- diff --git a/rtl/core/neorv32_top.vhd b/rtl/core/neorv32_top.vhd index 2540c38c9..2a7c015c6 100644 --- a/rtl/core/neorv32_top.vhd +++ b/rtl/core/neorv32_top.vhd @@ -149,12 +149,12 @@ entity neorv32_top is -- External bus interface (available if XBUS_EN = true) -- xbus_adr_o : out std_ulogic_vector(31 downto 0); -- address - xbus_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- read data xbus_dat_o : out std_ulogic_vector(31 downto 0); -- write data xbus_we_o : out std_ulogic; -- read/write xbus_sel_o : out std_ulogic_vector(03 downto 0); -- byte enable xbus_stb_o : out std_ulogic; -- strobe xbus_cyc_o : out std_ulogic; -- valid cycle + xbus_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- read data xbus_ack_i : in std_ulogic := 'L'; -- transfer acknowledge xbus_err_i : in std_ulogic := 'L'; -- transfer error diff --git a/rtl/system_integration/neorv32_litex_core_complex.vhd b/rtl/system_integration/neorv32_litex_core_complex.vhd index a0571ffa2..f414c21c8 100644 --- a/rtl/system_integration/neorv32_litex_core_complex.vhd +++ b/rtl/system_integration/neorv32_litex_core_complex.vhd @@ -161,12 +161,12 @@ begin jtag_tms_i => jtag_tms_i, -- mode select -- External bus interface -- xbus_adr_o => wb_adr_o, -- address - xbus_dat_i => wb_dat_i, -- read data xbus_dat_o => wb_dat_o, -- write data xbus_we_o => wb_we_o, -- read/write xbus_sel_o => wb_sel_o, -- byte enable xbus_stb_o => open, -- strobe xbus_cyc_o => wb_cyc, -- valid cycle + xbus_dat_i => wb_dat_i, -- read data xbus_ack_i => wb_ack_i, -- transfer acknowledge xbus_err_i => wb_err_i, -- transfer error -- CPU Interrupts -- diff --git a/sim/neorv32_tb.vhd b/sim/neorv32_tb.vhd index 02f1d3405..6dcd0779d 100644 --- a/sim/neorv32_tb.vhd +++ b/sim/neorv32_tb.vhd @@ -295,12 +295,12 @@ begin jtag_tms_i => '0', -- mode select -- External bus interface (available if XBUS_EN = true) -- xbus_adr_o => wb_cpu.addr, -- address - xbus_dat_i => wb_cpu.rdata, -- read data xbus_dat_o => wb_cpu.wdata, -- write data xbus_we_o => wb_cpu.we, -- read/write xbus_sel_o => wb_cpu.sel, -- byte enable xbus_stb_o => wb_cpu.stb, -- strobe xbus_cyc_o => wb_cpu.cyc, -- valid cycle + xbus_dat_i => wb_cpu.rdata, -- read data xbus_ack_i => wb_cpu.ack, -- transfer acknowledge xbus_err_i => wb_cpu.err, -- transfer error -- Stream Link Interface (available if IO_SLINK_EN = true) -- diff --git a/sim/simple/neorv32_tb.simple.vhd b/sim/simple/neorv32_tb.simple.vhd index 0487ce781..7d880ebd6 100644 --- a/sim/simple/neorv32_tb.simple.vhd +++ b/sim/simple/neorv32_tb.simple.vhd @@ -271,12 +271,12 @@ begin jtag_tms_i => '0', -- mode select -- External bus interface (available if XBUS_EN = true) -- xbus_adr_o => wb_cpu.addr, -- address - xbus_dat_i => wb_cpu.rdata, -- read data xbus_dat_o => wb_cpu.wdata, -- write data xbus_we_o => wb_cpu.we, -- read/write xbus_sel_o => wb_cpu.sel, -- byte enable xbus_stb_o => wb_cpu.stb, -- strobe xbus_cyc_o => wb_cpu.cyc, -- valid cycle + xbus_dat_i => wb_cpu.rdata, -- read data xbus_ack_i => wb_cpu.ack, -- transfer acknowledge xbus_err_i => wb_cpu.err, -- transfer error -- Stream Link Interface (available if IO_SLINK_EN = true) -- From cd2b92a8b01d9d838fe24bdecf8c2a47339d4b72 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:15:16 +0200 Subject: [PATCH 2/6] :warning: [DMA] use FIRQ select instead of FIRQ mask --- rtl/core/neorv32_dma.vhd | 16 ++++++++-------- sw/lib/include/neorv32_dma.h | 20 ++++++++++---------- sw/lib/source/neorv32_dma.c | 8 ++++---- sw/svd/neorv32.svd | 6 +++--- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/rtl/core/neorv32_dma.vhd b/rtl/core/neorv32_dma.vhd index 570eef261..3f5ba3504 100644 --- a/rtl/core/neorv32_dma.vhd +++ b/rtl/core/neorv32_dma.vhd @@ -50,8 +50,8 @@ architecture neorv32_dma_rtl of neorv32_dma is constant ctrl_busy_c : natural := 10; -- r/-: DMA transfer in progress constant ctrl_done_c : natural := 11; -- r/c: a DMA transfer was executed/attempted -- - constant ctrl_firq_mask_lsb_c : natural := 16; -- r/w: FIRQ trigger mask LSB - constant ctrl_firq_mask_msb_c : natural := 31; -- r/w: FIRQ trigger mask MSB + constant ctrl_firq_sel_lsb_c : natural := 16; -- r/w: FIRQ trigger select LSB + constant ctrl_firq_sel_msb_c : natural := 19; -- r/w: FIRQ trigger select MSB -- transfer quantities -- constant qsel_b2b_c : std_ulogic_vector(1 downto 0) := "00"; -- byte to byte @@ -64,7 +64,7 @@ architecture neorv32_dma_rtl of neorv32_dma is enable : std_ulogic; -- DMA enabled when set auto : std_ulogic; -- FIRQ-driven auto transfer fence : std_ulogic; -- issue FENCE operation when DMA is done - firq_mask : std_ulogic_vector(15 downto 0); -- FIRQ trigger mask + firq_sel : std_ulogic_vector(03 downto 0); -- FIRQ trigger select src_base : std_ulogic_vector(31 downto 0); -- source base address dst_base : std_ulogic_vector(31 downto 0); -- destination base address num : std_ulogic_vector(23 downto 0); -- number of elements @@ -116,7 +116,7 @@ begin config.enable <= '0'; config.auto <= '0'; config.fence <= '0'; - config.firq_mask <= (others => '0'); + config.firq_sel <= (others => '0'); config.src_base <= (others => '0'); config.dst_base <= (others => '0'); config.num <= (others => '0'); @@ -143,7 +143,7 @@ begin config.auto <= bus_req_i.data(ctrl_auto_c); config.fence <= bus_req_i.data(ctrl_fence_c); config.done <= '0'; -- clear on write access - config.firq_mask <= bus_req_i.data(ctrl_firq_mask_msb_c downto ctrl_firq_mask_lsb_c); + config.firq_sel <= bus_req_i.data(ctrl_firq_sel_msb_c downto ctrl_firq_sel_lsb_c); end if; if (bus_req_i.addr(3 downto 2) = "01") then -- source base address config.src_base <= bus_req_i.data; @@ -169,7 +169,7 @@ begin bus_rsp_o.data(ctrl_error_wr_c) <= engine.err_wr; bus_rsp_o.data(ctrl_busy_c) <= engine.busy; bus_rsp_o.data(ctrl_done_c) <= config.done; - bus_rsp_o.data(ctrl_firq_mask_msb_c downto ctrl_firq_mask_lsb_c) <= config.firq_mask; + bus_rsp_o.data(ctrl_firq_sel_msb_c downto ctrl_firq_sel_lsb_c) <= config.firq_sel; when "01" => -- address of last read access bus_rsp_o.data <= engine.src_addr; when "10" => -- address of last write access @@ -205,8 +205,8 @@ begin end if; end process automatic_trigger; - -- logical OR of all enabled trigger FIRQs -- - match <= or_reduce_f(firq_buf and config.firq_mask); + -- select a single FIRQ -- + match <= firq_buf(to_integer(unsigned(config.firq_sel))); -- Bus Access Engine ---------------------------------------------------------------------- diff --git a/sw/lib/include/neorv32_dma.h b/sw/lib/include/neorv32_dma.h index cdb4bfa6d..f02e17a80 100644 --- a/sw/lib/include/neorv32_dma.h +++ b/sw/lib/include/neorv32_dma.h @@ -60,17 +60,17 @@ typedef volatile struct __attribute__((packed,aligned(4))) { /** DMA control and status register bits */ enum NEORV32_DMA_CTRL_enum { - DMA_CTRL_EN = 0, /**< DMA control register(0) (r/w): DMA enable */ - DMA_CTRL_AUTO = 1, /**< DMA control register(1) (r/w): Automatic trigger mode enable */ - DMA_CTRL_FENCE = 2, /**< DMA control register(2) (r/w): Issue FENCE downstream operation when DMA transfer is completed */ + DMA_CTRL_EN = 0, /**< DMA control register(0) (r/w): DMA enable */ + DMA_CTRL_AUTO = 1, /**< DMA control register(1) (r/w): Automatic trigger mode enable */ + DMA_CTRL_FENCE = 2, /**< DMA control register(2) (r/w): Issue FENCE downstream operation when DMA transfer is completed */ - DMA_CTRL_ERROR_RD = 8, /**< DMA control register(8) (r/-): Error during read access; SRC_BASE shows the faulting address */ - DMA_CTRL_ERROR_WR = 9, /**< DMA control register(9) (r/-): Error during write access; DST_BASE shows the faulting address */ - DMA_CTRL_BUSY = 10, /**< DMA control register(10) (r/-): DMA busy / transfer in progress */ - DMA_CTRL_DONE = 11, /**< DMA control register(11) (r/c): A transfer was executed when set */ + DMA_CTRL_ERROR_RD = 8, /**< DMA control register(8) (r/-): Error during read access; SRC_BASE shows the faulting address */ + DMA_CTRL_ERROR_WR = 9, /**< DMA control register(9) (r/-): Error during write access; DST_BASE shows the faulting address */ + DMA_CTRL_BUSY = 10, /**< DMA control register(10) (r/-): DMA busy / transfer in progress */ + DMA_CTRL_DONE = 11, /**< DMA control register(11) (r/c): A transfer was executed when set */ - DMA_CTRL_FIRQ_MASK_LSB = 16, /**< DMA control register(16) (r/w): FIRQ trigger mask LSB */ - DMA_CTRL_FIRQ_MASK_MSB = 31 /**< DMA control register(31) (r/w): FIRQ trigger mask MSB */ + DMA_CTRL_FIRQ_SEL_LSB = 16, /**< DMA control register(16) (r/w): FIRQ trigger select LSB */ + DMA_CTRL_FIRQ_SEL_MSB = 19 /**< DMA control register(19) (r/w): FIRQ trigger select MSB */ }; /** DMA transfer type bits */ @@ -127,7 +127,7 @@ void neorv32_dma_disable(void); void neorv32_dma_fence_enable(void); void neorv32_dma_fence_disable(void); void neorv32_dma_transfer(uint32_t base_src, uint32_t base_dst, uint32_t num, uint32_t config); -void neorv32_dma_transfer_auto(uint32_t base_src, uint32_t base_dst, uint32_t num, uint32_t config, uint32_t firq_mask); +void neorv32_dma_transfer_auto(uint32_t base_src, uint32_t base_dst, uint32_t num, uint32_t config, int firq_sel); int neorv32_dma_status(void); int neorv32_dma_done(void); /**@}*/ diff --git a/sw/lib/source/neorv32_dma.c b/sw/lib/source/neorv32_dma.c index 67e900483..f2dcaa76e 100644 --- a/sw/lib/source/neorv32_dma.c +++ b/sw/lib/source/neorv32_dma.c @@ -121,14 +121,14 @@ void neorv32_dma_transfer(uint32_t base_src, uint32_t base_dst, uint32_t num, ui * @param[in] base_dst Destination base address (has to be aligned to destination data type!). * @param[in] num Number of elements to transfer (24-bit). * @param[in] config Transfer type configuration/commands. - * @param[in] firq_mask FIRQ trigger mask (#NEORV32_CSR_MIP_enum). + * @param[in] firq_sel FIRQ trigger select (#NEORV32_CSR_MIP_enum); only FIRQ0..FIRQ15 = 16..31. **************************************************************************/ -void neorv32_dma_transfer_auto(uint32_t base_src, uint32_t base_dst, uint32_t num, uint32_t config, uint32_t firq_mask) { +void neorv32_dma_transfer_auto(uint32_t base_src, uint32_t base_dst, uint32_t num, uint32_t config, int firq_sel) { uint32_t tmp = NEORV32_DMA->CTRL; tmp |= (uint32_t)(1 << DMA_CTRL_AUTO); // automatic transfer trigger - tmp &= 0x0000ffffUL; // clear current FIRQ mask - tmp |= firq_mask & 0xffff0000UL; // set new FIRQ mask + tmp &= ~(0xf << DMA_CTRL_FIRQ_SEL_LSB); // clear current FIRQ select + tmp |= (uint32_t)((firq_sel & 0xf) << DMA_CTRL_FIRQ_SEL_LSB); // set new FIRQ select NEORV32_DMA->CTRL = tmp; NEORV32_DMA->SRC_BASE = base_src; diff --git a/sw/svd/neorv32.svd b/sw/svd/neorv32.svd index 922897767..7431ce9b1 100644 --- a/sw/svd/neorv32.svd +++ b/sw/svd/neorv32.svd @@ -422,9 +422,9 @@ DMA transfer done; auto-clears on write access - DMA_CTRL_FIRQ_MASK - [31:16] - FIRQ trigger mask + DMA_CTRL_FIRQ_SEL + [19:16] + FIRQ trigger select From 9b473174400b39d3e7ad351d5136c3be32acc831 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:19:04 +0200 Subject: [PATCH 3/6] [changelog] add v1.9.8.4 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72b877431..aa7e409f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12 | Date | Version | Comment | Link | |:----:|:-------:|:--------|:----:| +| 16.04.2024 | 1.9.8.4 | :warning: use a 4-bit FIRQ select instead of a 16-bit FIRQ mask for DMA auto-trigger configuration | [#877](https://github.com/stnolting/neorv32/pull/877) | | 15.04.2024 | 1.9.8.3 | :warning: simplify XBUS gateway logic and configuration generics; only "pipelined Wishbone" protocol is supported now | [#876](https://github.com/stnolting/neorv32/pull/876) | | 14.04.2024 | 1.9.8.2 | :warning: rename SLINK data interface registers; minor CPU control logic/area optimizations | [#874](https://github.com/stnolting/neorv32/pull/874) | | 13.04.2024 | 1.9.8.1 | minor rtl code cleanups and optimizations | [#872](https://github.com/stnolting/neorv32/pull/872) | From 65a9a1ca4dbc6302434441f5777ece19a29a19e3 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:30:24 +0200 Subject: [PATCH 4/6] [sw] update DMA example program --- sw/example/demo_dma/main.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/sw/example/demo_dma/main.c b/sw/example/demo_dma/main.c index 8556efb8d..94c90fe9b 100644 --- a/sw/example/demo_dma/main.c +++ b/sw/example/demo_dma/main.c @@ -155,6 +155,9 @@ int main() { (dma_dst[3] != 0xffee1100)) { neorv32_uart0_printf("Incorrect DST data!\n"); } + else { + neorv32_uart0_printf("Transfer succeeded!\n"); + } show_arrays(); @@ -199,6 +202,9 @@ int main() { (dma_dst[3] != 0x66778899)) { neorv32_uart0_printf("Incorrect DST data!\n"); } + else { + neorv32_uart0_printf("Transfer succeeded!\n"); + } show_arrays(); @@ -236,6 +242,9 @@ int main() { (dma_dst[3] != 0x00000066)) { neorv32_uart0_printf("Transfer failed!\n"); } + else { + neorv32_uart0_printf("Transfer succeeded!\n"); + } show_arrays(); @@ -262,11 +271,11 @@ int main() { DMA_CMD_DST_INC; // auto-increment destination address // configure automatic DMA transfer - neorv32_dma_transfer_auto((uint32_t)(&dma_src[3]), // source array base address (data = 0xff) - (uint32_t)(&dma_dst[0]), // destination array base address - 16, // number of elements to transfer: 16 - cmd, // transfer type configuration - 1 << GPTMR_FIRQ_PENDING); // trigger transfer on pending GPTMR interrupt + neorv32_dma_transfer_auto((uint32_t)(&dma_src[3]), // source array base address (data = 0xff) + (uint32_t)(&dma_dst[0]), // destination array base address + 16, // number of elements to transfer: 16 + cmd, // transfer type configuration + GPTMR_FIRQ_PENDING); // trigger transfer on pending GPTMR interrupt // sleep until interrupt (from DMA) neorv32_cpu_sleep(); @@ -281,6 +290,9 @@ int main() { (dma_dst[3] != 0xffffffff)) { neorv32_uart0_printf("Transfer failed!\n"); } + else { + neorv32_uart0_printf("Transfer succeeded!\n"); + } show_arrays(); } From fd59f246e4d8b11946c1e3bedfe0f0c9a98ed391 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:45:24 +0200 Subject: [PATCH 5/6] [sw] remove whitespaces --- sw/lib/source/neorv32_dma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sw/lib/source/neorv32_dma.c b/sw/lib/source/neorv32_dma.c index f2dcaa76e..f747c31c8 100644 --- a/sw/lib/source/neorv32_dma.c +++ b/sw/lib/source/neorv32_dma.c @@ -175,5 +175,4 @@ int neorv32_dma_done(void) { else { return 0; // no transfer executed } - } From 5dc46386914f52923e0de323717a2b74378e3dad Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Tue, 16 Apr 2024 21:48:10 +0200 Subject: [PATCH 6/6] [docs] update DMA auto-trigger section --- docs/datasheet/soc_dma.adoc | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/docs/datasheet/soc_dma.adoc b/docs/datasheet/soc_dma.adoc index b85052345..1ab388c26 100644 --- a/docs/datasheet/soc_dma.adoc +++ b/docs/datasheet/soc_dma.adoc @@ -5,12 +5,12 @@ [cols="<3,<3,<4"] [frame="topbot",grid="none"] |======================= -| Hardware source file(s): | neorv32_dma.vhd | -| Software driver file(s): | neorv32_dma.c | -| | neorv32_dma.h | -| Top entity port: | none | -| Configuration generics: | `IO_DMA_EN` | implement DMA when `true` -| CPU interrupts: | fast IRQ channel 10 | DMA transfer done (see <<_processor_interrupts>>) +| Hardware source files: | neorv32_dma.vhd | +| Software driver files: | neorv32_dma.c | +| | neorv32_dma.h | +| Top entity ports: | none | +| Configuration generics: | `IO_DMA_EN` | implement DMA when `true` +| CPU interrupts: | fast IRQ channel 10 | DMA transfer done (see <<_processor_interrupts>>) |======================= @@ -98,19 +98,18 @@ data quantity has to be set to **word** (32-bit) since all IO registers can only **Automatic Trigger** As an alternative to the manual trigger mode, the DMA can be configured to **automatic trigger mode** starting a pre-configured -transfer if a specific processor-internal peripheral issues an interrupt request. The automatic trigger mode is enabled by +transfer if a specific processor-internal peripheral issues a FIRQ interrupt request. The automatic trigger mode is enabled by setting the `CTRL` register's `DMA_CTRL_AUTO` bit. In this configuration _no_ transfer is started when writing to the DMA's `TTYPE` register. -The actual trigger is configured via the control register `DMA_CTRL_FIRQ_MASK`. These bits reflect the state of the CPU's -<<_mip>> CSR showing any pending fast interrupt requests (for a full list see <<_neorv32_specific_fast_interrupt_requests>>). -The same bit definitions/locations as for the <<_mip>> and <<_mie>> CPU CSRs are used. -If any of the enabled sources issues an interrupt the DMA will start the pre-configured transfer (note that all enabled -sources are logically OR-ed). +The actually triggering FIRQ channel is configured via the control register's `DMA_CTRL_FIRQ_SEL` bits. Writing a 0 will +select FIRQ channel 0, writing a 1 will select FIRQ channel 1, and so on. See section <<_processor_interrupts>> +for a list of all FIRQ channels and their according sources. .FIRQ Trigger [NOTE] -The DMA transfer will start if a **rising edge** is detected on _any_ of the enabled FIRQ source channels. +The DMA transfer will start if a **rising edge** is detected on the configured FIRQ channel. Hence, the DMA is triggered only +once even if the selected FIRQ channel keeps pending. **Memory Barrier / Fence Operation** @@ -135,16 +134,17 @@ register). [options="header",grid="all"] |======================= | Address | Name [C] | Bit(s), Name [C] | R/W | Function -.10+<| `0xffffed00` .10+<| `CTRL` <|`0` `DMA_CTRL_EN` ^| r/w <| DMA module enable - <|`1` `DMA_CTRL_AUTO` ^| r/w <| Enable automatic mode (FIRQ-triggered) - <|`2` `DMA_CTRL_FENCE` ^| r/w <| Issue a downstream FENCE operation when DMA transfer completes (without errors) - <|`7:3` _reserved_ ^| r/- <| reserved, read as zero - <|`8` `DMA_CTRL_ERROR_RD` ^| r/- <| Error during read access, clears when starting a new transfer - <|`9` `DMA_CTRL_ERROR_WR` ^| r/- <| Error during write access, clears when starting a new transfer - <|`10` `DMA_CTRL_BUSY` ^| r/- <| DMA transfer in progress - <|`11` `DMA_CTRL_DONE` ^| r/c <| Set if a transfer was executed; auto-clears on write-access - <|`15:12` _reserved_ ^| r/- <| reserved, read as zero - <|`31:16` `DMA_CTRL_FIRQ_MASK_MSB : DMA_CTRL_FIRQ_MASK_LSB` ^| r/w <| FIRQ trigger mask (same bits as in <<_mip>>) +.11+<| `0xffffed00` .11+<| `CTRL` <|`0` `DMA_CTRL_EN` ^| r/w <| DMA module enable + <|`1` `DMA_CTRL_AUTO` ^| r/w <| Enable automatic mode (FIRQ-triggered) + <|`2` `DMA_CTRL_FENCE` ^| r/w <| Issue a downstream FENCE operation when DMA transfer completes (without errors) + <|`7:3` _reserved_ ^| r/- <| reserved, read as zero + <|`8` `DMA_CTRL_ERROR_RD` ^| r/- <| Error during read access, clears when starting a new transfer + <|`9` `DMA_CTRL_ERROR_WR` ^| r/- <| Error during write access, clears when starting a new transfer + <|`10` `DMA_CTRL_BUSY` ^| r/- <| DMA transfer in progress + <|`11` `DMA_CTRL_DONE` ^| r/c <| Set if a transfer was executed; auto-clears on write-access + <|`15:12` _reserved_ ^| r/- <| reserved, read as zero + <|`19:16` `DMA_CTRL_FIRQ_SEL_MSB : DMA_CTRL_FIRQ_SEL_LSB` ^| r/w <| FIRQ trigger select (FIRQ0=0 ... FIRQ15=15) + <|`31:20` _reserved_ ^| r/- <| reserved, read as zero | `0xffffed04` | `SRC_BASE` |`31:0` | r/w | Source base address (shows the last-accessed source address when read) | `0xffffed08` | `DST_BASE` |`31:0` | r/w | Destination base address (shows the last-accessed destination address when read) .6+<| `0xffffed0c` .6+<| `TTYPE` <|`23:0` `DMA_TTYPE_NUM_MSB : DMA_TTYPE_NUM_LSB` ^| r/w <| Number of elements to transfer (shows the last-transferred element index when read)