/****************************************************************************** * * Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * Use of the Software is limited solely to applications: * (a) running on a Xilinx device, or * (b) that interact with a Xilinx device through a bus or interconnect. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of the Xilinx shall not be used * in advertising or otherwise to promote the sale, use or other dealings in * this Software without prior written authorization from Xilinx. * ******************************************************************************/ /*****************************************************************************/ /** * @file xiicps_eeprom_polled_example.c * * This file consists of a polled mode design example which uses the Xilinx PS * IIC device and XIicPs driver to exercise the EEPROM. * * The XIicPs_MasterSendPolled() API is used to transmit the data and * XIicPs_MasterRecvPolled() API is used to receive the data. * * The example is tested with a 2Kb/8Kb serial IIC EEPROM (ST M24C02/M24C08). * The WP pin of this EEPROM is hardwired to ground in the HW in which this * was tested. * * The AddressType should be u8 as the address pointer in the on-board * EEPROM is 1 bytes. * * This code assumes that no Operating System is being used. * * @note * * None. * *
* MODIFICATION HISTORY: * * Ver Who Date Changes * ----- ---- -------- --------------------------------------------------------- * 1.00a sdm 03/15/10 First release * 1.01a sg 04/13/12 Added MuxInit function for initializing the IIC Mux * on the ZC702 board and to configure it for accessing * the IIC EEPROM. * Updated to use usleep instead of delay loop * 1.04a hk 09/03/13 Removed GPIO code to pull MUX out of reset - CR#722425. * 2.3 sk 10/07/14 Removed multiple initializations for read buffer. ** ******************************************************************************/ /***************************** Include Files *********************************/ #include "xparameters.h" #include "sleep.h" #include "xiicps.h" #include "xil_printf.h" #include "xplatform_info.h" /************************** Constant Definitions *****************************/ /* * The following constants map to the XPAR parameters created in the * xparameters.h file. They are defined here such that a user can easily * change all the needed parameters in one place. */ #define IIC_DEVICE_ID XPAR_XIICPS_0_DEVICE_ID /* * The following constant defines the address of the IIC Slave device on the * IIC bus. Note that since the address is only 7 bits, this constant is the * address divided by 2. */ #define IIC_SLAVE_ADDR 0x54 #define IIC_SCLK_RATE 100000 #define IIC_MUX_ADDRESS 0x74 /* * The page size determines how much data should be written at a time. * The write function should be called with this as a maximum byte count. */ #define PAGE_SIZE 16 /* * The Starting address in the IIC EEPROM on which this test is performed. */ #define EEPROM_START_ADDRESS 128 /**************************** Type Definitions *******************************/ /* * The AddressType should be u8 as the address pointer in the on-board * EEPROM is 1 bytes. */ typedef u16 AddressType; /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ int IicPsEepromPolledExample(void); int EepromWriteData(u16 ByteCount); int MuxInit(void); int EepromReadData(u8 *BufferPtr, u16 ByteCount); /************************** Variable Definitions *****************************/ XIicPs IicInstance; /* The instance of the IIC device. */ u32 Platform; /* * Write buffer for writing a page. */ u8 WriteBuffer[sizeof(AddressType) + PAGE_SIZE]; u8 ReadBuffer[PAGE_SIZE]; /* Read buffer for reading a page. */ /************************** Function Definitions *****************************/ /*****************************************************************************/ /** * Main function to call the Iic EEPROM polled example. * * @param None. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note None. * ******************************************************************************/ int main(void) { int Status; xil_printf("IIC EEPROM Polled Mode Example Test \r\n"); /* * Run the Iic EEPROM Polled Mode example. */ Status = IicPsEepromPolledExample(); if (Status != XST_SUCCESS) { xil_printf("IIC EEPROM Polled Mode Example Test Failed\r\n"); return XST_FAILURE; } xil_printf("Successfully ran IIC EEPROM Polled Mode Example Test\r\n"); return XST_SUCCESS; } /*****************************************************************************/ /** * This function writes, reads, and verifies the data to the IIC EEPROM. It * does the write as a single page write, performs a buffered read. * * @param None. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note None. * ******************************************************************************/ int IicPsEepromPolledExample(void) { u32 Index; int Status; XIicPs_Config *ConfigPtr; /* Pointer to configuration data */ AddressType Address = EEPROM_START_ADDRESS; int WrBfrOffset; /* * Initialize the IIC driver so that it is ready to use. */ ConfigPtr = XIicPs_LookupConfig(IIC_DEVICE_ID); if (ConfigPtr == NULL) { return XST_FAILURE; } Status = XIicPs_CfgInitialize(&IicInstance, ConfigPtr, ConfigPtr->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the IIC serial clock rate. */ XIicPs_SetSClk(&IicInstance, IIC_SCLK_RATE); /* * Set the channel value in IIC Mux if * it is Zynq platform */ Platform = XGetPlatform_Info(); if(Platform == XPLAT_ZYNQ) { Status = MuxInit(); if (Status != XST_SUCCESS) { return XST_FAILURE; } } /* * Initialize the data to write and the read buffer. */ if (Platform == XPLAT_ZYNQ) { WriteBuffer[0] = (u8) (Address); WrBfrOffset = 1; } else { WriteBuffer[0] = (u8) (Address >> 8); WriteBuffer[1] = (u8) (Address); WrBfrOffset = 2; } for (Index = 0; Index < PAGE_SIZE; Index++) { WriteBuffer[WrBfrOffset + Index] = 0xFF; ReadBuffer[Index] = 0; } /* * Write to the EEPROM. */ Status = EepromWriteData(WrBfrOffset + PAGE_SIZE); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read from the EEPROM. */ Status = EepromReadData(ReadBuffer, PAGE_SIZE); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Verify the data read against the data written. */ for (Index = 0; Index < PAGE_SIZE; Index++) { if (ReadBuffer[Index] != WriteBuffer[Index + WrBfrOffset]) { return XST_FAILURE; } } /* * Initialize the data to write and the read buffer. */ if (Platform == XPLAT_ZYNQ) { WriteBuffer[0] = (u8) (Address); WrBfrOffset = 1; } else { WriteBuffer[0] = (u8) (Address >> 8); WriteBuffer[1] = (u8) (Address); WrBfrOffset = 2; } for (Index = 0; Index < PAGE_SIZE; Index++) { WriteBuffer[WrBfrOffset + Index] = Index + 10; ReadBuffer[Index] = 0; } /* * Write to the EEPROM. */ Status = EepromWriteData(WrBfrOffset + PAGE_SIZE); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read from the EEPROM. */ Status = EepromReadData(ReadBuffer, PAGE_SIZE); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Verify the data read against the data written. */ for (Index = 0; Index < PAGE_SIZE; Index++) { if (ReadBuffer[Index] != WriteBuffer[Index + WrBfrOffset]) { return XST_FAILURE; } } return XST_SUCCESS; } /*****************************************************************************/ /** * This function writes a buffer of data to the IIC serial EEPROM. * * @param ByteCount contains the number of bytes in the buffer to be * written. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note The Byte count should not exceed the page size of the EEPROM as * noted by the constant PAGE_SIZE. * ******************************************************************************/ int EepromWriteData(u16 ByteCount) { int Status; /* * Send the Data. */ Status = XIicPs_MasterSendPolled(&IicInstance, WriteBuffer, ByteCount, IIC_SLAVE_ADDR); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait until bus is idle to start another transfer. */ while (XIicPs_BusIsBusy(&IicInstance)); /* * Wait for a bit of time to allow the programming to complete */ usleep(250000); return XST_SUCCESS; } /*****************************************************************************/ /** * This function reads data from the IIC serial EEPROM into a specified buffer. * * @param BufferPtr contains the address of the data buffer to be filled. * @param ByteCount contains the number of bytes in the buffer to be read. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note None. * ******************************************************************************/ int EepromReadData(u8 *BufferPtr, u16 ByteCount) { int Status; AddressType Address = EEPROM_START_ADDRESS; int WrBfrOffset; /* * Position the Pointer in EEPROM. */ if (Platform == XPLAT_ZYNQ) { WriteBuffer[0] = (u8) (Address); WrBfrOffset = 1; } else { WriteBuffer[0] = (u8) (Address >> 8); WriteBuffer[1] = (u8) (Address); WrBfrOffset = 2; } Status = EepromWriteData(WrBfrOffset); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Receive the Data. */ Status = XIicPs_MasterRecvPolled(&IicInstance, BufferPtr, ByteCount, IIC_SLAVE_ADDR); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait until bus is idle to start another transfer. */ while (XIicPs_BusIsBusy(&IicInstance)); return XST_SUCCESS; } /*****************************************************************************/ /** * This function initializes the IIC MUX to select EEPROM. * * @param None. * * @return XST_SUCCESS if pass, otherwise XST_FAILURE. * * @note None. * ****************************************************************************/ int MuxInit(void) { u8 WriteBuffer; u8 MuxIicAddr = IIC_MUX_ADDRESS; u8 Buffer = 0; int Status = 0; /* * Channel select value for EEPROM. */ WriteBuffer = 0x04; /* * Send the Data. */ Status = XIicPs_MasterSendPolled(&IicInstance, &WriteBuffer,1, MuxIicAddr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait until bus is idle to start another transfer. */ while (XIicPs_BusIsBusy(&IicInstance)); /* * Receive the Data. */ Status = XIicPs_MasterRecvPolled(&IicInstance, &Buffer,1, MuxIicAddr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait until bus is idle to start another transfer. */ while (XIicPs_BusIsBusy(&IicInstance)); return XST_SUCCESS; }