AnsweredAssumed Answered

Issue with SPI interrupt

Question asked by samuel boivineau on Jan 21, 2016
Latest reply on Jan 22, 2016 by samuel boivineau

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

Outcomes