Project

General

Profile

RE: SPI interface for ADC5560 (MityDSP L138F) » ADS5560.cpp

Vivek Ponnani, 07/24/2017 03:40 PM

 
/**
* @file ADS5560.cpp
* @author James Thesing <james.thesing@criticallink.com>
* @version 1.0
*
* @section LICENSE
*
*
* o 0
* | / Copyright (c) 2005-2011
* (CL)---o Critical Link, LLC
* \
* O
*
*
* @section DESCRIPTION
*
* This class handles exercising the ADS5560 on the DSP. Input data is
* acquired through an analog source, and capture data is sent back
* to the ARM.
*/



#include "ADS5560.h"
#include "core/DspUpp.h"
#include "core/DspSyscfg.h"
#include "core/chipconfig.h"
#include "core/cl_ipc_inbound.h"
#include "core/cl_ipc_outbound.h"


#include <std.h>
#include <tsk.h>
#include <clk.h>
#include <vector>
#include <string>
#include <cmath>
#include <stdio.h>


using namespace std;
using namespace MityDSP;

const int BUFF_SIZE = 32000; //size of buffers used in upp link
const int SAMPLE_SIZE = 200000; //amount of data to collect

//set up buffers
#pragma DATA_ALIGN( 64 );
int16_t buff1[ BUFF_SIZE ];
int16_t buff2[ BUFF_SIZE ];
int16_t buff3[ BUFF_SIZE ];


// Forward declarations
string convertInt(int number);
void init();
void debugPrint( char *buffer );
int handleInboundMessage( void *apBuffer, uint32_t anLength, void *apUserArg ) ;


// Object for sending debug messages (these are received and printed to stdout by tcDspApp)
tcCL_IPCOutbound* gpDebug;
// Object for sending GPPMSGQ1 messages that the ARM will receive
tcCL_IPCOutbound* gpOutbound;
// Object for receiving DSPMSGQ0 messages that the DSP will receive
tcCL_IPCInbound* gpInbound;

// Initialize static member variables
ADS5560* ADS5560::mpUppSignal = NULL;

// uPP configuration record
static const tcDspUpp::tsDspUppConfig gsUppConfig =
{
4, // Interrupt level. Must be between 4 and 15.
9, // Chan A DMA thread handling priority
9, // Chan B DMA thread handling priority
tcDspUpp::eeTransmit, // Directionality of Channel A.
tcDspUpp::eeReceive, // Directionality of Channel B.
tcDspUpp::ee16Bit, // Chan A data bit width.
tcDspUpp::ee16Bit, // Chan B data bit width.
false, // Use XData[7:0] for ChanA[15:8] even if ChanB is
// disabled. See Table 3 in uPP User's Guide for details.
4, // Size of MBX for Channel A.
4, // Size of MBX for Channel B.
1, // Clock divider for Channel A (37.5 MHz output clock)
// (only in transmit mode). See Section 2.1.1 in uPP User's
// Guide for details. Value must be between 1 and 16.
0, // Clock divider for Channel B
// (only in transmit mode). See Section 2.1.1 in uPP User's
// Guide for details. Value must be between 1 and 16.
tcDspUpp::ee256Bytes, // Chan A Transmit Thresh
tcDspUpp::ee256Bytes, // Chan A Receive Thresh
tcDspUpp::ee256Bytes, // Chan B Transmit Thresh
tcDspUpp::ee256Bytes, // Chan B Receive Thresh
false, // Do not use Chan A start signal
false, // Do not use Chan B start signal
//tcDspUpp::eeUPP_2xTXCLK, // Using external 2xTxClk for Transmit
tcDspUpp::eePLL0_SYSCLK2,
0 // uPP DMA Master Priority
};

/**
* Private Constructor - initializes the digital output logic
*/
ADS5560::ADS5560()
: mpDspUpp(NULL)
, meXmitChan(tcDspUpp::eeChanA)
, mhXmitMbx(NULL)
, meRecvChan(tcDspUpp::eeChanB)
, mhRecvMbx(NULL)
, filled(false)
{
char debug2[] = "getting instance of DSPuPP\n";
char debug3[] = "configuring UPP\n";
char debug4[] = "upp configured\n";
// Get instance of DspUpp
debugPrint(debug2);
mpDspUpp = tcDspUpp::getInstance();

// Configure uPP
debugPrint(debug3);
if (0 != mpDspUpp->initialize(&gsUppConfig))
{
char debug1[] = "failed configuring upp";
debugPrint(debug1);
}
else
{
debugPrint(debug4);
// Get the receive and transmit mailboxes
mhXmitMbx = mpDspUpp->getMBX(meXmitChan);
mhRecvMbx = mpDspUpp->getMBX(meRecvChan);
}
//while(lbWaitForMe == true){};
}

/**
* Initializes the DSP link and registers message handler
*/
void init()
{
// Message to ARM core.
char lpReturnMessage[] = "DSP Initialization finished.";
// Buffer for return message
char* lpMessageBuffer = NULL;

// Create the outbound debug link
gpDebug = new tcCL_IPCOutbound("debug");

// Create the inbound link for messages to the DSP
gpInbound = new tcCL_IPCInbound();

gpInbound->Open("DSPMSGQ0", 8);

// Create the outbound controller for sending messages to the ARM
gpOutbound = new tcCL_IPCOutbound("GPPMSGQ1");

if (NULL != gpInbound)
{
// Register a callback function to handle messages from the ARM
gpInbound->RegisterCallback(handleInboundMessage, (void*)NULL);
}

// Now that initialization is complete, let the ARM know with a message

// Obtain a dsplink buffer for the return message
lpMessageBuffer = (char*)gpOutbound->GetBuffer(strlen(lpReturnMessage) + 1);

// Make sure we received a valid buffer
if (NULL != lpMessageBuffer)
{
// Copy our message to the buffer
strcpy(lpMessageBuffer, lpReturnMessage);

// Send the message back to the ARM
gpOutbound->SendMessage(lpMessageBuffer);
}
}

