Reply by Oever, Rein van den August 28, 20022002-08-28
I have made a filter program last year using Multichannel operation and DMA.
The program continiously reads 32 succesive channel slots and stores them in
memory.
The problem I encoutered was, that the DSP didn't automatically synchronized
the DMA with the reception of a new frame sync of the data in this mode! The
way data was put in memory was actually dependent of when you started the
program.
Finally I had to synchronize this myself, generating an external
synchronization signal, a few microseconds before reception of the
framesync. This synchronization signal triggered an external interrupt in
the DSP that fired off DMA, for storage of a new set of channel slots.
A bit complicated but it works as it should.
I am curious if you will run into the same problem, or I somehow missed
something. In any case, nobody could help me at the time. The manual is far
too vague about these issues.

Succes,
Rein
-----Oorspronkelijk bericht-----
Van: Kenneth Porter [mailto:]
Verzonden: dinsdag 27 augustus 2002 18:41
Aan: Analog Devices DSP List
Onderwerp: Re: [adsp] SHARC SPORT Multichannel (TDM) mode Kenneth Porter <> wrote in
news::

> Can anyone point me to code examples for multichannel mode?

Answering my own question, I found a good appnote at ADI's website, EE-74,
"Serial Port Development and Troubleshooting Guide". It includes sample
assembler code for both 21xx and SHARC multichannel use. I'm reading
through it now and will try it shortly.

One thing I note right away is that the SPORT is reset in the interrupt not
by disabling/enabling the SPEN bit but instead the SDEN (DMA enable) bit. _____________________________________
Note: If you do a simple "reply" with your email client, only the author of
this message will receive your answer. You need to do a "reply all" if you
want your answer to be distributed to the entire group.

_____________________________________
About this discussion group:

To Join: Send an email to

To Post: Send an email to

To Leave: Send an email to

Archives: http://groups.yahoo.com/group/adsp

Other Groups: http://www.dsprelated.com/groups.php3 ">http://docs.yahoo.com/info/terms/


Reply by Kenneth Porter August 27, 20022002-08-27
Kenneth Porter <> wrote in
news::

> Can anyone point me to code examples for multichannel mode?

Answering my own question, I found a good appnote at ADI's website, EE-74,
"Serial Port Development and Troubleshooting Guide". It includes sample
assembler code for both 21xx and SHARC multichannel use. I'm reading
through it now and will try it shortly.

One thing I note right away is that the SPORT is reset in the interrupt not
by disabling/enabling the SPEN bit but instead the SDEN (DMA enable) bit.


Reply by Kenneth Porter August 27, 20022002-08-27
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();
}