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 Fri Sep 23 16:33:45 2011 for MityDSP Core by  Doxygen Version 1.6.1
Copyright © 2009, Critical Link LLC, All rights reserved.