/**
* Gets data from the upp interface
* @param SAMPLE_SIZE amount of samples to collect
*/
void ADS5560::getData( int SAMPLE_SIZE ){
char debug1[] = "failed to send received buffer to upp\n";
char debug7[] = "failed to send data\n ";

int dataR = 0; //keep track of amount of data collected
bool finished = false; //do not calculate if already done

//get a receive mailbox
tcDspUpp::tsMbxMsg lsRecvMbxMsg;
int16_t* lpMessageBuffer = NULL;

//turn on ADC by writing to register 0x66000202
unsigned short *ptr = ( unsigned short* )0x66000202;
*ptr = 1;

//send buffers to upp to fill
if (0 != mpDspUpp->receive(meRecvChan, (uint8_t*)buff1,
(uint16_t)(BUFF_SIZE * 2) ) )
{
debugPrint(debug1);
}

if (0 != mpDspUpp->receive(meRecvChan, (uint8_t*)buff2,
(uint16_t)(BUFF_SIZE * 2) ) )
{
debugPrint(debug1);
}

if (0 != mpDspUpp->receive(meRecvChan, (uint8_t*)buff3,
(uint16_t)(BUFF_SIZE * 2) ) )
{
debugPrint(debug1);
}

// Wait for receive to finish, send data to ARM and give
// upp buffer back
while( !finished )
{

MBX_pend(mhRecvMbx, &lsRecvMbxMsg, SYS_FOREVER);
//get finished buffer
lpMessageBuffer = (int16_t*)gpOutbound->GetBuffer(sizeof(int16_t)*BUFF_SIZE);
if (NULL != lpMessageBuffer)
{

// Copy uppData to the send buffer
memmove(lpMessageBuffer, lsRecvMbxMsg.pBufPtr ,sizeof(int16_t)*BUFF_SIZE );

// Send the message back to the ARM
gpOutbound->SendMessage(lpMessageBuffer);
//send buffer to upp to fill
if (0 != mpDspUpp->receive(meRecvChan, (uint8_t*)lsRecvMbxMsg.pBufPtr,
(uint16_t)(BUFF_SIZE * 2) ) )
{
debugPrint(debug1);
}
//check to see if enough samples have been collected
if (dataR < (SAMPLE_SIZE - BUFF_SIZE))
{
dataR += BUFF_SIZE;
}
else
{
//loop break when enough data collected
finished = true;
}
}
else
{
debugPrint(debug7);
}

}
//turn off ADC by writing to register 0x66000202
*ptr = 0;
}



/**
* Return instance of object or create one to enforce
* singleton use
*/
ADS5560*
ADS5560::getInstance()
{
if (NULL == mpUppSignal)
mpUppSignal = new ADS5560();
return mpUppSignal;
}

/**
* Destructor
*/
ADS5560::~ADS5560()
{

}

/**
* Main routine for DSPAPP
*/
int main(int argc, char* argv[])
{

// initialize the DSPLink system
tcCL_IPCInit::GetInstance();

// Launch an initialization task
TSK_Attrs* lpAttrs = new TSK_Attrs;
*lpAttrs = TSK_ATTRS;
lpAttrs->name = "Initialize";
lpAttrs->stacksize = 8192*2;
lpAttrs->priority = 5;
TSK_create((Fxn)init,lpAttrs);
return 0;
}

/**
* handles messages received from the arm
* @param apBuffer buffer location of message
* @param anLength length of buffer used
* @param apUserArg user given arguments
* @return 0;
*/
int handleInboundMessage(void* apBuffer, uint32_t anLength, void* apUserArg)
{
char debug1[] = "Failure to communicate with arm\n";
char returnMsg[] = "DSP App finished\n";
char* lpMessageBuffer = NULL;

lpMessageBuffer = (char*)gpOutbound->GetBuffer(strlen(returnMsg) + 1);
if (NULL != lpMessageBuffer)
{
// Copy message to the buffer
strcpy(lpMessageBuffer, returnMsg);
}
else
{
debugPrint( debug1 );
}
ADS5560* mhUppSignal = ADS5560::getInstance();
mhUppSignal->getData( SAMPLE_SIZE );
gpOutbound->SendMessage( lpMessageBuffer );
return 0;
}

/**
* prints a character array through a debug IPC object
* output is: "[DSP] <msg>"
* @param pMsg - character array of message to print
*/
void debugPrint(char* pMsg)
{
// The length of the message to be sent
int len = strlen(pMsg);
// Pointer to dsplink buffer where to write the message
char* pBuffer;

// Make sure the debug IPC outbound object has been initialized
if (gpDebug == NULL)
return;

// Get a buffer for the message
pBuffer = (char *)gpDebug->GetBuffer(len+1);

// Check that the buffer is valid
if (pBuffer)
{
// Copy the message to the buffer
strcpy(pBuffer, pMsg);
// Send the message
gpDebug->SendMessage(pBuffer);
}
}

(2-2/4)