Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

FIFO -> DMA -> ONChipMem - Almost there.

Hello everyone my system consists of a fifo being filled inside my SOPC system, when it gets half full i get an IRQ and my DMA starts transfering DATA from the fifo to a onchip mem.

My fifo has 64 positions, half full is at 32 which means usedw will be at 6b'100000

My Onchip mem has 32bits of data, just like my FIFO and my DMA.

Everything is ALMOST working exepct for a lil thing..

My memory initialization and my memory after the DMA operation are having 4 times the same value.. I THINK that is because of my IOWR and IORD. If i try to read 8bits i have the value plus 3 zeros..

I am trying to get the 32 positions that are in my fifo correctly in my memory but i can't.

Please help me this is drivin me crazy

static volatile int txrx_done = 0;
int i,reg;
static void handle_button_interrupts(void* context, alt_u32 id);
volatile alt_u8 led=0;
/* A variable to hold the value of the button pio edge capture register. */
volatile int edge_capture;
volatile int irq_count;
//callback function when DMA transfer done
static void txrxDone(void * handle, void * data)
{
    txrx_done = 1;
}
void initMEM(int base_addr,int len)
{
    for ( i=0;i<len;i++)
    {
        IOWR(base_addr,i,i);
    }
}
int initdma(void)
{
    printf("testing fifo & onchip : dma operation\n");
    reg = IORD_ALTERA_AVALON_DMA_CONTROL (DMA_0_BASE);
    IOWR_ALTERA_AVALON_DMA_CONTROL (DMA_0_BASE, reg | ALTERA_AVALON_DMA_CONTROL_RCON_MSK);
   // alt_16 buffer;
    //memset((void *)SSRAM_0_BASE,0x7a,0x10);//this write base on byte
    initMEM(DESTINO_BASE,32);
 //   memset((void *)(DESTINO_BASE),10,32);
    printf("content of fifo:before DMA operation\n");
  //  for ( i=0;i<32;i++)
   // {
    //printf("%d: %x\n",0,IORD_8DIRECT(FIFOWRAPPER_0_BASE,0));
   // }
    printf("content of onchip:before DMA operation\n");
    for ( i=0;i<32;i++)
    {
        printf("%d: %x\n",i,IORD_32DIRECT(DESTINO_BASE,i));
    }
    int rc;    //request
    alt_dma_txchan txchan;
    alt_dma_rxchan rxchan;
    void* tx_data = (void*)FIFOWRAPPER_0_BASE; /* pointer to data to send */
    void* rx_buffer = (void*)(DESTINO_BASE); /* pointer to rx buffer */
    /* Create the transmit channel */
    if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == NULL)
    {
        printf ("Failed to open transmit channel\n");
        exit (1);
    }
    /* Create the receive channel */
    if ((rxchan = alt_dma_rxchan_open("/dev/dma_0")) == NULL)
    {
        printf ("Failed to open receive channel\n");
        exit (1);
    }
    /* Post the transmit request */
    if ((rc = alt_dma_txchan_send (txchan,
            tx_data,
            32,
            NULL,
            NULL)) < 0)
    {
        printf ("Failed to post transmit request, reason = %i\n", rc);
        //exit (1);
    }
    /* Post the receive request */
    if ((rc = alt_dma_rxchan_prepare (rxchan,
            rx_buffer,
            32,
            txrxDone,
            NULL)) < 0)
    {
        printf ("Failed to post read request, reason = %i\n", rc);
        //exit (1);
    }
    /* wait for transfer to complete */
    while (!txrx_done);
    printf ("Transfer successful!\n");
    printf("content of onchip:after DMA operation\n");
    for ( i=0;i<32;i++)
    {
        printf("%d: %x\n",i,IORD_32DIRECT(DESTINO_BASE,i));
    }
    return 0;
}
int main()
{
// Enable all 4 button interrupts.
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_0_BASE, 0xf);
// Reset the edge capture register.
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_0_BASE, 0x0);
// Register the interrupt handler.
alt_irq_register( PIO_0_IRQ,&edge_capture, handle_button_interrupts );
alt_irq_enable_all;
printf("loop start\n");
while(1)
{
    usleep(100000);
    if(led==1)
    {
        led = 2;
        initdma();
    }
    if (led==2){
        printf("FIM");
        while (1){}
    }
    printf("%i:",led);
}
return 0;
}
static void handle_button_interrupts(void* context, alt_u32 id)
{
// Cast context to edge_capture&#39;s type. It is important that this be
// declared volatile to avoid unwanted compiler optimization.
//
volatile int* edge_capture_ptr = (volatile int*) context;
// Store the value in the Button&#39;s edge capture register in *context.
*edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PIO_0_BASE);
// Reset the Button&#39;s edge capture register.
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_0_BASE, 0);
led=1;
}

