Hi NXP team,
I am working on iMX8QXP SPI. I need to know the supported modes for SPI in iMX8QXP. I understand from the manual that it supports both master and slave mode. So I am using spidev to communicate with the SPI interface. When I tried to set the 3-wire mode(which is half-duplex), I was not able to set it. Please find below the test code used and the output
=========================SPI Test Code BEGIN==============================
#include <fcntl.h>
#include <sys/ioctl.h>
int main(int argc, char *argv[])
{
int fd;
int ret = 0;
char mode;
fd = open("/dev/spidev0.0", O_RDWR);
if (fd >= 0)
{
/* write mode */
mode = SPI_MODE_0;
ret = ioctl(fd,SPI_IOC_WR_MODE,&mode);
if (ret == -1)
perror("mode0:");
/* read mode */
ioctl(fd,SPI_IOC_RD_MODE,&mode);
printf("mode0 = %u\n",mode);
/* write mode */
mode = SPI_MODE_1;
ret = ioctl(fd,SPI_IOC_WR_MODE,&mode);
if (ret == -1)
perror("mode1:");
/* read mode */
ioctl(fd,SPI_IOC_RD_MODE,&mode);
printf("mode1 = %u\n",mode);
/* write mode */
mode = SPI_MODE_2;
ret = ioctl(fd,SPI_IOC_WR_MODE,&mode);
if (ret == -1)
perror("mode2:");
/* read mode */
ioctl(fd,SPI_IOC_RD_MODE,&mode);
printf("mode2 = %u\n",mode);
/* write mode */
mode = SPI_MODE_3;
ret = ioctl(fd,SPI_IOC_WR_MODE,&mode);
if (ret == -1)
perror("mode3:");
/* read mode */
ioctl(fd,SPI_IOC_RD_MODE,&mode);
printf("mode3 = %u\n",mode);
/* write mode */
mode = SPI_3WIRE;
ret = ioctl(fd,SPI_IOC_WR_MODE,&mode);
if (ret == -1)
perror("mode-3wire:");
/* read mode */
ioctl(fd,SPI_IOC_RD_MODE,&mode);
printf("mode16 = %u\n",mode);
if (ret == -1)
perror("mode3:");
/* read mode */
ioctl(fd,SPI_IOC_RD_MODE,&mode);
printf("mode3 = %u\n",mode);
/* write mode */
mode = SPI_3WIRE;
ret = ioctl(fd,SPI_IOC_WR_MODE,&mode);
if (ret == -1)
perror("mode-3wire:");
/* read mode */
ioctl(fd,SPI_IOC_RD_MODE,&mode);
printf("mode16 = %u\n",mode);
}
close(fd);
return 0;
}
=========================SPI Test Code ENDS==============================
The output I have got is below which shows that 3-wire(half-duplex) is not supported:
mode0 = 4[ 1162.005031] spidev spi0.0: setup: unsupported mode bits 10
mode1 = 5
mode2 = 6
mode3 = 7
mode-3wire:: Invalid argument
mode16 = 7
Queries:
Thank you,
Vijay.
已解决! 转到解答。
Here is spi test code in BSP, you can refer that.
https://github.com/nxp-imx/imx-test/blob/lf-5.15.32_2.0.0/test/mxc_spi_test/mxc_spi_test1.c
Please refer driver logic, the mode you set from userspace will be handled in fsl_lpspi_set_cmd function.
static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
{
u32 temp = 0;
temp |= fsl_lpspi->config.bpw - 1;
temp |= (fsl_lpspi->config.mode & 0x3) << 30;
temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
if (!fsl_lpspi->is_slave) {
temp |= fsl_lpspi->config.prescale << 27;
/*
* Set TCR_CONT will keep SS asserted after current transfer.
* For the first transfer, clear TCR_CONTC to assert SS.
* For subsequent transfer, set TCR_CONTC to keep SS asserted.
*/
if (!fsl_lpspi->usedma) {
temp |= TCR_CONT;
if (fsl_lpspi->is_first_byte)
temp &= ~TCR_CONTC;
else
temp |= TCR_CONTC;
}
}
writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp);
}
For controller, it doesn't support SPI_3WIRE feature.
controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
For modes, it can support :
Here is spi test code in BSP, you can refer that.
https://github.com/nxp-imx/imx-test/blob/lf-5.15.32_2.0.0/test/mxc_spi_test/mxc_spi_test1.c
Please refer driver logic, the mode you set from userspace will be handled in fsl_lpspi_set_cmd function.
static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
{
u32 temp = 0;
temp |= fsl_lpspi->config.bpw - 1;
temp |= (fsl_lpspi->config.mode & 0x3) << 30;
temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
if (!fsl_lpspi->is_slave) {
temp |= fsl_lpspi->config.prescale << 27;
/*
* Set TCR_CONT will keep SS asserted after current transfer.
* For the first transfer, clear TCR_CONTC to assert SS.
* For subsequent transfer, set TCR_CONTC to keep SS asserted.
*/
if (!fsl_lpspi->usedma) {
temp |= TCR_CONT;
if (fsl_lpspi->is_first_byte)
temp &= ~TCR_CONTC;
else
temp |= TCR_CONTC;
}
}
writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp);
}
For controller, it doesn't support SPI_3WIRE feature.
controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
For modes, it can support :
Thank you @Zhiming_Liu for the support