Hi All,
We are using iMX8M Mini based custom board. We have loaded Linux (using uBoot + Yocto) whose Kernel version is 4.14.98-2.2.0.
We are have written SPI driver for ecSPI3. We would like to use SPI in Mode 3 (i.e., CPOL = CPOH = 1).
Following are the parameters we are using
void init_eeprom_spi(void)
{
strcpy(eeprom_spiconfig.spi_device, SPI_EEPROM_DEVICE);
eeprom_spiconfig.spi_bits = 8;
eeprom_spiconfig.spi_mode = 0x03;//SPI_EEPROM_MODE;
eeprom_spiconfig.spi_speed = 4000000;//SPI_SPEED_6MHZ; /*5 MHz */
eeprom_spiconfig.spi_tx_buffer = (char *)spi_eeprom_txbuffer;
eeprom_spiconfig.spi_rx_buffer = (char *)spi_eeprom_rxbuffer;
eeprom_spiconfig.spi_buffsz = SPI_BUFFER_MAX_SIZE;
eeprom_spiconfig.spi_fd = -1;
}
And here is the code were we are writing the data to SPI driver
int spi_transfer(struct spi_eeprom_conf *conf, char *txBuff, char *rxBuff, int size, int endian)
{
int ret;
void *txptr, *rxptr;
txptr = (void *)txBuff;
rxptr = (void *)rxBuff;
/* Check endianess and swap if necessary*/
if (endian == SPI_BIG_ENDIAN)
for (int i = 0; i < (size/M_FOUR); i ++)
SwapEndian((uint32_t *)txptr + i);
/* Was not getting proper clock polarity, hence adding CPOL, CPOH init here */
/* Set read mode */
if ((ret = ioctl(conf->spi_fd, SPI_IOC_RD_MODE, &conf->spi_mode)) < M_ZERO) {
printdbg(("\n spi_open: set read mode failed"));
close(conf->spi_fd);
return M_INVALID;
}
printdbg(("\n spi_open: set read mode successfull"));
/* Set write mode */
if ((ret = ioctl(conf->spi_fd, SPI_IOC_WR_MODE, &conf->spi_mode)) < M_ZERO) {
printdbg(("\n spi_open: set write mode failed"));
close(conf->spi_fd);
return M_INVALID;
}
printdbg(("\n spi_open: set wrie mode successfull"));
/* Initialize transfer structure for SPI linux API */
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)(char *)txBuff,
.rx_buf = (unsigned long)(char *)rxBuff,
.len = size,
.delay_usecs = conf->spi_delay,
.speed_hz = conf->spi_speed,
.bits_per_word = conf->spi_bits,
};
/* Initiate SPI transfer */
if ((ret = ioctl(conf->spi_fd, SPI_IOC_MESSAGE(1), &tr)) < M_ZERO) {
printdbg(("\n spi_transfer: transfer failed"));
return M_INVALID;
}
/* Check endianess and swap bytes if necessary */
if (endian == SPI_BIG_ENDIAN)
for (int i = 0; i < (size/M_FOUR); i ++)
SwapEndian((uint32_t *)rxptr + i);
printdbg(("\n spi_transfer: transfer success [Size = %d bytes]", ret));
/* Return no of bytes trasnferred */
return ret;
}
In-spite of all the trials, I am not able to change the mode of SPI. It is stuck with "CLOCK being Low in Idle". Interestingly, I can manipulate clock frequency without any problem. I am able to get the data out from MOSI also.
Can some one guide me how to change SPI mode? Do you see any problem in code?
Regards,
Aravind