AnsweredAssumed Answered

DSPI multiple Peripheral chip select

Question asked by PETER SHIH on Dec 23, 2015
Latest reply on Jan 5, 2016 by xiangjun.rong

Hi:

 

I am working on a custom board equipped with K66 MCU(120MHz, and 60MHz bus clock), serial Flash, Ethernet switch, and other peripherals. The purpose of serial Flash is just for data storage. The Ethernet switch is configurable through SPI interface. Both device are on SPI1 bus and I have successfully read both device ID at 500KHz baud. However I have Ethernet problem after I have some data write to serial flash. Investigate problem more detail, I found whenever SPI initialization DSPI_DRV_MasterInit() is called, the un-selected PCS will keep asserted even during data transferring. I am not sure if I utilize KSDK properly. Please let me know if you have any idea. Thank you very much.

Read serial flash ID with PCS0

yellow: PCS0 (PTB10)

green: PCS1 (PTB9)

blue: SCK (PTB11)

pink: SOUT (PTB16)

 

Read Ethernet switch ID with PCS1

yellow: PCS0

green: PCS1

blue: SCK

pink: SOUT

int main(void) {     uint32_t    int32utmp;     uint8_t        int8utmp;      /* 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("\r\nW25Q128FV is detected.");      /* Initialize Ethernet switch internal registers */     int8utmp = readRegisters(0);            //read family ID = 0x88     if (int8utmp == 0x88) {         printf("\r\nKSZ8863 Rev%d is detected ", (int8utmp & 0x0E)>1);     }      /* This for loop should be replaced. By default this loop allows a single stepping. */     for (;;) {      }     /* Never leave main */     return 0; }

 

In W25QxFVFlash.c

dspi_master_state_t w25Q128FV_masterState; dspi_device_t w25Q128FV_masterDevice; dspi_master_user_config_t w25Q128FV_masterUserConfig;  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_LOW_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;     SPI_Type         *dspiBaseAddr = g_dspiBase[instance];      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;     }      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_read(uint32_t instance, uint8_t *txData, uint32_t txSize, uint8_t *rxData, uint32_t rxSize) {     dspi_status_t     dspiResult;     uint32_t        i, tempPushr;     uint32_t         wordsTransfer = 0;      // Send/Receive 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; }

 

In ethSwitch.c

dspi_master_state_t ksz8863_masterState; dspi_device_t ksz8863_masterDevice; dspi_master_user_config_t ksz8863_masterUserConfig; dspi_status_t dspiResult;  uint8_t readRegisters (uint8_t addr) {     uint8_t            send_buf[5];     uint8_t            recv_buf[5];     uint32_t         result;      /* Protect SPI transaction in multitask environment */     result= dspicomm_ethsw_init(DSPI_KSZ8863_INSTANCE, TRANSFER_LOW_BAUDRATE);     if (result != kStatus_DSPI_Success)    {         return (0xFF);     }      send_buf[0] = READ_REG;     send_buf[1] = addr;      //Send and receive data.     dspicomm_ethsw_read(DSPI_KSZ8863_INSTANCE, send_buf, 2, recv_buf, 1);      dspicomm_ethsw_close(DSPI_KSZ8863_INSTANCE);      return recv_buf[2]; }  static int8_t dspicomm_ethsw_init(uint32_t instance, uint32_t speed) {     uint32_t calculatedBaudRate;      ksz8863_masterUserConfig.isChipSelectContinuous = true;     ksz8863_masterUserConfig.isSckContinuous = false;     ksz8863_masterUserConfig.pcsPolarity = kDspiPcs_ActiveLow;     ksz8863_masterUserConfig.whichCtar = kDspiCtar1;     ksz8863_masterUserConfig.whichPcs = kDspiPcs1;      // Initialize master driver.     dspiResult = DSPI_DRV_MasterInit(instance,                                      &ksz8863_masterState,                                      &ksz8863_masterUserConfig);     if (dspiResult != kStatus_DSPI_Success)     {         printf("\r\nERROR: Can not initialize master driver \n\r");         return -1;     }      // Configure bus.     ksz8863_masterDevice.dataBusConfig.bitsPerFrame = 8;     ksz8863_masterDevice.dataBusConfig.clkPhase     = kDspiClockPhase_FirstEdge;     ksz8863_masterDevice.dataBusConfig.clkPolarity  = kDspiClockPolarity_ActiveHigh;     ksz8863_masterDevice.dataBusConfig.direction    = kDspiMsbFirst;      // Configure baudrate.     ksz8863_masterDevice.bitsPerSec = TRANSFER_LOW_BAUDRATE;     dspiResult = DSPI_DRV_MasterConfigureBus(instance,                                              &ksz8863_masterDevice,                                              &calculatedBaudRate);     if (dspiResult != kStatus_DSPI_Success)     {         printf("\r\nERROR: failure in configuration bus\n\r");         return -1;     }      return (kStatus_DSPI_Success); }  static int32_t dspicomm_ethsw_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 / receive 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; }  static int8_t dspicomm_ethsw_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); }

 

In pin_mux.c

void configure_spi_pins(uint32_t instance) {   switch(instance) {     case SPI0_IDX:                       /* HW_SPI0 */ //      /* Affects PORTA_PCR17 register */ //      PORT_HAL_SetMuxMode(PORTA,17UL,kPortMuxAlt2); //      /* Affects PORTA_PCR16 register */ //      PORT_HAL_SetMuxMode(PORTA,16UL,kPortMuxAlt2); //      /* Affects PORTA_PCR15 register */ //      PORT_HAL_SetMuxMode(PORTA,15UL,kPortMuxAlt2); //      /* Affects PORTA_PCR14 register */ //      PORT_HAL_SetMuxMode(PORTA,14UL,kPortMuxAlt2);       break;     case SPI1_IDX:                       /* HW_SPI1 */       /* Affects PORTB_PCR10 register */       PORT_HAL_SetMuxMode(PORTB,10u,kPortMuxAlt2);       /* Affects PORTB_PCR9 register */       PORT_HAL_SetMuxMode(PORTB,9u,kPortMuxAlt2);       /* Affects PORTB_PCR17 register */       PORT_HAL_SetMuxMode(PORTB,17u,kPortMuxAlt2);       /* Affects PORTB_PCR11 register */       PORT_HAL_SetMuxMode(PORTB,11u,kPortMuxAlt2);       /* Affects PORTB_PCR16 register */       PORT_HAL_SetMuxMode(PORTB,16u,kPortMuxAlt2);       break;     case SPI2_IDX:                       /* HW_SPI2 */ //      /* Affects PORTD_PCR11 register */ //      PORT_HAL_SetMuxMode(PORTD,11UL,kPortMuxAlt2); //      /* Affects PORTD_PCR15 register */ //      PORT_HAL_SetMuxMode(PORTD,15UL,kPortMuxAlt2); //      /* Affects PORTD_PCR14 register */ //      PORT_HAL_SetMuxMode(PORTD,14UL,kPortMuxAlt2); //      /* Affects PORTD_PCR12 register */ //      PORT_HAL_SetMuxMode(PORTD,12UL,kPortMuxAlt2); //      /* Affects PORTD_PCR13 register */ //      PORT_HAL_SetMuxMode(PORTD,13UL,kPortMuxAlt2);       break;     default:       break;   } }

Outcomes