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.

LAUNCHXL-F28379D: connect to ADS1259 via SPI

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: ADS1259

i'm trying to connect ADS1259 to LAUNCHXL-F28379D via hardware SPI. I have working implementation of communication protocol via software SPI, and now i'm trying to replace software SPI read/write to hardware ones. So, problems is: lock on SPI_readDataBlockingNonFIFO() on second or third iteration, and anyway it's returns not correct data. In loopback mode it's works, but sometimes locks too(i dont understent how in possible, what it waiting for? software implementation have no such problem).
details:

standart init.

//
// Initialize device clock and peripherals
//
Device_init();

//
// Disable pin locks and enable internal pullups.
//
Device_initGPIO();

//
// Initialize PIE and clear PIE registers. Disables CPU interrupts.
//
Interrupt_initModule();

//
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
//
Interrupt_initVectorTable();

GPIO_setPadConfig(76, GPIO_PIN_TYPE_PULLUP); //START
GPIO_setPinConfig(GPIO_76_GPIO76);

GPIO_setPadConfig(111, GPIO_PIN_TYPE_PULLUP); //DATA READY
GPIO_setPinConfig(GPIO_111_GPIO111);

GPIO_setPadConfig(60, GPIO_PIN_TYPE_PULLUP); //RESET
GPIO_setPinConfig(GPIO_60_GPIO60);

/////////////////////////////
GPIO_setPadConfig(0, GPIO_PIN_TYPE_PULLUP); //GREEN LED
GPIO_setPinConfig(GPIO_0_GPIO0);
GPIO_setDirectionMode(0, GPIO_DIR_MODE_OUT);

GPIO_setPadConfig(1, GPIO_PIN_TYPE_PULLUP); //RED LED
GPIO_setPinConfig(GPIO_1_GPIO1);
GPIO_setDirectionMode(1, GPIO_DIR_MODE_OUT);

GPIO_setPadConfig(2, GPIO_PIN_TYPE_PULLUP); //BLUE LED
GPIO_setPinConfig(GPIO_2_GPIO2);
GPIO_setDirectionMode(2, GPIO_DIR_MODE_OUT);

GPIO_setPadConfig(3, GPIO_PIN_TYPE_PULLUP); //TRANS LED
GPIO_setPinConfig(GPIO_3_GPIO3);
GPIO_setDirectionMode(3, GPIO_DIR_MODE_OUT);

#define SPI_BASE SPIB_BASE

