So I have freertos running on the m4. The linux kernel 4.9 on the A7. When I run the SPI without running linux, there is no issue to run SPI without Linux. As soon as linux started, the SPI stop working. I checked with a logic analyzer.
The SPI works almost like this example: main.c « master « ecspi_interrupt « ecspi « driver_examples « imx7_colibri_m4 « examples - freertos-toradex.git - FreeRTOS for the Cortex M4 core of Heterogeneous Multicore modules
+----------+ +----------+ +-----------+
| | | | RPMSG| |
| | SPI | +----->+ |
| ADC +----->+ Cortex-M4| | Cortex-A7|
| | | +<-----+ |
| | | | | |
+----------+ +----------+ +-----------+
Before asking the question, I looked for similar questions. I found those ones:
I paid espcially attention to the the answer from @andy.tx talking about a bug from cache. i.MX7 M4 Atomic Cache Bug – Ryan Schaefer I also use mutliple memories by modifying the linker. I wonder whether it caused my issues.
@andy.tx talked about a potential fix. Is it done yet ?
According to me the problem is not completely solved by the seccond questions, but I have feeling that it could have been solved recently.
My SPI implementation below.
/******************************************************************************
*
* Function Name: ECSPI_MasterConfig
* Comments: ECSPI module initialize
*
******************************************************************************/
void ECSPI_MasterConfig(ecspi_init_config_t* initConfig)
{
/* Initialize ECSPI transfer state. */
ecspiState.isBusy = false;
/* Initialize ECSPI, parameter configure */
ECSPI_Init(BOARD_ECSPI_BASEADDR, initConfig);
/* SPI RDY */
ECSPI_SetSPIDataReady(BOARD_ECSPI_BASEADDR,ecspiRdyFallEdgeTrig);
/* Thersholds */
ECSPI_SetFIFOThreshold(BOARD_ECSPI_BASEADDR,ecspiRxfifoThreshold,8);
ECSPI_SetFIFOThreshold(BOARD_ECSPI_BASEADDR,ecspiTxfifoThreshold,8);
/* ECSPI interrupts */
ECSPI_SetIntCmd(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoEmpty, true);
ECSPI_SetIntCmd(BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoDataRequest, true);
ECSPI_SetIntCmd(BOARD_ECSPI_BASEADDR, ecspiFlagRxfifoFull, true);
ECSPI_SetIntCmd(BOARD_ECSPI_BASEADDR, ecspiFlagRxfifoDataRequest, true);
/* Set SPI IRQ Priority */
NVIC_SetPriority(BOARD_ECSPI_IRQ_NUM, APP_SPI_IRQ_PRIORITY);
/* Call core API to enable the IRQ. */
NVIC_EnableIRQ(BOARD_ECSPI_IRQ_NUM);
}
/******************************************************************************
*
* Function Name: BOARD_ECSPI_MASTER_HANDLER
* Comments: The interrupt service routine triggered by ECSPI interrupt
*
******************************************************************************/
void BOARD_ECSPI_HANDLER(void)
{
// See FreeRTOS reference manual
static int32_t i = 0;
static int32_t j = 0;
static int32_t k = 0;
struct sampleBlockInfo outputBlock;
union sample_t sample[8];
BaseType_t ret;
BaseType_t xHigherPriorityTaskWoken;
xHigherPriorityTaskWoken = pdFALSE;
if(ECSPI_GetStatusFlag (BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoDataRequest))
{
for(i=0;i<8;i++)
{
ECSPI_SendData(BOARD_ECSPI_BASEADDR, 0xDEADBEEF);
}
ECSPI_StartBurst(BOARD_ECSPI_BASEADDR);
ECSPI_ClearStatusFlag(BOARD_ECSPI_BASEADDR,ecspiFlagTxfifoDataRequest);
}
if(ECSPI_GetStatusFlag (BOARD_ECSPI_BASEADDR, ecspiFlagTxfifoEmpty))
{
/* Clear Flag */
ECSPI_ClearStatusFlag(BOARD_ECSPI_BASEADDR,ecspiFlagTxfifoEmpty);
}
if(ECSPI_GetStatusFlag (BOARD_ECSPI_BASEADDR, ecspiFlagRxfifoFull))
{
/* ERROR */
/* Clear Flag */
ECSPI_ClearStatusFlag(BOARD_ECSPI_BASEADDR,ecspiFlagRxfifoFull);
}
if(ECSPI_GetStatusFlag (BOARD_ECSPI_BASEADDR, ecspiFlagRxfifoDataRequest))
{
for(i=0;i<8;i++)
{
sample[i].u32 = ECSPI_ReceiveData(BOARD_ECSPI_BASEADDR);
}
for(i = 0; i<ACQ_TASK_CHANNEL_NUMBER;i++)
{
//sample_acq[k][i][j] = ((float) sample[i].i16[0]);
}
j++;
if(j>=SAMPLE_BLOCK_LENGTH)
{
outputBlock.timestamp = GPT_ReadCounter(BOARD_GPTA_BASEADDR);
//outputBlock.timestamp = xTaskGetTickCount() * 1e9 / configTICK_RATE_HZ;
outputBlock.blockNum = k;
//ret = xQueueSendToBackFromISR(xAcqsampleQueue,&outputBlock,xHigherPriorityTaskWoken);
//configASSERT(ret == pdTRUE);
j=0;
k++;
if(k>=ACQ_TASK_SAMPLE_BLOCK_NB)
{
k=0;
}
}
ECSPI_ClearStatusFlag(BOARD_ECSPI_BASEADDR,ecspiFlagRxfifoDataRequest);
ecspiState.isBusy = false;
}
}