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.

DRV10983: Unable to read device registers using I²C (using Atmega324PA or USB2ANY).

Part Number: DRV10983
Other Parts Discussed in Thread: , USB2ANY, MSP430G2553,

Hello,

I have been using a DRV10983EVM board for driving a motor for my internship assignment (peristaltic pump). I have been using my own I²C library (which does the same as Peter Fleury's TWI library) and it worked great. I was able to configure the DRV10983 and read its registers without any problems. After designing and soldering my own PCB, I was unable to read from the DRV10983.

Whenever I write to the device, I get an acknowledge after every byte of data, as is expected. But whenever I try to read a register, the register returns only zero values and afterwards it holds the SDA line. I tried setting the VregSel bit to get VREG to output 3V3 instead of 5V (after sitting SIdata bit), but it keeps outputting 5V, confirming that writing operations are unsuccesful as well (even though they seem fine on my logic analyzer).

I tried using my DRV10983EVM board again, but I accidentally blew up the chip. After replacing the chip with a spare one, The GUI keeps outputting the following error message whenever I try to configure the device:

DRV10983 USB2ANY.lvclass:Read Register.vi<ERR>
Register reading not successful!!
Please restart the GUI and try again

So it's not just I²C communication with the Atmega324PA, but also with the USB2ANY device and the GUI from TI. On both the EVM board and my own PCB I checked for sorts and bad connections, but everything looked good. Furthermore, I checked, double checked, triple checked and quadruple checked my PCB design for flaws, but there too, nothing strange. Both ends of the I²C bus are connected and the 4k7 pull-ups are properly connected as well.

I have seen similar threads, but these were all closed without a solution.

  • Hello Stan,

    Thank you for the info and for posting to the MD forum. The device on your EVM was communicating just fine but when it was replaced with the new device you began to get the "DRV10983 USB2ANY.lvclass:Read Register.vi<ERR>", is that correct? Just to make sure the device you have soldered onto your PCB and the replaced on the EVM, was this a DRV10983 or a DRV10983Z? The have the same pinout but the versions are slightly different if you could confirm which was placed on the board just to make sure we are troubleshooting for the correct part.

    If you have captures from your logic analyzer it might be helpful in troubleshooting the issue as well. Additionally, I am not sure if you have reviewed he programming guide for the DRV10983, I will link it since it here for you to review: https://www.ti.com/lit/an/slvuaa5/slvuaa5.pdf?ts=1631116128096

    I will be waiting for your response!

    Best,

    Isaac

  • Hello Isaac,

    The device I have is the DRV10983, not the DRV10983Z. I have reviewed the programming guide and I know how to operate the device properly.

    I have added screenshots from my logic analyzer. The first picture shows a read operation. The register that I'm reading was previously written with the value 0xCC (without power cycling the device), but reads 0x00. Afterwards, the SDA line is kept low. The second picture shows how the bus recovers after the read operation, performing a write operation (same one I did before reading the register). It behaves as expected, getting ACK back after every byte sent and the SCL and SDA lines being released after transfer.
    Only the clock cycling at the beginning (which is not coded by me) is odd.

    This is what I read on a Microchip forum on the clock cycling:

    "If you get reset in the middle of reading from an I2C slave, the slave could still be driving SDA low.
    You need to float SDA and toggle SCL nine times to ensure the slave comes out of the read operation."

    My microcontroller does not have a watchdog active, nor any interrupts and the power supply is stable. If my microcontroller would get interrupted during I²C operation, I would not have a clue as to what would interrupt it.

  • Hey Stan,

    Thanks for the info here. On the write is it possible that having the extra clock cycles at the beginning could be affecting the register write? Perhaps that's why the data you are entering is actually not being stored into a register. I would alter the code to prevent the clock from togging so early, you did mention this code did work in the past where you configuring the device on the EVM using this method? 

    Is the SDA line being held low after every read when using the Atmega324PA? or does this only occur occasionally? Have you tried the reset you read about on Microchip to toggle the line back high?

    Sorry for the questions just trying to understand the problem here. I know you were having GUI issues as well have you been unsuccessful getting the GUI to communicate with the new device on your EVM?

    Best,

    Isaac

  • is it possible that having the extra clock cycles at the beginning could be affecting the register write?

    No, when I execute a write action while the SDA line is high, the clock pulses do not occur, since the device has nothing to recover from.

    I would alter the code to prevent the clock from togging so early
    Have you tried the reset you read about on Microchip to toggle the line back high?

    The clock toggling is the reset, and it is being issued by hardware. Even if I can prevent it, I don't think it would be wise.

    Every time I try to write data to the device using the GUI, it gives me the aforementioned error message.

  • Hey Stan,

    Thank you for clarifying those details. 

    For the GUI issue I found a thread that is similar but it looks like this user was having a similar issue but instead it was writing registers and not reading them. Try following these steps used to see if we can hopefully get your GUI back up an running for your EVM. You can read the thread here.

    Another issue with the GUI is that this error can happen when the GUI cannot access a runtime engine. 

    Specifically, the user either doesn't have administrator rights (or didn't run the GUI as an administrator) when the run time engine was installed. Or, when the GUI (or the runtime) was installed, it wasn't installed in the right place. Finally, if the user has any part of the labview library installed at all, that can interfere with the GUI.

    So, here's the things to try:

    • Run GUI in administrator mode (or obtain administrator rights on computer OR try other computer with administrator rights)
    • Ask if any other of module of labview is installed in the system and try again
    • Reinstall GUI and run time engine in their default paths and try again

    For the device on your custom board what voltage are you using for Vcc?

    Have you tried following the steps to program the EEPROM? Perhaps this might yield different results from just attempting to write a register normally. Make sure that Vcc is at least  22V when following these steps.

    1. Set SIdata = 1.
    2. Write the desired motor parameters into the corresponding registers (address 0x20:0x2B) 
    3. Write 1011 0110 (0xB6) to enProgKey in the DevCtrl register.
    4. Ensure that VCC is at or above 22 V.
    5. Write eeWrite = 1 in EECtrl register to start the EEPROM programming.
    6. The programming time is about 24 ms, and eeWrite bit is reset to 0 when programming is done.

    You can check section 2.2 of the Programming Guide I linked above for info on writing registers to EEPROM.

    Additionally here is an I2C code example for the MSP430G2553 for the DRV10983. You can use to compare your code for any discrepancies.

    /*
     * I2C_MSP430G2553.c
     *
     * This file contains the software I2C used to configure the DRV10983 or
     * DRV10975. It is designed to be used with the MSP430G2553 LaunchPad and
     * programming socket board.
     *
     * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
     *
     *
     *  Redistribution and use in source and binary forms, with or without
     *  modification, are permitted provided that the following conditions
     *  are met:
     *
     *    Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     *    Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the
     *    distribution.
     *
     *    Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
    */
    
    
    #include "msp430.h"
    #include "Register_Values.h"
    
    #define SDA_1       P1OUT |=  BIT6              //SDA = 1
    #define SDA_0       P1OUT &=~ BIT6              //SDA = 0
    #define SCL_1       P2OUT |=  BIT5              //SCL = 1
    #define SCL_0       P2OUT &=~ BIT5              //SCL = 0
    #define DIR_IN      P1DIR &=~ BIT6;             //SDA Input
    #define DIR_OUT     P1DIR |=  BIT6              //SDA Output
    #define SDA_IN      ((P1IN >> 6) & 0x01)        //Read SDA
    
    #define LED_ON      P1OUT |= BIT0
    #define LED_OFF     P1OUT &=~BIT0
    
    unsigned int r_result_all[12];
    unsigned int end_result=1;
    unsigned int write_data_all[]={REG_20, REG_21, REG_22, REG_23, REG_24, REG_25,
                                   REG_26, REG_27, REG_28, REG_29, REG_2A, REG_2B};
    
    static void Delay(unsigned int n)
    {
       unsigned int i;
       for (i=0; i<n; i++ );
    }
    
    void Init(void)
    {
      SCL_1;
      Delay(5);
      SDA_1;
      Delay(5);
    }
    
    void Start(void)
    {
      SDA_1;
      Delay(5);
      SCL_1;
      Delay(5);
      SDA_0;
      Delay(5);
      SCL_0;
      Delay(5);
    }
    
    void Stop(void)
    {
      SDA_0;
      Delay(5);
      SCL_1;
      Delay(5);
      SDA_1;
      Delay(5);
    }
    
    void WriteByte(unsigned char WriteData)
    {
      unsigned char i;
      for (i=0; i<8; i++)
      {
        SCL_0;
        Delay(5);
        if (((WriteData >> 7) & 0x01) == 0x01)
        {
          SDA_1;
        }
        else
        {
          SDA_0;
        }
        Delay(5);
        SCL_1;
        WriteData = WriteData << 1;
        Delay(5);
      }
      SCL_0;
      DIR_IN;
      Delay(5);
      SCL_1;
      Delay(5);
      SCL_0;
      DIR_OUT;
    }
    
    unsigned char ReadByte(void)
    {
      unsigned char i;
      unsigned char TempBit  = 0;
      unsigned char TempData = 0;
      SCL_0;
      Delay(5);
      SDA_1;
      for (i=0; i<8; i++)
      {
        Delay(5);
        SCL_1;
        Delay(5);
        if (SDA_IN == 0x01 )
        {
          TempBit = 1;
        }
        else
        {
          TempBit = 0;
        }
        TempData = (TempData << 1) | TempBit;
        SCL_0;
      }
      Delay(5);
      return(TempData);
    }
    
    void ReceiveAck(void)
    {
      unsigned char i = 0;
      SCL_1;
      Delay(5);
      DIR_IN;
      while ((SDA_IN == 0x01) && (i < 255))
      {
        i++;
      }
      DIR_OUT;
      SCL_0;
      Delay(5);
    }
    
    void Acknowledge(void)
    {
      SCL_0;
      Delay(5);
      DIR_OUT;
      SDA_0;
      SCL_1;
      Delay(5);
      SCL_0;
    }
    
    void main(void)
    {
      unsigned int i;
      unsigned int vcc=0;
      WDTCTL = WDTPW + WDTHOLD;   // Stop Watchdog Timer
      BCSCTL1 = CALBC1_1MHZ; 	  // set up the clocks
      DCOCTL = CALDCO_1MHZ;
      
      DIR_OUT;
      P2DIR |= BIT5;  //clock as an output
      P1DIR |= BIT0;  //LED as an output
      LED_OFF;
      P1DIR &=~ BIT3; //push button input
      P1REN |= BIT3;  //enable the pull up
      P1OUT |=  BIT3; //set the pull up
      
      while(vcc<0xBB) //wait for VCC to be 22V
      {
      //begin read command for 0x1A
      Start();
      WriteByte(0xA4);
      WriteByte(0x1A);
      Stop();
    
      //read 0x1A
      Start();
      WriteByte(0xA5);
      P1OUT &=~BIT6;
      P1REN &=~BIT6;
      DIR_IN;
    
      //read register with Nack
      vcc=ReadByte();
      Acknowledge();
      Stop();
      }
    
      while(((P1IN >> 3) & 0x01)); //wait for push button
    
      //set Sidata bit to 1
      Start();
      WriteByte(0xA4);
      WriteByte(0x03);
      WriteByte(0x40);
      Stop();
    
    
      for(i=0; i<12; i++)
      {
    	//write each register 0x20 to 0x2B
        Start();
        WriteByte(0xA4);
        WriteByte(0x20+i);
        WriteByte(write_data_all[i]);
        Stop();
      }
      
      //enter the program key
      Start();
      WriteByte(0xA4);
      WriteByte(0x02);
      WriteByte(0xB6);
      Stop();
    
      //set eeWrite to 1
      Start();
      WriteByte(0xA4);
      WriteByte(0x03);
      WriteByte(0x50);
      Stop();
    
      //delay to allow eeWrite to finish
      for(i=0;i<20000;i++)
      {
    	  Delay(10000);
      }
    
      //set eeRefresh bit
      Start();
      WriteByte(0xA4);
      WriteByte(0x03);
      WriteByte(0x20);
      Stop();
    
    
      for(i=0;i<12;i++)
      {
    	//begin the read command for each register
        Start();
        WriteByte(0xA4);
        WriteByte(0x20+i);
        Stop();
      
        //send the read command for each register
        Start();
        WriteByte(0xA5);
        P1OUT &=~BIT6;
        P1REN &=~BIT6;
        DIR_IN;
        
        ///read register with Nack
        r_result_all[i]=ReadByte();
        Acknowledge();
        Stop();
        
        //compare each register value read to the write
        //register 8 bit 0 can be 0 or 1 so shift right to compare
        if(r_result_all[i] == write_data_all[i])
          end_result &= 1;
        else if(r_result_all[8]>>1 == write_data_all[8]>>1)
          end_result &= 1;
        else
          end_result=0;
      }
        //if all reads match writes turn the LED ON
        if(end_result)
          LED_ON;
        else
          LED_OFF;
      
        //loop forever
        while (1);
      
    }

    Please let me know if this still follows similar behavior.

    Best,

    Isaac

  • Hello Isaac,

    Nothing has changed on my pc, filepath, administrator rights and so on are the same as when it did work. No version of LabView has been installed and re-installing did not work.

    I desoldered the speed pin, thinking maybe it issued the DRV10983 into standby mode (it was soldered to ground), and connected it to a 3V3 supply. It did not change anything.

    I did notice however, that after writing 0x81 to speedctrl2, I got a reading of 0x3F afterwards. Also, the SDA line did get released after the read operation. If the register value wasn't complete bollocks, I'd actually be a little happy, but alas.

    It only did this after reading that specific register, when I try to read other registers, the same old stuff happens, reading 0x00 and something holding the SDA line.

    Well, back to nothing I guess.

    Greetings,
    Stan

  • Hello Isaac,

    Nothing has changed on my pc, filepath, administrator rights and so on are the same as when it did work. No version of LabView has been installed and re-installing did not work.

    I desoldered the speed pin, thinking maybe it issued the DRV10983 into standby mode (it was soldered to ground), and connected it to a 3V3 supply. It did not change anything.

    I did notice however, that after writing 0x81 to speedctrl2, I got a reading of 0x3F afterwards. Also, the SDA line did get released after the read operation. If the register value wasn't complete bollocks, I'd actually be a little happy, but alas.

    It only did this after reading that specific register, when I try to read other registers, the same old stuff happens, reading 0x00 and something holding the SDA line.

    Well, back to nothing I guess.

    Greetings,
    Stan

    EDIT: I WAS WRITING TO THE WRONG REGISTERS! Turns out I didn't know the existence of the DRV10983-Q1, which has different registers. Mine did say DRV10983SQ1 and also Farnell sells them under the name "DRV10983SQPWPRQ1" without stating any of the automotive a. I was under the impression that this was just referring to the package and package specifications.

    There's still something up with the GUI though, even when I choose DRV10983Q1, it is unable to read the registers.

    Anyway, thank you for your time so far, hopefully the GUI part is not too much of a hassle to solve.

  • Hello Stan,

    Glad to hear that it was just a device being mislabeled and not another issue that you were encountering. You populated the DRV10983-Q1 device into the same EVM as a DRV10983 correct?

    I am not aware of many board differences on there except the capacitor value for the charge pump. Did it give you the same error when you changed the GUI settings to DRV10983-Q1? I am going to have to check with the team on this since I have not tried populating a Q1 device into the DRV10983 EVM. I do not see why there should be any differences since they are pin to pin compatible.

    Best,

    Isaac

  • Hello Isaac,

    Indeed I did choose the DRV10983-Q1 option in the DRV10983xx GUI. This time, instead of being unable to read registers, the GUI complains about writing to the registers. Furthermore, the current from my power supply to the DRV10983EVM board seems to choose it's return path through the USB2ANY device, it does not require the negative terminal of the supply to be connected. The current draw is also higher than before, at 13mA, instead of >.5mA (showing 0.000A on the supply).

    Regards,

    Stan

  • Hey Stan,

    Try the workaround in this thread now: https://e2e.ti.com/support/motor-drivers-group/motor-drivers/f/motor-drivers-forum/634488/drv10983q1evm-register-writing-not-succesful since the issue seems to be the same now it should hopefully solve your problem with the GUI. Let me know if this does not work.

    Hmm that is interesting, have you tried ground the device first without the USB2ANY device present to see if it the current draw increase to 13mA again? Not quite sure what is going on here it might worth it to check the grounds to make sure they were soldered correctly when you replaced the device on the EVM board.

    Best,

    Isaac

  • Hey Isaac,

    Thank you for your time, but I have decided to stop looking into the EVM board and the GUI. Instead I'm putting my time and effort in running the DRV10983Q1 with the ATmega324P, which is working out fine so far.

    Regards,

    Stan

  • Hey Stan,

    Of course, not sure what the issue could be on the GUI perhaps some sort of difference in the DRV10983 and DRV10983-Q1 boards we may have overlooked. But I am glad that it is working on your custom board and I will close this thread. Feel free to post another question if you are having any more issues!

    Best,

    Isaac