Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
All support for Intel NUC 7 - 13 systems has transitioned to ASUS. Read latest update.
12577 Discussions

could not use SGDMA callback function in uCOS depneding on NiosII

Honored Contributor II

hellow, i use the SGDMA API in a task of uCOS based on nios, i send the data through "SGDMA mem to streaming" , and receive data through "SGDMA streaming to mem", i connect the out pins of "SGDMA mem to streaming" and in pins of "SGDMA streaming to mem" derectly. 


it can work that receive the data, but it always drop some points, and when i change the buffer mem of sending(store_buff), the number of drop points. i do not know why. 


Moreover, i can not use callback function of SGDMA that it call error when isr function is added to coding. 


Can anyone help me? the coding is following: 

/* <stdlib.h>: Contains C "rand()" function. */# include <stdlib.h> /* <stdio.h>: Contains C "printf()" function. */# include <stdio.h> /* MicroC/OS-II definitions */# include "includes.h" # include <string.h># include "sys/alt_alarm.h"# include "system.h"# include "nios2.h" /* * Device driver accessor macros for peripherial I/O component * (used for leds).) */# include "altera_avalon_pio_regs.h" /* Simple Socket Server definitions */# include "niosII_simple_socket_server.h" /* Altera Error Handler suite of development error * handling functions. */# include "alt_error_handler.h" //SG-DMA DEFINITION.# include "altera_avalon_sgdma_descriptor.h"# include "altera_avalon_sgdma_regs.h"# include "altera_avalon_sgdma.h"# include "alt_types.h" # include "altera_avalon_tse.h" # include "sys/alt_irq.h" /* * The LedManagementTask() is a simple MicroC/OS-II task that controls the * LEDBlinkTask based on commands received by the * SSSimpleSocketServerTask in the SSSLEDCommandQ. * * The task will read the SSSLedCommandQ for an * in-coming message command from the SSSimpleSocketServerTask, convert the * command to an led frequency, and post the frequency to the * SSSLEDFreqMailbox mailbox for the LEDBlinkTask. */ /*when use callback function , the irq function(sgdma_rx_isr() ) adds into code, it will make error. void sgdma_rx_isr(void *context); { if(IORD_ALTERA_AVALON_SGDMA_STATUS(MY_FFT_FFT_SGDMA_RX_BASE) & ALTERA_AVALON_SGDMA_STATUS_EOP_ENCOUNTERED_MSK) { sgdma_rx_finish = 1; } printf("tx interrupt routine.\n\r"); } void sgdma_tx_isr(void *context); { if(IORD_ALTERA_AVALON_SGDMA_STATUS(MY_FFT_FFT_SGDMA_RX_BASE) & ALTERA_AVALON_SGDMA_STATUS_EOP_ENCOUNTERED_MSK) { sgdma_tx_finish = 1; } printf("tx interrupt routine.\n\r"); } */ void ManagementTask() { INT32U fft_point; INT8U error_code = 0; INT8U error_code_1 = 0; alt_u32 rx_payload; alt_u32 store_buff; // when change the store_buff size, the number of drop points will change. alt_u32 *store_wr_pos; store_wr_pos= store_buff; alt_u32 *store_rd_pos; store_rd_pos= rx_payload; int pend_rx_loop = 1024; int point_to_send = 1024; int timeout0=0; int timeout1=0; int timeout2=0; int sgdma_tx_flag=1; int sgdma_rx_flag=1; alt_u16 sgdma_tx_bytes_num = 4096; static INT32U send_point; alt_sgdma_dev *sgdma_tx_dev; alt_sgdma_dev *sgdma_rx_dev; alt_sgdma_descriptor *desc; //define desc DISCRIPTOR_MEMORY_BASE in system.h desc = (alt_sgdma_descriptor *) SGDMA_SUB_FFT_DECRIPTOR_BASE; //open sgdma_tx and sgdma_rx sgdma_tx_dev = alt_avalon_sgdma_open(SGDMA_SUB_FFT_SGDMA_TX_NAME); if(!sgdma_tx_dev) { printf(" Error opening TX SGDMA\n"); } sgdma_rx_dev = alt_avalon_sgdma_open(SGDMA_SUB_FFT_SGDMA_RX_NAME); if(!sgdma_rx_dev) { printf(" Error opening RX SGDMA\n"); } printf("sgdma_tx_dev is %d,sgdma_rx_dev is %d\n\r",(int) sgdma_tx_dev,(int)sgdma_rx_dev); printf("base_tx is %d,base_rx is %d\n\r",(int) sgdma_tx_dev->base,(int)sgdma_rx_dev->base); // Reset RX-side SGDMA IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_SUB_FFT_SGDMA_RX_BASE, ALTERA_AVALON_SGDMA_CONTROL_SOFTWARERESET_MSK); IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_SUB_FFT_SGDMA_RX_BASE, CHAIN_CONTORL); // Reset TX-side SGDMA IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_SUB_FFT_SGDMA_TX_BASE, ALTERA_AVALON_SGDMA_CONTROL_SOFTWARERESET_MSK); IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_SUB_FFT_SGDMA_TX_BASE, CHAIN_CONTORL); IOWR_ALTERA_AVALON_SGDMA_STATUS(SGDMA_SUB_FFT_SGDMA_TX_BASE, 0xFF); /* //regist sgdma_tx callback; alt_avalon_sgdma_register_callback( sgdma_tx_dev, (alt_avalon_sgdma_callback) &sgdma_tx_isr, (alt_u16) CHAIN_CONTORL, NULL); //regist sgdma_rx callback; alt_avalon_sgdma_register_callback( sgdma_rx_dev, (alt_avalon_sgdma_callback) &sgdma_rx_isr, (alt_u16) CHAIN_CONTORL, NULL); // initial interrupt of tx&rx sgdma_tx_irq_initial(sgdma_tx_dev); sgdma_rx_irq_initial(sgdma_rx_dev); */ //construct stream to mem descriptor; alt_avalon_sgdma_construct_stream_to_mem_desc( &desc, //descriptor now &desc, //descriptor next rx_payload, //receive addr 0, //length or eop 0); //write_fixed //construct mem to stream descriptor; alt_avalon_sgdma_construct_mem_to_stream_desc( &desc, //descriptor now &desc, //descriptor next store_buff, //tx_pointer (sgdma_tx_bytes_num), //tx_size 0, //read_fixed 1, //SOP 1, //EOP 0); // while(1) { // receive the data through Queue. while(pend_rx_loop--) { fft_point = (INT32U)OSQPend(MsgQueue, 0, &error_code); alt_uCOSIIErrorHandler(error_code, 0); *store_wr_pos = fft_point; store_wr_pos = store_wr_pos +1; } //start sgdma_rx while(IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_SUB_FFT_SGDMA_RX_BASE)&ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) { printf("timeout_rx is %d\r\n",(int)timeout1); timeout1++; } sgdma_rx_flag = alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc); //start sgdma_tx while((IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_SUB_FFT_SGDMA_TX_BASE)&ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK)) { printf("timeout_tx is %d\r\n",(int)timeout0); timeout0++; } sgdma_tx_flag = alt_avalon_sgdma_do_sync_transfer(sgdma_tx_dev, &desc); store_wr_pos = store_buff; if(!sgdma_rx_flag) { if(IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_SUB_FFT_SGDMA_RX_BASE) & ALTERA_AVALON_SGDMA_STATUS_EOP_ENCOUNTERED_MSK) { if(IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_SUB_FFT_SGDMA_RX_BASE)&(RD_READY)) { printf("RX descriptor reported OK,rx_payload is %d\n\r",(int) rx_payload); while(point_to_send--) { send_point=*(store_rd_pos++); printf("send_point is %d\n\r",(int)send_point); error_code_1 = OSQPost(SendQueue, (void *)send_point); alt_SSSErrorHandler(error_code_1, 0); } } } int tx_act_bytes= IORD_ALTERA_TSE_SGDMA_DESC_ACTUAL_BYTES_TRANSFERRED(desc+2) ; int rx_act_bytes= IORD_ALTERA_TSE_SGDMA_DESC_ACTUAL_BYTES_TRANSFERRED(desc) ; int tx_bytes= IORD_ALTERA_TSE_SGDMA_DESC_BYTES_TO_TRANSFER(desc+2); int rx_bytes= IORD_ALTERA_TSE_SGDMA_DESC_BYTES_TO_TRANSFER(desc); int rx_wradd = IORD_ALTERA_TSE_SGDMA_DESC_WRITE_ADDR(desc); int tx_rdadd = IORD_ALTERA_TSE_SGDMA_DESC_READ_ADDR(desc+2); printf("rx_payload is %d,rx_payload is %d\n\r ",(int)rx_payload,(int)rx_payload); printf("tx_bytes_transfer is %d,rx_actual_transfer is %d\n\r tx_actual_bytes_transfer is %d,rx_actual_bytes_transfer is %d\n\r", (int)tx_bytes,(int)rx_bytes,(int)tx_act_bytes,(int)rx_act_bytes); printf("rx_wradd is %d,rx_payload is %d\n\r tx_rdadd is %d,store_buff is %d\n\r", (int)rx_wradd,(int)rx_payload,(int)tx_rdadd,(int)store_buff); } } // while(1) }
0 Kudos
1 Reply
Honored Contributor II

i had solve this problem that, i put the sub-routine into another c file, such as "sgdma_rx", "sgdma_tx", and the isr routines for tx and rx;  

then in the task of uCOS, calling these sub-routine, then it worked and can use the callback function , and enter into interrupt routines.
0 Kudos