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.

TMS320F28379D: LDC1000-Q1 MIKROE clickboard: proximity register not being updated with exposure to conductor.

Part Number: TMS320F28379D
Other Parts Discussed in Thread: LDC1000EVM, LDC1614, LDC1101, LDC3114

Hello everyone,

Up until recently, I was using sensors from the LDC1000EVM evaluation module. I snapped off the USB module from the EVM, and wired the different terminals separately to my microcontroller. 

Below is the code I wrote to read the sensor's proximity registers. My approach is as follows:

* I set up the sensors with the appropriate register values

* I then poll the proximity registers through the use of an infinite for loop

// Included Files

#define DLY 21
#include "preprocessor.h"
#include "F28x_Project.h"
#include "spi_globals.h"
#include "spi_defines.h"
#include "function_defs.h"

void scan_test(void);


void main(void)
{
// INITIALISATION
//

// SETUP CLOCK FREQUENCY
    EALLOW;
//        ClkCfgRegs.LOSPCP.bit.LSPCLKDIV = 0b100;
    EDIS;



// SETUP CODE
//

// PRELIMINARY STEPS
       InitSysCtrl();               // Step 1. Initialize System Control:

       InitSpiaGpio();              // Step 2. Initialize GPIO:
//       InitSpibGpio();              // SPIB initialisation

       DINT;                        // Step 3. Clear all interrupts:

       InitPieCtrl();               // Initialize PIE control registers to their default state.


// Disable CPU __interrupts and clear all CPU __interrupt flags:
       IER = 0x0000;
       IFR = 0x0000;

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


// Step 4. Initialize the Device Peripherals:
       spi_fifo_init();     // Initialize the Spi FIFO
       spi_init();          // init SPI

// GPIO initialisation:
#if 0
       EALLOW;
       GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1;              // This is to explicitly control chip select
       EDIS;
#endif




// COMMAND SECTION
//


// WRITE COMMANDS
//
#if 1
       // WRITE COMMANDS
           // 2. rp max
           write_command(ADR.Rp_MAX, 0x0E);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           // 3. rp min
           write_command(ADR.Rp_MIN, 0x3A);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           // 4. sensor frequency
           write_command(ADR.SEN_FREQ, 0x94);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           // 5. ldc config
           write_command(ADR.LDC_CONF, 0x17);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           // 6. clk config
           write_command(ADR.CLK_CFG, 0x02);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           // 7. comparator threshold high lsb
           write_command(ADR.HI_LSB_CMP_LIM, 0x50);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           // 8. comparator threshold high msb
           write_command(ADR.HI_MSB_CMP_LIM, 0x14);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           // 9. comparator threshold low lsb
           write_command(ADR.LO_LSB_CMP_LIM, 0xC0);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           // 10. comparator threshold low lsb
           write_command(ADR.LO_MSB_CMP_LIM, 0x12);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           // 11. intb pin configuration
           write_command(ADR.INTB_CFG, 0x04);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG

           //12. Power config
           write_command(ADR.PWR_CFG, 0x01);
           rxdat = store();                         //read data into rxdat to clear INT_FLAG
#endif

#if 1
       // READ COMMANDS
       //
           read(0x00);                      // Read device id: address 0x00
           device_id = store();             // Write data into variable to clear int_flag

           read(0x01);                      // Read Rp max: address 0x01
           rp_max = store();                // Write data into variable to clear int_flag

           read(0x02);                      // Read Rp_min: address 0x02
           rp_min = store();                // Write data into variable to clear int_flag

           read(0x03);                      // Read Sensor frequency: address 0x03
           sen_freq = store();              // Write data into variable to clear int_flag

           read(0x04);                      // Read LDC configuration: address 0x04
           ldc_cfg = store();               // Write data into variable to clear int_flag

           read(0x05);                      // Read clock configuration: address 0x05
           clk_cfg = store();               // Write data into variable to clear int_flag

           read(0x06);                      // Read comparator threshold high LSB: address 0x06
           lim_hi_lsb = store();            // Write data into variable to clear int_flag

           read(0x07);                      // Read comparator threshold high MSB: address 0x07
           lim_hi_msb = store();            // Write data into variable to clear int_flag

           read(0x08);                      // Read comparator threshold low LSB: address 0x08
           lim_lo_lsb = store();            // Write data into variable to clear int_flag

           read(0x09);                      // Read comparator threshold low MSB: address 0x09
           lim_lo_lsb = store();            // Write data into variable to clear int_flag

           read(0x0A);                      // Read INTB Pin configuration: address 0x0A
           intb_cfg = store();              // Write data into variable to clear int_flag

           read(0x0B);                      // Read Power configuration: address 0x0B
           pwr_cfg = store();               // Write data into variable to clear int_flag

           read(0x20);                      // Read status: address 0x20
           status = store();                // Write data into variable to clear int_flag


           // Test loop
           //
           for(;;)                          // TEST LOOP
           {
               read(0x21);                  // Read lsb proximity data: address 0x21
               proxdat_lsb = store();       // Write data into variable to clear int_flag

               read(0x22);                  // Read msb proximity data: address 0x22
               proxdat_msb = store();       // Write data into variable to clear int_flag

               data =  proxdat_msb<<8 | proxdat_lsb;

               DELAY_US(100);
           }
#endif

}

// FUNCTION DEFINITIONS:
//

void write_command(Uint16 wcom, Uint16 wdat)
{
    SpiaRegs.SPITXBUF = wcom<<8 | wdat;             // Concatenating command field and data field to transmit signal
    while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG !=0){}   // Read only: set to 0 when tx'd data loaded into SPIDAT
    while(SpiaRegs.SPISTS.bit.INT_FLAG !=1){}       // Set to indicate SPI completed tx or rx
}


