AnsweredAssumed Answered

ADSP BFin-532: SPORT data-dependent transmit problem

Question asked by allenyin on Nov 12, 2015
Latest reply on Nov 30, 2015 by allenyin

Hi all,

 

I'm trying to interface BF532 with the Intan RHD2132 amplifiers (listing the amp in case someone has worked with them before). The amplifiers uses SPI: 16-bits commands and data are exchanged through MOSI and MISO when _CS is held low. In between each commands, _CS needs to be pulsed high for >154ns.

 

I'm using both SPORT channels, and both primary and secondary ports to talk to four amps with the following wiring connections, based on the application note (http://www.analog.com/media/en/technical-documentation/application-notes/EE_304_Blackfin.pdf)

    RFS0 connected to TFS0 --> connected to _CS

    RFS1 connected to TFS1 --> connected to _CS

    DTxPRI and DTxSEC connected to MOSI

    DRxPRI and DRxSEC connected to MISO

 

My SCLK is 80MHz, as a test, I used the following settings:

    *pSPORT0_TCLKDIV = 1;

    *pSPORT0_TFSDIV = 4;

    *pSPORT0_TCR2 = TXSE | 0xf;

    *pSPORT0_RCR2 = RXSE | 0xf;

 

    *pSPORT1_TCLKDIV = 1;

    *pSPORT1_TFSDIV = 4;

    *pSPORT1_TCR2 = TXSE | 0xf;

    *pSPORT1_RCR2 = RXSE | 0xf;

 

    *pSPORT0_TCR1 = TCKFE | LATFS | LTFS | TFSR | ITFS | ITCLK | DITFS;    // data-independent transmit, active low, late FS

    *pSPORT1_TCR1 = TCKFE | LATFS | LTFS | TFSR | ITFS | ITCLK | DITFS;    // data-independent transmit, active low, late FS

    *pSPORT0_RCR1 = RCKFE | LARFS | LRFS | RFSR;                                        // RFS taken from external TFS

    *pSPORT1_RCR1 = RCKFE | LARFS | LRFS | RFSR;                                        // RFS taken from external TFS

 

I would have the TCLK running at 20MHz. Frame-sync is asserted low for 16 TCLK cycles (800ns), followed by 4 TCLK cycles high (200ns), fulfilling my requirements. This works, as confirmed on the oscilloscope.

 

But making the TFS data-dependent (by taking out DITFS), and continually pushing contents into SPORTx_TX, I should get the same frame-sync behavior. However this is not the case. With the following code:

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

int main() {

    // turn all SPORT off

    *pSPORT0_TCR1 = 0x0000;

    *pSPORT0_RCR1 = 0x0000;

    *pSPORT1_TCR1 = 0x0000;

    *pSPORT1_RCR1 = 0x0000;

  

      *pSPORT0_TCLKDIV = 1;

    *pSPORT0_TFSDIV = 4;

    *pSPORT0_TCR2 = TXSE | 0xf;

    *pSPORT0_RCR2 = RXSE | 0xf;

 

    *pSPORT1_TCLKDIV = 1;

    *pSPORT1_TFSDIV = 4;

    *pSPORT1_TCR2 = TXSE | 0xf;

    *pSPORT1_RCR2 = RXSE | 0xf;

 

    *pSPORT0_TCR1 = TCKFE | LATFS | LTFS | TFSR | ITFS | ITCLK;    // data-DEPENDENT transmit

    *pSPORT1_TCR1 = TCKFE | LATFS | LTFS | TFSR | ITFS | ITCLK;    // data-DEPENDENT transmit

    *pSPORT0_RCR1 = RCKFE | LARFS | LRFS | RFSR;                          // RFS taken from external TFS

    *pSPORT1_RCR1 = RCKFE | LARFS | LRFS | RFSR;                          // RFS taken from external TFS

 

    asm volatile("ssync;");

    radio_bidi_asm();

    return 0;

}

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

// In frame_sync_test.asm

#define NEXT_CHANNEL 0x3f00

.global _radio_bidi_asm

_radio_bidi_asm:

    p5.l = LO(SPORT0_TCR1);

    p5.h = HI(SPORT0_TCR1);

    r0.l = TCKFE | LATFS | LTFS | TFSR | ITFS | ITCLK | TSPEN;    // data-DEPENDENT transmit

    w[p5] = r0;

 

    p5.l = LO(SPORT1_TCR1);

    p5.h = HI(SPORT1_TCR1);

    w[p5] = r0;

 

    p5.l = LO(SPORT0_RCR1);

    p5.h = HI(SPORT0_RCR1);

    r0.l = RCKFE | LARFS | LRFS | RFSR | RSPEN;

    w[p5] = r0;

 

    p5.l = LO(SPORT1_RCR1);

    p5.h = HI(SPORT1_RCR1);

    w[p5] = r0;

    ssync;

 

    p0.l = LO(SPORT0_RX);

    p0.h = HI(SPORT0_RX);

 

// push one set to TX-fifo

    r0 = 0 (z);

    w[p0] = r0;

    w[p0] = r0;

    w[p0 + (SPORT1_TX - SPORT0_RX)] = r0;

    w[p0 + (SPORT1_TX - SPORT0_RX)] = r0;

 

// push another one to TX-fifo

    r0 = NEXT_CHANNEL (z);

    w[p0] = r0;

    w[p0] = r0;

    w[p0 + (SPORT1_TX - SPORT0_RX)] = r0;

    w[p0 + (SPORT1_TX - SPORT0_RX)] = r0;  

    jump get_samples;

 

// there should always be one set of values in transmit FIFO

get_samples:

    r7 = NEXT_CHANNEL (z);

 

wait_samples:  // wait until we have finished receiving/transmitting one set of 16-bit words

    r3 = w[p0 + (SPORT1_STAT - SPORT0_RX)];

    cc = bittst(r3,0);

    if !cc jump wait_samples;

  

    // should still be one more set in the FIFO  

 

    // queue next channel in transmit FIFO.

    w[p0 + (SPORT0_TX - SPORT0_RX)] = r7;  // SPORT0 primary TX

    w[p0 + (SPORT0_TX - SPORT0_RX)] = r7;  // SPORT0 sec TX

    w[p0 + (SPORT1_TX - SPORT0_RX)] = r7;  // SPORT1 primary TX

    w[p0 + (SPORT1_TX - SPORT0_RX)] = r7;  // SPORT1 sec TX

  

    // read out the samples just received

    r1 = w[p0 + (SPORT1_RX - SPORT0_RX)];

    r0 = w[p0 + (SPORT1_RX - SPORT0_RX)];

    r1 = w[p0];

    r0 = w[p0];

    jump wait_samples;

 

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

What I get on the oscilloscope is that, frame-sync is ALWAYS low! The signals are the DTxPRI and DTxSEC are what I sent in the code. But since the frame-sync is always low, the amplifier will never execute the commands I send it.

 

Why is this happening? Since my SCLK is running at 80Mhz, a new set of values is loaded into the transmit FIFO before the current word is finished transmit, so the transmit FIFO is never empty and data is always available for transmission.

 

What can I do to fix this? Using data-independent frame-sync instead?

 

Thanks,

Allen

Outcomes