//SPI
#if USE_HARDWARE_SPI
GPIO_setPadConfig(63, GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig(64, GPIO_PIN_TYPE_PULLUP);
GPIO_setPadConfig(65, GPIO_PIN_TYPE_PULLUP);

GPIO_setPinConfig(GPIO_63_SPISIMOB);
GPIO_setPinConfig(GPIO_64_SPISOMIB);
GPIO_setPinConfig(GPIO_65_SPICLKB);

GPIO_setQualificationMode(63, GPIO_QUAL_ASYNC); // asynch input
GPIO_setQualificationMode(64, GPIO_QUAL_ASYNC); // asynch input
GPIO_setQualificationMode(65, GPIO_QUAL_ASYNC); // asynch input
#else
GPIO_setPadConfig(64, GPIO_PIN_TYPE_PULLUP); //MISO
GPIO_setPinConfig(GPIO_64_GPIO64);

GPIO_setPadConfig(63, GPIO_PIN_TYPE_PULLUP); //MOSI
GPIO_setPinConfig(GPIO_63_GPIO63);

GPIO_setPadConfig(65, GPIO_PIN_TYPE_PULLUP); //CLOCK
GPIO_setPinConfig(GPIO_65_GPIO65);

ads_device.spi_port.spi_sclk_pin = 65;
ads_device.spi_port.spi_mosi_pin = 63;
ads_device.spi_port.spi_miso_pin = 64;
ads_device.spi_port.period = 11;
#endif

SPI init

int init_spi_port(spi_port_t* spi_port)
{
int err = 0;
#if USE_HARDWARE_SPI
// Must put SPI into reset before configuring it
//
SPI_disableModule(SPI_BASE);
//
// SPI configuration. Use a 1MHz SPICLK and 16-bit word size.
//
SPI_setConfig(SPI_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA1,
SPI_MODE_MASTER, 1000000, 8);

SPI_disableFIFO(SPI_BASE);


SPI_setEmulationMode(SPI_BASE, SPI_EMULATION_STOP_AFTER_TRANSMIT);



//
// Configuration complete. Enable the module.
//
SPI_enableModule(SPI_BASE);


EINT;
ERTM;

#else
GPIO_setDirectionMode(spi_port->spi_sclk_pin, GPIO_DIR_MODE_OUT);
GPIO_setDirectionMode(spi_port->spi_mosi_pin, GPIO_DIR_MODE_OUT);
GPIO_setDirectionMode(spi_port->spi_miso_pin, GPIO_DIR_MODE_IN);
#endif
return err;
}

void write_spi_byte(spi_port_t* spi_port, uint16_t byte)
{
#if USE_HARDWARE_SPI
SPI_writeDataBlockingNonFIFO(SPI_BASE, byte);
#else
uint16_t si = 0;
for(si = 0; si < 8; si ++)
{
GPIO_WRITE(spi_port->spi_sclk_pin, 1);
byte&0x80 ? GPIO_WRITE(spi_port->spi_mosi_pin, 1) : GPIO_WRITE(spi_port->spi_mosi_pin, 0);
byte <<= 1;
half_spi_clock;
GPIO_WRITE(spi_port->spi_sclk_pin, 0);
half_spi_clock;
}
#endif
}

inline uint16_t read_spi_byte(spi_port_t* spi_port)
{
uint16_t byte = 0;
#if USE_HARDWARE_SPI
byte = SPI_readDataBlockingNonFIFO(SPI_BASE);
byte = __byte(&byte, 1);
#else

uint16_t si = 0;
int bit = 0;
for(si = 0; si < 8; si ++)
{
GPIO_WRITE(spi_port->spi_sclk_pin, 1);
byte <<= 1;
half_spi_clock;
GPIO_WRITE(spi_port->spi_sclk_pin, 0);
half_spi_clock;
bit = GPIO_READ(spi_port->spi_miso_pin);

byte = bit ? byte|0x01 : byte&0xfe;
}
#endif
return byte;
}

  • Pavel,

    • Have you looked in the  write and read functions to see where they are hanging? Is it only hanging in one of them?  There really is not a whole lot in the functions themselves. It blocks on either TXRDY or INT_FLAG then writes to or reads from the buffers.
    • Are you observing the data being transmitted on an oscilloscope? Does the data appear on the line as expected?
    • Do you ever see any overrun on the receiver?
    • Check your order of operations. Ensure that there is always a transmit before a receive.  

    -Mark

  • Problem with lock on SPI_readDataBlockingNonFIFO() solved. first reading clears INT_FLAG register, and then this register dont set anymore. To read from SPI you should writ dummy data to SPIDAT register.
    But, anyway its not works, looking like clocking scheme is not Rising edge with delay (no enough delay in my case), but CLK_PHASE set to 1.

    software (working) write 0x11

    hardware (not working) write 0x11

  • That's correct. To read valid SPI data from the slave, the master needs to initiate a transmission. The master needs to clock the data OUT of the slave, this is accomplished through a dummy write.

    The difference between the working and not working captures would appear to be purely a timing issue. The C2000 SPI will change the SIMO pin immediately on the edge. Your working capture shows that there is nearly 1/4 cycle delays between each transition.

    What does your slave expect? the Master is transmitting data on the rising edge and sampling it on a the falling edge. Your slave should match that.

    -Mark
  • ADS1259 works in SPI mode 1, polarity 0 phase 1. As documentation says: Data and control communication are handled over a 4MHz. So i set my SPI to lowest bitrate.
    strange situation, in mode 1 i recive nothin, but in mode 0 i recive some data. from my really bad logic analizer a see that MOSI pattern is unstable. what can i check more?

  • Pavel,

    Compare the ADS1259 Polarity and Phase definitions. All SPI's seem to choose different definitions. Make sure the F28379D and the ADS1259 are transmitting on the same edge and receiving on the same edge.
    It looks like the ADS1259 will transmit on the rising edge and receive on the falling edge of the clock. See Figure 1 in the ADS1259 DS. To match that on the F28379D, choose POL = 0, PH = 0. You can look at the timing diagrams in the DS to determine this, or the SPI Clocking Scheme Selection Guide table in the TRM http://www.ti.com/lit/spruhm8

    -Mark
  • Thank you for your answer, it doesn't solve my problem directly, but it helps me to take a sober look.I have tried POL = 0, PH = 0 but it give strange result. I looking all documentation again and understood that you are right, POL = 0, PH = 0 it's what i need. and next i started to looking for another sources of mistakes. i found that i receive first byte CONFIG1 with correct values, but not in first position and another registers returned zeros. So, i changed CONFIG1, set SPI bit to zero (setting SPI really resets ADS1259). After this i received almost all registers, they are looks one byte shifted. solution of this problem was much more obviously. reading SPIRXBUF register after sending write register command to clear INT_FLAG before receiving data.
    Now it works on full range of speed.
    thank you a lot.

  • Glad you were able to resolve it! You may notice here on the forums that while a lot of us might be able to just tell you the answer, it does not get you thinking about your issues. We want to enable you in figuring out your own issues as much as possible. This way you can confidently understand the C2000 device (and use it again and again) but also your application..

    Thanks again, please don't hesitate to post new questions in the future if you get stuck!
    -Mark