I'm trying to use the SHARC SPORT in multichannel mode and I'm
having
trouble understanding how to structure the code. I only get a couple of
receive interrupts with my current code, although the transmitter seems
to keep interrupting. Can anyone point me to code examples for
multichannel mode?
My objective is to connect several boards, each with a single 21065L, to
a common TDM cable. All will receive 32 32-bit words. Each will write
its own field into some of the words. (Eg. in a 5-SHARC system, each
SHARC would get 6 words to write in, with two spare words.)
As a test setup, I set up one board to act as the master for clock and
frame sync. I'm appending my code below. I'm testing with a
Summit-ICE
and scope leads attached to clock, frame sync, and data.
I have a small test board with some shift registers, 5 byte-wide
displays, a byte of input, and some timing and control logic to simulate
a TDM receiver.
As I said, I'm now getting two receive interrupts, and lots of transmit
interrupts, using the counters in the code. What do I need to do to get
the receiver to keep going?
// test of DSP axis TDM interface
#include <Cdef21065l.h>
#include <sport.h>
#include <21065l.h> // idle
#include <signal.h>
// size of two shift chains
const unsigned DISPLAY_BIT_COUNT = 5 * 8;
const unsigned INPUT_BIT_COUNT = 8;
const unsigned WORD_BIT_COUNT = 32;
// round up bit count to nearest word
#define BITS_TO_WORDS(bits) (((bits) + (WORD_BIT_COUNT - 1)) /
WORD_BIT_COUNT)
const unsigned CHANNEL_COUNT = 32;
const unsigned DISPLAY_WORD_COUNT = BITS_TO_WORDS(DISPLAY_BIT_COUNT);
const unsigned INPUT_WORD_COUNT = BITS_TO_WORDS(INPUT_BIT_COUNT);
// board should be configured with 4 bit-count values.
// _END must be greater than corresponding _OFFSET.
// INPUT_OFFSET must be greater than DISPLAY_END
const unsigned DISPLAY_OFFSET = WORD_BIT_COUNT;
const unsigned INPUT_OFFSET = 3 * WORD_BIT_COUNT;
const unsigned DISPLAY_END = DISPLAY_OFFSET + DISPLAY_BIT_COUNT;
const unsigned INPUT_END = INPUT_OFFSET + INPUT_BIT_COUNT;
const unsigned DISPLAY_WORD_OFFSET = BITS_TO_WORDS(DISPLAY_OFFSET);
const unsigned CLKIN = 33; // SHARC input freq
const unsigned SCLK = 1; // SPORT frequency in MHz
const unsigned CLKDIV = ((2 * CLKIN) / SCLK) - 1;
// one frame sync every 32 32-bit words
const unsigned FSDIV = CHANNEL_COUNT * WORD_BIT_COUNT - 1;
union {
__sport_transmit_control_register c;
unsigned u;
} tx;
union {
__sport_receive_control_register c;
unsigned u;
} rx;
// one word per possible time slot
unsigned sport_tx_buffer[DISPLAY_WORD_COUNT];
unsigned sport_rx_buffer[CHANNEL_COUNT];
// ISR counts
unsigned rx_count = 0;
unsigned tx_count = 0;
void sport_receive_isr(int)
{
sport_disable_receive(0);
// reset DMA channel 0 pointers (RX0_A)
*pII0 = reinterpret_cast<unsigned>(sport_rx_buffer);
*pC0 = CHANNEL_COUNT;
*pIM0 = 1;
*pCP0 = 0;
*pGP0 = 0;
// re-enable SPORT
sport_enable_receive(0);
++rx_count;
}
void sport_transmit_isr(int)
{
sport_disable_transmit(0);
// reset DMA channel 4 pointers (TX0_A)
*pII4 = reinterpret_cast<unsigned>(sport_tx_buffer);
*pC4 = DISPLAY_WORD_COUNT;
*pIM4 = 1;
*pCP4 = 0;
*pGP4 = 0;
sport_tx_buffer[0]++;
// implement multi-precision counter
unsigned* pBuf = sport_tx_buffer + 1;
for (int i = 0; (i < DISPLAY_WORD_COUNT) && (0 == pBuf[-1]); i++)
(*pBuf++)++;
// re-enable SPORT
sport_enable_transmit(0);
++tx_count;
}
// sport parameters
void main()
{
*pSTCTL0 = 0;
*pSRCTL0 = 0;
// word match not used
*pKEYWD0 = 0;
*pIMASK0 = 0;
// no companding
*pMTCCS0 = 0;
*pMRCCS0 = 0;
// transmit clock comes from receiver
*pTDIV0 = (FSDIV << 16) | CLKDIV;
*pRDIV0 = (FSDIV << 16) | CLKDIV;
// channel selects
// transmit selection to be computed from constants above
*pMTCS0 = 0;
for (int i = DISPLAY_WORD_OFFSET;
i < DISPLAY_WORD_OFFSET + DISPLAY_WORD_COUNT;
i++)
*pMTCS0 |= 1 << i;
// receive all channels
*pMRCS0 = 0xFFFFFFFF;
// install handlers
interrupts(SIG_SPR0I,sport_receive_isr);
interrupts(SIG_SPT0I,sport_transmit_isr);
// now set control registers to enable SPORTs
// transmit:
__sport_transmit_control_register txc;
tx.u = 0;
tx.c.sden = 1; // enable DMA
tx.c.ltfs = 1; // active low frame sync
tx.c.slen = WORD_BIT_COUNT - 1; // 32 bit word length
tx.c.spen = 1; // enable SPORT
rx.u = 0;
rx.c.nch = CHANNEL_COUNT - 1; // 32 channels
rx.c.mce = 1;
rx.c.sden = 1;
rx.c.ltfs = 1; // misnamed, really lrfs
rx.c.iclk = 1; // internal clock source
rx.c.irfs = 1; // internal frame sync
rx.c.slen = WORD_BIT_COUNT - 1;
rx.c.spen = 1; // enable SPORT
// reset DMA pointers and start SPORT's
sport_transmit_isr(0);
sport_receive_isr(0);
for (;;)
idle();
}
|