- UID
- 164940
- 性别
- 男
|
我在做一个nios+vga显示的东东。
配置文件已经烧写到配置芯片中。
但是写的程序。在第一次上电或复位后可以进入dma中断一次,之后就无法进入了。而且这时再重新运行一遍程序也无法进入中断。这是为什么?可以知道程序在运行,我外接二极管在走跑马灯。
程序如下;
#include <stdio.h>
#include "sys/alt_dma.h"
#include "../inc/sopc.h"
#include <system.h>
#include <alt_types.h>
#include "altera_avalon_dma.h"
#include "sys/alt_irq.h"
#include "altera_avalon_dma_regs.h"
#define VGA_WIDTH 640
#define VGA_HEIGHT 480
static volatile unsigned char *P_VGA = (unsigned char *)(VGA_CONTROLLER_STREAM_0_BASE);
static volatile unsigned char *P_VGA_RAM = (unsigned char *)(SDRAM_BASE + 0x300000);
const unsigned long TLENGTH = VGA_WIDTH * VGA_HEIGHT;
//void clear_bk(unsigned int left, unsigned int top, unsigned int width, unsigned int height, unsigned char color);
//void init_dma(void);
//void DMA_interrupts(void * context, alt_u32id);
void clear_bk(unsigned int left, unsigned int top, unsigned int width, unsigned int height, unsigned char color)
{
unsigned long addr;
unsigned int i,j;
for(i=0; i<height; i++)
{
for(j=0;j<width;j++)
{
addr = (VGA_WIDTH * (top + i)) + left + j;
if(addr > TLENGTH)
addr %= TLENGTH;
P_VGA_RAM[addr] = color;
}
}
}
void DMA_interrupts(void * context, unsigned int id)
{
int si = IORD_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE);
if(si & 0x1)
{
IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE,0);
IOWR_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE,0);
IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE,0);
IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_0_BASE,TLENGTH);
IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_0_BASE,(int)P_VGA_RAM);
IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_0_BASE,(int)P_VGA);
IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE,
ALTERA_AVALON_DMA_CONTROL_WORD_MSK |
ALTERA_AVALON_DMA_CONTROL_GO_MSK |
ALTERA_AVALON_DMA_CONTROL_I_EN_MSK |
ALTERA_AVALON_DMA_CONTROL_WCON_MSK |
// ALTERA_AVALON_DMA_CONTROL_WEEN_MSK |
ALTERA_AVALON_DMA_CONTROL_LEEN_MSK
);
IOWR_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE,0);
alt_dma_txchan_open("/dev/dma_0");
}
}
void init_dma(void)
{
if(alt_irq_register(DMA_0_IRQ,0,DMA_interrupts)==0)
{
printf("irq ok!\n");
}
IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE,0);
IOWR_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE,0);
IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_0_BASE,TLENGTH);
IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_0_BASE,(int)P_VGA_RAM);
IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_0_BASE,(int)P_VGA);
IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE,
ALTERA_AVALON_DMA_CONTROL_WORD_MSK |
ALTERA_AVALON_DMA_CONTROL_GO_MSK |
ALTERA_AVALON_DMA_CONTROL_I_EN_MSK |
ALTERA_AVALON_DMA_CONTROL_WCON_MSK |
// ALTERA_AVALON_DMA_CONTROL_WEEN_MSK |
ALTERA_AVALON_DMA_CONTROL_LEEN_MSK
);
alt_dma_txchan_open("/dev/dma_0");
}
int main()
{
clear_bk(0,0,VGA_WIDTH,VGA_HEIGHT,0x3);
init_dma();
while(1)
{
int i;
for(i=0; i<3; i++)
{
LED->DATA = 1<<i;
}
}
return 0;
} |
|