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; }