KSDK DSPI PCS to CLK delay scaler

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

KSDK DSPI PCS to CLK delay scaler

Jump to solution
1,016 Views
petershih
Contributor III

Hi:

 

I am working on a custom board equipped with K66 MCU, 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. However, based on the scope observation, the delay between the chip enable (PCS) to clock (CLK) is too long (approximately  39us). Please refer to the following scope screenshot,

Yellow signal: PCS0 on DSPI1,

Green signal: SIN,

Blue signal: CLK, and

Pink signal: SOUT.

92346_92346.pngpastedImage_0.png

 

Based on the datasheet, the delay between the PCS to the first raising clock can be adjusted by bit15-12 PCS to SCK Delay Scaler in the SPIx_CTARn register. The delay is calculated by tcsc=(1/fp)*PCSSCK*CSSCK. I have K66 running at 120MHz clock and the system speed is 60MHz. That means the minimum delay should be (1/60M)*1*2=32ns.

92347_92347.jpgpastedImage_1.jpg

92486_92486.jpgpastedImage_2.jpg

The software development is based on KDS3.0 and KSDK1.2. I don't have any special delay settings (DSPI_DRV_MasterSetDelay()) in the source code, and I have verified the PCSSCK=00 and CSSCK=1 in the CTAR1 from DSPI1, which should be (1/60M)*1*4=64ns. This value, initial set from  DSPI_HAL_SetDelay(base, userConfig->whichCtar, 0, 1, kDspiPcsToSck) in the DSPI_DRV_MasterInit(), doesn't match the signal I saw on the scope. I wonder if I misunderstand somewhere. Is any way I can short the time between the PCS and the 1st CLK? Please let me know if you have any idea or recommendation. Thanks!

 

#include <stdio.h> #include "main.h" #include "ethSwitch.h" #include "W25QxFVFlashDriver.h"  //----------------------------------------------------------------------- // Function Prototypes //----------------------------------------------------------------------- void main_task(uint32_t param); void task_example(task_param_t param); void gpio_Init(void);  //----------------------------------------------------------------------- // Constants //----------------------------------------------------------------------- #define MAIN_TASK              8U const TASK_TEMPLATE_STRUCT  MQX_template_list[] = {    { MAIN_TASK, main_task, 0xC00, 20, "main_task", MQX_AUTO_START_TASK},    { 0L,        0L,        0L,    0L,  0L,         0L } }; #define TASK_EXAMPLE_PRIO            6U #define TASK_EXAMPLE_STACK_SIZE   1024U  //----------------------------------------------------------------------- // Macros //----------------------------------------------------------------------- OSA_TASK_DEFINE(task_example, TASK_EXAMPLE_STACK_SIZE);  //----------------------------------------------------------------------- // Main Function //----------------------------------------------------------------------- void main_task(uint32_t param) {     uint32_t    int32utmp;     osa_status_t result = kStatus_OSA_Error;      printf("\n\nRunning the SPIFFS project.");      // Configure SPI pins     configure_spi_pins(BOARD_ETHSW_SERFLASH_SPI_INSTANCE);    //configure SPI1 for Ethernet switch     gpio_Init();      /* Initialize Ethernet Switch KSZ8895RQ */     OSA_TimeDelay(100);        //wait for Ethernet switch ready     Initialize_EthSW();      int32utmp = W25Q128FV_ReadID();     if (int32utmp == 0xEF4018)    printf("\nW25Q128FV is detected.");      OSA_Init();  //    result = OSA_TaskCreate(task_example, //                    (uint8_t *)"example", //                    TASK_EXAMPLE_STACK_SIZE, //                    task_example_stack, //                    TASK_EXAMPLE_PRIO, //                    (task_param_t)0, //                    false, //                    &task_example_task_handler); //    if (result != kStatus_OSA_Success) //    { //        printf("Failed to create example task\r\n"); //        return; //    }      OSA_Start();      for (;;)                                         // Forever loop     {         OSA_TimeDelay(100);        //500ms delay     }   } //----------------------------------------------------------------------- // Task Functions //----------------------------------------------------------------------- // //void task_example(task_param_t param) //{ //    printf("\r\nHellow World.\r\n"); // //    while(1) //    { //        __asm("NOP"); //    } //}  void gpio_Init(void) {     gpio_output_pin_user_config_t     outputPinConfig;      outputPinConfig.pinName = kGpioC5;     outputPinConfig.config.outputLogic = 1;     outputPinConfig.config.slewRate = kPortSlowSlewRate;     outputPinConfig.config.isOpenDrainEnabled = false;     outputPinConfig.config.driveStrength = kPortLowDriveStrength;     GPIO_DRV_OutputPinInit(&outputPinConfig);      outputPinConfig.pinName = kGpioC6;     outputPinConfig.config.outputLogic = 1;     outputPinConfig.config.slewRate = kPortSlowSlewRate;     outputPinConfig.config.isOpenDrainEnabled = false;     outputPinConfig.config.driveStrength = kPortLowDriveStrength;     GPIO_DRV_OutputPinInit(&outputPinConfig); }

 

