MityDSP Documentation Index
tcDspLvds

Introduction

The tcDspLvds class is used to provide an interface to an instance of the MityDSP LVDS core firmware.

For transmit, the LVDS interface utilizes a dual port RAM structure that is segmented into 3 working areas: Idle, Transmit Buffer A, and Transmit Buffer B. The sizes of these working areas may be arbitrarily set. When enabled, the interface continuously transmits the content defined as the idle message until data is made available in either transmit Buffer A or B. The design is such that there are no stalls between any packets.

For receive, properly qualified packets (including address match and valid header and checksums) are clocked into a 32-bit wide receive buffer. A "promiscuous mode" is provided to bypass these checks and qualify all packets.

Interrupt mechanisms are provided for both transmit buffer available notifications, as well as receive data status. The application may register routines to be run in ISR context to provide specific functionality for type of interrupt.

An instance of the tcDspLvds class is created by specifying the firmware base address of the core and the receive packet size to be used on the interface.

See also:
MityDSP::tcDspInterruptDispatch Class Reference
MityDSP::tcDspLvds Class Reference

Example

This is a simple example of tcDspLvds creation and usage:

{
SEM_handle MyClass::mhTxAAvail, MyClass::mhTxBAvail,
MyClass::mhRxDataAvail;
tcDspLvds *MyClass::myLvds;
volatile unsigned int *MyClass::mpRxFifo;
unsigned int MyClass::mnRxDepth;
unsigned int MyClass::mpRxBuf[4096];
static void MyClass::myIsrCallback(tcDspLvds *apLvds, int aeLevel, void *apUser)
{
// do different things based on interrupt
switch ((tcDspLvds::teFIFOLevelMask)aeLevel)
{
// one of the TX buffers has been sent... mark it as available
case tcDspLvds::eeTxAEmpty:
{
SEM_ipost(mhTxAAvail);
break;
}
case tcDspLvds::eeTxBEmpty:
{
SEM_ipost(mhTxBAvail);
break;
}
// RX FIFO is 1/4 full, transfer data from receive buffer
case tcDspLvds::eeRxOneQ:
{
// transfer data from RX buffer...
for (int i=0; i<(mnRxDepth / 4); i++)
{
mpRxBuf[i] = *mpRxFifo;
}
// re-enable interrupt
((tcDspLvds *)apUser)->EnableInterrupts(eeRxOneQ, true);
break;
}
}
return;
}
void MyClass::doSomething(void)
{
int i;
unsigned int my_base_addr = 0xA0000200;
unsigned int rx_packet_nibbles = 40;
// initialize semaphores
mhTxAAvail = SEM_create(0, NULL);
mhTxBAvail = SEM_create(0, NULL);
mhRxDataAvail = SEM_create(0, NULL);
// create access to the LVDS
myLvds = new tcDspLvds((void *)my_base_addr, rx_packet_nibbles);
// Set receive address and mask
myLvds->SetRxAddress(1);
myLvds->SetRxAddrMask(false);
// Get receive FIFO address and size
mpRxFifo = myLvds->GetRxFifoDataPtr();
mnRxDepth = myLvds->GetRxFifoSize();
// register callback when TX buffers are complete,
// and when RX FIFO is 1/4 full
myLvds->RegisterIsrCallback((tcDspLvds::eeRxOneQ | tcDspLvds::eeAllTxEmpty),
myIsrCallback, (void *)myLvds);
// enable the receive interrupt
myLvds->EnableInterrupts(eeRxOneQ, true);
// load idle buffer with data and activate
myLvds->LoadIdleBuffer("The Idle message for this interface", 40);
// enable interface
myLvds->EnableLink(true);
// do something for a long time...
while (true)
{
// wait for ISR to trigger RX data available
if (SEM_pend(mhRxDataAvail, 0))
{
// do something application-specific
:
:
}
// wait for ISR to trigger TX A available
if (SEM_pend(mhTxAAvail, 0))
{
myLvds->LoadTxABuffer("A transmit message of some kind", 40);
// enable the TX A empty interrupt
myLvds->EnableInterrupts(eeTxAEmpty, true);
}
// wait for ISR to trigger TX B available
if (SEM_pend(mhTxBAvail, 0))
{
myLvds->LoadTxBBuffer("Another transmit message...", 40);
// enable the TX B empty interrupt
myLvds->EnableInterrupts(eeTxBEmpty, true);
}
}
}
}

  
Generated on Mon Apr 22 2013 11:33:02 for MityDSP Core by  Doxygen Version 1.8.1.1
Copyright © 2009, Critical Link LLC, All rights reserved.