Thanks for the info Socrates. I've come a long way in the past few days using some example code that you or BadOmen posted. Im still a little hazy on my SOPC/ADC driver design though. Attached is a Jpeg and the driver VHDL code.
Lastly, like I mentioned above, I modified the C code that you or BadOmen posted in another thread to read off the onboard ram once it is filled by the ADC and print to the screen via stdout. Unfortunately, it is only printing addresses even though I am de-referencing the memory address pointer.
If you could, can you take a look at the following and attached code? Im not sure what I am doing wrong, but I think I'm pretty close.
Thanks
Matt
#include "io.h"# include "stdio.h"# include "stdlib.h"# include "system.h"# include "alt_types.h"# include "altera_avalon_sgdma.h"# include "altera_avalon_sgdma_regs.h"# include <sys/alt_cache.h># include <sys/stdio.h># include <math.h>
# define NUMBER_OF_BUFFERS 10 /* each direction so double this for the total */# define MINIMUM_BUFFER_LENGTH 50# define MAXIMUM_BUFFER_LENGTH 1500 /* set this to the same value as the min for a fixed size, also don't exceed 65535 */
volatile alt_u8 rx_done = 0;
alt_sgdma_dev *DEVICE;
alt_sgdma_descriptor *dma_descriptors, *dma_descriptors_copy;
void dma_interrupt(void * context) {
rx_done=1; /* main will be polling for this value being 1 */
}
alt_u8 allocate_descriptors(alt_sgdma_descriptor **dma_descriptors,
alt_sgdma_descriptor **dma_descriptors_copy,
alt_u32 num_buffers)
{
void *temp_pointer;
temp_pointer = malloc((num_buffers + 2) * ALTERA_AVALON_SGDMA_DESCRIPTOR_SIZE);
if(temp_pointer==NULL) return 1;
*dma_descriptors_copy = (alt_sgdma_descriptor *)temp_pointer;
while((((alt_u32)temp_pointer) % ALTERA_AVALON_SGDMA_DESCRIPTOR_SIZE) != 0) temp_pointer++; // Limit size @ 32 bytes
*dma_descriptors = (alt_sgdma_descriptor *)temp_pointer;
dma_descriptors->control = 0; // Set IE_ERROR=0 bit in control register
return 0;
}
alt_u8 allocate_dma_buffers(alt_sgdma_descriptor *dma_descriptors, alt_u32 num_buffers) {
alt_u32 i, length = 0;
alt_u32 *data_pointer;
for(i=0; i<num_buffers; i++){
length = MINIMUM_BUFFER_LENGTH;
data_pointer = (alt_u32 *)malloc(length);
if(data_pointer == NULL) return 1;
alt_avalon_sgdma_construct_stream_to_mem_desc(&dma_descriptors, // descriptor
&dma_descriptors, // next descriptor
data_pointer, // write buffer location
MINIMUM_BUFFER_LENGTH, //(alt_u16)length, // I will wait for End Of Packet instead of fixed length
0); // writes are not to a fixed location
}
alt_dcache_flush_all();
return 0;
}
/* Making sure that there will be enough space for code (maximum of 1.5MB) */
int main(){
alt_putstr("Here");
alt_u8 returned = 0;
DEVICE = alt_avalon_sgdma_open("/dev/sgdma_0");
if(DEVICE == NULL)
{
alt_putstr("Could Not Find SGDMA Device");
return 1;
}
else
{
alt_putstr("Found SGDMA Device");
}
IOWR_ALTERA_AVALON_SGDMA_CONTROL(DEVICE->base,ALTERA_AVALON_SGDMA_CONTROL_SOFTWARERESET_MSK); // Reset SGDMA
IOWR_ALTERA_AVALON_SGDMA_CONTROL(DEVICE->base,0x0);
IOWR_ALTERA_AVALON_SGDMA_CONTROL(DEVICE->base, ALTERA_AVALON_SGDMA_CONTROL_PARK_MSK); // change park
returned = allocate_descriptors(&dma_descriptors, &dma_descriptors_copy, NUMBER_OF_BUFFERS);
if(returned) alt_putstr("### ERROR: Failed to allocate memory for descriptors!\n");
returned = allocate_dma_buffers(dma_descriptors,NUMBER_OF_BUFFERS); // Allocate data buffers and construct descriptors
if(returned) alt_putstr("### ERROR: Failed to allocate memory for data receive!\n");
alt_avalon_sgdma_register_callback(DEVICE, &dma_interrupt,
(ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK | ALTERA_AVALON_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK),
NULL);
//printf("%d", sizeof(alt_sgdma_descriptor));
// last descriptor needs to point to the first
dma_descriptors.next = (alt_sgdma_descriptor *)dma_descriptors;
printf("descriptor address: %d \n", dma_descriptors);
printf("final descriptor next: %d \n", dma_descriptors.next);
if(alt_avalon_sgdma_do_async_transfer(DEVICE, &dma_descriptors) != 0)
alt_putstr("FAIL! (Writing the head of the descriptor list to the DMA failed)\n");
int i = 0;
int j = 0;
for( i = 0; i < 10; i++)
{
if(alt_avalon_sgdma_do_async_transfer(DEVICE, &dma_descriptors) != 0)
alt_putstr("FAIL! (Writing the head of the descriptor list to the DMA failed)\n");
usleep(5000);
int k = 0;
/// problem area
for(j = 0; j < NUMBER_OF_BUFFERS; j++)
{
printf("%d ", IORD_32DIRECT((&dma_descriptors.write_addr),0));
//alt_putstr(&dma_descriptors.write_addr);
dma_descriptors.control = dma_descriptors.control | ALTERA_AVALON_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK;
}
// int k = 0;
// for(k = 0; k < NUMBER_OF_BUFFERS; k ++)
// {
// dma_descriptors.control = dma_descriptors.control | 0b10000001;
// }
}
//
// alt_putstr(">>> Starting SGDMA transfers... \n");
//
// if(alt_avalon_sgdma_do_async_transfer(DEVICE, &dma_descriptors) != 0)
// alt_putstr("FAIL! (Writing the head of the descriptor list to the DMA failed)\n");
//
//// while(rx_done == 0) {
//// alt_putstr("Something\n");
//// usleep(5000);
//// }
//
//
// usleep(500000);
//
// //alt_putstr(">>> The SGDMA transfer has completed, Done = %u\n",(unsigned int)rx_done);
//
//
//
//
//
// alt_avalon_sgdma_stop(DEVICE);
// //free(dma_descriptors_copy);
// //free(dma_descriptors);
//
// // do stuff to transfer the data off
//
// alt_putstr(" dumping data ");
// alt_u32 *data_pointer;
// int i = 0;
// for(i = 0; i < NUMBER_OF_BUFFERS; i++)
// {
// data_pointer = dma_descriptors.write_addr;
// alt_putstr(&data_pointer);
// }
//free(dma_descriptors_copy);
//free(dma_descriptors);
//alt_putstr("Working...\n");
return 0;
}