I am having trouble using the ECSPI from the Cortex-M4 of the i.MX8MM with the functions available in fsl_ecspi.c.
Eventually, I need to communicate with complex ADC and DAC devices. To try and simplify things to prove the interface I have gone back to an SPI flash device and trying to read the manufacturer ID. The flash data sheet shows the following diagram:
Looking at the SPI bus on a logic analyser I don't ever seem to see any data coming from the device. I appear to have 4 bytes being written to the slave device and the CS# going high then low between each byte being sent.
The setup of the ESCPI controller is as per the SDK sample:
/* Master config:
* masterConfig.channel = kECSPI_Channel0;
* masterConfig.burstLength = 8;
* masterConfig.samplePeriodClock = kECSPI_spiClock;
* masterConfig.baudRate_Bps = TRANSFER_BAUDRATE;
* masterConfig.chipSelectDelay = 0;
* masterConfig.samplePeriod = 0;
* masterConfig.txFifoThreshold = 1;
* masterConfig.rxFifoThreshold = 0;
*/
ECSPI_MasterGetDefaultConfig(&masterConfig);
masterConfig.baudRate_Bps = TRANSFER_BAUDRATE;
ECSPI_MasterInit(EXAMPLE_ECSPI_MASTER_BASEADDR, &masterConfig, ECSPI_MASTER_CLK_FREQ);
Anyone got any ideas how I make this work?
-Andy.
Hi @AldoG
Let me try to explain better...
The ECSPI interface is being configured as per the driver/ecspi/polling_b2b_transfer/master example in the SDK (I have SDK v2.11.0). I then run the following code to try to query the SPI flash for it's manufacturer ID:
Hi,
Thank you for sharing more information, from the piece of code you have shared and the analyzer image, it seems that the output you're seeing after 0x9f are random stuff because you have set a datasize of 4.
masterXfer.dataSize = 4;
Since only the first byte have a value the other 3 bytes will be dummy data, and you could see this in the ecspi driver located at: SDK_2_11_0_EVK-MIMX8MM\devices\MIMX8MM6\drivers\fsl_ecspi.c
while (xfer->dataSize > 0UL)
{
/* ECSPI will transmit and receive at the same time, if txData is NULL,
* instance will transmit dummy data, the dummy data can be set by user.
* if rxData is NULL, data will be read from RX FIFO buffer, but the
* data will be ignored by driver.
* Note that, txData and rxData cannot be both NULL.
*/
state = ECSPI_WriteBlocking(base, xfer->txData, dataCounts);
if (kStatus_Success != state)
{
return state;
}
if (NULL != xfer->txData)
{
xfer->txData += dataCounts;
}
state = ECSPI_ReadBlocking(base, xfer->rxData, dataCounts);
if (kStatus_Success != state)
{
return state;
}
if (NULL != xfer->rxData)
{
xfer->rxData += dataCounts;
}
xfer->dataSize -= dataCounts;
}
Also, if you need the SS to stay active, you'll need to have SS_CTL clear and after looking into the driver code this is not supported, but that does not mean it could not be added on your side, you may refer to the reference manual for more information on this:
Please refer to the fsl_ecspi.c function:
void ECSPI_SetChannelConfig(ECSPI_Type *base, ecspi_channel_source_t channel, const ecspi_channel_config_t *config)
Best regards,
Aldo.
Hi @AldoG
Thanks for the additional information.
Can I just confirm that in order to keep the SS signal active I need to set the SS_CTL bit to be 0?
Looking at the Reference Manual and the source code for ECSPI_MasterInit() then it looks like currently that bit is being ignored as the SMC bit in ECSPI_CONREG is set to 1.
I'm guessing that means that I need to modify ECSPI_MasterInit() to make the SMC bit configurable and if SMC bit is cleared then the transfers need to be initiated by setting the XCH bit.
Can you confirm all of the above is correct.
-Andy.
Hello,
Yes, you're correct
Best regards,
Aldo.
Hello,
I do not understand clearly which part is not responding, I believe it is the slave right?
I think it would be better to try an ECSPI example, i.e. b2b_transfer so you could see the SPI bus with you analyzer.
Best regards,
Aldo.