📄 dma.c
字号:
/*****************************************************************************
* dma.c: DMA module file for NXP LPC2xxx Family Microprocessors
*
* Copyright(C) 2006, NXP Semiconductor
* All rights reserved.
*
* History
* 2006.07.20 ver 1.00 Prelimnary version, first Release
*
******************************************************************************/
#include "LPC288x.h" /* LPC2xxx definitions */
#include "type.h"
#include "irq.h"
#include "ex_sdram.h"
#include "dma.h"
volatile DWORD DMA_SWICount = 0;
volatile DWORD DMA_AbortCount = 0;
volatile DWORD DMACompCount[DMA_CHANNELS];
volatile DWORD DMAHalfCount[DMA_CHANNELS];
/******************************************************************************
** Function name: DMA_CH_Enable
**
** Descriptions: Enable DMA channel based on the channel number
**
** parameters: ChannelNum
** Returned value: None
**
******************************************************************************/
void DMA_CH_Enable(DWORD channelNum)
{
DMA_Enable |= (0x01<<channelNum);
DMA_Stat |= (0x03<<(channelNum*2));
/* Unmask IRQ, only care about comp bit, not half comp. */
DMA_IRQMask &= ~(0x01<<(channelNum*2));
return;
}
/******************************************************************************
** Function name: DMA_CH_Disable
**
** Descriptions: Disable DMA channel based on the channel number
**
** parameters: ChannelNum
** Returned value: None
**
******************************************************************************/
void DMA_CH_Disable(DWORD channelNum)
{
DMA_Enable &= ~(0x01<<channelNum);
/* Clear global status */
DMA_Stat |= (0x03<<(channelNum*2));
/* Mask IRQ, mask both comp bit and half comp bit. */
DMA_IRQMask |= (0x03<<(channelNum*2));
return;
}
/******************************************************************************
** Function name: DMA_ISR
**
** Descriptions: DMA interrupt handler
**
** parameters: None
** Returned value: None
**
******************************************************************************/
void DMA_ISR(void)
{
DWORD i, regVal, channelMask;
regVal = DMA_Stat;
if ( regVal & 0x80000000 ) /* Abort DMA */
{
DMA_AbortCount++;
DMA_Stat |= 0x8000FFFF; /* Clear all channel status */
return;
}
if ( regVal & 0x40000000 ) /* SoftInterrupt Request */
{
DMA_SWICount++;
DMA_Stat |= 0x40000000;
return;
}
for ( i = 0; i < DMA_CHANNELS; i++ )
{
channelMask = (regVal >> (i*2)) & 0x03;
if ( channelMask & 0x03 )
{
DMA_CH_Disable(i);
if ( channelMask & 0x01 ) /* i: channel, COMP interrupt */
{
DMACompCount[i]++;
}
if ( channelMask & 0x02 ) /* i: channel, HALF COMP interrupt */
{
DMAHalfCount[i]++;
}
}
}
return;
}
/******************************************************************************
** Function name: DMA_MCI_Init
**
** Descriptions: Enable DMA channel 0 through 3, 0 is MCI TX,
** 1 is MCI RX
**
** parameters: None
** Returned value: TRUE or FALSE, FALSE if ISR is not installed.
**
******************************************************************************/
DWORD DMA_MCI_Init( void )
{
/* clear all interrupts */
DMA_IRQMask = 0xC000FFFF;
DMA_Stat = 0xC000FFFF;
DMA_Enable = 0x00000000;
DMA0Count = DMA1Count = 0;
/* channel 0 is for MCI Write */
DMA0Source = SDRAM_WR_ADDR;
DMA0Dest = DMA_MCI_PORT;
/* This MCI_DATA_LENGTH should be the same as BLOCK_LENGTH
defined in mci.h. */
DMA0Length = MCI_DATA_LENGTH;
/* 8 bit, src is SDRAM, dest is MCI */
DMA0Config = (0x0<<10)|(0x0<<5)|(DMA_MCI_BURST<<0);
/* channel 1 is for MCI Read */
DMA1Source = DMA_MCI_PORT;
DMA1Dest = SDRAM_RD_ADDR;
/* This MCI_DATA_LENGTH should be the same as BLOCK_LENGTH
defined in mci.h. */
DMA1Length = MCI_DATA_LENGTH;
/* 8 bit, src is MCI, dest is memory */
DMA1Config = (0x0<<10)|(DMA_MCI_BURST<<5)|(0x0<<0);
if ( install_IRQ(25, 1, DMA_ISR ) == FALSE )
{
return( FALSE );
}
INT_REQ25=(1<<28)|(1<<27)|(1<<26)|(1<<16)|0x1;
INT_VECTOR0=IRQ_TABLE_BASE & MASK_INDEX;
return (TRUE);
}
/******************************************************************************
** Function name: DMA_UART_Init
**
** Descriptions: Enable DMA channel 2 is UART TX, 3 is UART RX
**
**
** parameters: None
** Returned value: TRUE or FALSE, FALSE if ISR is not installed.
**
******************************************************************************/
DWORD DMA_UART_Init( void )
{
/* clear all interrupts */
DMA_IRQMask = 0xC000FFFF;
DMA_Stat = 0xC000FFFF;
DMA_Enable = 0x00000000;
DMA2Count = DMA3Count = 0;
/* channel 2 is for UART TX */
DMA2Source = SDRAM_WR_ADDR;
DMA2Dest = DMA_UART_PORT;
DMA2Length = UART_DATA_LENGTH;
/* 8 bit, src is memory, dest is UART */
DMA2Config = (0x02<<10)|(0x0<<5)|(DMA_UART_TX<<0);
/* channel 3 is for UART RX */
DMA3Source = DMA_UART_PORT;
DMA3Dest = SDRAM_RD_ADDR;
DMA3Length = UART_DATA_LENGTH;
/* 8 bit, src is UART, dest is memory */
DMA3Config = (0x02<<10)|(DMA_UART_RX<<5)|(0x0<<0);
if ( install_IRQ(25, 1, DMA_ISR ) == FALSE )
{
return( FALSE );
}
INT_REQ25=(1<<28)|(1<<27)|(1<<26)|(1<<16)|0x1;
INT_VECTOR0=IRQ_TABLE_BASE & MASK_INDEX;
return (TRUE);
}
/******************************************************************************
** End Of File
******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -