123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- /**
- * @file dma.c
- * @author chipsea
- * @brief
- * @version 0.1
- * @date 2020-11-30
- * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
- * @note
- */
- #include <string.h>
- #include "clock.h"
- #include "pwrmgr.h"
- #include "error.h"
- #include "log.h"
- #include "jump_function.h"
- #include "dma.h"
-
- typedef struct{
- bool init_flg;
- DMA_CH_Ctx_t dma_ch_ctx[DMA_CH_NUM];
- }dma_ctx_t;
- dma_ctx_t s_dma_ctx = {
- .init_flg = FALSE,
- };
- static DMA_CONN_e GetSrcConn(uint32_t addr)
- {
- if(addr == (uint32_t)&(AP_SPI0->DataReg))
- return DMA_CONN_SPI0_Rx;
- if(addr == (uint32_t)&(AP_SPI1->DataReg))
- return DMA_CONN_SPI1_Rx;
- if(addr == (uint32_t)&(AP_I2C0->IC_DATA_CMD))
- return DMA_CONN_I2C0_Rx;
- if(addr == (uint32_t)&(AP_I2C1->IC_DATA_CMD))
- return DMA_CONN_I2C1_Rx;
- if(addr == (uint32_t)&(AP_UART0->RBR))
- return DMA_CONN_UART0_Rx;
- if(addr == (uint32_t)&(AP_UART1->RBR))
- return DMA_CONN_UART1_Rx;
- return DMA_CONN_MEM;
- }
- static DMA_CONN_e GetDstConn(uint32_t addr)
- {
- if(addr == (uint32_t)&(AP_SPI0->DataReg))
- return DMA_CONN_SPI0_Tx;
- if(addr == (uint32_t)&(AP_SPI1->DataReg))
- return DMA_CONN_SPI1_Tx;
- if(addr == (uint32_t)&(AP_I2C0->IC_DATA_CMD))
- return DMA_CONN_I2C0_Tx;
- if(addr == (uint32_t)&(AP_I2C1->IC_DATA_CMD))
- return DMA_CONN_I2C1_Tx;
- if(addr == (uint32_t)&(AP_UART0->THR))
- return DMA_CONN_UART0_Tx;
- if(addr == (uint32_t)&(AP_UART1->THR))
- return DMA_CONN_UART1_Tx;
- return DMA_CONN_MEM;
- }
- static void DMAWakeupHandler(void)
- {
- hal_clk_gate_enable(MOD_DMA);
- NVIC_SetPriority((IRQn_Type)DMAC_IRQn, IRQ_PRIO_HAL);
- NVIC_EnableIRQ((IRQn_Type)DMAC_IRQn);
- JUMP_FUNCTION(V19_IRQ_HANDLER) = (uint32_t)&HalDMAIRQHandler;
- AP_DMA_MISC->DmaCfgReg = DMA_DMAC_E;
- }
- int HalDMAInitChannel(HAL_DMA_t cfg)
- {
- DMA_CH_Ctx_t* pctx;
- DMA_CH_t ch;
- if(!s_dma_ctx.init_flg)
- return ERR_NOT_REGISTED;
- ch = cfg.dma_channel;
-
- if(ch >= DMA_CH_NUM)
- return ERR_INVALID_PARAM;
- pctx = &s_dma_ctx.dma_ch_ctx[ch];
- if(pctx ->init_ch)
- return ERR_INVALID_STATE;
- pctx->evt_handler = cfg.evt_handler;
- pctx->init_ch = true;
-
- return SUCCESS;
- }
- int HalDMAConfigChannel(DMA_CH_t ch, DMA_CH_CFG_t* cfg)
- {
- DMA_CH_Ctx_t* pctx;
- DMA_CONN_e src_conn,dst_conn;
- uint32_t cctrl = 0;
- uint32_t transf_type = DMA_TRANSFERTYPE_M2M;
- uint32_t transf_per = 0;
- uint32_t spif_protect = AP_SPIF->wr_protection;
- uint32_t cache_bypass = AP_PCR->CACHE_BYPASS;
- if(!s_dma_ctx.init_flg)
- {
- return ERR_NOT_REGISTED;
- }
- if(ch >= DMA_CH_NUM)
- {
- return ERR_INVALID_PARAM;
- }
- if(cfg->sinc >DMA_INC_NCHG || cfg->dinc >DMA_INC_NCHG)
- {
- return ERR_INVALID_PARAM;
- }
- if(cfg->src_tr_width >DMA_WIDTH_8WORD || cfg->dst_tr_width >DMA_WIDTH_8WORD)
- {
- return ERR_INVALID_PARAM;
- }
- if(cfg->src_msize >DMA_BSIZE_256 || cfg->dst_msize >DMA_BSIZE_256)
- {
- return ERR_INVALID_PARAM;
- }
- pctx = &s_dma_ctx.dma_ch_ctx[ch];
- if(!pctx->init_ch)
- return ERR_INVALID_STATE;
-
- if ((AP_DMA_MISC->ChEnReg & (DMA_DMACEnbldChns_Ch(ch))) || \
- (pctx->xmit_busy)){
- // This channel is enabled, return ERROR, need to release this channel first
- return ERR_BUSY;
- }
- // Reset the Interrupt status
- AP_DMA_INT->ClearTfr = DMA_DMACIntTfrClr_Ch(ch);
- // UnMask interrupt
- AP_DMA_INT->MaskTfr = DMA_DMACCxIntMask_E(ch);
- src_conn = GetSrcConn(cfg->src_addr);
- dst_conn = GetDstConn(cfg->dst_addr);
-
- /* Assign Linker List Item value */
- if(src_conn && dst_conn){
- transf_type = DMA_TRANSFERTYPE_P2P;
- transf_per = DMA_DMACCxConfig_SrcPeripheral(src_conn-1)| \
- DMA_DMACCxConfig_DestPeripheral(dst_conn-1);
-
- }
- else if(src_conn){
- transf_type = DMA_TRANSFERTYPE_P2M;
- transf_per = DMA_DMACCxConfig_SrcPeripheral(src_conn-1);
- }
- else if(dst_conn){
- transf_type = DMA_TRANSFERTYPE_M2P;
- transf_per = DMA_DMACCxConfig_DestPeripheral(dst_conn-1);
- }
- if((cfg->dst_addr > 0x11000000) && (cfg->dst_addr <= 0x11080000))
- {
- pctx->xmit_flash = DMA_DST_XIMT_IS_FLASH;
- if(spif_protect)
- {
- AP_SPIF->wr_protection = 0;
- }
- if(cache_bypass == 0)
- {
- AP_PCR->CACHE_BYPASS = 1;
- }
- }
- else
- {
- pctx->xmit_flash = DMA_DST_XIMT_NOT_FLASH;
- }
- AP_DMA_CH_CFG(ch)->SAR = cfg->src_addr;
- AP_DMA_CH_CFG(ch)->DAR = cfg->dst_addr;
- AP_DMA_CH_CFG(ch)->LLP = 0;
- if(DMA_GET_MAX_TRANSPORT_SIZE(ch) < cfg->transf_size)
- {
- return ERR_INVALID_PARAM;
- }
- AP_DMA_CH_CFG(ch)->CTL_H = DMA_DMACCxControl_TransferSize(cfg->transf_size);
-
- subWriteReg(&(AP_DMA_CH_CFG(ch)->CFG_H),15,7 ,transf_per);
-
- AP_DMA_CH_CFG(ch)->CFG = 0;
-
- cctrl = DMA_DMACCxConfig_TransferType(transf_type)| \
- DMA_DMACCxControl_SMSize(cfg->src_msize)| \
- DMA_DMACCxControl_DMSize(cfg->dst_msize)| \
- DMA_DMACCxControl_SWidth(cfg->src_tr_width)| \
- DMA_DMACCxControl_DWidth(cfg->dst_tr_width)| \
- DMA_DMACCxControl_SInc(cfg->sinc)| \
- DMA_DMACCxControl_DInc(cfg->dinc)| \
- DMA_DMAC_INT_E;
-
- AP_DMA_CH_CFG(ch)->CTL = cctrl;
- if(cfg->enable_int)
- {
- AP_DMA_INT->MaskTfr = DMA_DMACCxConfig_E(ch) | BIT(ch);
- pctx->interrupt = true;
- }
- else
- {
- AP_DMA_INT->ClearTfr = DMA_DMACIntTfrClr_Ch(ch);
- AP_DMA_INT->MaskTfr = DMA_DMACCxIntMask_E(ch);
- pctx->interrupt = false;
- }
-
- return SUCCESS;
- }
- int HalDMAStartChannel(DMA_CH_t ch)
- {
- DMA_CH_Ctx_t* pctx;
-
- if(!s_dma_ctx.init_flg)
- return ERR_NOT_REGISTED;
- if(ch >= DMA_CH_NUM)
- {
- return ERR_INVALID_PARAM;
- }
- pctx = &s_dma_ctx.dma_ch_ctx[ch];
- AP_DMA_MISC->ChEnReg = DMA_DMACCxConfig_E(ch) | BIT(ch);
- pctx->xmit_busy = TRUE;
- hal_pwrmgr_lock(MOD_DMA);
-
- return SUCCESS;
- }
- int HalDMAStopChannel(DMA_CH_t ch)
- {
- uint32_t spif_protect = AP_SPIF->wr_protection;
- uint32_t cache_bypass = AP_PCR->CACHE_BYPASS;
- DMA_CH_Ctx_t* pctx;
- if(!s_dma_ctx.init_flg)
- return ERR_NOT_REGISTED;
- if(ch >= DMA_CH_NUM)
- {
- return ERR_INVALID_PARAM;
- }
- pctx = &s_dma_ctx.dma_ch_ctx[ch];
- if(pctx->xmit_flash == DMA_DST_XIMT_IS_FLASH)
- {
- if(spif_protect)
- {
- AP_SPIF->wr_protection = 2;
- }
- if(cache_bypass == 0)
- {
- AP_PCR->CACHE_BYPASS = 0;
- AP_CACHE->CTRL0 = 0x01;
- }
- }
- // Reset the Interrupt status
- AP_DMA_INT->ClearTfr = DMA_DMACIntTfrClr_Ch(ch);
- // UnMask interrupt
- // AP_DMA_INT->MaskTfr = DMA_DMACCxIntMask_E(ch);
- AP_DMA_MISC->ChEnReg = DMA_DMACCxConfig_E(ch);
- pctx->xmit_busy = FALSE;
- hal_pwrmgr_unlock(MOD_DMA);
- return SUCCESS;
- }
- int HalDMAStatusControl(DMA_CH_t ch)
- {
- DMA_CH_Ctx_t* pctx;
- if(!s_dma_ctx.init_flg)
- return ERR_NOT_REGISTED;
- if(ch >= DMA_CH_NUM)
- {
- return ERR_INVALID_PARAM;
- }
- pctx = &s_dma_ctx.dma_ch_ctx[ch];
- if(pctx->interrupt == false)
- HalDMAWaitChannelComplete(ch);
- return SUCCESS;
- }
- int HalDMAWaitChannelComplete(DMA_CH_t ch)
- {
- uint32_t Temp = 0;
-
- if(!s_dma_ctx.init_flg)
- return ERR_NOT_REGISTED;
-
- if(ch >= DMA_CH_NUM)
- {
- return ERR_INVALID_PARAM;
- }
-
- while(1){
- Temp ++;
- if(AP_DMA_INT->RawTfr)
- {
- break;
- }
- }
- HalDMAStopChannel(ch);
- // LOG("wait count is %d\n",Temp);
-
- return SUCCESS;
- }
- int HalDMAInit(void)
- {
- uint8_t ret;
-
- hal_clk_gate_enable(MOD_DMA);
- hal_clk_reset(MOD_DMA);
- NVIC_SetPriority((IRQn_Type)DMAC_IRQn, IRQ_PRIO_HAL);
- NVIC_EnableIRQ((IRQn_Type)DMAC_IRQn);
- JUMP_FUNCTION(V19_IRQ_HANDLER) = (uint32_t)&HalDMAIRQHandler;
- ret = hal_pwrmgr_register(MOD_DMA,NULL, DMAWakeupHandler);
- if(ret == SUCCESS)
- {
- s_dma_ctx.init_flg = TRUE;
- memset(&(s_dma_ctx.dma_ch_ctx[0]), 0, sizeof(DMA_CH_Ctx_t)*DMA_CH_NUM);
-
- //dmac controller enable
- AP_DMA_MISC->DmaCfgReg = DMA_DMAC_E;
- }
- else
- {
- return ret;
- }
- return SUCCESS;
- }
- int HalDMADeinit(void)
- {
- //dmac controller disable
- AP_DMA_MISC->DmaCfgReg = DMA_DMAC_D;
- s_dma_ctx.init_flg = FALSE;
- memset(&(s_dma_ctx.dma_ch_ctx[0]), 0, sizeof(DMA_CH_Ctx_t)*DMA_CH_NUM);
- hal_clk_gate_disable(MOD_DMA);
-
- return SUCCESS;
- }
- void __attribute__((used)) HalDMAIRQHandler(void)
- {
- DMA_CH_t ch;
- for(ch = DMA_CH_0;ch < DMA_CH_NUM;ch++)
- {
- if(AP_DMA_INT->StatusTfr & BIT(ch))
- {
- HalDMAStopChannel(ch);
- if(s_dma_ctx.dma_ch_ctx[ch].evt_handler != NULL)
- {
- s_dma_ctx.dma_ch_ctx[ch].evt_handler(ch);
- }
- }
- }
- }
|