1 // at29.cxx - Implementation of ATMEL's 29xxx flash memory. -*- C++ -*-
3 // Copyright (C) 1999, 2000 Red Hat.
4 // This file is part of SID and is licensed under the GPL.
5 // See the file COPYING.SID for conditions for redistribution.
22 at29_flash_memory::at29_flash_memory (size_t ms, size_t ss, host_int_1 id) throw (bad_alloc)
25 noSectorNum(0xFFFFFFFF),
26 sectorNum(noSectorNum),
27 manufacturerCode(0x1F)
29 // set incoming parameters
32 bool ok = attempt_resize (ms);
34 throw bad_alloc (); // abort constructor
36 add_bus("read-write-port", &this->my_bus);
37 add_attribute("device-code", &deviceIdCode, "setting");
38 add_attribute_ro("manufacturer-code", &manufacturerCode, "setting");
42 at29_flash_memory::stream_state (ostream& out) const
44 flash_uniform_sector_memory::stream_state(out);
48 out << ':' << "device-code " << deviceIdCode;
52 at29_flash_memory::destream_state (istream& in)
54 flash_uniform_sector_memory::destream_state(in);
64 in.setstate(ios::badbit);
68 if (key != "device-code")
70 in.setstate(ios::badbit);
77 at29_flash_memory::write_ok(host_int_4 address)
79 if (sectorNum == noSectorNum)
81 sectorNum = address / sector_size;
85 if (sectorNum != address / sector_size)
90 return (state == PROG);
95 at29_bus::read(host_int_4 address,
96 little_int_1& data) throw ()
98 if (target->state == at29_flash_memory::IDENT)
102 data = target->manufacturerCode;
105 data = target->deviceIdCode;
108 return bus::unpermitted;
112 // Bounds check the memory read.
113 if (address > target->buffer_length)
115 return bus::unmapped;
117 data = target->buffer[address];
123 at29_bus::read(host_int_4 address,
124 big_int_1& data) throw ()
126 little_int_1 littleData(data);
128 bus::status result = read(address, littleData);
136 at29_bus::write(host_int_4 address,
137 little_int_1 le_data) throw()
139 host_int_1 data = le_data;
141 if (target->state == at29_flash_memory::PROG &&
142 address == SEQ_ADDR1 && data == START_CMD1)
144 target->state = at29_flash_memory::LOCKED;
147 if (target->state == at29_flash_memory::IDENT &&
148 address == SEQ_ADDR1 && data == START_CMD1)
150 target->state = at29_flash_memory::START1;
154 if (target->state == at29_flash_memory::LOCKED &&
155 address == SEQ_ADDR1 && data == START_CMD1)
157 target->state = at29_flash_memory::START1;
161 if (target->state == at29_flash_memory::START1 &&
162 address == SEQ_ADDR2 && data == START_CMD2)
164 target->state = at29_flash_memory::START2;
168 if (target->state == at29_flash_memory::START2 &&
169 address == SEQ_ADDR1 && data == ID_CMD)
171 target->state = at29_flash_memory::IDENT;
175 if (target->state == at29_flash_memory::START2 &&
176 address == SEQ_ADDR1 && data == STOP_CMD)
178 target->state = at29_flash_memory::LOCKED;
182 if (target->state == at29_flash_memory::START2 &&
183 address == SEQ_ADDR1 && data == PROG_CMD)
185 target->state = at29_flash_memory::PROG;
186 target->sectorNum = target->noSectorNum;
190 // Bounds check the memory write.
191 if (address > target->buffer_length)
193 return bus::unmapped;
196 if (target->write_ok(address))
198 target->buffer[address] = data;
206 at29_bus::write(host_int_4 address,
207 big_int_1 data) throw ()
209 return write(address, little_int_1(data));
213 // static const description table for flash family
214 // Details taken from Atmel Flash Application Note AN-3, Rev. 0518B-10/98.
216 const at29_flash_memory_type at29_flash_memory::types[] =
218 { "c256", 32*1024, 64, 0xDC },
219 { "lv256", 32*1024, 64, 0xBC },
220 { "c257", 32*1024, 64, 0xDC },
221 { "c512", 64*1024, 128, 0x5D },
222 { "lv512", 64*1024, 128, 0x3D },
223 { "c010a", 128*1024, 128, 0xD5 },
224 { "lv010a", 128*1024, 128, 0x35 },
225 { "bv010a", 128*1024, 128, 0x35 },
226 // at29c1024 and at29lv1024 are 16-bit-wide devices, not supported by this code
227 { "c020", 256*1024, 256, 0xDA },
228 { "lv020", 256*1024, 256, 0xBA },
229 { "bv020", 256*1024, 256, 0xBA },
230 { "c040", 512*1024, 512, 0x5B },
231 { "lv040", 512*1024, 512, 0x3B },
232 { "bv040", 512*1024, 512, 0x3B },
233 { "c040a", 512*1024, 256, 0xA4 },
234 { "lv040a", 512*1024, 256, 0xC4 },
235 { "bv040a", 512*1024, 256, 0xC4 },