/******************************************************************************* * 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 2021-2022 Renesas Electronics Corporation All rights reserved. *******************************************************************************/ /******************************************************************************* * DESCRIPTION : DMA driver ******************************************************************************/ /****************************************************************************** * @file dma.c * - Version : 0.07 * @brief DMA driver. * . *****************************************************************************/ /****************************************************************************** * History : DD.MM.YYYY Version Description * : 28.07.2021 0.01 First Release * : 30.09.2021 0.02 Change function name load_start and * load_end function. * : 15.10.2021 0.03 modified to not use CHCLR. * : 06.01.2022 0.04 Add exception handling for ICUMX_WDTA. * : 02.02.2022 0.05 Add MFIS Lock/Unlock. * : 22.06.2022 0.06 Replace address align check to function. * : Remove some defines. * : 20.12.2022 0.07 Add mask when writing to TCR register. *****************************************************************************/ #include #include #include #include #include #include #include #define DMOR_INIT (uint16_t)(0x0301U) #define DMOR_HW_INIT (uint16_t)(0x0000U) #define TCR_CNT_SHIFT (6U) #define TCR_UPPER8BIT_MASK (0x00FFFFFFU) #define CHCR_TRN_MODE (0x00105409U) #define CHCR_TE_BIT (0x00000002U) #define TE_FLAG (0x00000000U) #define CHCR_CAE_BIT (0x80000000U) #define CHCR_CAE_BIT_NOERROR (0x00000000U) #define CHCR_CAIE_BIT (0x40000000U) #define CHCR_DPM_BIT (0x30000000U) #define CHCR_RPT_BIT (0x0F000000U) #define CHCR_WAIT_BIT (0x00800000U) #define CHCR_DPB_BIT (0x00400000U) #define CHCR_DSE_BIT (0x00080000U) #define CHCR_DSIE_BIT (0x00040000U) #define CHCR_DM_BIT (0x0000C000U) #define CHCR_SM_BIT (0x00003000U) #define CHCR_RS_BIT (0x00000F00U) #define CHCR_TS_BIT (0x00300018U) #define CHCR_IE_BIT (0x00000004U) #define CHCR_TE_BIT (0x00000002U) #define CHCR_DE_BIT (0x00000001U) #define CHCR_CONF_MASK (CHCR_TS_BIT | CHCR_DM_BIT | CHCR_SM_BIT | CHCR_RS_BIT | CHCR_DE_BIT) #define CHCR_DESCRIPTOR_CONF_MASK (CHCR_DPM_BIT | CHCR_RPT_BIT | CHCR_WAIT_BIT | CHCR_DPB_BIT) #define CHCR_INTERRUPT_MASK (CHCR_CAIE_BIT | CHCR_DSIE_BIT | CHCR_IE_BIT) #define CHCR_FLAG_MASK (CHCR_CAE_BIT | CHCR_DSE_BIT | CHCR_TE_BIT) #define CHCR_ALL_BIT_MASK (CHCR_CONF_MASK | CHCR_DESCRIPTOR_CONF_MASK | CHCR_INTERRUPT_MASK | CHCR_FLAG_MASK) #define DAR_HW_INIT (0x00000000U) #define SAR_HW_INIT (0x00000000U) #define TCR_HW_INIT (0x00000000U) /* fraction mask for 256-byte units */ #define FRACTION_MASK_256_BYTE (0x000000FFU) void dma_init(void) { uint32_t reg; /* DMA operation */ mem_write16(RTDMA_DMOR, DMOR_INIT); /* DMA secure control register */ reg = mem_read32(RTDMA_DMSEC); reg |= ((uint32_t)1U << DMACH); mem_write32(RTDMA_DMSEC, reg); reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH)); reg &= ~(CHCR_ALL_BIT_MASK); mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg); } /* End of function dma_init(void) */ void dma_trans_start(uint32_t dst, uint32_t src, uint32_t len) { uint32_t reg; /* dst and src must be 64-byte boundary. */ dma_address_align_check(dst, src); /* round up 256 byte alignment */ len += FRACTION_MASK_256_BYTE; len &= (~(uint32_t)(FRACTION_MASK_256_BYTE)); /* DMA destination address */ mem_write32(dma_get_rtdma_dar_addr(DMACH), dst); /* DMA source address */ mem_write32(dma_get_rtdma_sar_addr(DMACH), src); /* DMA 64bytes-unit transfer count */ mem_write32(dma_get_rtdma_tcr_addr(DMACH), ((len >> TCR_CNT_SHIFT) & TCR_UPPER8BIT_MASK)); /* Lock to avoid conflict with RPC */ mfis_lock(); /* DMA channel control */ reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH)); reg |= CHCR_TRN_MODE; mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg); } /* End of function dma_trans_start(uint32_t dst, uint32_t src, uint32_t len) */ void dma_trans_end_check(void) { uint32_t reg; /* Check end of DMA transfer. */ do { wdt_restart(); reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH)); /* Check error of DMA transfer */ if ((reg & CHCR_CAE_BIT) != CHCR_CAE_BIT_NOERROR) { ERROR("DMA - Channel Address Error\n"); panic; } } while ((reg & CHCR_TE_BIT) == TE_FLAG); reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH)); reg &= ~(CHCR_ALL_BIT_MASK); mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg); rpc_end_state_check(); /* Unlock to avoid conflict with RPC */ mfis_unlock(); } /* End of function dma_trans_end_check(void) */ void dma_release(void) { uint32_t reg; /* DMA channel control */ reg = mem_read32(dma_get_rtdma_chcr_addr(DMACH)); reg &= ~(CHCR_ALL_BIT_MASK); mem_write32(dma_get_rtdma_chcr_addr(DMACH), reg); /* DMA destination address */ mem_write32(dma_get_rtdma_dar_addr(DMACH), DAR_HW_INIT); /* DMA source address */ mem_write32(dma_get_rtdma_sar_addr(DMACH), SAR_HW_INIT); /* DMA 64bytes-unit transfer count */ mem_write32(dma_get_rtdma_tcr_addr(DMACH), TCR_HW_INIT); reg = mem_read32(RTDMA_DMSEC); reg &= (~((uint32_t)1U << DMACH)); mem_write32(RTDMA_DMSEC, reg); /* DMA operation */ mem_write16(RTDMA_DMOR, DMOR_HW_INIT); } /* End of function dma_release(void) */