This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28035: Reading ADC128S052 on C2000 issues

Part Number: TMS320F28035

Hello,

I am using f28035 with ADS128S052 as external ADC over SPI.

I have set up ADC peripheral as follows:

    CLK_enableSpiaClock(clk);
    // As per TI spruh18g, first we clear SPI SW reset to force reset state
    SPI_reset(spi);

    // Master
    SPI_setMode(spi, SPI_Mode_Master);

    SPI_setClkPhase(spi, SPI_ClkPhase_Normal);
    SPI_setClkPolarity(spi, SPI_ClkPolarity_OutputFallingEdge_InputRisingEdge);

    SPI_setTriWire(spi, SPI_TriWire_NormalFourWire);
    SPI_setCharLength(spi, SPI_CharLength_16_Bits);
    SPI_enableTx(spi);
    SPI_setBaudRate(spi, SPI_BaudRate_LSPCLK_Over_Eight);

    SPI_setPriority(spi, SPI_Priority_FreeRun);

    // FIFO part
    SPI_enableTxFifoEnh(spi);
    SPI_resetTxFifo(spi);
    SPI_resetRxFifo(spi);
    SPI_enableTxFifo(spi);
    SPI_enableRxFifo(spi);
    SPI_clearTxFifoInt(spi);
    SPI_clearRxFifoInt(spi);
    SPI_setRxFifoIntLevel(spi, SPI_FifoLevel_3_Words);
    SPI_setTxFifoIntLevel(spi, SPI_FifoLevel_4_Words);

    // Enable RX INT in PIE
    PIE_clearInt(self->priv->pie, PIE_GroupNumber_6);
    PIE_enableInt(self->priv->pie, PIE_GroupNumber_6, PIE_InterruptSource_SPIARX);
    EALLOW;
    self->priv->pie->SPIRXINTA = hal_spi_rx_isr;
    EDIS;
    CPU_enableInt(self->priv->cpu, CPU_IntNumber_6);
    // Enable peripheral INT
    SPI_enableRxFifoInt(spi);

    SPI_enable(spi);

The hal_spi_rx_isr looks like this:

uint16_t spi_rx_data[6];
uint16_t spi_rx_round;


__attribute__((ramfunc)) static void hal_adc_spi_write(struct hal_app *self, uint16_t channel)
{
    uint16_t       temp;

    temp = channel << (3 + 8);
    SPI_FifoStatus_e status;
    do {
        status = SPI_getTxFifoStatus(spi);
    } while (status == SPI_FifoLevel_4_Words);
    SPI_write(spi, temp);
}

__attribute__((ramfunc)) static int32_t hal_adc_spi_read(struct hal_app *self)
{
    uint16_t cnt = 10;

    SPI_FifoStatus_e status;
    do {
        status = SPI_getRxFifoStatus(self->priv->priv->spi);
        if (--cnt == 0) {
            return -1;
        }
    } while (status == SPI_FifoLevel_Empty);

    return SPI_read(spi);
}

__attribute__((ramfunc)) interrupt void hal_spi_rx_isr()
{
    struct hal *    hal  = hal_inst();
    struct hal_app *self = hal->app;
    uint16_t        i;
    int32_t adc_val;

    for (i = 0; i < 3; ++i) {
        adc_val = hal_adc_spi_read(self);
        if (adc_val < 0) {
            while(1);
        }
        spi_rx_data[i] = adc_val;
    }

    SPI_clearRxFifoInt(spi);
    PIE_clearInt(pie, PIE_GroupNumber_6);
}

__attribute__((ramfunc)) static void control_isr_callback(struct hal_app *self)
{
    int i;
    for (i = 0; i < 3; ++i) { // 0, 1, 2
        // TODO: Investigate why this hack is needed (it gives 1, 2, 0 ...)
        hal_adc_spi_write(self, (i + 4) % 3);
    }
}

Now the first problem maybe already apparent to get samples from ADC in order of channel 0, 1, 2 I have to request them in order 1, 2, 0...

The second problem is that the received samples have noise of 4 LSB is the control_isr_callback() is called at rate of 10 kHz, while there is no noise if this is 20kHz (the callback is registered to ISR of PWM pefipheral which will be issued either at 10 or 20 kHz). The interesting part is also that this LSB noise problem does not occur on some harware modules we have and appears on some (so it's something marginal, like setup/hold violation or something like that)..

Clearly there is some intermittent problem with consistency of the data received with SPI peripheral. Have you seen this kind of problem.. data corruption and swap of the order of received words?

Thank you

Bruno

  • Is the F2803x sending the channel requests in the right order but the external ADC is sending the wrong data? Or is the message coming from the F2803x incorrect in the first place?

    I'm not sure what to suggest for the second issue since it sounds like it may be a problem with the board and not likely the F2803x itself?

    Whitney

  • Hello Whitney, I can reply to this question for my colleague.

    The ADC has several channels, as you send SPI command, you get back the converted data of the requested channel back in the SAME frame.

    This is what the SPI peripheral should do (pseudo code without FIFO or interrupts, just to demonstrate):

    While(1) {
    SPI_write(addressA);
    dataA = SPI_read();

    SPI_write(addressB);

    dataB = SPI_read();

    }

    But instead the dataA would always contain result from the previous operation (which in this case would be dataB).

    So if we kept requesting only addressA in a cycle, each time you would get dataA, but 'old' sample. This is independent on whether we use FIFO or not, and oscilloscope shows that data clocked back is indeed the right one.

    So most likely there is something wrong in the way how we use the SPI peripheral, or how we configure it, but the problem is eluding us. Bad configuration could be causing both of the issues we are describing (permanent data out of phase + occasional glitching).

  • What does the FIFO level look like when you read the data? Since the transmission itself looks okay, I'm wondering if there's an extra word popping up in the FIFO that's causing everything to be shifted? Although if it happens even when you aren't using the FIFO that theory makes less sense...

    Whitney

  • Any updates? Were you able to resolve this issue?

    Whitney