📄 dma.c
字号:
DMA_ERROR_LISR,
DMA_ERROR_LISR,
DMA_ERROR_LISR,
DMA_ERROR_LISR,
DMA_ERROR_LISR,
DMA_ERROR_LISR
};
#endif
static DMA_GBL_CLASS dma_gbl_class_g;
static const kal_uint8 dma_gbl_class_to_grade[DMA_MAX_GBL_CLASS + 1]
= { 0 /* CLASS 0 */, 10 /* CLASS 1 */, 50 /* CLASS 2 */, 100 /* CLASS 3 */, 200 /* CLASS 4 */ };
static kal_uint16 dma_gbl_count[DMA_MAX_GBL_CLASS]
= { 0 /* CLASS 1 */, 0 /* CLASS 2 */, 0 /* CLASS 3 */, 0 /* CLASS 4 */ };
static const DMA_GBL_PRIORITY_BANK dma_gbl_priority_bank[DMA_GBL_TOTAL_PRIORITY_BANK]
= { {0, 9, 1}, {10, 39, 2}, {40, 89, 3}, {90, 119, 4}, {120, 169, 5}, {170, 199, 6}, {200, 249, 7}, {250, 255, 8} };
kal_uint32 DMA_Channel_Status = 0xffff;
DMA_PWRCTRL DMA_PWR;
DMA_Master DMA_Owner[DMA_MAX_CHANNEL];
static void DMA_HISR(void);
void DMA_Stop(kal_uint8 channel)
{
DMA_Stop_Now(channel);
DMA_ACKI(channel);
}
void DMA_Run(kal_uint8 channel)
{
DMA_Stop(channel);
DMA_Start(channel);
}
void DMA_SleepEnable(kal_uint8 channel)
{
kal_uint32 savedMask;
#if defined(MT6218B)
return;
#endif /*MT6218B*/
savedMask = SaveAndSetIRQMask();
DMA_PWR.sleepDisable &= ~(1 << channel);
if (DMA_PWR.sleepDisable == 0)
DRVPDN_Enable(DRVPDN_CON0,DRVPDN_CON0_DMA,PDN_DMA);
RestoreIRQMask(savedMask);
}
void DMA_SleepDisable(kal_uint8 channel)
{
kal_uint32 savedMask;
#if defined(MT6218B)
return;
#endif /*MT6218B*/
savedMask = SaveAndSetIRQMask();
if (DMA_PWR.sleepDisable == 0)
DRVPDN_Disable(DRVPDN_CON0,DRVPDN_CON0_DMA,PDN_DMA);
DMA_PWR.sleepDisable |= (1 << channel);
RestoreIRQMask(savedMask);
}
kal_uint8 DMA_GetChannel(DMA_Master DMA_CODE)
{
kal_uint8 index;
kal_uint8 handle=0xff;
kal_uint32 savedMask;
savedMask = SaveAndSetIRQMask();
for (index = 4; index <= DMA_MAX_CHANNEL; index++)
{
if ((DMA_Channel_Status & (0x01<<index)) != 0)
{
handle = index;
DMA_Channel_Status &= ~(0x01<<index);
break;
}
}
RestoreIRQMask(savedMask);
ASSERT(handle!=0xff);
#ifndef __PRODUCTION_RELEASE__
for (index = 4; index <= DMA_MAX_CHANNEL; index++)
{
if (DMA_Owner[index-1]==DMA_CODE)
ASSERT(0);
}
#endif /*__PRODUCTION_RELEASE__*/
DMA_Owner[handle-1] = DMA_CODE;
return handle;
}
void DMA_FreeChannel(kal_uint8 handle)
{
kal_uint32 savedMask;
savedMask = SaveAndSetIRQMask();
DMA_Channel_Status |= (0x01<<handle);
DMA_Stop(handle);
DMA_Owner[handle-1] = DMA_IDLE;
RestoreIRQMask(savedMask);
}
kal_uint8 DMA_FullSize_GetChannel(DMA_Master DMA_CODE) /* Hw handler. handle = 1~3 */
{
kal_uint8 index;
kal_uint8 handle=0xff;
kal_uint32 savedMask;
savedMask = SaveAndSetIRQMask();
#ifdef MT6218B
for (index = 2; index <= DMA_MAX_FULL_CHANNEL; index++)
#else
for (index = 1; index <= DMA_MAX_FULL_CHANNEL; index++)
#endif
{
if ((DMA_Channel_Status & (0x01<<index)) != 0)
{
handle = index;
DMA_Channel_Status &= ~(0x01<<index);
break;
}
}
RestoreIRQMask(savedMask);
ASSERT(handle!=0xff);
#ifndef __PRODUCTION_RELEASE__
for(index=1;index<=DMA_MAX_FULL_CHANNEL;index++)
{
if (DMA_Owner[index-1]==DMA_CODE)
ASSERT(0);
}
#endif /*__PRODUCTION_RELEASE__*/
DMA_Owner[handle-1] = DMA_CODE;
return handle;
}
void DMA_FullSize_FreeChannel(kal_uint8 handle)
{
kal_uint32 savedMask;
savedMask = SaveAndSetIRQMask();
DMA_Channel_Status |= (0x01<<handle);
DMA_Stop(handle);
DMA_Owner[handle-1] = DMA_IDLE;
RestoreIRQMask(savedMask);
}
void DMA_Config_Internal(kal_uint8 dma_no, DMA_INPUT *dma_menu, kal_bool fullsize, kal_bool b2w, kal_uint8 limit, kal_bool start)
{
kal_uint32 dma_con = 0;
kal_uint32 temp;
kal_uint32 _savedMask;
kal_uint32 priority;
DMA_GBL_CLASS dma_gbl_class;
kal_uint8 dma_gbl, bank = 0;
if (DMA_CheckRunStat(dma_no) || DMA_CheckITStat(dma_no))
ASSERT(0);
ASSERT(DMA_Owner[dma_no - 1] != DMA_IDLE);
if (fullsize == KAL_TRUE)
ASSERT(b2w == KAL_FALSE);
ASSERT(dma_menu->count<=0xffff);
DMA_Stop(dma_no);
switch(dma_menu->type) {
case DMA_HWTX:
if (fullsize == KAL_TRUE)
temp = (kal_uint32)(((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->master);
else
temp = (kal_uint32)(((DMA_HWMENU *)dma_menu->menu)->master);
dma_con |= (kal_uint32)(temp << 20);
dma_con |= DMA_CON_TXCONTRL;
dma_con |= DMA_CON_DRQ;
if (fullsize == KAL_TRUE) {
if (((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->TMOD.burst_mode) {
#ifdef MT6218
dma_con |= DMA_CON_TMOD;
dma_con |= (kal_uint32)(((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->TMOD.cycle) << 9;
#endif /* MT6218 */
}
} else {
if (((DMA_HWMENU *)dma_menu->menu)->TMOD.burst_mode) {
#ifdef MT6218
dma_con |= DMA_CON_TMOD;
dma_con |= (kal_uint32)(((DMA_HWMENU *)dma_menu->menu)->TMOD.cycle) << 9;
#endif /* MT6218 */
}
}
if (fullsize == KAL_TRUE) {
DRV_WriteReg32(DMA_SRC(dma_no), ((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->source);
DRV_WriteReg32(DMA_DST(dma_no), ((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->destination);
}
else {
DRV_WriteReg32(DMA_PGMADDR(dma_no), ((DMA_HWMENU *)dma_menu->menu)->addr);
#if !defined(MT6218)
if(b2w == KAL_TRUE)
dma_con |= DMA_CON_B2W;
#endif
}
break;
case DMA_HWRX:
if (fullsize == KAL_TRUE)
dma_con |= (kal_uint32)(((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->master) << 20;
else
dma_con |= (kal_uint32)(((DMA_HWMENU *)dma_menu->menu)->master) << 20;
dma_con |= DMA_CON_RXCONTRL;
dma_con |= DMA_CON_DRQ;
if (fullsize == KAL_TRUE) {
if (((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->TMOD.burst_mode) {
#ifdef MT6218
dma_con |= DMA_CON_TMOD;
dma_con |= (kal_uint32)(((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->TMOD.cycle) << 9;
#endif /* MT6218 */
}
} else {
if (((DMA_HWMENU *)dma_menu->menu)->TMOD.burst_mode) {
#ifdef MT6218
dma_con |= DMA_CON_TMOD;
dma_con |= (kal_uint32)(((DMA_HWMENU *)dma_menu->menu)->TMOD.cycle) << 9;
#endif /* MT6218 */
}
}
if (fullsize == KAL_TRUE) {
DRV_WriteReg32(DMA_SRC(dma_no), ((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->source);
DRV_WriteReg32(DMA_DST(dma_no), ((DMA_FULLSIZE_HWMENU *)dma_menu->menu)->destination);
} else {
DRV_WriteReg32(DMA_PGMADDR(dma_no), ((DMA_HWMENU *)dma_menu->menu)->addr);
#if !defined(MT6218)
if(b2w == KAL_TRUE)
dma_con |= DMA_CON_B2W;
#endif
}
break;
case DMA_SWCOPY:
DRV_WriteReg32(DMA_SRC(dma_no), ((DMA_SWCOPYMENU *)dma_menu->menu)->srcaddr);
DRV_WriteReg32(DMA_DST(dma_no), ((DMA_SWCOPYMENU *)dma_menu->menu)->dstaddr);
dma_con = DMA_CON_SWCOPY;
break;
case DMA_HWTX_RINGBUFF:
if (fullsize == KAL_TRUE)
dma_con |= ((kal_uint32)((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->master) << 20;
else
dma_con |= ((kal_uint32)((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->master) << 20;
dma_con |= DMA_CON_TXCONTRL;
dma_con |= DMA_CON_DRQ;
if (fullsize == KAL_TRUE) {
if (((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->TMOD.burst_mode) {
#ifdef MT6218
dma_con |= DMA_CON_TMOD;
dma_con |= (kal_uint32)(((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->TMOD.cycle) << 9;
#endif /* MT6218 */
}
} else {
if (((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->TMOD.burst_mode) {
#ifdef MT6218
dma_con |= DMA_CON_TMOD;
dma_con |= (kal_uint32)(((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->TMOD.cycle) << 9;
#endif /* MT6218 */
}
}
dma_con |= DMA_CON_WPEN; /*RAM->Register*/
if (fullsize == KAL_TRUE) {
DRV_WriteReg32(DMA_WPPT(dma_no), ((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->WPPT);
DRV_WriteReg32(DMA_WPTO(dma_no), ((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->WPTO);
DRV_WriteReg32(DMA_SRC(dma_no), ((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->source);
DRV_WriteReg32(DMA_DST(dma_no), ((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->destination);
} else {
DRV_WriteReg32(DMA_WPPT(dma_no), ((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->WPPT);
DRV_WriteReg32(DMA_WPTO(dma_no), ((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->WPTO);
DRV_WriteReg32(DMA_PGMADDR(dma_no), ((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->addr);
#if !defined(MT6218)
if(b2w == KAL_TRUE)
dma_con |= DMA_CON_B2W;
#endif
}
break;
case DMA_HWRX_RINGBUFF:
if (fullsize == KAL_TRUE)
dma_con |= ((kal_uint32) ((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->master) << 20;
else
dma_con |= ((kal_uint32) ((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->master) << 20;
dma_con |= DMA_CON_RXCONTRL;
dma_con |= DMA_CON_DRQ;
if (fullsize == KAL_TRUE) {
if (((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->TMOD.burst_mode) {
#ifdef MT6218
dma_con |= DMA_CON_TMOD;
dma_con |= (kal_uint32)(((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->TMOD.cycle) << 9;
#endif /* MT6218 */
}
} else {
if (((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->TMOD.burst_mode) {
#ifdef MT6218
dma_con |= DMA_CON_TMOD;
dma_con |= (kal_uint32)(((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->TMOD.cycle) << 9;
#endif /* MT6218 */
}
}
dma_con |= DMA_CON_WPSD; /*Register->RAM*/
dma_con |= DMA_CON_WPEN;
if (fullsize == KAL_TRUE) {
DRV_WriteReg32(DMA_WPPT(dma_no), ((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->WPPT);
DRV_WriteReg32(DMA_WPTO(dma_no), ((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->WPTO);
DRV_WriteReg32(DMA_SRC(dma_no), ((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->source);
DRV_WriteReg32(DMA_DST(dma_no), ((DMA_FULLSIZE_HWRINGBUFF_MENU *)dma_menu->menu)->destination);
} else {
DRV_WriteReg32(DMA_WPPT(dma_no), ((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->WPPT);
DRV_WriteReg32(DMA_WPTO(dma_no), ((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->WPTO);
DRV_WriteReg32(DMA_PGMADDR(dma_no), ((DMA_HWRINGBUFF_MENU *)dma_menu->menu)->addr);
#if !defined(MT6218)
if(b2w == KAL_TRUE)
dma_con |= DMA_CON_B2W;
#endif
}
break;
default:
ASSERT(0);
break;
}
switch(dma_menu->size) {
case DMA_BYTE:
#if !defined(MT6218)
if (dma_menu->type != DMA_SWCOPY) {
if ( (((DMA_TMODE *)(dma_menu->menu))->burst_mode==KAL_TRUE) &&
(((DMA_TMODE *)(dma_menu->menu))->cycle & 0xf0) )
dma_con |= DMA_CON_BURST_16BEAT;
else if ( (((DMA_TMODE *)(dma_menu->menu))->burst_mode==KAL_TRUE) &&
(((DMA_TMODE *)(dma_menu->menu))->cycle & 0x08) )
dma_con |= DMA_CON_BURST_8BEAT;
else if ( (((DMA_TMODE *)(dma_menu->menu))->burst_mode==KAL_TRUE) &&
(((DMA_TMODE *)(dma_menu->menu))->cycle & 0x04) )
dma_con |= DMA_CON_BURST_4BEAT;
}
#endif /* ! MT6218 */
break;
case DMA_SHORT:
#if !defined(MT6218)
if (dma_menu->type != DMA_SWCOPY) {
if ( (((DMA_TMODE *)(dma_menu->menu))->burst_mode==KAL_TRUE) &&
(((DMA_TMODE *)(dma_menu->menu))->cycle & 0xf8) )
dma_con |= DMA_CON_BURST_8BEAT;
else if ( (((DMA_TMODE *)(dma_menu->menu))->burst_mode==KAL_TRUE) &&
(((DMA_TMODE *)(dma_menu->menu))->cycle & 0x04) )
dma_con |= DMA_CON_BURST_4BEAT;
}
#endif /* ! MT6218 */
dma_con |= DMA_CON_SIZE_SHORT;
break;
case DMA_LONG:
#if !defined(MT6218)
if (dma_menu->type != DMA_SWCOPY) {
if ( (((DMA_TMODE *)(dma_menu->menu))->burst_mode==KAL_TRUE) &&
(((DMA_TMODE *)(dma_menu->menu))->cycle & 0xfc) )
dma_con |= DMA_CON_BURST_4BEAT;
}
#endif /* !MT6218 */
dma_con |= DMA_CON_SIZE_LONG;
break;
default:
ASSERT(0);
break;
}
if (dma_menu->callback != NULL)
{
dma_con |= DMA_CON_ITEN;
DMA_LISR_FUNC[dma_no-1] = dma_menu->callback;
}
DRV_WriteReg32(DMA_CON(dma_no),dma_con);
DRV_WriteReg32(DMA_COUNT(dma_no),(kal_uint32)dma_menu->count);
/* set the bandwidth limiter */
_savedMask = SaveAndSetIRQMask();
dma_gbl_class = dma_gbl_class_g;
RestoreIRQMask(_savedMask);
if (dma_gbl_class == 0) {
/* full speed */
DRV_WriteReg8(DMA_LIMITER(dma_no), 0);
} else {
dma_gbl = dma_gbl_class_to_grade[dma_gbl_class];
priority = kal_get_mytask_priority();
if (priority <= dma_gbl_priority_bank[0].upper && priority >= dma_gbl_priority_bank[0].lower)
bank = dma_gbl_priority_bank[0].bank;
else if (priority <= dma_gbl_priority_bank[1].upper && priority >= dma_gbl_priority_bank[1].lower)
bank = dma_gbl_priority_bank[1].bank;
else if (priority <= dma_gbl_priority_bank[2].upper && priority >= dma_gbl_priority_bank[2].lower)
bank = dma_gbl_priority_bank[2].bank;
else if (priority <= dma_gbl_priority_bank[3].upper && priority >= dma_gbl_priority_bank[3].lower)
bank = dma_gbl_priority_bank[3].bank;
else if (priority <= dma_gbl_priority_bank[4].upper && priority >= dma_gbl_priority_bank[4].lower)
bank = dma_gbl_priority_bank[4].bank;
else if (priority <= dma_gbl_priority_bank[5].upper && priority >= dma_gbl_priority_bank[5].lower)
bank = dma_gbl_priority_bank[5].bank;
else if (priority <= dma_gbl_priority_bank[6].upper && priority >= dma_gbl_priority_bank[6].lower)
bank = dma_gbl_priority_bank[6].bank;
else if (priority <= dma_gbl_priority_bank[7].upper && priority >= dma_gbl_priority_bank[7].lower)
bank = dma_gbl_priority_bank[7].bank;
else
EXT_ASSERT(0, dma_gbl, priority, bank);
DRV_WriteReg8(DMA_LIMITER(dma_no), DMA_GBL_PRIORITY_2_BL(bank, dma_gbl));
}
#if defined(MT6218B) || defined(MT6217)
lcd_dma_slow_down(dma_gbl_class);
#endif
if (start) {
/* configuration is done and start the DMA */
DMA_Start(dma_no);
}
}
void DMA_ERROR_LISR(void)
{
while(1);
}
void DMA_HISR(void)
{
kal_uint8 index;
for(index = 0; index < DMA_MAX_CHANNEL; index++)
{
if (DRV_Reg32(DMA_INTSTA(index+1)) & DMA_INTSTA_BIT)
{
DMA_Stop(index+1);
DMA_ACKI(index+1);
DMA_LISR_FUNC[index]();
}
}
#ifdef __DMA_UART_VIRTUAL_FIFO__
// handle virtual fifo interrupt
for(index=DMA_VFIFO_CH_S; index<=DMA_VFIFO_CH_E; index++)
{
kal_uint32 con = DRV_Reg32(DMA_CON(index));
if (DRV_Reg32(DMA_INTSTA(index)) & DMA_INTSTA_BIT)
{
switch(con >> 20)
{
case DMA_CON_MASTER_UART1RX:
UART_RecHandler_VFIFO(&UARTPort[uart_port1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -