Здравствуйте.
Счас пытаюсь освоить ДМА для ниоса.
Прочитал описание альтеры для компонента, на ниос-форуме посмотрел примеры и сваял свою реализацию..
В обсчем код выглядит так(звиняйте если большой, но коментарии присутствуют):
Код
//===ISR part===
static void dma_isr ( void * context2, alt_u32 irqnum2 )
{
asm("nop");
//set flag
dmaf=1;
/* Clear any pending interrupts and the DONE flag */
IOWR_ALTERA_AVALON_DMA_STATUS (DMA_BASE, 0);
}
//===END ISR part===
//---MAIN---
int main (void)
{
asm ("nop");
//
unsigned char i=0;
// initial values
cnt_val=0;
ch=0;
txf=0;
dmaf=0;
//
for (i=0;i<12;i++)
{
inbuffer[i]=0;
outbuffer[i]=i+1;
}
//
//
asm("nop");
//register DMA ISR
alt_irq_register(DMA_IRQ,(void*)DMA_BASE,dma_isr);
asm("nop");
asm("nop");
//
//DMA_Init
/* Clear any pending interrupts and the DONE flag */
IOWR_ALTERA_AVALON_DMA_STATUS (DMA_BASE, 0);
asm("nop");
asm("nop");
//clear control register
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_BASE, 0);
asm("nop");
asm("nop");
/* Halt any current transactions (reset the device) */
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_BASE, ALTERA_AVALON_DMA_CONTROL_SOFTWARERESET_MSK);
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_BASE, ALTERA_AVALON_DMA_CONTROL_SOFTWARERESET_MSK);
asm("nop");
asm("nop");
asm("nop");
//asm("nop");
//set initial values for tranmit
//byte orientating transfer
alt_u32 control=0;
control |= ALTERA_AVALON_DMA_CONTROL_BYTE_MSK;//byte transfer
control |= ALTERA_AVALON_DMA_CONTROL_I_EN_MSK;//enable int
control |= ALTERA_AVALON_DMA_CONTROL_LEEN_MSK;//enable end of transaction by reacing Len 0
//1st try with mem massives -> no uart
//control |= ALTERA_AVALON_DMA_CONTROL_RCON_MSK;//read from constant mem - we use uart, so mem == const
//store control
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_BASE, control);
asm("nop");
asm("nop");
//**
//DMA_start((int)&inbuffer[0],(int)&outbuffer[0],10);
//**
waddr = (int)&inbuffer[0];
raddr = (int)&outbuffer[0];
len=10;
//alt_u32 control;
control=0;
//wrire read addr
IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE, raddr);
asm("nop");
asm("nop");
//wrire write addr
IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE, waddr);
asm("nop");
asm("nop");
//write length
IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE,len);
asm("nop");
asm("nop");
//start transfer
control = IORD_ALTERA_AVALON_DMA_CONTROL (DMA_BASE);
control |= ALTERA_AVALON_DMA_CONTROL_GO_MSK;
IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_BASE, control);
//
dmaf=0;
asm("nop");
//**
while (1)
{
/***/
wlabel:
asm("nop");
//
if (dmaf==0) goto wlabel;
asm("nop");
IOWR_ALTERA_AVALON_PIO_DATA(SEVEN_SEGMENT_PORT_BASE,segments[inbuffer[0]] );
asm("nop");
while (1);
/***/
}
return 0;
}
В обсчем, компилируется всё нормально, код вроде выглядить при дебуге нормально,
однако есть непонятные моменты...
Если поставить точек прерываний по коду в ключевых местах - регистрация прерывания, запись контрола ДМА, старт ДМА - то всё отрабатывается нормально, если только на старте ДМА - то интерупт генерится а действия никакого..
Если вообсче не ставить точек прерывания - то ничего не отрабатывается - интерупта нет.. ничего нет...
Дебаг юнит в НИОСЕ - 2-й, 3-й - без разницы.
Read и Write каналы соединены с уартом и сдрам, программа находтся в сдрам, переменные - тоже.
В принципе такое поведение наталкивает на мысль , что не хватает задержек (только не пойму зачем, вроде в описании к ДМА не было про них...) , потому и наставил нопов - однако с ними и без них - работает одинаково...
Кто работал с ДМА - подскажите что не так ..
Спасибо.