EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Using the SSC on the ARM processor

Started by dave June 13, 2005
Hello,

  Has anybody ever used this device?
  I am having enormous problems with the synch signal.
  The transmitter seems to start whenever it feels like it, not when the 
synch signal is asserted.
  The receiver never receives a synch signal, or if it does, it never starts 
receiving.
  The transmitter generates the synch signal, and the clock. The receiver 
should start on a synch.
  No combinations of the frame mode and clock mode registers will make it 
work properly.
  Is the SSC broken on the ARM9?
  Should I find another way to talk with the si3050?

Dave


"dave" <dsomerton@commtech.com.au> skrev i meddelandet 
news:42ad27ea$1@quokka.wn.com.au...
> Hello, > > Has anybody ever used this device? > I am having enormous problems with the synch signal. > The transmitter seems to start whenever it feels like it, not when the > synch signal is asserted. > The receiver never receives a synch signal, or if it does, it never > starts receiving. > The transmitter generates the synch signal, and the clock. The receiver > should start on a synch. > No combinations of the frame mode and clock mode registers will make it > work properly. > Is the SSC broken on the ARM9? > Should I find another way to talk with the si3050? > > Dave >
If you are referring to the AT91RM9200 then the SSC is not "broken". I know of people that wrote a Linux driver and got it to play sound. This driver has not been completed unfortunately. The SSC supports I2S easily. AC97 is more complex to use and you probably should talk to a local contact about that. -- Best Regards, Ulf Samuelsson This is intended to be my personal opinion which may, or may bot be shared by my employer Atmel Nordic AB
On Mon, 13 Jun 2005 14:27:33 +0800, dave <dsomerton@commtech.com.au> wrote:

> Is the SSC broken on the ARM9?
ARM9 does not have SSC, ARMxx is just a processor core. What processor are you using? Vadim
Hello,

The processor is the AT91RM9200.

Connections: TF --> FSYNC (frame synch 8kHz)

TK --> PCLK (clock 256kHz)

TD --> DRX

RD --> DTX

TFMR -- AT91_SSC_TFMR_FSOS_POSITIVE | // output frame synch is rising

((state->synchLen << 16) & AT91_SSC_TFMR_FSLEN) | // synch pattern

((state->numData << 8) & AT91_SSC_TFMR_DATNB) | // num values

AT91_SSC_TFMR_MSBF | // send MSB first

AT91_SSC_TFMR_DATDEF | // mark silence with high level

(state->numBits & AT91_SSC_TFMR_DATLEN) | // transfer bit count

0);

TCMR --(((state->period << 24) & AT91_SSC_TCMR_PERIOD) | // period pulse

((state->delay << 16) & AT91_SSC_TCMR_STTDLY) | // delay

AT91_SSC_TCMR_START_RISE_TF | // when the frame bit rises

AT91_SSC_TCMR_CKI | // xmit on rising edge

AT91_SSC_TCMR_CKO_CONTINOUS | // emit clock out TK pin

AT91_SSC_TCMR_CKS_DIV | // use CPU clock

0);

RFMR -- (AT91_SSC_RFMR_FSOS_POSITIVE | // no frame synch out, use tx in

((state->synchLen << 16) & AT91_SSC_RFMR_FSLEN) | // synch pattern

((state->numData << 8) & AT91_SSC_RFMR_DATNB) | // num values

AT91_SSC_RFMR_MSBF | // receive MSB first

#ifdef LOOPBACK

AT91_SSC_RFMR_LOOP |

#endif

state->numBits & AT91_SSC_RFMR_DATLEN) | // receive bit count

0);

RCMR --(((state->period << 24) & AT91_SSC_RCMR_PERIOD) | // period pulse

((state->delay << 16) & AT91_SSC_RCMR_STTDLY) | // delay

AT91_SSC_RCMR_START_RISE_RF | // when the frame bit rises, from tx in

AT91_SSC_RCMR_CKI | // rx on falling edge

AT91_SSC_RCMR_CKO_NONE | // no clock output

AT91_SSC_RCMR_CKS_TK | // use transmitter clock

0);



#define NUM_CHANNELS 4

#define BITS_PER_CHANNEL 8 // 8 bit data

#define BIT_RATE 8000 // 8k samples

#define CHANNELS_PER_FRAME NUM_CHANNELS

sscState.numBits = BITS_PER_CHANNEL-1;

