Project

General

Profile

Sample uPP Device Driver » DspUpp.h

DSP based uPP Driver header file - Thomas Catalino, 01/26/2012 01:40 AM

 
/**
* \file tcDspUpp.h
*
* \brief DSP uPP driver header file
*
* o 0
* | / Copyright (c) 2005-2011
* (CL)---o Critical Link, LLC
* \
* O
*/

//TODO:
// -Think about interleave mode...

#ifndef _DSPUPP_H_
#define _DSPUPP_H_

#include <stdint.h>
#include <std.h>
#include <mbx.h>
#include <sem.h>
#include <tsk.h>

#include "regs_upp.h"

namespace MityDSP
{

class tcDspUpp
{
public:

// Enumerations for uPP channels.
enum teUppChan
{
eeChanA,
eeChanB
};

// Channel data transfer directionality.
enum teChanDir
{
eeTransmit,
eeReceive,
eeDisabled
};

// Channel data bit width.
enum teChanBitWidth
{
ee8Bit = 0,
ee9Bit = 1,
ee10Bit = 2,
ee11Bit = 3,
ee12Bit = 4,
ee13Bit = 5,
ee14Bit = 6,
ee15Bit = 7,
ee16Bit = 8
};

// Read/Transmit threshold for UPTCR register bits
enum teThreshold
{
ee64Bytes = 0,
ee128Bytes = 1,
ee256Bytes = 3
};

// uPP Transmit clock selection options
enum teTxClockSel
{
eeUPP_2xTXCLK = 0, //!< External Tx clock source
eePLL0_SYSCLK2 = 1, //!< Same as uPP Module clock. Runs at
//!< 1/2 CPU speed
eePLL1_SYSCLK2 = 2 //!< PLL1_SYSCLK2
};

// Structure for configuring the uPP device.
struct tsDspUppConfig
{
uint32_t nHWInterruptLevel; //!< Interrupt level. Must be
//!< between 4 and 15.
uint32_t nTskPriorityChanA; //!< Priority for thread handling
//!< DMA programming for Channel A.
uint32_t nTskPriorityChanB; //!< Priority for thread handling
//!< DMA programming for Channel B.
teChanDir eChanADir; //!< Directionality of Channel A.
teChanDir eChanBDir; //!< Directionality of Channel B.
teChanBitWidth eChanBitWidthA; //!< Chan A data bit width.
teChanBitWidth eChanBitWidthB; //!< Chan B data bit width.
bool bChanAUseXData; //!< Use XData[7:0] for ChanA[15:8]
//!< even if ChanB is disabled. See Table 3 in uPP
//!< User's Guide for details.
uint32_t nMbxLenA; //!< Size of MBX for Channel A.
uint32_t nMbxLenB; //!< Size of MBX for Channel B.
uint8_t nChanAClkDiv; //!< Clock divider for Channel A
//!< (only in transmit mode). See Section 2.1.1 in uPP
//!< User's Guide for details. Value must be between 0
//!< and 15.
uint8_t nChanBClkDiv; //!< 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 0
//!< and 15.
teThreshold eThresholdTxA; //!< Chan A Transmit Thresh.
teThreshold eThresholdRxA; //!< Chan A Receive Thresh.
teThreshold eThresholdTxB; //!< Chan B Transmit Thresh.
teThreshold eThresholdRxB; //!< Chan B Receive Thresh.
bool bChanAUseStart; //!< Use start signal for Chan A.
bool bChanBUseStart; //!< Use start signal for Chan B.
teTxClockSel eTxClockSel; //!< Select transmit clock source.
//!< Only used if Chan A or Chan B is set to transmit.
uint8_t nDmaMasterPriority; //!< Set the DMA master priority
//!< for uPP. Valid number, range 0-7. 0 is highest
//!< priority.
// Chan A single/double data rate?
// Chan B single/double data rate?
// Multiplexing/interleaving mode options?
// Chan A data packing format?
// Chan B data packing format?
};

// MBX message structure.
struct tsMbxMsg
{
uint8_t* pBufPtr; //!< Pointer to filled/emptied buffer.
uint16_t nByteCnt; //!< # bytes per line DMAed to/from buf.
uint16_t nLineCnt; //!< DMA line count.
uint16_t nLineOffset; //!< DMA offset between lines.
void* pOptArg; //!< Pointer to optional additional arguments.
};

// Typdef for error callback function
typedef int (*tfErrorCallback)(uint32_t anErrNum);

/**
* Get instance of tcDspUpp.
*
* \return Poiner to the tcDspUpp object or NULL on failure.
*/
static tcDspUpp* getInstance();

/**
* Perform software reset of the uPP.
*
* @return None.
*/
void reset();

/**
* Intiailize the uPP device.
*
* \param apDspUppConfig Specifies configuration options.
*
* \return 0 on success, negative on failure.
*/
int initialize(tsDspUppConfig const* apDspUppConfig);

/**
* Get handle to mailbox for associated channel where info on
* processed buffers are stored.
*
* \param aeChan The uPP channel.
*
* \return Handle to the channel's mailbox or NULL on failure.
*/
MBX_Handle getMBX(teUppChan aeChan);

/**
* Queue transmit of given data buffer. Use getMBX() to get
* corresponding mailbox where pointer info will be posted once data
* has been tramsmitted.
*
* \param aeChan The uPP channel to transmit on. Note: If the given
* channel is not configured for transmit, function call
* will fail.
* \param apXmitData Pointer to transmit data. (note: Address must be
* be 64-bit aligned).
* \param anByteCnte Number of bytes in a line to DMA. (must be even).
* \param anLineCnt (Optional) Set the number of lines in the DMA
* channel window. If set > 1 and anLineOffset = 0,
* apXmitData will tranmist anLineCnt times.
* \param anLineOffset (Optional) Set the offset address between lines
* within DMA channel. (must be 64-bit aligned).
*
* \return 0 on succes, negative on failure.
*/
int transmit(teUppChan aeChan, const uint8_t* apXmitData,
uint16_t anByteCnt, uint16_t anLineCnt = 1,
uint16_t anLineOffset = 0);

/**
* Add buffer to receive queue. Use getMBX() to get corresponding
* mailbox where pointer info will be posted once data has been
* received.
*
* \param aeChan The uPP channel to receive on. Note: If the given
* channel is not configured for receive, function call
* will fail.
* \param apRcvData Pointer to location where to store receive data.
* (note: Address must be 64-bit aligned).
* \param anByteCnte Number of bytes in a line to DMA. (must be even).
* \param anLineCnt (Optional) Set the number of lines in the DMA
* channel window.
* \param anLineOffset (Optional) Set the offset address between lines
* within DMA channel. (must be 64-bit aligned).
*
* \return 0 on succes, negative on failure.
*/
int receive(teUppChan aeChan, uint8_t* apRcvData, uint16_t anByteCnt,
uint16_t anLineCnt = 1, uint16_t anLineOffset = 0);

/**
* Register an error callback function.
*
* \param afErrorCallback The error callback function.
*
* return None.
*/
void registerErrorCallback(tfErrorCallback afErrorCallback);

private:

/**
* Thread for programming the DMA for the specified channel.
*
* \param apDspUpp Pointer to singleton.
* \param aeChan The specified channel.
*
* \return None.
*/
static void programDMA(tcDspUpp* apDspUpp, teUppChan aeChan);

/**
* Handle any uPP related interrupts that might occur.
*
* \param apDspUpp Pointer to singleton.
*
* \return 0 on success, negative on failure.
*/
static int isr(tcDspUpp* acDspUpp);

/**
* Private constructor.
*/
tcDspUpp();

/**
* Private destructor.
*/
~tcDspUpp();

/**
* Private Copy Constructor to enforce use of getInstance().
*/
tcDspUpp(tcDspUpp const&); // Note implemented.
/**
* Private assignment operator to enforce use of getInstance().
*/
tcDspUpp& operator=(tcDspUpp const&); // Not implemented


tfErrorCallback mpErrorCallback; //!< Callback function for errors.

volatile tsUppRegs* const mpUppRegs; //!< Constant pointer to uPP Control Regs.
static tcDspUpp* mpDspUpp; //!< Singleton object.

static SEM_Handle mhGetInstSem; //!< Static semaphore to be used in
//!< getInstance method so that we do not accidentally
//!< instantiate too many objects.

bool mbFirstInit; //!< True if we have not been initialized before.

teChanDir meChanADir; //!< Directionality of Channel A.
teChanDir meChanBDir; //!< Directionality of Channel B.

TSK_Handle mhDmaTskA; //!< Task for programming Channel A DMA.
TSK_Handle mhDmaTskB; //!< Task for programming Channel B DMA.

MBX_Handle mhMbxDoneA; //!< MBX for eeChanA or eeInterleave to store
//!< pointers than have been filled or transmitted.
MBX_Handle mhMbxDoneB; //!< MBX for eeChanB to store pointers that
//!< have been filled or transmitted.

MBX_Handle mhMbxIntA; //!< Intermdiate MBX holding info on pointers
//!< that have been sent for DMAing on Chan A.
MBX_Handle mhMbxIntB; //!< Intermdiate MBX holding info on pointers
//!< that have been sent for DMAing on Chan B.

MBX_Handle mhMbxQueueA; //!< Queue of pointers to be transmitted or
//!< filled by eeChanA or eeInterleave.
MBX_Handle mhMbxQueueB; //!< Queue of pointers to be transmitted or
//!< filled by eeChanB.
};

}

#endif

(2-2/3)