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.

  • TI Thinks Resolved

CCS/ADS8699: ADS8699 SPI DMA example c code

Intellectual 360 points

Replies: 25

Views: 631

Part Number: ADS8699

Tool/software: Code Composer Studio

Hi,

I try to get sampled values from the ADS8699 but it is not really clear how to reach this in c code. I saw code like this https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/421491 .

I also read the datasheet and the SPI section from MSP432® Peripheral Driver Library USERS GUIDE. There are a lot of details to understand...

It would be grateful if there is an example how to read a raw value from the ADC. In the end I want to get 8192 samples via DMA.

I hope there are some examples or you can give me some help.

my setup: ADS8699, msp432P401R, CCS Version: 8.2.0.00007

  • Hi there,

    Unfortunately, we don't have any example code for the ADS8699 with the MSP430P401R to share with you. However, I see that you've been asking similar questions on the MSP430 forum and it seemed like you had some working code at one point (e2e.ti.com/.../753655). Can you perhaps post a screen shot of your existing SPI control lines (SCLK, SDI, SDO and CONVST/CS)? Maybe we can see what the issue is that way. The code you pointed to above had an active high chip select, the ADS8699 would require an active low chip select as shown in Figure 3 of the datasheet.

     

    Regards,

    Tom

  • In reply to Tom Hendrick:

    Hi,

    thank you for writing. CS is low I recognised. I wired it as you can see in the code. At first i want to test directly with SPI, later with SPI with DMA because its more complicated.

    From the example I changed the clock and EUSCI_B0_MODUL to EUSCI_B0_BASE because ...MODUL i isn't declared a msp432 i would say.

    It looks like this:

    /* MSP432 = SPI master,                                          external device = SPI slave
     *
     *            MSP432P401                                                    ADS8699
     *          -----------------                                           -----------------
     *         |                 |                                         |                 |
     *         |            5V   |->                                     ->| DVDD            |
     *         |                 |                                         |                 |
     *         |            GND  |->                                     ->| DGND            |
     *         |                 |                                         |                 |
               |            P4.3 |-> _CS                                 ->| CST/CS          |
     *         |                 |                                         |                 |
     *         |            P1.6 |-> Data Out (UCB0SIMO)                 ->| SDI             |
     *         |                 |                                         |                 |
     *         |            P1.7 |<- Data In (UCB0SOMI)                  <-| SDO0            |
     *         |                 |                                         |                 |
     *         |            P1.5 |-> Serial Clock Out (UCB0CLK)          ->| SCLK            |
     **********************************************************************************************/
    
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    #include <ti/devices/msp432p4xx/driverlib/spi.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    static volatile uint8_t RXData[10];
    static volatile uint8_t i = 0;
    static uint8_t TXData = 0;
    static uint8_t ii = 0;
    
    
    /* SPI Master Configuration Parameter */
    const eUSCI_SPI_MasterConfig spiMasterConfig =
    {
            EUSCI_B_SPI_CLOCKSOURCE_SMCLK,              // SMCLK Clock Source
            3000000,                                    // SMCLK = DCO = 3MHz
            500000,                                     // SPICLK = 500kHz
            EUSCI_B_SPI_MSB_FIRST,                      // MSB First
            EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT,    // Phase
            EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW,   // low polarity
            EUSCI_B_SPI_3PIN                            // 3Wire SPI Mode
    };
    
    
    int main(void)
    {
        volatile uint32_t ii;
    
        /* Halting WDT  */
        WDT_A_holdTimer();
    
        /* Starting and enabling LFXT (3MHz) */
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ, GPIO_PIN0 | GPIO_PIN1, GPIO_PRIMARY_MODULE_FUNCTION);
        CS_setExternalClockSourceFrequency(3000000, 0);
        CS_initClockSignal(CS_SMCLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
        CS_startLFXT(CS_LFXT_DRIVE0);
    
    
        /* Selecting P1.0 as LED */
        GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
        GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
        GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
    
    
        /* SPI --> P4.3 = _CS, P1.5 = CLK, P1.6 = MOSI & P1.7 = MISO */
        GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
        GPIO_setAsOutputPin(GPIO_PORT_P4, GPIO_PIN3);
        GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN3);
    
    
        /* Configuring SPI in 3-wire master mode & enabling it & interrupts */
        SPI_initMaster(EUSCI_B0_BASE, &spiMasterConfig);
        SPI_enableModule(EUSCI_B0_BASE);
        SPI_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_SPI_RECEIVE_INTERRUPT);
        Interrupt_enableInterrupt(INT_EUSCIB0);
        //Interrupt_enableSleepOnIsrExit();
        /* Delaying waiting for the module to initialize */
        for(ii=0;ii<100;ii++);
    
    
        /* SPI, put _CS low P4.3 and polling to see if the TX buffer is ready or busy */
        GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN3);
    
    
    //    TXData = 0x40;
    //    while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_B_SPI_TRANSMIT_INTERRUPT)));
    //    SPI_transmitData(EUSCI_B0_BASE, TXData);
    //    TXData = 0x00;
    //    while (!(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_B_SPI_TRANSMIT_INTERRUPT)));
    //    SPI_transmitData(EUSCI_B0_BASE, TXData);
    
    
        while(1) {}
        /*PCM_gotoLPM0();
        __no_operation();*/
    }
    
    
    void euscib0_isr(void)
    {
        int i = 0;
        uint32_t status = SPI_getEnabledInterruptStatus(EUSCI_B0_BASE);
        SPI_clearInterruptFlag(EUSCI_B0_BASE, status);
    
        if(status & EUSCI_B_SPI_RECEIVE_INTERRUPT)
        {
            RXData[i++] = SPI_receiveData(EUSCI_B0_BASE);
            if ((i % 2) == 1) {
                 for( ii=0;ii<10;ii++);
                 GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN3);
            }
            GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
            for(i=0;i<48000000;i++); // delay 1s
            GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
        }
    }
    

    The Software is always at while(1), the function euscib0_isr() isn't entered. I think that with _CS low the ADC starts working and send an interrupt.

    But how does this work "send an interrupt" to the msp432?

  • In reply to user5841294:

    Hi,

    I was hoping you had screen shots to share with us. The ADS8699 uses its CONVST/CS pin as the mechanism to begin the conversion process. You would need to toggle that pin high, which starts the conversion and drives the RVS pin low. Once the RVS pin toggles back to a high state, you would need to send CONVST/CS low again start driving the SCLK pin to retrieve the conversion results from the ADC. Take a look at Figure 1 and Figure 3 on page 11, it's the RVS pin that basically acts as an interrupt to your processor.

     

    Regards,

    Tom

  • In reply to Tom Hendrick:

    Hi,

    in the c code you can see the new pin configuration. I extended it with the RVS signal.

    1. I want to use the max. SPI speed of 16MHz. I'm not really sure about the constant:

    /* SPI Master Configuration Parameter */
    const eUSCI_SPI_MasterConfig spiMasterConfig =
    {
            EUSCI_B_SPI_CLOCKSOURCE_SMCLK,              // SMCLK Clock Source
            3000000,                                    // clockSourceFrequency: SMCLK = DCO = 3MHz
            16000000,                                   // desiredSpiClock: SPICLK = 16MHz
            EUSCI_B_SPI_MSB_FIRST,
    
          // MSB First
            EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT,    // Phase
            EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW,   // low polarity
            EUSCI_B_SPI_3PIN                            // 3Wire SPI Mode
    };

    Which/what clock ist the clockSourceFrequency? I only can choose SMCLK and ACLK.

    Furthermore, I can't recognise a clock at pin 1.5 with a oscilloscope while the  while loop (se below) is running. Because of this, I think there is something wrong with the clock setting.

    2. In reference to p.11 fig. 1 and 3 I made a simple test sequence:

        while(1) {
            // conversion start with rising edge on CONV:
            GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN3);
            GPIO_setOutputHighOnPin(GPIO_PORT_P4, GPIO_PIN3);
            // Wait until conversion is done (RVS -> high):
            while (GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN6) == 0);
            // set CONV to low for reading buffer:
            GPIO_setOutputLowOnPin(GPIO_PORT_P4, GPIO_PIN3);
            int k;
            for (k = 0; k < 4; ++k) {
                RXData[k] = SPI_receiveData(EUSCI_B0_BASE);
            }
        }
    

    But everytime I read with SPI_receiveData 0x0000311C. The value never changes. What's wrong?

    Regards

  • In reply to Tom Hendrick:

    ... sorry I forgot the pin configuration:

    /*
     * whole circuit like figure 67 and 98 in the datasheet
     * 
     * MSP432 = SPI master,                                          external device = SPI slave
     *
     *            MSP432P4111                                                   ADS8699
     *          -----------------                                           -----------------
     *         |                 |                                         |                 |
     *         |            5V   |->                                     ->| DVDD            |
     *         |                 |                                         |                 |
     *         |            GND  |->                                     ->| DGND            |
     *         |                 |                                         |                 |
               |            P4.3 |-> _CS                                 ->| CST/CS          |
     *         |                 |                                         |                 |
     *         |            P4.6 |<- Conv. ready                         <-| RVS             |
     *         |                 |                                         |                 |
     *         |            P1.6 |-> Data Out (UCB0SIMO)                 ->| SDI             |
     *         |                 |                                         |                 |
     *         |            P1.7 |<- Data In (UCB0SOMI)                  <-| SDO0            |
     *         |                 |                                         |                 |
     *         |            P1.5 |-> Serial Clock Out (UCB0CLK)          ->| SCLK            |
     */

  • In reply to user5841294:

    Hi,

    Can you send the scope screen capture? Normally, the SPI master sends the clock, which means you have to initiate a transmit to get the SDO from the device.

     

    Regards,

    Tom

  • In reply to Tom Hendrick:

    Hi,

    the problem is, that I have no clock!

    /* SPI Master Configuration Parameter */
    const eUSCI_SPI_MasterConfig spiMasterConfig =
    {
            EUSCI_B_SPI_CLOCKSOURCE_SMCLK,              // SMCLK Clock Source
            48000000,                                    // SMCLK = DCO = 3MHz
            16000000,                                     // SPICLK = 500kHz
            EUSCI_B_SPI_MSB_FIRST,
          // MSB First
            EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT,    // Phase
            EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW,   // low polarity
            EUSCI_B_SPI_3PIN                            // 3Wire SPI Mode
    };
    
    int main(void)
    {
        /* Halting WDT  */
        WDT_A_holdTimer();
    
        /* Starting and enabling HFXT */
        GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_PJ, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
    
        CS_setExternalClockSourceFrequency(32000, 48000000);
    
        /* Starting HFXT in non-bypass mode without a timeout. Before we start
         * we have to change VCORE to 1 to support the 48MHz frequency */
        MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
        MAP_FlashCtl_A_setWaitState(FLASH_A_BANK0, 3);
        MAP_FlashCtl_A_setWaitState(FLASH_A_BANK1, 3);
        CS_startHFXT(false);
    
        /* Starting HFXT in non-bypass mode without a timeout. Before we start
         * we have to change VCORE to 1 to support the 48MHz frequency */
        MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
        MAP_FlashCtl_A_setWaitState(FLASH_A_BANK0, 3);
        MAP_FlashCtl_A_setWaitState(FLASH_A_BANK1, 3);
        CS_startHFXT(false);
    
        //![Simple SPI Example]
        /* Selecting P1.5 P1.6 and P1.7 in SPI mode */
        GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);

    I need a SPI clock of 16MHz. I tried to create it from the 48MHz HFXT and SMCLK. Can you see the problem?

  • In reply to user5841294:

    You have to initiate a data transfer by 'writing' to the SPI port - what that means is that the master device (your MSP432P4111) has to move data (usually just zeros) to the transmit buffer. Otherwise, you won't get a clock.

     

    Regards,

    Tom

  • In reply to Tom Hendrick:

    Hi,
    if I send "SPI_transmitData(EUSCI_B0_BASE, 0x00);" then the clock is started?
    I thought when I create a rising edge on CONV P4.3 the conversion starts. After the RVS reaches high level the conversion is finished.
  • In reply to user5841294:

    When using the internal clock for conversion, yes - pulsing CONV takes care of the actual conversion process. You still need to generate the SCLK from your host controller to read the conversion results.

     

    Regards,

    Tom

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.