Tool/software:
Hi Team,
Using DRV8311P.
Using the tSPI protocol for register reading and writing, it was found that the written data is inconsistent with the read data
1) NSLEEP pull down ->pull up
2) PWM_SYNC ->Pull up
3) Register writing and reading
Can you help me see what the reason is?
The schematic diagram and communication program are as follows:
#include <stdio.h>
#include <stdint.h>
#include <linux/spi/spidev.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define SPI_DEVICE "/dev/spidev3.1"
#define SPI_SPEED 10000000 // 10MHz
#define REG_DEV_STS1 0x00
#define REG_OT_STS 0x04
#define REG_SUP_STS 0x05
#define REG_DEV_STS 0x06
#define REG_SYS_STS 0x07
#define REG_PWM_SYNC_PRD 0x0C
#define REG_FLT_MODE 0x10
#define REG_SYSF_CTRL 0x12
#define REG_DRVF_CTRL 0x13
#define REG_FLT_TCTRL 0x16
#define REG_FLT_CLR 0x17
#define REG_PWMG_PERIOD 0x18
#define REG_PWMG_A_DUTY 0x19
#define REG_PWMG_B_DUTY 0x1A
#define REG_PWMG_C_DUTY 0x1B
#define REG_PWM_STATE 0x1C
#define REG_PWMG_CTRL 0x1D
#define REG_PWM_CTRL1 0x20
#define REG_DRV_CTRL 0x22
#define REG_CSA_CTRL 0x23
#define REG_SYS_CTRL 0x3F
#define DEVICE_ID 0x03
#define TSPI_WRITE_FLAG 0x00
#define TSPI_READ_FLAG 0x80
#define SPI_BIT_PER_WORD 8
static int s_spi_dev_fd;
int drv8311_spi_init(void)
{
s_spi_dev_fd = open(SPI_DEVICE, O_RDWR);
if (s_spi_dev_fd < 0) {
perror("Failed to open SPI device");
return -1;
}
printf("open SPI_DEVICE = %s ok\n", SPI_DEVICE);
uint8_t mode = SPI_MODE_1;
if (ioctl(s_spi_dev_fd, SPI_IOC_WR_MODE, &mode) < 0) {
perror("Failed to set SPI mode");
close(s_spi_dev_fd);
return -1;
}
uint32_t speed = SPI_SPEED;
if (ioctl(s_spi_dev_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) {
perror("Failed to set SPI_IOC_WR_MAX_SPEED_HZ");
close(s_spi_dev_fd);
return -1;
}
if (ioctl(s_spi_dev_fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0) {
perror("Failed to set SPI SPI_IOC_RD_MAX_SPEED_HZ");
close(s_spi_dev_fd);
return -1;
}
int bit = SPI_BIT_PER_WORD;
if (ioctl(s_spi_dev_fd, SPI_IOC_WR_BITS_PER_WORD, &bit)) {
perror("Failed to set SPI SPI_IOC_WR_BITS_PER_WORD");
close(s_spi_dev_fd);
return -1;
}
if (ioctl(s_spi_dev_fd, SPI_IOC_RD_BITS_PER_WORD, &bit)) {
perror("Failed to set SPI SPI_IOC_WR_BITS_PER_WORD");
close(s_spi_dev_fd);
return -1;
}
return 0;
}
int drv8311_tspi_read(int spi_fd, uint8_t reg_addr, uint16_t *data, uint32_t data_len) {
uint8_t tx_buf[4] = {0};
uint8_t rx_buf[4] = {0};
tx_buf[0] = TSPI_READ_FLAG | (DEVICE_ID << 3) | ((reg_addr >> 5) & 0x07);
tx_buf[1] = ((reg_addr & 0x1F) << 3);
tx_buf[2] = 0x00;
tx_buf[3] = 0x00;
struct spi_ioc_transfer msg;
memset(&msg, 0, sizeof(msg));
msg.tx_buf = (unsigned long)tx_buf;
msg.rx_buf = (unsigned long)rx_buf;
msg.len = 4;
msg.speed_hz = SPI_SPEED;
msg.bits_per_word = SPI_BIT_PER_WORD;
msg.cs_change = 0;
if (ioctl(spi_fd, SPI_IOC_MESSAGE(1), &msg) < 0) {
perror("SPI Read Error");
return -1;
}
*data = (rx_buf[1] << 8) | rx_buf[2];
*data &= 0x7FFF;
printf("\r\n");
printf("=============================read==============================\n");
printf("tspi read reg_addr = 0x%x, status = 0x%x, data = 0x%x\n", reg_addr, rx_buf[0], *data);
printf("drv8311_tspi_read tx_buf[0] = 0x%x, tx_buf[1] = 0x%x, tx_buf[2] = 0x%x\n", tx_buf[0], tx_buf[1], tx_buf[2]);
printf("===========================================================\n");
printf("\r\n");
return 0;
}
int drv8311_tspi_write(int spi_fd, uint8_t reg_addr, uint16_t data) {
uint8_t tx_buf[4] = {0};
tx_buf[0] = TSPI_WRITE_FLAG | (DEVICE_ID << 3) | ((reg_addr >> 5) & 0x07);
tx_buf[1] = ((reg_addr & 0x1F) << 3);
tx_buf[2] = (data >> 8) & 0xFF;
tx_buf[3] = data & 0xFF;
struct spi_ioc_transfer msg;
memset(&msg, 0, sizeof(msg));
msg.tx_buf = (unsigned long)tx_buf;
msg.rx_buf = 0;
msg.len = 4;
msg.speed_hz = SPI_SPEED;
msg.bits_per_word = SPI_BIT_PER_WORD;
msg.cs_change = 0;
if (ioctl(spi_fd, SPI_IOC_MESSAGE(1), &msg) < 0) {
perror("SPI Write Error");
return -1;
}
printf("\r\n");
printf("===========================write================================\n");
printf("tspi write reg_addr = 0x%x data = 0x%x\n", reg_addr, data);
printf("drv8311_tspi_write tx_buf[0] = 0x%x, tx_buf[1] = 0x%x, tx_buf[2] = 0x%x, tx_buf[3] = 0x%x\n", tx_buf[0], tx_buf[1], tx_buf[2], tx_buf[3]);
printf("===========================================================\n");
printf("\r\n");
uint16_t reg_status = 0;
drv8311_tspi_read(spi_fd, reg_addr, ®_status, 2);
return 0;
}
int drv8311_exit(void)
{
if (s_spi_dev_fd > 0 ) {
if (drv8311_tspi_write(s_spi_dev_fd, REG_PWMG_CTRL, 0) < 0) {
close(s_spi_dev_fd);
return -1;
}
close(s_spi_dev_fd);
printf("drv8311_exit done\n");
return 0;
}
printf("invalid s_spi_dev_fd \n");
return -1;
}
static int drv8311_check_status(void)
{
printf("drv8311_check_status \n");
uint16_t reg_status = 0;
if (drv8311_tspi_read(s_spi_dev_fd, REG_DEV_STS1, ®_status, 2) < 0) { // 0x80 default
printf("read REG_DEV_STS1 faied \n");
}
if (drv8311_tspi_read(s_spi_dev_fd, REG_OT_STS, ®_status, 2) < 0) {
printf("read REG_OT_STS faied \n");
}
if (drv8311_tspi_read(s_spi_dev_fd, REG_SUP_STS, ®_status, 2) < 0) {
printf("read REG_SUP_STS faied \n");
}
if (drv8311_tspi_read(s_spi_dev_fd, REG_SYS_STS, ®_status, 2) < 0) {
printf("read REG_SYS_STS faied \n");
}
return 0;
}
static int drv8311_set_param(void)
{
printf("drv8311_set_param \n");
// clean
if (drv8311_tspi_write(s_spi_dev_fd, REG_FLT_CLR, 0x0001) < 0) {
printf("write REG_PWMG_A_DUTY faied \n");
}
// set mode
if (drv8311_tspi_write(s_spi_dev_fd, REG_PWM_CTRL1, 0x0003) < 0) {
printf("write REG_PWM_CTRL1 faied \n");
}
// set TDEAD_CTRL and SLEW_RATE
if (drv8311_tspi_write(s_spi_dev_fd, REG_DRV_CTRL, 0x0013) < 0) {
printf("write REG_PWM_CTRL1 faied \n");
}
// set duty
if (drv8311_tspi_write(s_spi_dev_fd, REG_PWMG_A_DUTY, 0x0800) < 0) {
printf("write REG_PWMG_A_DUTY faied \n");
}
if (drv8311_tspi_write(s_spi_dev_fd, REG_PWMG_B_DUTY, 0x0800) < 0) {
printf("write REG_PWMG_B_DUTY faied \n");
}
if (drv8311_tspi_write(s_spi_dev_fd, REG_PWMG_C_DUTY, 0x0800) < 0) {
printf("write REG_PWMG_C_DUTY faied \n");
}
// set period
if (drv8311_tspi_write(s_spi_dev_fd, REG_PWMG_PERIOD, 0x0032) < 0) {
printf("write REG_PWM_CTRL1 faied \n");
}
// set pwm state
if (drv8311_tspi_write(s_spi_dev_fd, REG_PWM_STATE, 0x0777) < 0) {
printf("write REG_PWM_CTRL1 faied \n");
}
// enable gen pwm and PWM_OSC_SYNC
if (drv8311_tspi_write(s_spi_dev_fd, REG_PWMG_CTRL, 0x0420) < 0) {
printf("write REG_PWM_CTRL1 faied \n");
}
return 0;
}
int main() {
if (drv8311_spi_init()) {
printf("drv8311_spi_init failed\n");
return -1;
}
drv8311_set_param();
int loop_cnt = 0;
while (0) {
loop_cnt++;
drv8311_check_status();
sleep(1);
if (loop_cnt >= 15) {
loop_cnt = 0;
break;
}
}
drv8311_exit();
return 0;
}





