⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dma.c

📁 MTK平台绝密核心代码之 系统驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
   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 + -