Hello,
I am evaluating a K64 platform with the tower, and I am trying to use the SPI with interrupts but I always get some errors caught in the hardfault handler.
When i have crashed, I get :
lr = 0x79f7 =>
326 if (DSPI_DRV_MasterStartTransfer(instance, device) == kStatus_DSPI_Busy)
000079f2: bl 0x7914 <DSPI_DRV_MasterStartTransfer>
000079f6: cmp r0, #4
000079f8: beq.n 0x7a26 <DSPI_DRV_MasterTransferBlocking+90>
334 syncStatus = OSA_SemaWait(&dspiState->irqSync, timeout);
000079fa: add.w r0, r4, #40 ; 0x28
000079fe: ldr r1, [sp, #28]
00007a00: bl 0x82c6 <OSA_SemaWait>
335 }while(syncStatus == kStatus_OSA_Idle);
So I assume the next instruction should be a comparison between the result of DSPI_DRV_MasterStartTransfer and Busy (4) in the function DSPI_DRV_MasterTransferBlocking , but the crash occurs.
I have also pc = 0x1fff3b7c but I can't relate this adress ...
and psr = 0
I have created the IRQ using this declaration :
void MQX_SPI0_IRQHandler(void)
{
DSPI_DRV_IRQHandler(SPI0_IDX);
}
and this code :
{
int i;
dspi_status_t dspiResult;
dspi_master_state_t masterState;
dspi_device_t masterDevice;
dspi_master_user_config_t masterUserConfig = {
.isChipSelectContinuous = false,
.isSckContinuous = false,
.pcsPolarity = kDspiPcs_ActiveLow,
.whichCtar = kDspiCtar0,
.whichPcs = kDspiPcs0
};
uint32_t calculatedBaudRate;
if(!init_ok)
{
// Setup the configuration.
masterDevice.dataBusConfig.bitsPerFrame = 8;
masterDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge;
masterDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh;
masterDevice.dataBusConfig.direction = kDspiMsbFirst;
// Initialize master driver.
dspiResult = DSPI_DRV_MasterInit(DSPI_MASTER_INSTANCE,
&masterState,
&masterUserConfig);
if (dspiResult != kStatus_DSPI_Success)
{
PRINT("\r\nERROR: Can not initialize master driver \n\r");
return NONOS_RET_ERR;
}
// Configure baudrate.
masterDevice.bitsPerSec = TRANSFER_BAUDRATE;
dspiResult = DSPI_DRV_MasterConfigureBus(DSPI_MASTER_INSTANCE,
&masterDevice,
&calculatedBaudRate);
if (dspiResult != kStatus_DSPI_Success)
{
PRINT("\r\nERROR: failure in configuration bus\n\r");
return NONOS_RET_ERR;
}
else
{
printf("\r\n Transfer at baudrate %lu \r\n", calculatedBaudRate);
}
if (NULL == OSA_InstallIntHandler(SPI0_IRQn, MQX_SPI0_IRQHandler))
{
PRINT("spi_init:OSA_InstallIntHandler returned 4\n");
return NONOS_RET_ERR;
}
INT_SYS_EnableIRQ(SPI0_IRQn);
NVIC_SetPriority(SPI0_IRQn, 6U);
init_ok = 1;
}
else
{
PRINT("\r\nERROR: init already done\n\r");
return NONOS_RET_ERR;
}
#ifdef SL_PLATFORM_MULTI_THREADED
return OSI_OK;
#else
return NONOS_RET_OK;
#endif
}
The write (that fails and creates the crash) is done this way :
int spi_Write(Fd_t fd, unsigned char *pBuff, int len)
{
dspi_status_t dspiResult;
// Send the data.
dspiResult = DSPI_DRV_MasterTransferBlocking(DSPI_MASTER_INSTANCE,
NULL, // device conf ou NULL si aucun changement
pBuff, // buffer de data a envoyer ou null pour envoyer des 0
NULL, // buffer de data a recevoir ou null si data recue ignoree
len, // quantite de donnee
MASTER_TRANSFER_TIMEOUT); // duree de timeout
if (dspiResult != kStatus_DSPI_Success)
{
//PRINT("spi_Write error\r\n");
return 0;
}
return len;
}
Finally, those functions are called through a task.
I think there is some issue with the IRQ, but I can't get a breakpoint triggered in this IRQ before calling the DSPI driver. If someone has an idea about this ...
Regards
Solved! Go to Solution.
Solved, the data used in the init was local so not kept in memory, which was creating the overwrite.
solution : replace masterState by g_masterState (global)
After investigation, it appears the issue is related to printf, that overwrites data, especially data pointed by g_dspiStatePtr at 0x1fff89dc. I have set the stack size to 10000 and the heap size to 0x2000. If someone has any idea ...
Solved, the data used in the init was local so not kept in memory, which was creating the overwrite.
solution : replace masterState by g_masterState (global)