Here is my NIOS2 Terminal

loop start
0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:testing fifo & onchip : dma operation
content of fifo:before DMA operation
content of onchip:before DMA operation
0: 0
1: 0
2: 0
3: 0
4: 1
5: 1
6: 1
7: 1
8: 2
9: 2
10: 2
11: 2
12: 3
13: 3
14: 3
15: 3
16: 4
17: 4
18: 4
19: 4
20: 5
21: 5
22: 5
23: 5
24: 6
25: 6
26: 6
27: 6
28: 7
29: 7
30: 7
31: 7
Transfer successful!
content of onchip:after DMA operation
0: 1
1: 1
2: 1
3: 1
4: 3
5: 3
6: 3
7: 3
8: 5
9: 5
10: 5
11: 5
12: 7
13: 7
14: 7
15: 7
16: 9
17: 9
18: 9
19: 9
20: b
21: b
22: b
23: b
24: d
25: d
26: d
27: d
28: f
29: f
30: f
31: f
FIM

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    if i initialize the memory with the memset having all adressess with 33 and using IORD_8DIRECT instead of what i was using i get this:

    
    loop start
    0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:testing fifo & onchip : dma operation
    content of fifo:before DMA operation
    0: 1
    0: 3
    0: 5
    0: 7
    0: 9
    0: b
    0: d
    0: f
    0: 11
    0: 13
    0: 15
    0: 17
    0: 19
    0: 1b
    0: 1d
    0: 1f
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    0: 20
    content of onchip:before DMA operation
    0: 33
    1: 33
    2: 33
    3: 33
    4: 33
    5: 33
    6: 33
    7: 33
    8: 33
    9: 33
    10: 33
    11: 33
    12: 33
    13: 33
    14: 33
    15: 33
    16: 33
    17: 33
    18: 33
    19: 33
    20: 33
    21: 33
    22: 33
    23: 33
    24: 33
    25: 33
    26: 33
    27: 33
    28: 33
    29: 33
    30: 33
    31: 33
    Transfer successful!
    content of onchip:after DMA operation
    0: 20
    1: 0
    2: 0
    3: 0
    4: 20
    5: 0
    6: 0
    7: 0
    8: 20
    9: 0
    10: 0
    11: 0
    12: 20
    13: 0
    14: 0
    15: 0
    16: 20
    17: 0
    18: 0
    19: 0
    20: 20
    21: 0
    22: 0
    23: 0
    24: 20
    25: 0
    26: 0
    27: 0
    28: 20
    29: 0
    30: 0
    31: 0
    FIM
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Humm instead of having my fifo incremented 1 by 1 i am getting it incremented 2 by 2 and only 17 results instead of 34..

    That's weird

    and here is my logic to write in the fifo 1 by 1

    begin
            contador <= contador +1;
            valid <= 0;
               if(usedw == 6'b100000)
                begin
                    valid <= 1;
                end
                if(contador == 40000000)
                begin
                    data_in <= data_in + 1;
                    wrclk <=1;
                end
                if(contador == 50000000)
                begin
                    wrclk <=0;
                    contador <= 0;
                end
    end