|
/**
|
|
* @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);
|
|
}
|
|
}
|
|
|