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

📄 dma.c

📁 自己写的无线sinffer,可以通过串口查看空间内所有无线数据
💻 C
字号:

#include <string.h>
#include "dma.h"

// DMA不是直接进行或是讲不能逐一配置。把配置写到一块内存之后ARM命令自动加载
DMA_DESC dmaChannel1to2[2];

// 映射表,用来把DMA号与处理函数连接。.
DMA_TABLE_ENTRY dmaTable[DMA_ADM_NUMBER_OF_CHANNELS];


//-----------------------------------------------------------------------------
// See cul.h for a description of this function.
//-----------------------------------------------------------------------------
void DmaInit(void){
   // 清0DMA结构内存
   memset((void*)dmaChannel1to2, 0, sizeof(dmaChannel1to2));
   // 清0DMA映射表,
   memset((void*)dmaTable, 0, sizeof(dmaTable));
   // 1到4的所有装配位清0,到用时单个使能
   DMAARM &= DMA_CHANNEL_0;
   // 1到4的DMA请求位清0,这些位由硬件自动置位,也可以人工置位
   DMAREQ &= DMA_CHANNEL_0;
   // 中断标志1到4清0,这是传输完毕后置位,相当于中断中的局部中断
   DMAIRQ &= DMA_CHANNEL_0;
   // 清0 DMA中断标志位,在全局中断里
   INT_SETFLAG(INUM_DMA, INT_CLR);
   // 使能中断标志,在全局中断里
   INT_ENABLE(INUM_DMA, INT_ON);
   // DMA1到4的配置导入到寄存器,其实就要配置内存的一个指针。(多个DMA不能并行的工作,1到4共用一个配置REG)
   DMA_SET_ADDR_DESC12(dmaChannel1to2);

} // ends culDmaInit()


//分配DMA通道
DMA_DESC *DmaAllocChannel(UINT8* pDmaChannelNumber, FUNCTION* callBackFunction){
   DMA_DESC* dmaDesc;
   BYTE savedIntEnable = 0x00;
   INT8 i;

   // 查看那个DMA通道没使用
   for(i = 1; i <= DMA_ADM_NUMBER_OF_CHANNELS; i++){
      if(dmaTable[i].assigned == FALSE){
         break;
      }
   }

   // If no channel is available, the function returns.
   if(i > DMA_ADM_NUMBER_OF_CHANNELS){
      *pDmaChannelNumber = 0x00;
      dmaDesc = NULL;
   }
   // An available table entry was found
   else {
      // Deactivating the channel and erasing old interrupt flag
      DMA_ABORT_CHANNEL(i);
      DMAIRQ &= ~(1 << i);

      // Storing interrupt enable register and turning off interrupts.
      savedIntEnable = IEN0;
      GLOBAL_INT_ENABLE(INT_OFF);

      // Reserving the DMA channel.
      dmaTable[i].assigned = TRUE;
      dmaTable[i].callBackFunction = callBackFunction;
      *pDmaChannelNumber = i;

      // Restoring old interrupt enable register.
      IEN0 = savedIntEnable;

      dmaDesc = &dmaChannel1to2[i-1];
   }

   // Returning pointer to the DMA descriptor
   return dmaDesc;
}

void DmaFromRadio(DMA_DESC* pDmaChannel, BYTE *pDstAddr, BOOL generateInterrupt)
{
   SET_WORD(pDmaChannel->SRCADDRH, pDmaChannel->SRCADDRL,   &X_RFD);   // The start address of the segment
   SET_WORD(pDmaChannel->DESTADDRH, pDmaChannel->DESTADDRL, pDstAddr); // Tx FiFo address
   SET_WORD(pDmaChannel->LENH, pDmaChannel->LENL, 255);                // Maximum of the Tx FiFo.
   pDmaChannel->VLEN       = VLEN_1_P_VALOFFIRST;// The first byte indicates transfer length
   pDmaChannel->PRIORITY   = PRI_HIGH;
   pDmaChannel->M8         = M8_USE_7_BITS;

   pDmaChannel->IRQMASK    = generateInterrupt; // The DMA complete interrupt flag is set at completion.
   pDmaChannel->DESTINC    = DESTINC_1;         // The destination is constant
   pDmaChannel->SRCINC     = SRCINC_0;          // The address for data fetch is incremented by 1 byte after each transfer.
   pDmaChannel->TRIG       = DMATRIG_RADIO;     // DMA is started by the radio receiver.
   pDmaChannel->TMODE      = TMODE_SINGLE;      // One byte is transferred at each DMA trigger.
   pDmaChannel->WORDSIZE   = WORDSIZE_BYTE;     // Byte transfer.

   return;
}




#pragma vector=DMA_VECTOR
__interrupt void dma_IRQ (void){

   GLOBAL_INT_ENABLE(INT_OFF);
   // Clearing the interrupt flag.
   DMAIF = 0;

   if(DMAIRQ & DMA_CHANNEL_0){
      // Clearing interrupt flag
      DMAIRQ &= ~DMA_CHANNEL_0;

      // Calling the callback function.
      if(dmaTable[0].callBackFunction){
         dmaTable[0].callBackFunction();
      }
   }
   if(DMAIRQ & DMA_CHANNEL_1){
      // Clearing interrupt flag
      DMAIRQ &= ~DMA_CHANNEL_1;

      // Calling the callback function.
      if(dmaTable[1].callBackFunction){
         dmaTable[1].callBackFunction();
      }
   }
   if(DMAIRQ & DMA_CHANNEL_2){
      // Clearing interrupt flag
      DMAIRQ &= ~DMA_CHANNEL_2;

      // Calling the callback function.
      if(dmaTable[2].callBackFunction){
         dmaTable[2].callBackFunction();
      }
   }

   GLOBAL_INT_ENABLE(INT_ON);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -