AnsweredAssumed Answered

DSPI EDMA Always Busy

Question asked by Jon Mundall on May 13, 2015
Latest reply on May 22, 2015 by Jon Mundall

Using the latest ksdk 1.2.0


I'm including the interrupt handler files




Building with keil uvision 5 (Build settings are basically textbook examples including using MicroLib and the -C99 flags)

also using the proper freertos library (libksdk_platform_freertos.lib)


I'm initializing the pins for the spi bus with the following code:

      /* Affects PORTD_PCR0 register */       PORT_HAL_SetMuxMode(PORTD,0u,kPortMuxAlt2);       /* Affects PORTD_PCR3 register */       PORT_HAL_SetMuxMode(PORTD,3u,kPortMuxAlt2);       /* Affects PORTD_PCR1 register */       PORT_HAL_SetMuxMode(PORTD,1u,kPortMuxAlt2);       /* Affects PORTD_PCR2 register */       PORT_HAL_SetMuxMode(PORTD,2u,kPortMuxAlt2);



Here's the spi setup code:

uint8_t receiveBuffer[32] = {0}; uint8_t sendBuffer[32] = {0}; edma_software_tcd_t stcdDspiMasterTest __attribute__((aligned (32)));         int spi_init(){    uint32_t calculatedBaudRate;       edma_state_t dmaState;     edma_user_config_t dmaUserConfig;     dspi_edma_master_state_t edmaMasterState;     dspi_edma_device_t edmaDevice;     dspi_edma_master_user_config_t edmaMasterUserConfig =     {         .isChipSelectContinuous     = false,         .isSckContinuous            = false,         .pcsPolarity                = kDspiPcs_ActiveLow,         .whichCtar                  = kDspiCtar0,         .whichPcs                   = kDspiPcs0     };         //     dmaUserConfig.chnArbitration = kEDMAChnArbitrationRoundrobin;   // dmaUserConfig.notHaltOnError = false;     EDMA_DRV_Init(&dmaState, &dmaUserConfig);       // Print a note. //    PRINTF("\r\n DSPI Driver Starting...\n");       // Setup the configuration.     edmaDevice.dataBusConfig.bitsPerFrame = 8;     edmaDevice.dataBusConfig.clkPhase     = kDspiClockPhase_SecondEdge;     edmaDevice.dataBusConfig.clkPolarity  = kDspiClockPolarity_ActiveHigh;     edmaDevice.dataBusConfig.direction    = kDspiMsbFirst;       //Init the dspi module for DMA operation     dspiResult = DSPI_DRV_EdmaMasterInit(DSPI_MASTER_INSTANCE,                                          &edmaMasterState,                                          &edmaMasterUserConfig,                                          &stcdDspiMasterTest);         if (dspiResult != kStatus_DSPI_Success)     {         PRINTF("\r\nERROR: Can not initialize master driver, error=%d\n\r",dspiResult);         return -1;     }    //dspiResult = DSPI_DRV_MasterSetDelay(DSPI_MASTER_INSTANCE, kDspiAfterTransfer,1000,&calculatedBaudRate);       // Configure baudrate.     edmaDevice.bitsPerSec = TRANSFER_BAUDRATE;     dspiResult = DSPI_DRV_EdmaMasterConfigureBus(DSPI_MASTER_INSTANCE,                                                  &edmaDevice,                                                  &calculatedBaudRate);     if (dspiResult != kStatus_DSPI_Success)     {         PRINTF("\r\nERROR: failure in config bus, error=%d \n\r",dspiResult);         return -1;     }     else     {         PRINTF("\r\n Transfer at baudrate %lu\n", calculatedBaudRate);     }     //   PRINTF("\r\n DSPI Driver Started...\n");   return 1; } 



Here's the code that attempts to read from the spi bus

        dspiResult = DSPI_DRV_EdmaMasterTransfer(DSPI_MASTER_INSTANCE,                                              NULL,                                               receiveBuffer,                                               sendBuffer,                                              sizeof(sendBuffer));           if (dspiResult != kStatus_DSPI_Success)         {   PRINTF("\r\nE%d \n\r",dspiResult);             return -1;         }



Honestly I'm completely stumped.. All of the other peripherals work fine including I2C and Uart


I've tried removing the I2C and other KSDK drivers that are used aswell as moving the spi test code from the main function to threads and nothing is working...  Everything initializes fine without errors.. The first transmit executes without error (Doesn't transmit anything but at least completes without throwing an error)  any subsequent transfers return Error code 4, Busy State


I've tested this with SPI instance 1&2 aswell with the same result...


This is running on a custom board built around the Frdm K64f with the MK64FN1M0VLL12 CPU, Silicone Rev 1.1

The board is clocked identically to the frdmk64f with a 50mhz clock from the ethernet PHY and a 32khz RTC. 


The DSPI library calculates the buad rate correctly and all the clocks returned with the following command appear correct


uint32_t system,platform,bus,rtc,lpo;   CLOCK_SYS_GetFreq(kSystemClock,&system); CLOCK_SYS_GetFreq(kPlatformClock,&platform); CLOCK_SYS_GetFreq(kBusClock,&bus); CLOCK_SYS_GetFreq(kOsc32kClock,&rtc); CLOCK_SYS_GetFreq(kWdogLpoClkSrc,&lpo);   printf("System Clk = %d,Platform Clk = %d, Bus Clk = %d, RTC Clk = %d, LPO_CLK = %d\r\n",system,platform,bus,rtc,lpo);



I have also confirmed that the dma config holder is aligned to a 32 byte boundary and that the OSA freertos abstraction layer is working correctly.


I'm using the following linker scater file:

LR_IROM1 0x1A000 0x100000 { ER_IROM1 0x1A000 0x100000    {       *.o (RESET, +First)       *(InRoot$$Sections)       .ANY (+RO)    }        VECTOR_RAM 0x1FFF0000 EMPTY 0x00000400    {    }        RW_IRAM1 0x1FFF0400 0xEC00    {        .ANY (+RW +ZI)    }        ARM_LIB_STACK 0x20000000 EMPTY -0x1000    {    }        ARM_LIB_HEAP 0x20000000 EMPTY 0x30000    {    }       }



Please let me know what ideas you have to help me work around this issue, it's very confusing to me as all the other ksdk peripheral drivers (RTC, WDT, Uart, I2C, GPIO, Etc..) are working correctly


Kind Regards,