/***************************************************************************//** * @brief spi_init *******************************************************************************/ int32_t spi_init(uint32_t device_id, uint8_t clk_pha, uint8_t clk_pol) { uint32_t base_addr = 0; uint32_t spi_options = 0; #ifdef _XPARAMETERS_PS_H_ spi_config = XSpiPs_LookupConfig(device_id); base_addr = spi_config->BaseAddress; XSpiPs_CfgInitialize(&spi_instance, spi_config, base_addr); spi_options = XSPIPS_MASTER_OPTION | (clk_pol ? XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) | (clk_pha ? XSPIPS_CLK_PHASE_1_OPTION : 0) | (spi_decoded_cs ? XSPIPS_DECODE_SSELECT_OPTION : 0) | XSPIPS_FORCE_SSELECT_OPTION; XSpiPs_SetOptions(&spi_instance, spi_options); XSpiPs_SetClkPrescaler(&spi_instance, XSPIPS_CLK_PRESCALE_32); /* FIXME: Temporary 15.2 Fix */ XSpiPs_CfgInitialize(&spi_instance, spi_config, base_addr); XSpiPs_SetOptions(&spi_instance, spi_options); XSpiPs_SetClkPrescaler(&spi_instance, XSPIPS_CLK_PRESCALE_32); #else XSpi_Initialize(&spi_instance, device_id); XSpi_Stop(&spi_instance); spi_config = XSpi_LookupConfig(device_id); base_addr = spi_config->BaseAddress; XSpi_CfgInitialize(&spi_instance, spi_config, base_addr); spi_options = XSP_MASTER_OPTION | (clk_pol ? XSP_CLK_ACTIVE_LOW_OPTION : 0) | (clk_pha ? XSP_CLK_PHASE_1_OPTION : 0) | XSP_MANUAL_SSELECT_OPTION; XSpi_SetOptions(&spi_instance, spi_options); XSpi_Start(&spi_instance); XSpi_IntrGlobalDisable(&spi_instance); #endif return 0; }
/** * @brief Initialize the SPI communication peripheral. * @param desc - The SPI descriptor. * @param init_param - The structure that contains the SPI parameters. * @return SUCCESS in case of success, FAILURE otherwise. */ int32_t spi_init(struct spi_desc **desc, const struct spi_init_param *param) { spi_desc *descriptor; int32_t ret; descriptor = (struct spi_desc *) malloc(sizeof(*descriptor)); if (!descriptor) return FAILURE; descriptor->config = XSpiPs_LookupConfig(param->id); if (descriptor->config == NULL) goto error; ret = XSpiPs_CfgInitialize(&descriptor->instance, descriptor->config, descriptor->config->BaseAddress); if (ret != 0) goto error; XSpiPs_SetOptions(&descriptor->instance, XSPIPS_MASTER_OPTION | XSPIPS_DECODE_SSELECT_OPTION | XSPIPS_FORCE_SSELECT_OPTION | ((descriptor->mode & SPI_CPOL) ? XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) | ((descriptor->mode & SPI_CPHA) ? XSPIPS_CLK_PHASE_1_OPTION : 0)); XSpiPs_SetClkPrescaler(&descriptor->instance, XSPIPS_CLK_PRESCALE_64); XSpiPs_SetSlaveSelect(&descriptor->instance, 0xf); descriptor->chip_select = param->chip_select; descriptor->mode = param->mode; *desc = descriptor; return SUCCESS; error: free(descriptor); return FAILURE; }
/***************************************************************************//** * @brief spi_init *******************************************************************************/ int32_t spi_init(uint32_t device_id, uint8_t clk_pha, uint8_t clk_pol) { uint32_t base_addr = 0; uint32_t control_val = 0; #ifdef _XPARAMETERS_PS_H_ uint8_t byte = 0; spi_config = XSpiPs_LookupConfig(device_id); base_addr = spi_config->BaseAddress; XSpiPs_CfgInitialize(&spi_instance, spi_config, base_addr); control_val = XSPIPS_CR_SSFORCE_MASK | XSPIPS_CR_SSCTRL_MASK | 4 << XSPIPS_CR_PRESC_SHIFT | (clk_pha ? XSPIPS_CR_CPHA_MASK : 0) | (clk_pol ? XSPIPS_CR_CPOL_MASK : 0) | XSPIPS_CR_MSTREN_MASK; XSpiPs_WriteReg(base_addr, XSPIPS_CR_OFFSET, control_val); for(byte = 0; byte < 128; byte++) { XSpiPs_ReadReg(base_addr, XSPIPS_RXD_OFFSET); } #else XSpi_Initialize(&spi_instance, device_id); XSpi_Stop(&spi_instance); spi_config = XSpi_LookupConfig(device_id); base_addr = spi_config->BaseAddress; XSpi_CfgInitialize(&spi_instance, spi_config, base_addr); control_val = XSP_MASTER_OPTION | XSP_CLK_PHASE_1_OPTION | XSP_MANUAL_SSELECT_OPTION; XSpi_SetOptions(&spi_instance, control_val); XSpi_Start(&spi_instance); XSpi_IntrGlobalDisable(&spi_instance); XSpi_SetSlaveSelect(&spi_instance, 1); #endif return SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in polled mode. This function writes and reads data * from a serial flash. * * @param SpiPtr is a pointer to the SPI driver instance to use. * * @param SpiDeviceId is the Instance Id of SPI in the system. * * @return * - XST_SUCCESS if successful * - XST_FAILURE if not successful * * @note * * If the device slave select is not correct and the device is not responding * on bus it will read a status of 0xFF for the status register as the bus * is pulled up. * *****************************************************************************/ int SpiPsFlashPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId) { int Status; u8 *BufferPtr; u8 UniqueValue; u32 Count; XSpiPs_Config *SpiConfig; /* * Initialize the SPI driver so that it's ready to use */ SpiConfig = XSpiPs_LookupConfig(SpiDeviceId); if (NULL == SpiConfig) { return XST_FAILURE; } Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig, SpiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XSpiPs_SelfTest(SpiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the SPI device as a master with manual start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MANUAL_START_OPTION | \ XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); /* * Set the SPI device pre-scalar to divide by 8 */ XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_8); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Initialize the write buffer for a pattern to write to the Flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Set the flash chip select */ XSpiPs_SetSlaveSelect(SpiInstancePtr, FLASH_SPI_SELECT); /* * Read the flash Id */ Status = FlashReadID(); if (Status != XST_SUCCESS) { xil_printf("SPI Flash Polled Example Read ID Failed\r\n"); return XST_FAILURE; } /* * Erase the flash */ FlashErase(SpiInstancePtr); TestAddress = 0x0; /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MAX_DATA, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MAX_DATA, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Initialize the write buffer for a pattern to write to the Flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Set the SPI device as a master with auto start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | \ XSPIPS_FORCE_SSELECT_OPTION); /* * Erase the flash */ FlashErase(SpiInstancePtr); TestAddress = 0x0; /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MAX_DATA, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MAX_DATA, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in interrupt mode. This function writes and reads data * from a serial FLASH. * * @param None. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls other functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int SpiFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; u32 Count; XSpiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */ u32 TempAddress; u32 MaxSize = MAX_DATA; u32 ChipSelect = FLASH_SPI_SELECT_1; if (XGetPlatform_Info() == XPLAT_ZYNQ_ULTRA_MP) { MaxSize = 1024 * 10; ChipSelect = FLASH_SPI_SELECT_0; /* Device is on CS 0 */ SpiIntrId = XPAR_XSPIPS_0_INTR; } /* * Lookup the device configuration in the temporary CROM table. Use this * configuration info down below when initializing this component. */ ConfigPtr = XSpiPs_LookupConfig(SpiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } XSpiPs_CfgInitialize(SpiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); /* Initialize the XILISF Library */ XIsf_Initialize(&Isf, SpiInstancePtr, ChipSelect, IsfWriteBuffer); XIsf_SetTransferMode(&Isf, XISF_INTERRUPT_MODE); /* * Connect the Spi device to the interrupt subsystem such that * interrupts can occur. This function is application specific */ Status = SpiSetupIntrSystem(IntcInstancePtr, SpiInstancePtr, SpiIntrId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the SPI that will be called from the * interrupt context when an SPI status occurs, specify a pointer to * the SPI driver instance as the callback reference so the handler is * able to access the instance data */ XIsf_SetStatusHandler(&Isf, SpiInstancePtr, (XSpiPs_StatusHandler) SpiHandler); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* Unprotect Sectors */ FlashWrite(&Isf, 0, 0, XISF_WRITE_STATUS_REG); FlashErase(&Isf, TEST_ADDRESS, MaxSize); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ TempAddress = TEST_ADDRESS; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++, TempAddress++) { WriteBuffer[0] = (u8)(UniqueValue); FlashWrite(&Isf, TempAddress, 1, XISF_WRITE); } /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command */ FlashRead(&Isf, TEST_ADDRESS, MaxSize, XISF_READ); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } SpiDisableIntrSystem(IntcInstancePtr, SpiIntrId); return XST_SUCCESS; }
int SpiFlashPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId) { u8 *BufferPtr; u8 UniqueValue; u32 Count; XSpiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */ u32 TempAddress; /* * Lookup the device configuration in the temporary CROM table. Use this * configuration info down below when initializing this component. */ ConfigPtr = XSpiPs_LookupConfig(SpiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } XSpiPs_CfgInitialize(SpiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); /* Initialize the XILISF Library */ XIsf_Initialize(&Isf, SpiInstancePtr, FLASH_SPI_SELECT, IsfWriteBuffer); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* Unprotect Sectors */ FlashWrite(&Isf, 0, 0, XISF_WRITE_STATUS_REG); FlashErase(&Isf, TEST_ADDRESS, MAX_DATA); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ TempAddress = TEST_ADDRESS; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++, TempAddress++) { WriteBuffer[0] = (u8)(UniqueValue); FlashWrite(&Isf, TempAddress, 1, XISF_WRITE); } /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command */ FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in interrupt mode. This function writes and reads data * from a serial flash. * * @param IntcInstancePtr is a pointer to Interrupt Controller instance. * * @param SpiInstancePtr is a pointer to the SPI driver instance to use. * * @param SpiDeviceId is the Instance Id of SPI in the system. * * @param SpiIntrId is the Interrupt Id for SPI in the system. * * @param None. * * @return * - XST_SUCCESS if successful * - XST_FAILURE if not successful * * @note * * This function calls other functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int SpiPsFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; u32 Count; u32 MaxSize = MAX_DATA; u32 ChipSelect = FLASH_SPI_SELECT_1; XSpiPs_Config *SpiConfig; if (XGetPlatform_Info() == XPLAT_ZYNQ_ULTRA_MP) { MaxSize = 1024 * 10; ChipSelect = FLASH_SPI_SELECT_0; /* Device is on CS 0 */ SpiIntrId = XPAR_XSPIPS_0_INTR; } /* * Initialize the SPI driver so that it's ready to use */ SpiConfig = XSpiPs_LookupConfig(SpiDeviceId); if (NULL == SpiConfig) { return XST_FAILURE; } Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig, SpiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XSpiPs_SelfTest(SpiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the Spi device to the interrupt subsystem such that * interrupts can occur. This function is application specific */ Status = SpiPsSetupIntrSystem(IntcInstancePtr, SpiInstancePtr, SpiIntrId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the SPI that will be called from the * interrupt context when an SPI status occurs, specify a pointer to * the SPI driver instance as the callback reference so the handler is * able to access the instance data */ XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr, (XSpiPs_StatusHandler) SpiPsHandler); /* * Set the SPI device as a master with manual start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MANUAL_START_OPTION | \ XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); /* * Set the SPI device pre-scalar to divide by 8 */ XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_8); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Initialize the write buffer for a pattern to write to the flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Assert the flash chip select */ XSpiPs_SetSlaveSelect(SpiInstancePtr, ChipSelect); /* * Read the flash ID */ Status = FlashReadID(SpiInstancePtr); if (Status != XST_SUCCESS) { xil_printf("SPI FLASH Interrupt Example Read ID Failed\r\n"); return XST_FAILURE; } /* * Erase the flash */ FlashErase(SpiInstancePtr); /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MaxSize, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MaxSize, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } /* * Set the SPI device as a master with auto start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | \ XSPIPS_FORCE_SSELECT_OPTION); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Initialize the write buffer for a pattern to write to the flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Erase the flash */ FlashErase(SpiInstancePtr); /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MaxSize, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MaxSize, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } SpiPsDisableIntrSystem(IntcInstancePtr, SpiIntrId); return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in polled mode. This test writes and reads data from a * serial EEPROM. The serial EEPROM part must be present in the hardware * to use this example. * * @param SpiInstancePtr is a pointer to the Spi Instance. * @param SpiDeviceId is the Device Id of Spi. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int SpiPsEepromPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId) { int Status; u8 *BufferPtr; u8 UniqueValue; int Count; int Page; XSpiPs_Config *SpiConfig; /* * Initialize the SPI driver so that it's ready to use */ SpiConfig = XSpiPs_LookupConfig(SpiDeviceId); if (NULL == SpiConfig) { return XST_FAILURE; } Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig, SpiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XSpiPs_SelfTest(SpiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the Spi device as a master. External loopback is required. */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_64); /* * Initialize the write buffer for a pattern to write to the EEPROM * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = 13, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { WriteBuffer[WRITE_DATA_OFFSET + Count] = (u8)(UniqueValue + Test); ReadBuffer[READ_DATA_OFFSET + Count] = 0xA5; } /* * Assert the EEPROM chip select */ XSpiPs_SetSlaveSelect(SpiInstancePtr, EEPROM_SPI_SELECT); /* * Write the data in the write buffer to the serial EEPROM a page at a * time, read the data back from the EEPROM and verify it */ UniqueValue = 13; for (Page = 0; Page < PAGE_COUNT; Page++) { EepromWrite(SpiInstancePtr, Page * PAGE_SIZE, PAGE_SIZE, &WriteBuffer[Page * PAGE_SIZE]); EepromRead(SpiInstancePtr, Page * PAGE_SIZE, PAGE_SIZE, ReadBuffer); BufferPtr = &ReadBuffer[READ_DATA_OFFSET]; for (Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } } return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in Slave mode. This function reads data from a SPI Master * and will echo it back to the Master. * * @param SpiDeviceId is the Instance Id of SPI in the system. * * @return * - XST_SUCCESS if successful * - XST_FAILURE if not successful * * @note None * * *****************************************************************************/ int SpiPsSlavePolledExample(u16 SpiDeviceId) { int Status; u8 *BufferPtr; XSpiPs_Config *SpiConfig; /* * Initialize the SPI driver so that it's ready to use */ SpiConfig = XSpiPs_LookupConfig(SpiDeviceId); if (NULL == SpiConfig) { return XST_FAILURE; } Status = XSpiPs_CfgInitialize((&SpiInstance), SpiConfig, SpiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * The SPI device is a slave by default and the clock phase * have to be set according to its master. In this example, CPOL is set * to quiescent high and CPHA is set to 1. */ Status = XSpiPs_SetOptions((&SpiInstance), (XSPIPS_CR_CPHA_MASK) | \ (XSPIPS_CR_CPOL_MASK)); if (Status != XST_SUCCESS) { return XST_FAILURE; } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Set the Rx FIFO Threshold to the Max Data */ XSpiPs_SetRXWatermark((&SpiInstance),MAX_DATA); /* * Enable the device. */ XSpiPs_Enable((&SpiInstance)); /* * Read the contents of the Receive buffer * Master is expected to send MAX_DATA number of bytes */ SpiSlaveRead(MAX_DATA); /* * Setup a pointer to the start of the data that was read into the read * buffer and the same back */ BufferPtr = ReadBuffer; /* * Send the data received back to Master * Master is expected to send MAX_DATA number of dummy bytes for * the slave to be able to echo previously received data. */ SpiSlaveWrite(BufferPtr, MAX_DATA); /* * Disable the device. */ XSpiPs_Disable((&SpiInstance)); return XST_SUCCESS; }
int main() { XSpiPs_Config *SpiConfig_EMIO; XGpioPs_Config *GPIOConfigPtr; //gpio config int delay; u8 cmd[1]; int byte_i, temp; int loop; init_platform(); printf("SPI Demo MicroZed Chronicles\n\r"); SpiConfig_EMIO = XSpiPs_LookupConfig((u16)SPI_EMIO); XSpiPs_CfgInitialize(&SpiInstance_EMIO, SpiConfig_EMIO,SpiConfig_EMIO->BaseAddress); XSpiPs_SetOptions(&SpiInstance_EMIO,XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); XSpiPs_SetClkPrescaler(&SpiInstance_EMIO, XSPIPS_CLK_PRESCALE_256); GPIOConfigPtr = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID); XGpioPs_CfgInitialize(&Gpio, GPIOConfigPtr,GPIOConfigPtr->BaseAddr); //set direction and enable output XGpioPs_SetDirectionPin(&Gpio, sig, 1); XGpioPs_SetOutputEnablePin(&Gpio, sig, 1); XGpioPs_SetDirectionPin(&Gpio, res, 1); XGpioPs_SetOutputEnablePin(&Gpio, res, 1); XGpioPs_SetDirectionPin(&Gpio, vdd, 1); XGpioPs_SetOutputEnablePin(&Gpio, vdd, 1); XGpioPs_SetDirectionPin(&Gpio, bat, 1); XGpioPs_SetOutputEnablePin(&Gpio, bat, 1); XGpioPs_SetDirectionPin(&Gpio, dc, 1); XGpioPs_SetOutputEnablePin(&Gpio, dc, 1); XGpioPs_WritePin(&Gpio, sig, 0); XGpioPs_WritePin(&Gpio, res, 0); XGpioPs_WritePin(&Gpio, vdd, 1); XGpioPs_WritePin(&Gpio, bat, 1); XGpioPs_WritePin(&Gpio, dc, 1); XGpioPs_WritePin(&Gpio, vdd, 0); for( delay = 0; delay < DELAY; delay++)//wait {} XGpioPs_WritePin(&Gpio, res, 1); config_oled(); XGpioPs_WritePin(&Gpio, bat, 0); blank_oled();//clear screen //output page 1 for(loop=0;loop<16;loop++){ temp = (line_1[loop] * 8); for(byte_i=0;byte_i<8;byte_i++){ data_conv[byte_i] = font[temp+byte_i]; } conv_alg(data_conv); //convert to array for(byte_i=0;byte_i<8;byte_i++){ page_0[(line_start-(char_size*loop))-byte_i] = results[byte_i]; } } cmd[0] = (u8) 0xB0; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, page_0, NULL, 128); //output page 2 for(loop=0;loop<16;loop++){ //loop =0; temp = (line_2[loop] * 8); for(byte_i=0;byte_i<8;byte_i++){ data_conv[byte_i] = font[temp+byte_i]; } conv_alg(data_conv); //convert to array for(byte_i=0;byte_i<8;byte_i++){ page_1[(line_start-(char_size*loop))-byte_i] = results[byte_i]; } } cmd[0] = (u8) 0xB1; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, page_1, NULL, 128); //output page 3 for(loop=0;loop<16;loop++){ //loop =0; temp = (line_3[loop] * 8); for(byte_i=0;byte_i<8;byte_i++){ data_conv[byte_i] = font[temp+byte_i]; } conv_alg(data_conv); //convert to array for(byte_i=0;byte_i<8;byte_i++){ page_2[(line_start-(char_size*loop))-byte_i] = results[byte_i]; } } cmd[0] = (u8) 0xB2; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, page_2, NULL, 128); //output page 4 for(loop=0;loop<16;loop++){ //loop =0; temp = (line_4[loop] * 8); for(byte_i=0;byte_i<8;byte_i++){ data_conv[byte_i] = font[temp+byte_i]; } conv_alg(data_conv); //convert to array for(byte_i=0;byte_i<8;byte_i++){ page_3[(line_start-(char_size*loop))-byte_i] = results[byte_i]; } } cmd[0] = (u8) 0xB3; XGpioPs_WritePin(&Gpio, dc, 0); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, cmd, NULL, 1); XGpioPs_WritePin(&Gpio, dc, 1); XSpiPs_SetSlaveSelect(&SpiInstance_EMIO, 0x01); XSpiPs_PolledTransfer(&SpiInstance_EMIO, page_3, NULL, 128); return 0; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in interrupt mode . This test writes and reads data from a * serial EEPROM. * This part must be present in the hardware to use this example. * * @param IntcInstancePtr is a pointer to the GIC driver to use. * @param SpiInstancePtr is a pointer to the SPI driver to use. * @param SpiDeviceId is the DeviceId of the Spi device. * @param SpiIntrId is the Spi Interrupt Id. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int SpiPsEepromIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; int Count; int Page; XSpiPs_Config *SpiConfig; /* * Initialize the SPI driver so that it's ready to use */ SpiConfig = XSpiPs_LookupConfig(SpiDeviceId); if (NULL == SpiConfig) { return XST_FAILURE; } Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig, SpiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XSpiPs_SelfTest(SpiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the Spi device to the interrupt subsystem such that * interrupts can occur. This function is application specific */ Status = SpiSetupIntrSystem(IntcInstancePtr, SpiInstancePtr, SpiIntrId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the SPI that will be called from the * interrupt context when an SPI status occurs, specify a pointer to * the SPI driver instance as the callback reference so the handler is * able to access the instance data */ XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr, (XSpiPs_StatusHandler) SpiHandler); /* * Set the Spi device as a master. External loopback is required. */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_64); /* * Initialize the write buffer for a pattern to write to the EEPROM * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = 13, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { WriteBuffer[WRITE_DATA_OFFSET + Count] = (u8)(UniqueValue + Test); ReadBuffer[READ_DATA_OFFSET + Count] = 0xA5; } /* * Assert the EEPROM chip select */ XSpiPs_SetSlaveSelect(SpiInstancePtr, EEPROM_SPI_SELECT); /* * Write the data in the write buffer to the serial EEPROM a page at a * time */ for (Page = 0; Page < PAGE_COUNT; Page++) { EepromWrite(SpiInstancePtr, Page * PAGE_SIZE, PAGE_SIZE, &WriteBuffer[Page * PAGE_SIZE]); } /* * Read the contents of the entire EEPROM from address 0, since this * function reads the entire EEPROM it will take some amount of time to * complete */ EepromRead(SpiInstancePtr, 0, MAX_DATA, ReadBuffer); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[READ_DATA_OFFSET]; for (UniqueValue = 13, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } SpiDisableIntrSystem(IntcInstancePtr, SpiIntrId); return XST_SUCCESS; }