Hi,
I have a project that sets up a PSP UPP driver for the C6748 DSP to capture 8 bit data from an ADC. I modeled the code from the PSP UPP example found in PSP driver 01.30.01.
I set the peripheral up for channel A receive mode, create the input channel using (SIO_create), set up the DMA using (SIO_issue), and then have the code run in a continuous for loop with the SIO_reclaim and SIO_issue functions to recycle the input buffers.
This setup works great when I set NUM_BUFS to 1. When I set NUM_BUFS to 2 or greater, the data collection still happens, but the data keeps shifting location within the receive buffers. When there was only 1 buffer, the data frame remained stationary.
The ADC spits out 8 bit data where an entire frame is equal to 2546 elements. I set up the receive buffer to be 2546 elements long. How do I get each receive buffer to capture each full frame without shifting to take place?
Here is my code:
/*===============================================================================================================================================
* Include Files
*=============================================================================================================================================*/
// DSP/BIOS and CSL Headers
#include <stdio.h>
#include <std.h>
#include <sio.h>
#include <iom.h>
#include <log.h>
#include <tsk.h>
#include <string.h>
#include "ti/pspiom/upp/Upp.h"
/* ========================================================================== */
/* IMPORTED VARIABLES */
/* ========================================================================== */
extern LOG_Obj trace;
/* ========================================================================== */
/* MACRO DEFINITIONS */
/* ========================================================================== */
#define NUM_BUFS 1 /* Max of 1 outstanding requests */
#define BUFALIGN 128 /* align buffers to 128 bytes */
#define BUFSIZE 2546 /* 2.5K of data receive */
/* ========================================================================== */
/* LOCAL VARIABLES */
/* ========================================================================== */
/* Handle for RX channel */
static SIO_Handle uppInHandle = NULL;
/* array to hold the pointer to the allocated buffers */
Ptr buf[NUM_BUFS];
/* Data structures to be used for submit */
Upp_transParam transParam[NUM_BUFS];
/* currently processed packet count */
Uint32 pktCount = 0;
/* parameters for channel A */
Upp_ChanParams uppChanparamA =
{
TRUE, /* enable cache */
Upp_ChanSel_A, /* channel A select */
Upp_bitWidth_8, /* 8 data bits */
Upp_dataRate_SINGLE, /* single data rate */
Upp_ChanMode_NORMAL, /* normal channel mode */
Upp_dataPackFmt_RJZE, /* right justified data packet */
750000, /* 750KHZ data rate */
0xFFFF, /* idle value */
NULL,
NULL,
NULL,
NULL,
Upp_fifoThreshold_64, /* FIFO threshold of 64 */
{
TRUE, /* start signal */
Upp_polarity_ACTIVE_HIGH,
TRUE, /* enable signal */
Upp_polarity_ACTIVE_HIGH,
TRUE, /* wait signal */
Upp_polarity_ACTIVE_HIGH,
Upp_clkPol_RISING_EDGE_SYNC, /* sync data to rising edge of input clock */
Upp_PinIdleState_IDLE_VAL,
}
};
/* ========================================================================== */
/* LOCAL FUNCTIONS */
/* ========================================================================== */
static Void uppCreateStreams(Void);
static Void uppDriverPrime(Void);
void delay(Uint32 count);
/* ========================================================================== */
/* FUNCTION DEFINTIONS */
/* ========================================================================== */
/*
* \brief This function demonstrates the use of Upp in receive mode
*
* \param None
*
* \return None
*/
Void startUPP(Void)
{
Upp_transParam *rcv = NULL;
Int32 nmadus0 = 0;
/* create the streams required for the transactions */
uppCreateStreams();
/* prime the driver */
uppDriverPrime();
printf("Starting data capture...\n");
for(;;)
{
/* Reclaim full buffer from the input stream */
nmadus0 = SIO_reclaim(uppInHandle, (Ptr *)&rcv, NULL);
if (nmadus0 < 0)
{
printf("Error reclaiming full buffer from the input stream\n");
}
/* Issue an empty buffer to the input stream */
if (SIO_issue(uppInHandle, rcv, BUFSIZE, NULL) != SYS_OK)
{
printf("Failed to issue empty buffer to stream\n");
}
pktCount++;
}
}
/**
* \brief Function to submit requests to the driver.
*
* \param None
*
* \return None
*/
static Void uppDriverPrime(Void)
{
Uint32 count = 0;
for (count = 0; count < NUM_BUFS; count++)
{
transParam[count].windowAddr = buf[count];
transParam[count].bytesPerLine = BUFSIZE;
transParam[count].lineCount = 1;
transParam[count].lineOffset = 0;
if (IOM_COMPLETED
!= SIO_issue(uppInHandle, (Ptr)&transParam[count], BUFSIZE, NULL))
{
printf("Issue to input stream failed.\n");
SYS_abort("Issue to input stream failed.\n");
}
}
printf("UPP DMA channel parameters set.\n");
}
/**
* \brief Function to create the required streams for the reception of Upp data.
*
* \params NONE
*
* \return NONE
*/
Void uppCreateStreams(Void)
{
SIO_Attrs sioAttrs = SIO_ATTRS;
Uint32 count = 0;
sioAttrs.nbufs = NUM_BUFS;
sioAttrs.align = BUFALIGN;
sioAttrs.model = SIO_ISSUERECLAIM;
/* Create RX channel */
uppInHandle = SIO_create("/dioUppIN", SIO_INPUT, BUFSIZE, &sioAttrs);
if (NULL == uppInHandle)
{
printf("Stream Creation Failed.\n");
SYS_abort("Stream Creation Failed.\n");
}
printf("Input UPP channel created.\n");
/* create and zero out the buffers required for the RX operation */
for (count = 0; count < (NUM_BUFS ); count++)
{
buf[count] = (Ptr)MEM_calloc(0, BUFSIZE, BUFALIGN);
if (NULL == buf[count])
{
printf("MEM_calloc failed.\n");
SYS_abort("MEM_calloc failed.\n");
}
}
printf("Input buffers allocated.\n");
}
/*
* \brief entry point function for the Upp task.
*
* \params None
*
* \return None.
*/
Void uppCaptureTask(Void)
{
printf("Starting Capture Task.\n");
startUPP();
}