/**************************************************************************//**
|
* @file pan_hal_dmac.c
|
* @version V0.0.0
|
* $Revision: 1 $
|
* $Date: 23/09/10 $
|
* @brief Panchip series DMAC (Direct Memory Access Controller) HAL source file.
|
* @note
|
* Copyright (C) 2023 Panchip Technology Corp. All rights reserved.
|
*****************************************************************************/
|
|
|
#include "pan_hal.h"
|
|
DMAC_HandleTypeDef DMAC_Channel_Array[DMAC_CHANNEL_NUMS] = {{0,}, {0,}};
|
|
|
//uart ReceiveDma
|
DMAC_ChannelConfigTypeDef dma_uart2mem_config = {
|
.TransferType = DMAC_TransferType_Per2Mem,
|
// Destination config (Memory)
|
.AddrChangeDst = DMAC_AddrChange_Increment,
|
.BurstLenDst = DMAC_BurstLen_8,
|
.DataWidthDst = DMAC_DataWidth_8,
|
.HandshakeDst = DMAC_Handshake_Default,
|
// Source config (Peripheral)
|
.AddrChangeSrc = DMAC_AddrChange_NoChange,
|
.BurstLenSrc = DMAC_BurstLen_8, //According to peripheral FIFO threshold
|
.DataWidthSrc = DMAC_DataWidth_8, //According to peripheral FIFO width
|
.HandshakeSrc = DMAC_Handshake_Hardware,
|
.PeripheralSrc = NULL, //Config to corresponding peripheral
|
|
.FlowControl = DMAC_FlowControl_DMA,
|
.IntEnable = ENABLE,
|
};
|
|
|
//uart sendDma
|
DMAC_ChannelConfigTypeDef dma_mem2uart_config = {
|
.TransferType = DMAC_TransferType_Mem2Per,
|
.AddrChangeDst = DMAC_AddrChange_NoChange,
|
.BurstLenDst = DMAC_BurstLen_8,
|
.DataWidthDst = DMAC_DataWidth_8,
|
.HandshakeDst = DMAC_Handshake_Hardware,
|
//.PeripheralDst = TGT_UART_DMA_DST,
|
.PeripheralDst = NULL,
|
.AddrChangeSrc = DMAC_AddrChange_Increment,
|
// .BurstLenSrc = DMAC_BurstLen_4,
|
.BurstLenSrc = DMAC_BurstLen_8,
|
|
//.DataWidthSrc = DMAC_DataWidth_32,
|
.DataWidthSrc = DMAC_DataWidth_8,
|
|
.HandshakeSrc = DMAC_Handshake_Default,
|
.FlowControl = DMAC_FlowControl_DMA,
|
.IntEnable = ENABLE
|
};
|
|
DMAC_ChannelConfigTypeDef dma_spi2mem_config = {
|
/* Set dma channel control & config register */
|
.TransferType = DMAC_TransferType_Per2Mem,
|
// Destination config (Memory)
|
.AddrChangeDst = DMAC_AddrChange_Increment,
|
.BurstLenDst = DMAC_BurstLen_4,
|
// .DataWidthDst = DMAC_DataWidth_32,
|
.DataWidthDst = DMAC_DataWidth_16,
|
.HandshakeDst = DMAC_Handshake_Default,
|
// Source config (Peripheral)
|
.AddrChangeSrc = DMAC_AddrChange_NoChange,
|
.BurstLenSrc = DMAC_BurstLen_4, // According to peripheral FIFO threshold
|
.DataWidthSrc = DMAC_DataWidth_16, // According to peripheral FIFO width
|
.HandshakeSrc = DMAC_Handshake_Hardware,
|
//.PeripheralSrc = TGT_SPI_DMA_SRC, // Config to corresponding peripheral
|
.PeripheralSrc = NULL, // Config to corresponding peripheral
|
// General config
|
.FlowControl = DMAC_FlowControl_DMA,
|
.IntEnable = ENABLE,
|
/* Items in RxConfigTmp which are not influenced here is initialized as 0 by compiler. */
|
};
|
|
DMAC_ChannelConfigTypeDef dma_mem2spi_config = {
|
/* Set dma channel control & config register */
|
.TransferType = DMAC_TransferType_Mem2Per,
|
// Destination config (Peripheral)
|
.AddrChangeDst = DMAC_AddrChange_NoChange,
|
.BurstLenDst = DMAC_BurstLen_4, // According to peripheral FIFO threshold
|
.DataWidthDst = DMAC_DataWidth_16, // According to peripheral FIFO width
|
.HandshakeDst = DMAC_Handshake_Hardware,
|
//.PeripheralDst = TGT_SPI_DMA_DST, // Config to corresponding peripheral
|
.PeripheralDst = NULL, // Config to corresponding peripheral
|
// Source config (Memory)
|
.AddrChangeSrc = DMAC_AddrChange_Increment,
|
.BurstLenSrc = DMAC_BurstLen_4,
|
// .DataWidthSrc = DMAC_DataWidth_32,
|
.DataWidthSrc = DMAC_DataWidth_16,
|
.HandshakeSrc = DMAC_Handshake_Default,
|
// General config
|
.FlowControl = DMAC_FlowControl_DMA,
|
.IntEnable = ENABLE,
|
/* Items in TxConfigTmp which are not influenced here is initialized as 0 by compiler. */
|
};
|
|
DMAC_ChannelConfigTypeDef dma_mem2i2c_config = {
|
/*set tx dma channel control&config register*/
|
.AddrChangeDst = DMAC_AddrChange_NoChange,
|
.AddrChangeSrc = DMAC_AddrChange_Increment,
|
.BurstLenDst = DMAC_BurstLen_1,
|
.BurstLenSrc = DMAC_BurstLen_1,
|
.DataWidthDst = DMAC_DataWidth_8,
|
.DataWidthSrc = DMAC_DataWidth_8,
|
.TransferType = DMAC_TransferType_Mem2Per,
|
.FlowControl = DMAC_FlowControl_DMA,
|
.HandshakeDst = DMAC_Handshake_Hardware,
|
.HandshakeSrc = DMAC_Handshake_Hardware,
|
// .PeripheralDst = DMAC_Peripheral_I2C0_Tx,
|
.PeripheralDst = NULL,
|
.IntEnable = ENABLE,
|
};
|
|
DMAC_ChannelConfigTypeDef dma_mem2i2c_u16_config = {
|
/*set tx dma channel control&config register*/
|
.AddrChangeDst = DMAC_AddrChange_NoChange,
|
.AddrChangeSrc = DMAC_AddrChange_Increment,
|
.BurstLenDst = DMAC_BurstLen_1,
|
.BurstLenSrc = DMAC_BurstLen_1,
|
.DataWidthDst = DMAC_DataWidth_16,
|
.DataWidthSrc = DMAC_DataWidth_16,
|
.TransferType = DMAC_TransferType_Mem2Per,
|
.FlowControl = DMAC_FlowControl_DMA,
|
.HandshakeDst = DMAC_Handshake_Hardware,
|
.HandshakeSrc = DMAC_Handshake_Hardware,
|
// .PeripheralDst = DMAC_Peripheral_I2C0_Tx,
|
.PeripheralDst = NULL,
|
.IntEnable = ENABLE,
|
};
|
|
|
DMAC_ChannelConfigTypeDef dma_i2c2mem_config = {
|
|
/*set tx dma channel control&config register*/
|
.AddrChangeDst = DMAC_AddrChange_Increment,
|
.AddrChangeSrc = DMAC_AddrChange_NoChange,
|
.BurstLenDst = DMAC_BurstLen_4,
|
.BurstLenSrc = DMAC_BurstLen_4,
|
.DataWidthDst = DMAC_DataWidth_8,
|
.DataWidthSrc = DMAC_DataWidth_8,
|
.TransferType = DMAC_TransferType_Per2Mem,
|
.FlowControl = DMAC_FlowControl_DMA,
|
.HandshakeDst = DMAC_Handshake_Hardware,
|
.HandshakeSrc = DMAC_Handshake_Hardware,
|
// .PeripheralSrc = DMAC_Peripheral_I2C0_Rx,
|
.PeripheralSrc = NULL,
|
.IntEnable = ENABLE,
|
|
};
|
|
DMAC_ChannelConfigTypeDef dma_adc2mem_config = {
|
.AddrChangeDst = DMAC_AddrChange_Increment,
|
.AddrChangeSrc = DMAC_AddrChange_NoChange,
|
.BurstLenDst = DMAC_BurstLen_8,
|
.BurstLenSrc = DMAC_BurstLen_8,
|
.DataWidthDst = DMAC_DataWidth_16,
|
.DataWidthSrc = DMAC_DataWidth_32,
|
.TransferType = DMAC_TransferType_Per2Mem,
|
.FlowControl = DMAC_FlowControl_DMA,
|
.HandshakeDst = DMAC_Handshake_Hardware,
|
.HandshakeSrc = DMAC_Handshake_Hardware,
|
.PeripheralSrc = DMAC_Peripheral_ADC,
|
.IntEnable = ENABLE
|
};
|
|
void HAL_DMA_Init(void)
|
{
|
CLK_AHBPeriphClockCmd(CLK_AHBPeriph_DMAC, ENABLE);
|
|
DMAC_Init(DMA);
|
|
NVIC_EnableIRQ(DMA_IRQn);
|
}
|
|
__WEAK void DMA_IRQHandlerOverlay(void)
|
{
|
int16_t remaind_cnt;
|
|
/* Handle DMA Transfer Complete Interrupt */
|
if (DMAC_CombinedIntStatus(DMA, DMAC_FLAG_MASK_TFR))
|
{
|
for (int i = 0; i < DMAC_CHANNEL_NUMS; i++)
|
{
|
if (DMAC_IntFlag(DMA, i, DMAC_FLAG_INDEX_TFR))
|
{
|
DMAC_ClrIntFlag(DMA, i, DMAC_FLAG_INDEX_TFR);
|
|
switch (DMAC_Channel_Array[i].PeriMode)
|
{
|
case DMAC_Peri_UART:
|
DMAC_Channel_Array[i].XferCount += DMAC_GetXferredBlockCount(DMA, i);
|
remaind_cnt = DMAC_Channel_Array[i].XferSize - DMAC_Channel_Array[i].XferCount;
|
if (remaind_cnt > 0)
|
{
|
if (remaind_cnt < 1024)
|
{
|
DMAC_ContinueChannel(DMA, i, remaind_cnt);
|
}
|
else
|
{
|
DMAC_ContinueChannel(DMA, i, 1023);
|
}
|
}
|
else
|
{
|
if (DMAC_Channel_Array[i].CallbackUart != NULL)
|
{
|
if (DMAC_Channel_Array[i].ConfigTmp.TransferType == DMAC_TransferType_Per2Mem)
|
{
|
((HAL_UART_HandleTypeDef*)DMAC_Channel_Array[i].periph)->isRxBusy = false;
|
}
|
else if (DMAC_Channel_Array[i].ConfigTmp.TransferType == DMAC_TransferType_Mem2Per)
|
{
|
((HAL_UART_HandleTypeDef*)DMAC_Channel_Array[i].periph)->isTxBusy = false;
|
}
|
DMAC_Channel_Array[i].CallbackUart(UART_CB_FLAG_DMA, (uint8_t *)DMAC_Channel_Array[i].pBuffPtr,
|
DMAC_Channel_Array[i].XferCount);
|
}
|
}
|
break;
|
case DMAC_Peri_I2C:
|
DMAC_ReleaseChannel(DMA, i);
|
if (DMAC_Channel_Array[i].CallbackI2c != NULL)
|
{
|
DMAC_Channel_Array[i].CallbackI2c(I2C_CB_FLAG_DMA, (uint8_t *)DMAC_Channel_Array[i].pBuffPtr,
|
DMAC_Channel_Array[i].XferSize);
|
}
|
case DMAC_Peri_SPI:
|
DMAC_ReleaseChannel(DMA, i);
|
if (DMAC_Channel_Array[i].CallbackSpi!= NULL)
|
{
|
DMAC_Channel_Array[i].CallbackSpi(SPI_CB_FLAG_DMA, (uint16_t *)DMAC_Channel_Array[i].pBuffPtr,
|
DMAC_Channel_Array[i].XferSize);
|
}
|
default:
|
break;
|
}
|
}
|
}
|
}
|
/* Handle Block Transfer Complete Interrupt */
|
if(DMAC_CombinedIntStatus(DMA, DMAC_FLAG_MASK_BLK))
|
{
|
if(DMAC_IntFlag(DMA, 0, DMAC_FLAG_INDEX_BLK)){
|
DMAC_ClrIntFlag(DMA, 0, DMAC_FLAG_INDEX_BLK);
|
}
|
if(DMAC_IntFlag(DMA, 1, DMAC_FLAG_INDEX_BLK)){
|
DMAC_ClrIntFlag(DMA, 1, DMAC_FLAG_INDEX_BLK);
|
}
|
if(DMAC_IntFlag(DMA, 2, DMAC_FLAG_INDEX_BLK)){
|
DMAC_ClrIntFlag(DMA, 2, DMAC_FLAG_INDEX_BLK);
|
}
|
}
|
/* Handle Source Transation Complete Interrupt */
|
if(DMAC_CombinedIntStatus(DMA, DMAC_FLAG_MASK_SRCTFR))
|
{
|
//idx_srctfr++;
|
if(DMAC_IntFlag(DMA, 0, DMAC_FLAG_INDEX_SRCTFR)){
|
DMAC_ClrIntFlag(DMA, 0, DMAC_FLAG_INDEX_SRCTFR);
|
}
|
if(DMAC_IntFlag(DMA, 1, DMAC_FLAG_INDEX_SRCTFR)){
|
DMAC_ClrIntFlag(DMA, 1, DMAC_FLAG_INDEX_SRCTFR);
|
}
|
if(DMAC_IntFlag(DMA, 2, DMAC_FLAG_INDEX_SRCTFR)){
|
DMAC_ClrIntFlag(DMA, 2, DMAC_FLAG_INDEX_SRCTFR);
|
}
|
}
|
/* Handle Destination Transaction Complete Interrupt */
|
if(DMAC_CombinedIntStatus(DMA, DMAC_FLAG_MASK_DSTTFR))
|
{
|
//idx_dsttfr++;
|
if(DMAC_IntFlag(DMA, 0, DMAC_FLAG_INDEX_DSTTFR)){
|
DMAC_ClrIntFlag(DMA, 0, DMAC_FLAG_INDEX_DSTTFR);
|
}
|
if(DMAC_IntFlag(DMA, 1, DMAC_FLAG_INDEX_DSTTFR)){
|
DMAC_ClrIntFlag(DMA, 1, DMAC_FLAG_INDEX_DSTTFR);
|
}
|
if(DMAC_IntFlag(DMA, 2, DMAC_FLAG_INDEX_DSTTFR)){
|
DMAC_ClrIntFlag(DMA, 2, DMAC_FLAG_INDEX_DSTTFR);
|
}
|
}
|
/* Handle Error Interrupt */
|
if(DMAC_CombinedIntStatus(DMA, DMAC_FLAG_MASK_ERR))
|
{
|
if(DMAC_IntFlag(DMA, 0, DMAC_FLAG_INDEX_ERR)){
|
DMAC_ClrIntFlag(DMA, 0, DMAC_FLAG_INDEX_ERR);
|
}
|
if(DMAC_IntFlag(DMA, 1, DMAC_FLAG_INDEX_ERR)){
|
DMAC_ClrIntFlag(DMA, 1, DMAC_FLAG_INDEX_ERR);
|
}
|
if(DMAC_IntFlag(DMA, 2, DMAC_FLAG_INDEX_ERR)){
|
DMAC_ClrIntFlag(DMA, 2, DMAC_FLAG_INDEX_ERR);
|
}
|
}
|
}
|
|
void DMA_IRQHandler(void)
|
{
|
PAN_IO_TIMING_TRACK_LEVEL(CONFIG_TRACK_PIN_DMA_IRQ, 1);
|
|
DMA_IRQHandlerOverlay();
|
|
PAN_IO_TIMING_TRACK_LEVEL(CONFIG_TRACK_PIN_DMA_IRQ, 0);
|
}
|