sscState.numData = CHANNELS_PER_FRAME-1;


// synch period

sscState.period = ((CHANNELS_PER_FRAME * BITS_PER_CHANNEL) / 2) - 1;

// no frame synch pattern

sscState.synchLen = 0;

// no delay

sscState.delay = 1;





-------------

If delay == 0, no receive interrupts are generated.



void sccStartTransmit(void)

{

unsigned int phys_addr;

// fill the buffer

fillTxBuffer();

#ifndef NO_PDC

// setup the transfer

phys_addr = sscState.physTxBuffer + (sscTxBufOut * RX_BLOCK_SIZE);

//phys_addr = getPhysTxOffset(sscState.physTxBuffer, sscTxBufOut);

if (++sscTxBufOut >= NUM_BLOCKS)

sscTxBufOut = 0;

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_TPR, phys_addr);

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_TCR, TX_BLOCK_SIZE);

phys_addr = sscState.physTxBuffer + (sscTxBufOut * RX_BLOCK_SIZE);

//phys_addr = getPhysTxOffset(sscState.physTxBuffer, sscTxBufOut);

if (++sscTxBufOut >= NUM_BLOCKS)

sscTxBufOut = 0;

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_TNPR, phys_addr);

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_TNCR, TX_BLOCK_SIZE);

// start the transfer

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_PTCR, AT91_SSC_PTCR_TXTEN);

// enable tx interrupts

sscIrqMask |= (AT91_SSC_IER_TXBUFE | AT91_SSC_IER_ENDTX);

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_IER, sscIrqMask);

#endif

AT91F_SSC_EnableTx(&sscState);

}

//

void sccStartReceive(void)

{

unsigned int phys_addr;

// ready the DTMF decoder, as we are about to start the PCM receiver

initDTMFDecoder();

sscReceiving = 1;

#ifndef NO_PDC

// start the receiver

phys_addr = sscState.physRxBuffer + (sscRxBufIn * RX_BLOCK_SIZE);

//phys_addr = getPhysRxOffset(sscState.physRxBuffer, sscRxBufIn);

if (++sscRxBufIn >= NUM_BLOCKS)

sscRxBufIn = 0;

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_RPR, phys_addr);

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_RCR, RX_BLOCK_SIZE);

phys_addr = sscState.physRxBuffer + (sscRxBufIn * RX_BLOCK_SIZE);

//phys_addr = getPhysRxOffset(sscState.physRxBuffer, sscRxBufIn);

if (++sscRxBufIn >= NUM_BLOCKS)

sscRxBufIn = 0;

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_RNPR, phys_addr);

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_RNCR, RX_BLOCK_SIZE);

// Enable the interrupts on the SSC

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_PTCR, AT91_SSC_PTCR_RXTEN);

// notify errors, notify all buffers full, notify one buffer full, chain 
next

sscIrqMask |= (AT91_SSC_IER_OVRUN | AT91_SSC_IER_RXBUFF | 
AT91_SSC_IER_ENDRX);

#ifdef DEBUG_IRQS

sscIrqMask |= set_debug_irqs();

#endif

HAL_WRITE_UINT32(sscState.sscBase+AT91_SSC_IER, sscIrqMask);

#endif

AT91F_SSC_EnableRx(&sscState);

}



Why does the transmitted data appear in any channel, when it should always 
appear in one.

It appears that the transmit is not waiting for the synch before it starts, 
or that the PDC is too slow

to reload, even though it has two buffers of 25mS each.

The receive data likewise appears in and accross random channels, again as 
if the synch is not being honoured.

So, obviously I have something wrong with the setup of the synch start 
condition.

But, i have tried every combination, to no avail.

Dave



"dave" <dsomerton@commtech.com.au> wrote in message 
news:42ad27ea$1@quokka.wn.com.au...
> Hello, > > Has anybody ever used this device? > I am having enormous problems with the synch signal. > The transmitter seems to start whenever it feels like it, not when the > synch signal is asserted. > The receiver never receives a synch signal, or if it does, it never > starts receiving. > The transmitter generates the synch signal, and the clock. The receiver > should start on a synch. > No combinations of the frame mode and clock mode registers will make it > work properly. > Is the SSC broken on the ARM9? > Should I find another way to talk with the si3050? > > Dave > >

The 2024 Embedded Online Conference