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.

DRV8316REVM: [DRV8316] SPI does not work properly

Part Number: DRV8316REVM
Other Parts Discussed in Thread: DRV8316, DRV8301

Hi.

I'm working on TI's DRV8316REVM to control BLDC motor. And I use STM32G474RE(Nucleo board) as MCU to control DRV8316.

Now, I have issue that I can't read and write register of DRV8316 via SPI properly.

The situation is like this:

  1. SPI communication is OK, I believe so.
  2. After, power on, I read the default register values, but return values form the DRV8316 is not same value as datasheet. So, I think read operation is not OK.
    ex.) I read Control3 register (address=0x05, reset value=0x00) and instead of 0x00 it was returned 0x46.
          I saw the schematic, but I couldn't to find out any pin wiring for this register to return 0x46.
          
  3. Write to register and read it. The written value is not read. The return values of each register, is same as the operation 2. So, I think write operation is not OK.

My question about this issue is, any special initialization or communication rules need to read and write DRV8316 register?
Also I put a part of my test code.

Please let me know if any processing or settings are missing.

Test code for SPI:


static uint8_t getParity(uint8_t x)
{
uint8_t count = 0;

for (uint8_t i = 0; i < 8; i++)
{
count += (x >> i) & 0x01;
}

uint8_t parity;

if ((count % 2) == 0)
{
parity = 0;
}
else
{
parity = 1;
}

return parity;
}

int dev_drv8316_init(dev_drv8316_t *dev)
{
static volatile uint16_t timeout = 0;
int isTimeout = 0;

HAL_Delay(100);
HAL_GPIO_WritePin(DRV_nSLEEP_GPIO_Port, DRV_nSLEEP_Pin, GPIO_PIN_SET);

HAL_Delay(10);
HAL_GPIO_WritePin(DRV_OFF_GPIO_Port, DRV_OFF_Pin, GPIO_PIN_RESET);

HAL_Delay(10);

/**
* Read status registers during startup.
*/
DRV8316_ReadWordFormat_t rw;

while (1)
{
rw = dev_drv8316_read(dev, IC_STATUS_REG_ADDR);
dev->ic_status.data = rw.bit.data;

if (dev->ic_status.bit.FAULT == 0)
{
break;
}

if (++timeout > 999)
{
isTimeout = 1;
}
}

rw = dev_drv8316_read(dev, IC_STATUS_REG_ADDR);
dev->ic_status.data = rw.bit.data;

rw = dev_drv8316_read(dev, STATUS_1_REG_ADDR);
dev->status1.data = rw.bit.data;

rw = dev_drv8316_read(dev, STATUS_2_REG_ADDR);
dev->status1.data = rw.bit.data;

/**
* Read control registers.
*/
rw = dev_drv8316_read(dev, CONTROL_1_REG_ADDR);
dev->control1.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_2_REG_ADDR);
dev->control2.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_3_REG_ADDR);
dev->control3.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_4_REG_ADDR);
dev->control4.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_5_REG_ADDR);
dev->control5.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_6_REG_ADDR);
dev->control6.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_10_REG_ADDR);
dev->control10.data = rw.bit.data;

HAL_Delay(5);
/**
* Write control registers.
*/
dev_drv8316_write(dev, CONTROL_1_REG_ADDR, DRV8316_RegLock_UnlockAll);

dev_drv8316_write(dev, CONTROL_2_REG_ADDR, \
DRV8301_PwmMode_SixPwmWithCurrentLimit | DRV8301_Slew_200VoltPerMicrosec | DRV8301_SdoMode_OpenDrain);

dev_drv8316_write(dev, CONTROL_3_REG_ADDR, \
DRV8316_Pwm100DutySel_20KHz | DRV8316_OvpSel_20Volt);

dev_drv8316_write(dev, CONTROL_4_REG_ADDR, 0xAA);
dev_drv8316_write(dev, CONTROL_5_REG_ADDR, 0xAA);
dev_drv8316_write(dev, CONTROL_6_REG_ADDR, 0xAA);
dev_drv8316_write(dev, CONTROL_10_REG_ADDR, 0xAA);

dev_drv8316_write(dev, CONTROL_1_REG_ADDR, DRV8316_RegLock_LockAll);

HAL_Delay(5);

/**
* Read control registers.
*/
rw = dev_drv8316_read(dev, CONTROL_1_REG_ADDR);
dev->control1.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_2_REG_ADDR);
dev->control2.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_3_REG_ADDR);
dev->control3.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_4_REG_ADDR);
dev->control4.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_5_REG_ADDR);
dev->control5.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_6_REG_ADDR);
dev->control6.data = rw.bit.data;

rw = dev_drv8316_read(dev, CONTROL_6_REG_ADDR);
dev->control6.data = rw.bit.data;

return isTimeout;
}


