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