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