DRV8316_ReadWordFormat_t dev_drv8316_write(dev_drv8316_t *dev, uint16_t reg, uint16_t data)
{
DRV8316_WriteWordFormat_t ww;

ww.bit.rw = WRITE_COMMAND;
ww.bit.address = reg & 0x003F;
ww.bit.data = data;
ww.bit.parity = getParity(data);

dev->tx_buffer[0] = ww.byte[1];
dev->tx_buffer[1] = ww.byte[0];

HAL_GPIO_WritePin(SPI3_CS_GPIO_Port, SPI3_CS_Pin, GPIO_PIN_RESET);

HAL_SPI_TransmitReceive_DMA(dev->hSPI, dev->tx_buffer, dev->rx_buffer, 2);

while (HAL_SPI_GetState(dev->hSPI) != HAL_SPI_STATE_READY)
{
;
}

HAL_GPIO_WritePin(SPI3_CS_GPIO_Port, SPI3_CS_Pin, GPIO_PIN_SET);

DRV8316_ReadWordFormat_t rw;
rw.bit.status = dev->rx_buffer[0];
rw.bit.data = dev->rx_buffer[1];
}

DRV8316_ReadWordFormat_t dev_drv8316_read(dev_drv8316_t *dev, uint16_t reg)
{
DRV8316_WriteWordFormat_t ww;

ww.bit.rw = READ_COMMAND;
ww.bit.address = reg & 0x003F;
ww.bit.data = DUMMY_DATA;
ww.bit.parity = getParity(DUMMY_DATA);

dev->tx_buffer[0] = ww.byte[1];
dev->tx_buffer[1] = ww.byte[0];

HAL_GPIO_WritePin(SPI3_CS_GPIO_Port, SPI3_CS_Pin, GPIO_PIN_RESET);

HAL_SPI_TransmitReceive_DMA(dev->hSPI, dev->tx_buffer, dev->rx_buffer, 2);
while (HAL_SPI_GetState(dev->hSPI) != HAL_SPI_STATE_READY)
{
;
}

HAL_GPIO_WritePin(SPI3_CS_GPIO_Port, SPI3_CS_Pin, GPIO_PIN_SET);

DRV8316_ReadWordFormat_t rw;
rw.bit.status = dev->rx_buffer[0];
rw.bit.data = dev->rx_buffer[1];

return rw;
}

  • Hi Kenji,

    Thank you for your question! The biggest issue I see with the waveform is with the clock timing. According to the datasheet the minimum period for the clock is 100ns, and the minimum high and low time is 50ns. 


    If you look at the waveform below I have circled 2 examples of several instances where the clock timing doesn't meet the datasheet minimum timing. The timing for the plot you provided is 100ns/division, and there are multiple instances where the clock signal is low or high for less than half the time of the division of the plot, which means that the timing would be less than 50ns and thus would violate the minimum timing requirements. This could create issues with capturing data properly. 

     

    If you still have issues with the SPI after correcting the clock timing please let us know.

    Regards,

    Anthony

  • Hi Anthony-san

    The picture that I upload was baud rate of 10.625MBits/s. Also I test with band rate of 5.3125MBits/s, 2.65625MBits/s, but not solved the problem.

    Is there any other possible factor?

  • Hi Kenji-san,

    Are you reading back the same value (0x46) even when testing across various baud rates? Would you be able to provide waveforms showing the clock timing at 5.3125MBits/s? 

    Regards,

    Anthony 

  • Dear Anthony-san

    Yes same value "0x46".

    I'm at home now, so I will post the figure tomorrow!

  • Hi Kenji-san,

    Thanks for the additional information! I will review the figure once you are able to post it.

    Regards,

    Anthony 

  • Hi Antony-san

    This is a waveform of 5.3MBits/s.

    No changed the situation that the reset (default) value of register is still not read. It remains different from the values in the data sheet.

    But now some registers can be written the value I Specified.

    Also I upload the original logic signal l recorded b Saleae.

    drv8316_spi5.3MBitsPerSec.zip

    Questions:

    • Is the reset value shown in the data sheet is correct?
    • Control register 1 have a REG_LOCK bits. When I write data to a register, I set "unlock" on these bits.
      After write I set "lock". You can see on the code I posted,  how I do it. 
      Is my procedure correct?

  • Dear Anthony-san

    I don't know why the reset value is different form the data sheet yet.

    For now, I will focus about writing register.
    And I found that Control 1/3/4/10 registers are possible to write. Control2/5/6/ registers couldn't rewrite it.

    Any special operation need for Control 2/5/6/ registers?

  • Hi Kenji-san,

    The contents of the registers reset to their default settings when the DRV is powered off and then powered on again (this is controlled by VM being removed then restored), or after the device enters SLEEP mode. This is different than using the DRVOFF pin, since the DRVOFF pin simply disables all the MOSFETs to prevent motor commutation. Using the DRVOFF pin doesn't reset the registers. Looking at your code it looks like this may be the reason that the registers are not resetting to the expected value.

    Regarding Control registers 2/5/6 there shouldn't be any special operation necessary to write to those registers. It may be good to check to make sure the parity bit is correct since the parity bit should be set such that the entire 16 bit command (including the address, read/write bit, and the data bits) has an even number of 1s. 

    Regards,

    Anthony 

  • Hi Anthony-san

    Thanks to you, I could rewrite all registers.

    I only checked the parity of 8 data bits. So, I miss to check read/write and address bits.

    I misunderstood the word "data", from the email received from TI.
    I thought that it means the 8-bits data, so I don't did the correct parity check length.

    Thank you.

  • Hi Kenji,

    I am sorry for the confusion on the meaning of the word "data", but I am glad I could help resolve the issue. I will see if there is anything we can change to avoid any further confusion in the future.

    Regards,

    Anthony