/******************************************************************************* * DISCLAIMER * This software is supplied by Renesas Electronics Corporation and is only * intended for use with Renesas products. No other uses are authorized. This * software is owned by Renesas Electronics Corporation and is protected under * all applicable laws, including copyright laws. * THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING * THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT * LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. * TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS * ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE * FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR * ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * Renesas reserves the right, without notice, to make changes to this software * and to discontinue the availability of this software. By using this software, * you agree to the additional terms and conditions found by accessing the * following link: * http://www.renesas.com/disclaimer * Copyright 2015-2022 Renesas Electronics Corporation All rights reserved. *******************************************************************************/ /******************************************************************************* * DESCRIPTION : DMA driver ******************************************************************************/ /****************************************************************************** * @file dma.c * - Version : 0.05 * @brief RT-DMAC driver. * . *****************************************************************************/ /****************************************************************************** * History : DD.MM.YYYY Version Description * : 15.10.2021 0.01 First Release * : 10.02.2022 0.02 Add dma_start_xbyte function. * : 18.03.2022 0.03 Modify to read modify write when write to * : register. * : 29.03.2022 0.04 Modify magic number to definition. * : 09.11.2022 0.05 License notation change. *****************************************************************************/ #include #include #include #include #include #include #include #include /* * from flash_writer's reg_rcar.h */ /* RT-DMA Control */ #define RTDMACTL_BASE (BASE_RTDMACTL_ADDR) #define RTDMAC_RDMOR (RTDMACTL_BASE + 0x0060U) /* R/W 16 DMA operation register (for channels 0 to 15) */ /* RT-DMAC0(for RPC) */ #define RTDMAC_BASE (BASE_RTDMA0_ADDR) #define RTDMAC_RDMSEC (RTDMAC_BASE + 0x00B0U) /* R/W 32 DMA secure control register (for channels 0 to 15) */ #define RTDMAC_RDMSAR(x) (RTDMAC_BASE + 0x0000U + (0x80U * (x))) /* R/W 32 DMA source address register_0 */ #define RTDMAC_RDMDAR(x) (RTDMAC_BASE + 0x0004U + (0x80U * (x))) /* R/W 32 DMA destination address register_0 */ #define RTDMAC_RDMTCR(x) (RTDMAC_BASE + 0x0008U + (0x80U * (x))) /* R/W 32 DMA transfer count register_0 */ #define RTDMAC_RDMCHCR(x) (RTDMAC_BASE + 0x000CU + (0x80U * (x))) /* R/W 32 DMA channel control register_0 */ #include "dma2.h" #define RDMOR_INITIAL (0x0301U) #define DMACH (0U) #define RDMTCR_CNT_SHIFT (6U) #define RDMCHCR_TRN_MODE (0x00105409U) #define RDMCHCR_TRN_MODE_SRC_FIX (0x00104409U) #define RDMCHCR_TRN_MODE_1BYTE (0x00005401U) #define RDMCHCR_TE_BIT (0x00000002U) #define TE_FLAG (0x00000000U) #define RDMCHCR_CAE_BIT (0x80000000U) #define RDMCHCR_CAE_BIT_NOERROR (0x00000000U) #define RDMCHCR_CAIE_BIT (0x40000000U) #define RDMCHCR_DPM_BIT (0x30000000U) #define RDMCHCR_RPT_BIT (0x0F000000U) #define RDMCHCR_WAIT_BIT (0x00800000U) #define RDMCHCR_DPB_BIT (0x00400000U) #define RDMCHCR_DSE_BIT (0x00080000U) #define RDMCHCR_DSIE_BIT (0x00040000U) #define RDMCHCR_DM_BIT (0x0000C000U) #define RDMCHCR_SM_BIT (0x00003000U) #define RDMCHCR_RS_BIT (0x00000F00U) #define RDMCHCR_TS_BIT (0x00300018U) #define RDMCHCR_IE_BIT (0x00000004U) #define RDMCHCR_TE_BIT (0x00000002U) #define RDMCHCR_DE_BIT (0x00000001U) #define RDMCHCR_CONF_MASK (RDMCHCR_TS_BIT | RDMCHCR_DM_BIT | RDMCHCR_SM_BIT \ | RDMCHCR_RS_BIT | RDMCHCR_DE_BIT) #define RDMCHCR_DESCRIPTOR_CONF_MASK (RDMCHCR_DPM_BIT | RDMCHCR_RPT_BIT | RDMCHCR_WAIT_BIT | RDMCHCR_DPB_BIT) #define RDMCHCR_INTERRUPT_MASK (RDMCHCR_CAIE_BIT | RDMCHCR_DSIE_BIT | RDMCHCR_IE_BIT) #define RDMCHCR_FLAG_MASK (RDMCHCR_CAE_BIT | RDMCHCR_DSE_BIT | RDMCHCR_TE_BIT) #define RDMCHCR_ALL_BIT_MASK (RDMCHCR_CONF_MASK | RDMCHCR_DESCRIPTOR_CONF_MASK \ | RDMCHCR_INTERRUPT_MASK | RDMCHCR_FLAG_MASK) #define CMNSR_TEND (0x00000001U) #define RDMTCR_UPPER_MASK (0xFF000000U) /* fraction mask for 64-byte units */ #define FRACTION_MASK_64_BYTE (0x0000003FU) /* fraction mask for 256-byte units */ #define FRACTION_MASK_256_BYTE (0x000000FFU) void dma2_init(void) { uint32_t reg; /* DMA transfer disabled */ reg = mem_read32(RTDMAC_RDMCHCR(DMACH)); reg &= ~(RDMCHCR_ALL_BIT_MASK); mem_write32(RTDMAC_RDMCHCR(DMACH), reg); /* DMA operation */ mem_write16(RTDMAC_RDMOR, RDMOR_INITIAL); /* DMA secure control register */ reg = mem_read32(RTDMAC_RDMSEC); reg |= ((uint32_t)1U << DMACH); mem_write32(RTDMAC_RDMSEC, reg); } /* End of function dma_init */ void dma2_start(uint32_t dst, uint32_t src, uint32_t len, uint32_t mode) { uint32_t reg; if (((dst & FRACTION_MASK_64_BYTE) != 0U) || ((src & FRACTION_MASK_64_BYTE) != 0U)) { /* dst or src are not 64-bit alignment. */ ERROR("not 64-bit alignment in DMA(2) transfer\n"); while(1) { ; /* panic */ } } /* round up 256 byte alignment */ len += FRACTION_MASK_256_BYTE; len &= (~(uint32_t)(FRACTION_MASK_256_BYTE)); /* DMA destination address */ mem_write32(RTDMAC_RDMDAR(DMACH), dst); /* DMA source address */ mem_write32(RTDMAC_RDMSAR(DMACH), src); /* DMA 64bytes-unit transfer count */ mem_write32(RTDMAC_RDMTCR(DMACH), ((len >> RDMTCR_CNT_SHIFT) & (~RDMTCR_UPPER_MASK))); /* DMA channel control */ reg = mem_read32(RTDMAC_RDMCHCR(DMACH)); if (mode == DMA_MODE_SRC_FIX) { reg |= RDMCHCR_TRN_MODE_SRC_FIX; mem_write32(RTDMAC_RDMCHCR(DMACH), reg); } else { reg |= RDMCHCR_TRN_MODE; mem_write32(RTDMAC_RDMCHCR(DMACH), reg); } } /* End of function dma_start */ void dma2_start_xbyte(uint32_t dst, uint32_t src, uint32_t len, uint32_t trns_unit) { uint32_t reg; /* DMA destination address */ mem_write32(RTDMAC_RDMDAR(DMACH), dst); /* DMA source address */ mem_write32(RTDMAC_RDMSAR(DMACH), src); /* DMA transfer count */ mem_write32(RTDMAC_RDMTCR(DMACH), ((len >> trns_unit) & (~RDMTCR_UPPER_MASK))); /* DMA channel control */ reg = mem_read32(RTDMAC_RDMCHCR(DMACH)); if (trns_unit == TRANS_UNIT_1BYTE) { /* DMA channel control (transfer unit is 1 byte)*/ reg |= RDMCHCR_TRN_MODE_1BYTE; mem_write32(RTDMAC_RDMCHCR(DMACH), reg); } if (trns_unit == TRANS_UNIT_64BYTES) { /* DMA channel control (transfer unit is 64 bytes) */ reg |= RDMCHCR_TRN_MODE; mem_write32(RTDMAC_RDMCHCR(DMACH), reg); } } /* End of function dma_start_byte */ void dma2_end(void) { uint32_t reg; /* Check end of DMA transfer. */ do { wdt_restart(); /* Check error of DMA transfer */ if ((mem_read32(RTDMAC_RDMCHCR(DMACH)) & RDMCHCR_CAE_BIT) != RDMCHCR_CAE_BIT_NOERROR) { ERROR("DMA(2) - Channel Address Error\n"); while(1) { ; /* panic */ } } } while ((mem_read32(RTDMAC_RDMCHCR(DMACH)) & RDMCHCR_TE_BIT) == TE_FLAG); /* DMA transfer disabled */ reg = mem_read32(RTDMAC_RDMCHCR(DMACH)); reg &= ~(RDMCHCR_ALL_BIT_MASK); mem_write32(RTDMAC_RDMCHCR(DMACH), reg); rpc_end_state_check(); } /* End of function dma_end */