]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/arm/netarm/v2_0/src/eeprom.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / eth / arm / netarm / v2_0 / src / eeprom.c
1 // ====================================================================
2 //
3 //      eeprom.c
4 //
5 // ====================================================================
6 //####ECOSGPLCOPYRIGHTBEGIN####
7 // -------------------------------------------
8 // This file is part of eCos, the Embedded Configurable Operating System.
9 // Copyright (C) 2005 eCosCentric Ltd.
10 //
11 // eCos is free software; you can redistribute it and/or modify it under
12 // the terms of the GNU General Public License as published by the Free
13 // Software Foundation; either version 2 or (at your option) any later version.
14 //
15 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
16 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 // for more details.
19 //
20 // You should have received a copy of the GNU General Public License along
21 // with eCos; if not, write to the Free Software Foundation, Inc.,
22 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 //
24 // As a special exception, if other files instantiate templates or use macros
25 // or inline functions from this file, or you compile this file and link it
26 // with other works to produce a work based on this file, this file does not
27 // by itself cause the resulting work to be covered by the GNU General Public
28 // License. However the source code for this file must still be made available
29 // in accordance with section (3) of the GNU General Public License.
30 //
31 // This exception does not invalidate any other reasons why a work based on
32 // this file might be covered by the GNU General Public License.
33 //
34 //####ECOSGPLCOPYRIGHTEND####
35 // ====================================================================
36 //#####DESCRIPTIONBEGIN####
37 //
38 // Author(s):           Harald Brandl (harald.brandl@fh-joanneum.at)
39 // Contributors:        Harald Brandl
40 // Date:                        10.03.2005
41 // Purpose:                     EEPROM I/O
42 // Description:
43 //
44 //####DESCRIPTIONEND####
45 //
46 // ====================================================================
47
48 #include <cyg/hal/hal_modnet50.h>
49 #include "eth_regs.h"
50
51 static void wait(int time)
52 {
53         int i;
54
55         for(i=0; i < time; i++);
56 }
57
58 /* send i2c stop condition */
59 static void i2cStop(void)
60 {
61         HAL_OR_UINT32(PORTC, 0x00c00000);
62         HAL_AND_UINT32(PORTC, ~0x000000c0);     // SDA = 0, SLK = 0
63         wait(5);
64         HAL_OR_UINT32(PORTC, 0x00000040);       // SLK = 1
65         wait(5);
66         HAL_OR_UINT32(PORTC, 0x00000080);       // SDA = 1
67 }
68
69 /* send i2c start condition */
70 static void i2cStart(void)
71 {
72         HAL_OR_UINT32(PORTC, 0x00c000c0);       // SDA = 1, SLK = 1
73         wait(5);
74         HAL_AND_UINT32(PORTC, ~0x00000080);     // SDA = 0
75         wait(5);
76         HAL_AND_UINT32(PORTC, ~0x00000040);     // SLK = 0
77 }
78
79 static void i2cPutByte(char byte)
80 {
81         int i, bit, reg;
82
83         HAL_OR_UINT32(PORTC, 0x00c00000);
84
85         for(i=7; i >= 0; i--)
86         {
87                 bit = (byte >> i) & 1;
88                 HAL_READ_UINT32(PORTC, reg);
89                 HAL_WRITE_UINT32(PORTC, (reg & ~0x80) | (bit << 7));    // SDA = data
90                 HAL_OR_UINT32(PORTC, 0x00000040);       // SLK = 1
91                 wait(5);
92                 HAL_AND_UINT32(PORTC, ~0x00000040);     // SLK = 0
93                 wait(5);
94         }
95         HAL_OR_UINT32(PORTC, 0x00000080);               // SDA = 1
96 }
97
98 static char i2cGetByte(void)
99 {
100         int i, reg;
101         char byte = 0;
102
103         HAL_AND_UINT32(PORTC, ~0x00800000);
104         for(i=7; i >= 0; i--)
105         {
106                 HAL_OR_UINT32(PORTC, 0x00000040);       // SLK = 1
107                 HAL_READ_UINT32(PORTC, reg);
108                 byte |= ((reg & 0x80) >> 7) << i;       // data = SDA
109                 wait(5);
110                 HAL_AND_UINT32(PORTC, ~0x00000040);     // SLK = 0
111                 wait(5);
112         }
113         HAL_OR_UINT32(PORTC, 0x00800080);               // SDA = 1
114         return byte;
115 }
116
117 /* acknowledge received bytes */
118 static void i2cGiveAck(void)
119 {
120         HAL_OR_UINT32(PORTC, 0x00c00000);
121         HAL_AND_UINT32(PORTC, ~0x00000080);     // SDA = 0
122         wait(5);
123         HAL_OR_UINT32(PORTC, 0x00000040);       // SLK = 1
124         wait(5);
125         HAL_AND_UINT32(PORTC, ~0x00000040);     // SLK = 0
126         wait(5);
127         HAL_OR_UINT32(PORTC, 0x00000080);       // SDA = 1
128         wait(5);
129 }
130
131 /* wait for acknowledge from slaves */
132 static void i2cGetAck(void)
133 {
134         unsigned reg;
135
136         HAL_AND_UINT32(PORTC, ~0x00800000);     // SDA in
137         HAL_OR_UINT32(PORTC, 0x00400040);       // SLK = 1
138         do
139         {
140                 HAL_READ_UINT32(PORTC, reg);
141         }while(reg & 0x80);                                     // wait for SDA = 1
142         HAL_AND_UINT32(PORTC, ~0x00000040);     // SLK = 0
143 }
144
145 void cyg_netarm_initI2C(void)
146 {
147         HAL_AND_UINT32(PORTC, ~0xc0000000);     // mode GPIO
148         i2cStop();
149 }
150
151 /* wait until eeprom's internal write cycle has finished */
152 void cyg_netarm_eepromPollAck(int deviceAddr)
153 {
154         unsigned reg;
155
156         deviceAddr <<= 1;
157
158         HAL_OR_UINT32(PORTC, 0x00400040);       // SLK = 1
159         while(1)
160         {
161                 i2cStart();
162                 i2cPutByte(deviceAddr);
163                 HAL_AND_UINT32(PORTC, ~0x00800000);             // SDA in
164                 HAL_OR_UINT32(PORTC, 0x00400040);               // SLK = 1
165                 HAL_READ_UINT32(PORTC, reg);
166                 if((reg & 0x80) == 0)
167                 {
168                         HAL_AND_UINT32(PORTC, ~0x00000040);     // SLK = 0
169                         break;
170                 }
171                 HAL_AND_UINT32(PORTC, ~0x00000040);             // SLK = 0
172         }
173 }
174
175 /* reads numBytes from eeprom starting at readAddr into buf */
176 void cyg_netarm_eepromRead(int deviceAddr, int readAddr, char *buf, int numBytes)
177 {
178         int i;
179
180         deviceAddr <<= 1;
181         i2cStart();
182         i2cPutByte(deviceAddr);
183         i2cGetAck();
184         i2cPutByte(readAddr >> 8);
185         i2cGetAck();
186         i2cPutByte(readAddr & 0xff);
187         i2cGetAck();
188         i2cStart();
189         i2cPutByte(deviceAddr | 1);             // set read flag
190         i2cGetAck();
191
192         for(i=0;i<numBytes;i++)
193         {
194                 buf[i] = i2cGetByte();
195                 if(i < numBytes - 1)
196                         i2cGiveAck();
197         }
198
199         i2cStop();
200 }
201
202 /* writes up to a page of 32 bytes from buf into eeprom;
203 max. number of bytes depends on the offset within a page, indexed by the
204 lower 5 bits of writeAddr and equals 32 - offset */
205 void cyg_netarm_eepromWrite(int deviceAddr, int writeAddr, char *buf, int numBytes)
206 {
207         int i;
208
209         deviceAddr <<= 1;
210         i2cStart();
211         i2cPutByte(deviceAddr);
212         i2cGetAck();
213         i2cPutByte(writeAddr >> 8);
214         i2cGetAck();
215         i2cPutByte(writeAddr & 0xff);
216         i2cGetAck();
217
218         for(i=0; i<numBytes; i++)
219         {
220                 i2cPutByte(buf[i]);
221                 i2cGetAck();
222         }
223
224         i2cStop();
225 }