AnsweredAssumed Answered

DSPI abnormal timing between frames

Question asked by PETER SHIH on Dec 8, 2015
Latest reply on Dec 9, 2015 by PETER SHIH



I am working on a custom board equipped with K66 MCU(120MHz, and 60MHz bus clock), serial Flash, and other peripherals. The purpose of serial Flash is just for data storage. I have successfully read the device JEDEC ID through DSPI bus 1 (20MHz baud). However, based on the scope observation, the delay between 8-bit frames are too long (approximately  3.2us). Please refer to the following scope screenshot,

Yellow signal: PCS0 on DSPI1,

Green signal: CLK,

Blue signal: SOUT, and

Pink signal: SIN.

I would like to have minimum delay between transfer by setting delay with DSPI_HAL_SetDelay() function. Based on the calculation,

PCSSCK=0, CSSCk=0 --> tcsc=(1/60M)*1*2=33.3ns

PASS=0, ASC=0, tasc=(1/60M)*1*2=33.3ns

PDT=0, DT=0, tdt=(1/60M)*1*2=33.3ns


I have verified the register has been correct set to zero before calling transfer. Based on the reference manual, the delay between transfer should be tasc+tcsc or maybe even none. However, I have 3.2us between transfer. This is too much away from specification. I wonder if any thing wrong in my code. Please let me know if you have idea or recommendation. Thank you very much.


The following are source code for my test:

int main(void) {     uint32_t    int32utmp;      /* Write your code here */     // Init hardware     hardware_init();     dbg_uart_init();      PRINTF("\r\n\nRunning SPI_Test example.");      // Configure SPI pins     configure_spi_pins(BOARD_ETHSW_SERFLASH_SPI_INSTANCE);    //configure SPI1     gpio_Init();      int32utmp = W25Q128FV_ReadID();     if (int32utmp == 0xEF4018)    printf("\nW25Q128FV is detected.");      /* This for loop should be replaced. By default this loop allows a single stepping. */     for (;;) {     }     /* Never leave main */     return 0; }


uint32_t W25Q128FV_ReadID(void) {     uint8_t            send_buf[5];     uint8_t            recv_buf[5];     uint32_t         result;      GPIOE_PSOR |= 0x00000001;     result = dspicomm_w25qxf_init(DSPI_W25QxFV_INSTANCE, TRANSFER_HIGH_BAUDRATE);     GPIOE_PCOR |= 0x00000001;     if (result != kStatus_DSPI_Success)    return (-1);      send_buf[0] = JEDEC_ID;     GPIOE_PSOR |= 0x00000001;     result = dspicomm_read(DSPI_W25QxFV_INSTANCE, send_buf, 1, recv_buf, 3);     GPIOE_PCOR |= 0x00000001;     dspicomm_close(DSPI_W25QxFV_INSTANCE);      result = (uint32_t)(recv_buf[1] << 16);    // Manuf ID     : Winbond             = 0xEF     result |= recv_buf[2] << 8;                // Memory Type     : SPI Serial Flash     = 0x40     result |= recv_buf[3];                   // Memory Size     : W25Q128FV         = 0x18      return result; }


int8_t dspicomm_w25qxf_init(uint32_t instance, uint32_t speed) {     dspi_status_t dspiResult;     uint32_t calculatedBaudRate;          w25Q128FV_masterUserConfig.isChipSelectContinuous = true;     w25Q128FV_masterUserConfig.isSckContinuous        = false;     w25Q128FV_masterUserConfig.pcsPolarity            = kDspiPcs_ActiveLow;     w25Q128FV_masterUserConfig.whichCtar              = kDspiCtar0;     w25Q128FV_masterUserConfig.whichPcs               = kDspiPcs0;      // Initialize master driver.     dspiResult = DSPI_DRV_MasterInit(instance,                                      &w25Q128FV_masterState,                                      &w25Q128FV_masterUserConfig);     if (dspiResult != kStatus_DSPI_Success)     {         PRINTF("\r\nERROR: Can not initialize SPI master driver!");         return -1;     }      // Setup the configuration.     w25Q128FV_masterDevice.dataBusConfig.bitsPerFrame = 8;     w25Q128FV_masterDevice.dataBusConfig.clkPhase     = kDspiClockPhase_FirstEdge;     w25Q128FV_masterDevice.dataBusConfig.clkPolarity  = kDspiClockPolarity_ActiveHigh;     w25Q128FV_masterDevice.dataBusConfig.direction    = kDspiMsbFirst;     w25Q128FV_masterDevice.bitsPerSec = speed; //    dspiResult = DSPI_DRV_MasterConfigureBus(instance, //                                             &w25Q128FV_masterDevice, //                                             &calculatedBaudRate); //    if (dspiResult != kStatus_DSPI_Success) //    { //        printf("\r\nERROR: failure in configuration SPI bus!"); //        return -1; //    }      // The original DSPI_DRV_MasterConfigureBus() routine takes about 30us to complete.     // The following initialization takes only about 2.5us     dspi_master_state_t * dspiState = (dspi_master_state_t *)g_dspiStatePtr[instance];     SPI_Type *base = g_dspiBase[instance];      SPI_BWR_CTAR_DBR(base, dspiState->whichCtar, 0x01);    //DBR = 1     SPI_BWR_CTAR_PBR(base, dspiState->whichCtar, 0x01);    //PBR = 1     SPI_BWR_CTAR_BR(base, dspiState->whichCtar, 0x00);    //BR = 0, Baud = (fp/PBR)*[(1+DBR)/BR] = (60M/3)*[(1+1)/2] = 20MHz      SPI_BWR_CTAR_FMSZ(base, dspiState->whichCtar, (w25Q128FV_masterDevice.dataBusConfig.bitsPerFrame - 1));     SPI_BWR_CTAR_CPOL(base, dspiState->whichCtar, w25Q128FV_masterDevice.dataBusConfig.clkPolarity);     SPI_BWR_CTAR_CPHA(base, dspiState->whichCtar, w25Q128FV_masterDevice.dataBusConfig.clkPhase);     SPI_BWR_CTAR_LSBFE(base, dspiState->whichCtar, w25Q128FV_masterDevice.dataBusConfig.direction);      DSPI_HAL_SetDelay(base, dspiState->whichCtar, 0x00, 0x00, kDspiPcsToSck);        //PCSSCK=0, CSSCK=0, Tcsc=(1/60M)*1*2=32ns     DSPI_HAL_SetDelay(base, dspiState->whichCtar, 0x00, 0x00, kDspiLastSckToPcs);    //PASC=0, ASC=0, Tasc=(1/60M)*1*2=32ns     DSPI_HAL_SetDelay(base, dspiState->whichCtar, 0x00, 0x00, kDspiAfterTransfer);    //PDT=0, DT=0, Tdt=(1/60M)*1*2=32ns      return (kStatus_DSPI_Success); }  int8_t dspicomm_close(uint32_t instance) {     dspi_status_t dspiResult;      dspiResult = DSPI_DRV_MasterDeinit(instance);     if (dspiResult != kStatus_DSPI_Success)     {         PRINTF("\r\nERROR: failure in configuration SPI bus!");         return -1;     }      return (kStatus_DSPI_Success); }  int32_t dspicomm_write(uint32_t instance, uint8_t *data, uint32_t size) {     dspi_status_t     dspiResult;     uint32_t         wordsTransfer = 0;      // Send the data.     dspiResult = DSPI_DRV_MasterTransfer(instance,                                          NULL,                                          data,                                          NULL,                                          size);     if (dspiResult != kStatus_DSPI_Success)     {         PRINTF("\r\nERROR: Write data transfer error!");         return (-1);     }     // Wait until the transfer is complete.     while (DSPI_DRV_MasterGetTransferStatus(instance, &wordsTransfer) == kStatus_DSPI_Busy)     {}      return size; }  int32_t dspicomm_read(uint32_t instance, uint8_t *txData, uint32_t txSize, uint8_t *rxData, uint32_t rxSize) {     dspi_status_t     dspiResult;     uint32_t         wordsTransfer = 0;      // Send the data.     dspiResult = DSPI_DRV_MasterTransfer(instance,                                          NULL,                                          txData,                                          rxData,                                          txSize+rxSize);     if (dspiResult != kStatus_DSPI_Success)     {         PRINTF("\r\nERROR: Read data transfer error!");         return (-1);     }     // Wait until the transfer is complete.     while (DSPI_DRV_MasterGetTransferStatus(instance, &wordsTransfer) == kStatus_DSPI_Busy)     {}      return rxSize; }