void read(Uint16 adr)
{
    adr = adr + 0x80;
    SpiaRegs.SPITXBUF = adr<<8 |0x00;                // Read command to transmit
    while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG !=0){}   // Read only: set to 0 when tx'd data loaded into SPIDAT
    while(SpiaRegs.SPISTS.bit.INT_FLAG !=1){}       // Set to indicate SPI completed tx or rx
}

Uint16 store(void)
{
    rxdat = SpiaRegs.SPIRXBUF;                      // Store data in dummy variable rxdat
    return rxdat;                                   // Return value of stored data in variable
                                                    // Now by 'variable = store()' you can read data into variable
                                                    // Used for read commands
}

Attached is the datasheet for the sensors I am using:

ldc1000-q1.pdf

Behaviour with LDC1000EVM module

On my LDC1000EVM module, with the code above, I was reading the proximity sensors. The data in the proximity registers was responsive to an approaching conductor, with the values increasing and decreasing accordingly. 

Behaviour with MIKROE LDC1000 click

After damaging my previous sensors, I went for the MIKROE LDC1000 click as a replacement. Running the same code, I found the following behaviour:

When I run my code initially, I can read all registers other than the proximity registers. The proximity registers always return 0x00. Note: all the other registers are written to and read from correctly. This is a screenshot of an attempt to read the proximity registers:

When I re-run the same code, I get data being read out of the proximity registers, however, this time that data doesn't change with the exposure of the device to a conductor. In fact, the registers stay stuck to the same value - this value is 0x2165.

I am not sure why I am having this problem. Previously, with the EVM board chip I was getting the appropriate readings. We've run this on a raspberry pi board and we've gotten the correct values again. However, when running the program from the TI board, I get the issues outlined in this post. 

The only difference I can see between the two is an 8 MHz oscillator crystal on the MIKROE clickboard. Below is the schematic of the LDC1000 MIKROE clickboard:

Another important point to mention:

*On the MIKROE clickboard, Probing the LC tank coils, I can see a response to bringing a conductor close to the sensor. This is also affected by changing the rp_min and rp_max registers on my LDC1000 sensor. This behaviour is observed while the proximity registers return zero. 

Thanks in advance

  • Hello, 

    Can you add a read of the status register (0x20) in your measurement loop and let us know what the value is and if it changes each iteration? 

    Additionally, what made your decision to use the LDC1000 instead of one of our other LDC devices like the LDC1101 (most similar to the LDC1000) or the LDC1614 for proximity sensing? 

    Best Regards, 

    Justin Beigel

  • Hello Justin,

    Thank you for your reply. I thought I'd just run you through my troubleshooting attempt. 


    Running the code I listed in the question, on first attempt I get the following values:

    • Reading the status register (0x20): I get 0x0070 back. 
    • I get a data value of 0x0000 back

    Upon re-running the code, however, the value in the status register changes and the sensor starts sending back data on the SDO line. Note: so far, no conductor has been brought close to the sensors. In this case I get:

    • Reading status register (0x20): I get 0x0020 back. 
    • I get a data value of 0x21EE - however, this stays at 0x21EE and doesn't change on my oscilloscope

    Re running the same code a few times without resetting the sensors, the status register value stays the same (0x0020), while the data values latch to the following values each re-run: 0x21EA, 0x21EF.

    Afterwards, I decided to bring a coin in proximity to my sensors - separated by layers of tissue from the sensor. I got the following results

    • Reading status register: (0x20): I get 0x0020 back.
    • Data value: 0x3B6B

    I then re-run my code with less layers of tissue between the coin and the sensor. The status register stayed the same. Now I got a larger data value of 0x52E7.

    Finally, I placed my coin on the sensor without any layers of tissue in between. In this case, the values were as follows:

    • Value of status: 0x0060
    • Value of data: 0x7D18

    Again in each case, the SDO lines latch to the values mentioned. 

    Afterwards, I reset my sensor by pulling out the 5V power wire. In this case, my status register went back to 0x0070, and my data value went back yo 0x0000. 

    I'm thinking that for some reason, my register values somehow get latched to the same values. When I brought the conductor close by and then took it away, the SDO waveform on my oscilloscope stayed the same - and I got the same values read into my microcontroller.

    On to your first question. We just happened to have the LDC1000 in our lab, and decided to start out with those. 

    Best wishes, 

    Eric

  • Hello Eric, 

    The LDC1000 is an old device and is no longer available from us so it would be best to look at alternatives. You can use the LDC Device Selection Guide (Rev. D) to help with determining the best part for your application. Based on what you have mentioned so far, I think the LDC131x, LDC161x or LDC3114 would be a good fit for your proximity sensing. We have EVMs of all these devices that can be used to evaluate their performance in your application as well as the LDCCOILEVM to test different sensor sizes. 

    Best Regards, 

    Justin Beigel

  • Hello Justin, 

    Thank you for your reply. I'll have a look into those devices.

    Do you have any ideas why my proximity values seem to be latching to certain values, as well as why 'status' is stuck on 0x20?

    Best wishes,

    Eric

  • Hello Eric, 

    Status being 0x20 would be the expected value for data being ready to read in your setup since you are not using the wake-up mode. When you get the value of 0x60 or 0x70, this correlates to data not being ready to read. 

    To clarify the use case, are you reading the status register every time you read a data point? Some of our devices won't update the data registers until the status register is read from. Also, if you connect your oscilloscope to the sensor, can you see change on the oscillation frequency when you are expecting the data code to change? 

    Thank you, 

    Justin Beigel