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)
{
switch ((tcDspLvds::teFIFOLevelMask)aeLevel)
{
case tcDspLvds::eeTxAEmpty:
{
SEM_ipost(mhTxAAvail);
break;
}
case tcDspLvds::eeTxBEmpty:
{
SEM_ipost(mhTxBAvail);
break;
}
case tcDspLvds::eeRxOneQ:
{
for (int i=0; i<(mnRxDepth / 4); i++)
{
mpRxBuf[i] = *mpRxFifo;
}
((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;
myLvds = new tcDspLvds((void *)my_base_addr, rx_packet_nibbles);
myLvds->SetRxAddress(1);
myLvds->SetRxAddrMask(false);
mpRxFifo = myLvds->GetRxFifoDataPtr();
mnRxDepth = myLvds->GetRxFifoSize();
myLvds->RegisterIsrCallback((tcDspLvds::eeRxOneQ | tcDspLvds::eeAllTxEmpty),
myIsrCallback, (void *)myLvds);
myLvds->EnableInterrupts(eeRxOneQ, true);
myLvds->LoadIdleBuffer("The Idle message for this interface", 40);
myLvds->EnableLink(true);
while (true)
{
{
:
:
}
{
myLvds->LoadTxABuffer("A transmit message of some kind", 40);
myLvds->EnableInterrupts(eeTxAEmpty, true);
}
{
myLvds->LoadTxBBuffer("Another transmit message...", 40);
myLvds->EnableInterrupts(eeTxBEmpty, true);
}
}
}
}