uint32_t W25Q128FV_ReadID(void) {     uint8_t            send_buf[5];     uint8_t            recv_buf[5];     uint32_t         result;      result = dspicomm_w25qxf_init(DSPI_W25QxFV_INSTANCE, TRANSFER_HIGH_BAUDRATE);     if (result != kStatus_DSPI_Success)    return (-1);      send_buf[0] = JEDEC_ID;     result = dspicomm_read(DSPI_W25QxFV_INSTANCE, send_buf, 1, recv_buf, 3);     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              = kDspiCtar1;     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;     }  //    /* Configure timing delays 200ns, it is optional, useful for slower peripheral diveces or "fine tune" SPI timings */ //    uint32_t delayInNanosec = 200; //    uint32_t calculatedDelay; //    /* Set pcs to sck delay */ //    DSPI_DRV_MasterSetDelay(instance, kDspiPcsToSck, delayInNanosec, &calculatedDelay); //    /* Set last sck to pcs delay */ //    DSPI_DRV_MasterSetDelay(instance, kDspiLastSckToPcs, delayInNanosec, &calculatedDelay); //    /* Set delay after transfer */ //    DSPI_DRV_MasterSetDelay(instance, kDspiAfterTransfer, delayInNanosec, &calculatedDelay);      /* SPI use interrupt, must be installed in MQX and file fsl_dspi_irq.c must not be included in project */     int32_t IRQNumber = g_dspiIrqId[instance];     _int_install_isr(IRQNumber, (INT_ISR_FPTR)DSPI_DRV_MasterIRQHandler, (void*)instance);      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); }  uint32_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; }
Labels (1)
0 Kudos
1 Solution
692 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Peter Shih:

What is the value of the macro TRANSFER_HIGH_BAUDRATE in your code? And the value of JEDEC_ID?

I tried to recreate your issue using a random SPI bus frequency of 1 MHz, but I only see a delay between PCS and CLK of 60 ns. See the pictures below (value 0x54 instead of your JEDEC_ID):

pastedImage_0.png

pastedImage_1.png

The only difference is that I did not use MQX, but I think that should not make any difference in this case.

Regards!

Jorge Gonzalez

View solution in original post

0 Kudos
2 Replies
692 Views
petershih
Contributor III

Hi Jorge:

I just got chance to review this problem. The communication baud rate is 20MHz. I redo the test based on MQX or non-MQX with KSDK, I had similar result as you have for tcsc.

pastedImage_0.png

pastedImage_1.png

However, Here I have another problem. I will post it on the different discussion. Thank you very much!

0 Kudos
693 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Peter Shih:

What is the value of the macro TRANSFER_HIGH_BAUDRATE in your code? And the value of JEDEC_ID?

I tried to recreate your issue using a random SPI bus frequency of 1 MHz, but I only see a delay between PCS and CLK of 60 ns. See the pictures below (value 0x54 instead of your JEDEC_ID):

pastedImage_0.png

pastedImage_1.png

The only difference is that I did not use MQX, but I think that should not make any difference in this case.

Regards!

Jorge Gonzalez

0 Kudos