Programming Flow for Shadow-Register-Based Multi-Block Transfer
- Software reads the DMAC channel enable register (DMAC_ChEnReg) to select an available (unused) channel.
- Software programs the CHx_CFG register with appropriate values for the DMA transfer.The SRC_MLTBLK_TYPE and/or DST_MLTBLK_TYPE bits must be set to 2’b10.
Note:
The CHx_CFG register must be programmed before programming the CHx_SAR, CHx_DAR, CHx_BLOCK_TS, or CHx_CTL registers, as the value of the SRC_MLTBLK_TYPE and/or DST_MLTBLK_TYPE fields are used for accessing the shadow registers.
If the slave interface data bus width or transfer size is less than 64 bits, CHx_CFG[7:0] should be updated in the first write to the CHx_CFG register. - Software programs the CHx_SAR and/or CHx_DAR, CHx_BLOCK_TS, and CHx_CTL registers with appropriate values for the first block.
DW_axi_dmac loads the corresponding shadow registers with these values.
The CHx_CTL register must be the last register to be programmed with the ShadowReg_Or_LLI_Valid bit set to 1 to indicate that the shadow register contents are valid. If the slave interface data bus width or transfer size is less than 64 bits, CHx_CTL[63:56] must be updated last. - Software enables the channel by writing 1 to the appropriate bit location in the DMAC_ChEnReg register.
Note:It is possible to swap the sequence of step 3 and step 4. However, if step 4 is performed before step 3, DW_axi_dmac might generate a
ShadowReg_Or_LLI_Invalid_ERR interrupt if the value of the ShadowReg_Or_LLI_Valid bit is 0 during the shadow register fetch phase. - DW_axi_dmac initiates the DMA block transfer operation based on the settings for the block transfer.
a. The block transfer might start immediately or after the hardware or software handshaking request, depending on the value of the TT_FC field in the CHx_CFG register.
b. DW_axi_dmac checks CHx_CTL_ShadowReg.ShadowReg_Or_LLI_Valid bit and if it is seen as ‘0’, DW_axi_dmac waits till software writes (any value) to CHx_BLK_TFR_ResumeReqReg to indicate valid LLI availability, before attempting another Shadow Register fetch operation. DW_axi_dmac might generate ‘ShadowReg_Or_LLI_Invalid_ERR’ Interrupt in this case.
c. DW_axi_dmac checks CHx_CTL_ShadowReg.ShadowReg_Or_LLI_Valid bit and if it is seen as ‘1,’ DW_axi_dmac copies the shadow register contents to the registers used for executing the DMA block transfer (CHx_SAR and/or CHx_DAR, CHx_BLOCK_TS and CHx_CTL registers) and clears the ShadowReg_Or_LLI_Valid bit in CHx_CTL and CHx_CTL_ShadowReg registers to 0.
i. If DW_axi_dmac sees CHx_CTL.ShadowReg_Or_LLI_Last bit of the copied Shadow Register as 1, it understands that the current block is the final block in the transfer and completes the DMA transfer operation at the end of current block transfer.
ii. If DW_axi_dmac sees CHx_CTL.ShadowReg_Or_LLI_Last bit of the copied Shadow Register as 0, it understands that there are one or more blocks to be transferred and checks CHx_CTL_ShadowReg.ShadowReg_Or_LLI_Valid bit again at the end of current block transfer. - Software polls the ShadowReg_Or_LLI_Valid bit in the CHx_CTL register till it is 0.
a. DW_axi_dmac clears this bit to 0 only after copying the shadow register contents to the registers used for executing the DMA block transfer (that is, the CHx_SAR and/or CHx_DAR, CHx_BLOCK_TS, and CHx_CTL registers).
b. Software must program the shadow registers with a new set of values only after the ShadowReg_Or_LLI_Valid bit is set to 0.
c. If software tries to programs the shadow registers when the ShadowReg_Or_LLI_Valid bit is set to 1, DW_axi_dmac ignores this write operation, sets the SLVIF_ShadowReg_WrOnValid_ERR bit of the CHx_IntStatusReg register to 1, and generates an interrupt (if the corresponding interrupt generation is not masked off). - Software programs the CHx_SAR and/or CHx_DAR, CHx_BLOCK_TS, and CHx_CTL registers with appropriate values for the next block.
a. The CHx_CTL register must be the last register to be programmed with the ShadowReg_Or_LLI_Valid bit set to 1 to indicate that the shadow register contents are valid.
b. If current block is the final block in the transfer, S/W must set CHx_CTL.ShadowReg_Or_LLI_Last bit to 1.
c. The DMA block transfer corresponding to the previous shadow register contents may be in progress during this time.
d. DW_axi_dmac loads the corresponding shadow registers with these new values. - DW_axi_dmac initiates the DMA block transfer operation based on the settings for the block transfer.
a. Based on the settings of TT_FC field in CHx_CFG register, the block transfer might start immediately or after the hardware/software handshaking request.
b. DW_axi_dmac checks CHx_CTL_ShadowReg.ShadowReg_Or_LLI_Valid bit and if it is seen as 0,DW_axi_dmac waits until software writes (any value) to CHx_BLK_TFR_ResumeReqReg to indicate valid LLI availability, before attempting another Shadow Register fetch operation. DW_axi_dmac might generate ShadowReg_Or_LLI_Invalid_ERR Interrupt in this case.
c. DW_axi_dmac checks CHx_CTL_ShadowReg.ShadowReg_Or_LLI_Valid bit and if it is seen as 1,DW_axi_dmac copies the shadow register contents to the registers used for executing the DMA block transfer (CHx_SAR and/or CHx_DAR, CHx_BLOCK_TS and CHx_CTL registers) and clears the ShadowReg_Or_LLI_Valid bit in CHx_CTL and CHx_CTL_ShadowReg registers to 0.
d. If DW_axi_dmac sees CHx_CTL.ShadowReg_Or_LLI_Last bit of the copied Shadow Register as 1,it understands that the current block is the final block in the transfer and completes the DMA transfer operation at the end of current block transfer.
e. If DW_axi_dmac sees CHx_CTL.ShadowReg_Or_LLI_Last bit of the copied Shadow Register as 0,it understands that there are one or more blocks to be transferred and checks CHx_CTL_ShadowReg.ShadowReg_Or_LLI_Valid bit again at the end of current block transfer. - Software waits for the block transfer completion interrupt or polls the block transfer completion indication bit (BLOCK_TFR_DONE) of the CHx_IntStatusReg register until it is set to 1.
- On block transfer completion:
a. DW_axi_dmac checks CHx_CTL_ShadowReg.ShadowReg_Or_LLI_Valid bit and if it is seen as 0,DW_axi_dmac waits until software writes (any value) to CHx_BLK_TFR_ResumeReqReg toindicate valid LLI availability, before attempting another Shadow Register fetch operation.DW_axi_dmac might generate a ShadowReg_Or_LLI_Invalid_ERR Interrupt in this case.
b. DW_axi_dmac checks CHx_CTL_ShadowReg.ShadowReg_Or_LLI_Valid bit and if it is seen as 1,DW_axi_dmac copies the shadow register contents to the registers used for executing the DMA block transfer (CHx_SAR and/or CHx_DAR, CHx_BLOCK_TS and CHx_CTL registers) and clears ShadowReg_Or_LLI_Valid bit in CHx_CTL and CHx_CTL_ShadowReg registers to 0.
■ If CHx_CTL.ShadowReg_Or_LLI_Last bit of the copied Shadow Register is 1, it understands that the current block is the final block in the transfer and completes the DMA transfer operation.
■ If CHx_CTL.ShadowReg_Or_LLI_Last bit of the copied Shadow Register is 0, it understands that there are one or more blocks to be transferred and checks CHx_CTL_ShadowReg.ShadowReg_Or_LLI_Valid bit again at the end of current block transfer.
c. If there are one or more blocks to be transferred, software polls CHx_CTL.ShadowReg_Or_LLI_Valid bit until it is seen as 0 and go to step 7. One read operation is enough as DW_axi_dmac should have already copied the shadow register contents and cleared this bit to 0.
Note: In case when ShadowReg_Or_LLI_Invalid_ERR is generated the recommended flow to resume transfer is:
■ Software programs CHx_SAR and/or CHx_DAR, CHx_BLOCK_TS and CHx_CTL registers with appropriate values for the next block.
■ Clear the interrupt using interrupt register CHx_IntClearReg.
■ Program block resume request CHx_BLK_TFR_ResumeReqReg.
基于DMA单channel 的shadow reg传输:
DMAC 寄存器配置:
apb_write('h10,'h3) ;//dmac_cfg reg enable dmac_en,int_en
apb_write('h40,'h1FFFFF);//dmac_commonreg_intstatus_enablereg
apb_write('h48,'h1FFFFF);//dmac_commonreg_intsignal_enablereg
apb_write('h124,'h7f8e0018);//CH1_CFG2
apb_write('h120,'ha);//CHX_CFG shadow reg
apb_write('h100,'h10000000);//ch1_SAR
apb_write('h108,'h20000000);//ch1_DAR
apb_write('h110,'fff);//CH1_block_ts 8K
apb_write('h118,'h1ded00);//ch1_ctl
apb_write('h11c,'h80000000);//最后影子寄存器/LLI有效。
apb_write('h180,'hffffffff);//intstatus_enable reg
apb_write('h184,'hffffffff);//int status enable reg2
apb_write('h190,'hffffffff);//int signal enable reg
apb_write('h194,'hffffffff);//int signal enable reg2
apb_write('h18,'h101);//dmac ch en reg
apb_write('h148,'h1);//transfer resume 传输恢复请求
shadow 寄存器配置
apb_write('h100,'h30000000);//ch1_SAR
apb_write('h108,'h40000000);//ch1_DAR
apb_write('h110,'fff);//CH1_block_ts 8K
apb_write('h118,'h1ded00);//ch1_ctl
apb_write('h11c,'h80000000);//最后影子寄存器/LLI有效。
apb_write('h148,'h1);//transfer resume 传输恢复请求
TS start:
apb_write('h148,'h1);//transfer resume 传输恢复请求
apb_write('h198,'hffffffff);//clear shadow reg or lli or invalid_err_instart
apb_write('h100,'h50000000);//ch1_SAR
apb_write('h108,'h60000000);//ch1_DAR
apb_write('h110,'fff);//CH1_block_ts 8K
apb_write('h118,'h1ded00);//ch1_ctl
apb_write('h11c,'hc0000000);//最后影子寄存器/LLI有效且是最后一个影子寄存器。如果这个位是1,DW_axi_dmac理解当前块是dma传输中的最后一个块,并在与当前块对应的AMBA传输完成后结束dma传输。
apb_write('h148,'h1);//transfer resume 传输恢复请求
部分databook说明
apb_write('h10,'h3) ;//dmac_cfg reg enable dmac_en,int_en
apb_write('h40,'h1FFFFF);//dmac_commonreg_intstatus_enablereg![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/fbcdf36197dd25b5d9b7c8352192fa7a.png)
apb_write('h48,'h1FFFFF);//dmac_commonreg_intsignal_enablereg![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0f1868eb864f02934c20375c2cc7622a.png)
apb_write('h120,'ha);//CHX_CFG shadow reg
apb_write('h124,'h7f8e0018);//CH1_CFG2
apb_write('h100,'h10000000);//ch1_SAR
apb_write('h108,'h20000000);//ch1_DAR
apb_write('h118,'h1ded00);//ch1_ctl
apb_write('h11c,'h80000000);//最后影子寄存器/LLI有效。