1 /******************************************************************************
5 * Instantiation of eeprom routines
7 * Revision information:
9 * 28AUG2004 kb_admin initial creation - adapted from Atmel sources
10 * 12JAN2005 kb_admin fixed clock generation, write polling, init
13 * No warranty, expressed or implied, is included with this software. It is
14 * provided "AS IS" and no warranty of any kind including statutory or aspects
15 * relating to merchantability or fitness for any purpose is provided. All
16 * intellectual property rights of others is maintained with the respective
17 * owners. This software is not copyrighted and is intended for reference
22 *****************************************************************************/
24 #include "at91rm9200_lowlevel.h"
25 #include "at91rm9200.h"
29 /******************************* GLOBALS *************************************/
32 /*********************** PRIVATE FUNCTIONS/DATA ******************************/
35 /* Use a macro to calculate the TWI clock generator value to save code space. */
36 #define AT91C_TWSI_CLOCK 100000
37 #define TWSI_EEPROM_ADDRESS 0x40
39 #define TWI_CLK_BASE_DIV ((AT91C_MASTER_CLOCK/(4*AT91C_TWSI_CLOCK)) - 2)
40 #define SET_TWI_CLOCK ((0x00010000) | (TWI_CLK_BASE_DIV) | (TWI_CLK_BASE_DIV << 8))
43 /*************************** GLOBAL FUNCTIONS ********************************/
47 * .KB_C_FN_DEFINITION_START
48 * void InitEEPROM(void)
49 * This global function initializes the EEPROM interface (TWI). Intended
50 * to be called a single time.
51 * .KB_C_FN_DEFINITION_END
57 AT91PS_TWI twiPtr = (AT91PS_TWI)AT91C_BASE_TWI;
59 AT91PS_PIO pPio = (AT91PS_PIO)AT91C_BASE_PIOA;
60 AT91PS_PMC pPMC = (AT91PS_PMC)AT91C_BASE_PMC;
62 pPio->PIO_ASR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
63 pPio->PIO_PDR = AT91C_PA25_TWD | AT91C_PA26_TWCK;
65 pPio->PIO_MDDR = ~AT91C_PA25_TWD;
66 pPio->PIO_MDER = AT91C_PA25_TWD;
68 pPMC->PMC_PCER = 1u << AT91C_ID_TWI;
70 twiPtr->TWI_IDR = 0xffffffffu;
71 twiPtr->TWI_CR = AT91C_TWI_SWRST;
72 twiPtr->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS;
74 twiPtr->TWI_CWGR = SET_TWI_CLOCK;
77 static inline unsigned
78 iicaddr(unsigned ee_off)
80 return (TWSI_EEPROM_ADDRESS | ((ee_off >> 8) & 0x7));
85 * .KB_C_FN_DEFINITION_START
86 * void ReadEEPROM(unsigned ee_addr, char *data_addr, unsigned size)
87 * This global function reads data from the eeprom at ee_addr storing data
88 * to data_addr for size bytes. Assume the TWI has been initialized.
89 * This function does not utilize the page read mode to simplify the code.
90 * .KB_C_FN_DEFINITION_END
93 EERead(unsigned ee_off, char *data_addr, unsigned size)
95 const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
98 if ((ee_off & ~0xff) != ((ee_off + size) & ~0xff)) {
99 printf("Crosses page boundary: 0x%x 0x%x\n", ee_off, size);
103 status = twiPtr->TWI_SR;
104 status = twiPtr->TWI_RHR;
105 twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) | AT91C_TWI_IADRSZ_1_BYTE |
107 twiPtr->TWI_IADR = ee_off & 0xff;
108 twiPtr->TWI_CR = AT91C_TWI_START;
110 while (!(twiPtr->TWI_SR & AT91C_TWI_RXRDY))
112 *(data_addr++) = twiPtr->TWI_RHR;
114 twiPtr->TWI_CR = AT91C_TWI_STOP;
115 status = twiPtr->TWI_SR;
116 while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
118 *data_addr = twiPtr->TWI_RHR;
123 * .KB_C_FN_DEFINITION_START
124 * void WriteEEPROM(unsigned ee_off, char *data_addr, unsigned size)
125 * This global function writes data to the eeprom at ee_off using data
126 * from data_addr for size bytes. Assume the TWI has been initialized.
127 * This function does not utilize the page write mode as the write time is
128 * much greater than the time required to access the device for byte-write
129 * functionality. This allows the function to be much simpler.
130 * .KB_C_FN_DEFINITION_END
133 EEWrite(unsigned ee_off, const char *data_addr, unsigned size)
135 const AT91PS_TWI twiPtr = AT91C_BASE_TWI;
140 // Set the TWI Master Mode Register
141 twiPtr->TWI_MMR = (iicaddr(ee_off) << 16) |
142 AT91C_TWI_IADRSZ_1_BYTE;
143 twiPtr->TWI_IADR = ee_off++;
144 status = twiPtr->TWI_SR;
146 // Load one data byte
147 twiPtr->TWI_THR = *(data_addr++);
148 twiPtr->TWI_CR = AT91C_TWI_START;
149 while (!(twiPtr->TWI_SR & AT91C_TWI_TXRDY))
151 twiPtr->TWI_CR = AT91C_TWI_STOP;
152 status = twiPtr->TWI_SR;
153 while (!(twiPtr->TWI_SR & AT91C_TWI_TXCOMP))
156 // wait for write operation to complete, it is done once
157 // we can read it back...
158 EERead(ee_off, &test_data, 1);