the SPI clk issue has been fixed now, and i define the spi read/write function, but i'm not sure if it is right:
static int vk32xx_read_reg(struct spi_device *spi,uint8_t port,uint8_t reg,uint8_t *dat)
{
struct spi_message msg;
uint8_t buf_wdat[2];
uint8_t buf_rdat[2];
int status = 0;
buf_wdat[0] = 0x7f&(((port-1)<<5)|(reg<<1));
buf_wdat[1] = 0x0;
buf_rdat[0] = 0x0;
buf_rdat[1] = 0x0;
status = spi_write_then_read(spi, buf_wdat, 2, buf_rdat, 2);
if(status)
printk("WWJ====vk32xx_read_reg failed status = %d\n", status);
printk("buf_rdat[0] = 0x%x, buf_rdat[1] = 0x%x\n", buf_rdat[0], buf_rdat[1]);
*dat = buf_wdat[1];
return 0;
}
static int vk32xx_write_reg(struct spi_device *spi,uint8_t port,uint8_t reg,uint8_t dat)
{
struct spi_message msg;
uint8_t buf_reg[2];
int status = 0;
struct spi_transfer index_xfer = {
.len = 2,
};
//spi_message_init(&msg);
/* register index */
buf_reg[0] = 0x80|((port-1)<<5)|(reg<<1);
buf_reg[1] = dat;
status = spi_write(spi, buf_reg, 2);
if(status)
printk("WWJ======vk32xx_write_reg failed status = %d\n", status);
return status;
}
you can refer to our linux bsp.
yes, i tried the below function, but the issue is still:
static int vk32xx_read_reg(struct spi_device *spi,uint8_t port,uint8_t reg,uint8_t *dat)
{
struct spi_message msg;
unsigned int txdata = 0, rxdata = 0;
uint8_t buf_wdat[2];
uint8_t buf_rdat[2];
int status;
// mutex_lock(&vk32xxs_lock);
struct spi_transfer index_xfer = {
.len = 2,
.cs_change = 1,
};
status =0;
spi_message_init(&msg);
buf_wdat[1] = 0x7f&(((port-1)<<5)|(reg<<1));
buf_wdat[0] = 0x00;
buf_rdat[0] = 0x00;
buf_rdat[1] = 0x00;
index_xfer.tx_buf = buf_wdat;
index_xfer.rx_buf =(void *) buf_rdat;
spi_message_add_tail(&index_xfer, &msg);
status = spi_sync(spi, &msg);
udelay(500);
if(status)
{
printk("spi_sync failed status = %d\n", status);
return status;
}
*dat = buf_rdat[1];
printk("buf_rdat[1] = 0x%x, buf_rdat[0] = 0x%x\n", buf_rdat[1], buf_rdat[0]);
printk("buf_wdat[1] = 0x%x, buf_wdat[0] = 0x%x\n", buf_wdat[1], buf_wdat[0]);
return 0;
}
i have measured the MISO line and the data wave is appeared, but the buf_rdat is still zero. i do not know why?
1. Please double check the linux/arch/arm/plat-mxc/include/mach/iomux-mx6q.h. The pad control of the ECSPI pins should use the MX6Q_ECSPI_PAD_CTRL.
For example:
#define MX6Q_PAD_KEY_COL0__ECSPI1_SCLK \
(_MX6Q_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL))
Should be changed to :
#define MX6Q_PAD_KEY_COL0__ECSPI1_SCLK \
(_MX6Q_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(MX6Q_ECSPI_PAD_CTRL))
2. You can try to use the "spidev" first. For example :
static struct spi_board_info vk32xx_spi_board_info[] __initdata = {
/* The modalias must be the same as spi device driver name */
.modalias = "spidev",
.max_speed_hz = 10000000,
.bus_num = 0,
.chip_select = 0,
};
3. Then try to use 'ioctl' to test the read/write. You can take the unit_test/test/mxc_spi_test/mxc_spi_test1.c for reference.
Here is an example for your reference :
Below is the timing of SPI read of a SPI device.
#define DEV_SPI "/dev/spidev0.0"
static uint8_t spi_transfer(int fd, uint8_t *tx)
{
int ret;
uint8_t rx[ARRAY_SIZE(tx)] = {0, };
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = 2,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret == 1)
printf("can't send spi message.\n");
return rx[1]; // rx[0] is not the data read from the device, rx[1] is the data D7-D0.
}
static void SPI_Write_register(int fd, uint8_t reg, uint8_t val)
{
uint8_t tx[] = { 0x00, 0x00, };
tx[0] = 0x80 | reg; // the first bit is 1 for SPI Write
tx[1] = val;
spi_transfer(fd, tx);
}
static uint8_t SPI_Read_register(int fd, uint8_t reg)
{
uint8_t tx[] = { 0x00, 0x00, };
tx[0] = 0x7F & reg; // the first bit is 0 for SPI Read
tx[1] = 0xFF;
return spi_transfer(fd, tx);
}
int main()
{
int fd, res;
uint8_t val;
unsigned char mode=0;
unsigned char bits_per_word = 8;
unsigned int speed = 10000000;
fd = open(DEV_SPI, O_RDWR);
res = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (res == -1) {
printf("can't set spi mode");
goto exit;
}
res = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (res == -1) {
printf("can't set spi mode");
goto exit;
}
res = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word);
if (res == -1) {
printf("can't set bits per word");
goto exit;
}
res = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits_per_word);
if (res == -1) {
printf("can't get bits per word");
goto exit;
}
res = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (res == -1) {
printf("can't set max speed hz");
goto exit;
}
res = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
if (res == -1) {
printf("can't get max speed hz");
goto exit;
}
//Read the value of the address 0x00 of SPI device
val = SPI_Read_register(fd,0x0);
printf("Read value : %X\n",val);
// write the 0x1 to the address 0x00 of SPI device
SPI_Write_register(fd,0x0,0x1);
exit:
close(fd);
return 0;
}
We test the spi on our platform. Do this issue only happen on your platform?
What's HW connection are you using and which version code are you work on?