Hi:
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; }