mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 14:17:51 -04:00
[DMA] add done flag to control register
This commit is contained in:
parent
0f7852b35d
commit
af5060dc0f
5 changed files with 33 additions and 2 deletions
|
@ -74,6 +74,7 @@ architecture neorv32_dma_rtl of neorv32_dma is
|
|||
constant ctrl_error_rd_c : natural := 8; -- r/-: error during read transfer
|
||||
constant ctrl_error_wr_c : natural := 9; -- r/-: error during write transfer
|
||||
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
|
||||
|
@ -97,6 +98,7 @@ architecture neorv32_dma_rtl of neorv32_dma is
|
|||
dst_inc : std_ulogic; -- constant (0) or incrementing (1) destination address
|
||||
endian : std_ulogic; -- convert endianness when set
|
||||
start : std_ulogic; -- transfer start trigger
|
||||
done : std_ulogic; -- transfer was executed (but might have failed)
|
||||
end record;
|
||||
signal config : config_t;
|
||||
|
||||
|
@ -146,12 +148,15 @@ begin
|
|||
config.dst_inc <= '0';
|
||||
config.endian <= '0';
|
||||
config.start <= '0';
|
||||
config.done <= '0';
|
||||
elsif rising_edge(clk_i) then
|
||||
config.start <= '0'; -- default
|
||||
config.done <= config.enable and (config.done or engine.done); -- set if enabled and transfer done
|
||||
if (bus_req_i.stb = '1') and (bus_req_i.rw = '1') then
|
||||
if (bus_req_i.addr(3 downto 2) = "00") then -- control and status register
|
||||
config.enable <= bus_req_i.data(ctrl_en_c);
|
||||
config.auto <= bus_req_i.data(ctrl_auto_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);
|
||||
end if;
|
||||
if (bus_req_i.addr(3 downto 2) = "01") then -- source base address
|
||||
|
@ -186,6 +191,7 @@ begin
|
|||
bus_rsp_o.data(ctrl_error_rd_c) <= engine.err_rd;
|
||||
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;
|
||||
when "01" => -- address of last read access
|
||||
bus_rsp_o.data <= engine.src_addr;
|
||||
|
|
|
@ -59,7 +59,7 @@ package neorv32_package is
|
|||
|
||||
-- Architecture Constants -----------------------------------------------------------------
|
||||
-- -------------------------------------------------------------------------------------------
|
||||
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080907"; -- hardware version
|
||||
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01080908"; -- hardware version
|
||||
constant archid_c : natural := 19; -- official RISC-V architecture ID
|
||||
constant XLEN : natural := 32; -- native data path width, do not change!
|
||||
|
||||
|
|
|
@ -59,13 +59,14 @@ typedef volatile struct __attribute__((packed,aligned(4))) {
|
|||
#define NEORV32_DMA ((neorv32_dma_t*) (NEORV32_DMA_BASE))
|
||||
|
||||
/** DMA control and status register bits */
|
||||
enum NEORV32_DMA_QSEL_enum {
|
||||
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_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 */
|
||||
|
@ -125,6 +126,7 @@ void neorv32_dma_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);
|
||||
int neorv32_dma_status(void);
|
||||
int neorv32_dma_done(void);
|
||||
/**@}*/
|
||||
|
||||
|
||||
|
|
|
@ -140,3 +140,21 @@ int neorv32_dma_status(void) {
|
|||
return DMA_STATUS_IDLE; // idle
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************//**
|
||||
* Check if a transfer has actually been executed.
|
||||
*
|
||||
* @return 0 if no transfer was executed, 1 if a transfer has actually been executed.
|
||||
* Use neorv32_dma_status(void) to check if there was an error during that transfer.
|
||||
**************************************************************************/
|
||||
int neorv32_dma_done(void) {
|
||||
|
||||
if (NEORV32_DMA->CTRL & (1 << DMA_CTRL_DONE)) {
|
||||
return 1; // there was a transfer
|
||||
}
|
||||
else {
|
||||
return 0; // no transfer executed
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -389,6 +389,11 @@
|
|||
<access>read-only</access>
|
||||
<description>DMA transfer in progress</description>
|
||||
</field>
|
||||
<field>
|
||||
<name>DMA_CTRL_DONE</name>
|
||||
<bitRange>[11:11]</bitRange>
|
||||
<description>DMA transfer done; auto-clears on write access</description>
|
||||
</field>
|
||||
<field>
|
||||
<name>DMA_CTRL_FIRQ_MASK</name>
|
||||
<bitRange>[31:16]</bitRange>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue