| mips/nand.hhp |
| 134 | 134 | // 33: 9-byte ecc of 4th 512 bytes |
| 135 | 135 | // 42: unused |
| 136 | 136 | // 64: end of space |
| 137 | | unsigned col = (1 << page_bits) + 2 |
| 137 | unsigned col = (1 << page_bits) + 6 + 9 * (column >> 9) |
| 138 | 138 | cmd (CMD_READ0) |
| 139 | 139 | addr (col) |
| 140 | 140 | addr (col >> 8) |
| ... | ... | |
| 142 | 142 | addr (row >> 8) |
| 143 | 143 | addr (row >> 16) |
| 144 | 144 | cmd (CMD_READSTART) |
| 145 | | bool valid = false |
| 146 | | for unsigned t = 0; t < 3; ++t: |
| 147 | | if rdata () == 0: |
| 148 | | valid = true |
| 149 | | break |
| 150 | | if !valid: |
| 151 | | //debug ("invalid page for nand read: %x\n", a) |
| 152 | | for unsigned i = 0; i < 1 << (9 - 2); ++i: |
| 153 | | ((unsigned *)buffer)[i] = ~0 |
| 154 | | return false |
| 155 | | col = (1 << page_bits) + 6 + 9 * (column >> 9) |
| 156 | | cmd (CMD_RNDOUT) |
| 157 | | addr (col) |
| 158 | | addr (col >> 8) |
| 159 | | cmd (CMD_RNDOUTSTART) |
| 160 | 145 | //debug ("parity data:") |
| 161 | 146 | for unsigned t = 0; t < 9; ++t: |
| 162 | 147 | error[t] = rdata () |
| ... | ... | |
| 192 | 177 | data ^= mask << offset |
| 193 | 178 | buffer[byte] = data |
| 194 | 179 | buffer[byte + 1] = data >> 8 |
| 180 | #if 0 |
| 195 | 181 | for unsigned i = 0; i < 0x10; ++i: |
| 196 | 182 | if (buffer[i] & 0xff) < 0x10: |
| 197 | | //debug (" 0") |
| 183 | debug (" 0") |
| 198 | 184 | else: |
| 199 | | //debug (" ") |
| 200 | | //debug ("%x", buffer[i] & 0xff) |
| 201 | | //debug ("\n") |
| 185 | debug (" ") |
| 186 | debug ("%x", buffer[i] & 0xff) |
| 187 | debug ("\n") |
| 188 | #endif |
| 202 | 189 | return true |
| 203 | 190 | |
| 204 | 191 | static void write (unsigned a, char *buffer): |
| 205 | | dbgl () |
| 206 | 192 | unsigned row = a >> page_bits |
| 207 | 193 | //debug ("writing: %x/%x\n", a, row) |
| 208 | 194 | cmd (CMD_SEQIN) |
| ... | ... | |
| 211 | 197 | addr (row) |
| 212 | 198 | addr (row >> 8) |
| 213 | 199 | addr (row >> 16) |
| 214 | | char ecc[4][12] |
| 215 | | dbgl () |
| 216 | | for unsigned i = 0; i < 0x4; ++i: |
| 217 | | dbgl () |
| 200 | char ecc[8][12] |
| 201 | for unsigned i = 0; i < 1 << (page_bits - 9); ++i: |
| 218 | 202 | bool all_ff = true |
| 219 | 203 | EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING | EMC_NFECR_ERST |
| 220 | 204 | //debug ("writing data from %x\n", (unsigned)buffer + i * 0x200) |
| ... | ... | |
| 225 | 209 | if !all_ff: |
| 226 | 210 | while !(EMC_NFINTS & EMC_NFINTS_ENCF): |
| 227 | 211 | DELAY () |
| 228 | | dbgl () |
| 229 | 212 | for unsigned t = 0; t < 9; ++t: |
| 230 | 213 | ecc[i][t] = ((volatile char *)&EMC_NFPAR (0))[t] |
| 231 | | dbgl () |
| 232 | 214 | //debug ("parity for %x:", i * 0x200 + a) |
| 233 | 215 | //for unsigned t = 0; t < 9; ++t: |
| 234 | 216 | //debug (" %x", ecc[i][t] & 0xff) |
| 235 | 217 | //kdebug ("\n") |
| 236 | 218 | else: |
| 237 | | dbgl () |
| 238 | 219 | for unsigned t = 0; t < 9; ++t: |
| 239 | 220 | ecc[i][t] = 0xff |
| 240 | | dbgl () |
| 241 | 221 | // Spare space (starts at 1 << page_bits) |
| 242 | 222 | // 0: unused |
| 243 | 223 | // 2: detect valid data (at least 1 byte == 0 means valid) |
| ... | ... | |
| 250 | 230 | // 64: end of space |
| 251 | 231 | for unsigned i = 0; i < 6; ++i: |
| 252 | 232 | wdata (0) |
| 253 | | for unsigned i = 0; i < 4; ++i: |
| 233 | for unsigned i = 0; i < 1 << (page_bits - 9); ++i: |
| 254 | 234 | for unsigned j = 0; j < 9; ++j: |
| 255 | 235 | wdata (ecc[i][j]) |
| 256 | | dbgl () |
| 257 | 236 | cmd (CMD_PAGEPROG) |
| 258 | 237 | // Wait at least 100 ns. |
| 259 | 238 | DELAY () |
| 260 | | dbgl () |
| 261 | 239 | cmd (CMD_READ0) |
| 262 | 240 | addr (0) |
| 263 | 241 | addr (0) |
| ... | ... | |
| 265 | 243 | addr (row >> 8) |
| 266 | 244 | addr (row >> 16) |
| 267 | 245 | cmd (CMD_READSTART) |
| 268 | | dbgl () |
| 269 | | for unsigned i = 0; i < 4; ++i: |
| 270 | | dbgl () |
| 246 | for unsigned i = 0; i < 1 << (page_bits - 9); ++i: |
| 271 | 247 | EMC_NFINTS = 0 |
| 272 | 248 | EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST |
| 273 | 249 | for unsigned t = 0; t < 0x200; ++t: |
| ... | ... | |
| 292 | 268 | unsigned offset= bit & 7 |
| 293 | 269 | unsigned byte = bit / 8 |
| 294 | 270 | debug ("error detected by parity: %x on %x+%d\n", mask, byte, offset) |
| 295 | | dbgl () |
| 296 | 271 | for unsigned i = 0; i < 6; ++i: |
| 297 | 272 | if rdata () != 0: |
| 298 | 273 | debug ("extra data not 0 at byte %d\n", i) |
| 299 | | dbgl () |
| 300 | | for unsigned i = 0; i < 4; ++i: |
| 274 | for unsigned i = 0; i < 1 << (page_bits - 9); ++i: |
| 301 | 275 | for unsigned j = 0; j < 9; ++j: |
| 302 | 276 | unsigned r = rdata () & 0xff |
| 303 | 277 | if r != (ecc[i][j] & 0xff): |
| 304 | 278 | debug ("ecc doesn't match: %x != %x\n", r, ecc[i][j] & 0xff) |
| 305 | | dbgl () |
| 306 | 279 | //debug ("nand program %x:", a) |
| 280 | #if 0 |
| 307 | 281 | for unsigned i = 0; i < 0x10; ++i: |
| 308 | 282 | if (buffer[i] & 0xff) < 0x10: |
| 309 | | //debug (" 0") |
| 283 | debug (" 0") |
| 310 | 284 | else: |
| 311 | | //debug (" ") |
| 312 | | //debug ("%x", buffer[i] & 0xff) |
| 313 | | dbgl () |
| 314 | | //debug ("\n") |
| 285 | debug (" ") |
| 286 | debug ("%x", buffer[i] & 0xff) |
| 287 | debug ("\n") |
| 288 | #endif |
| 315 | 289 | |
| 316 | 290 | static void erase (unsigned a): |
| 317 | 291 | unsigned row = a >> page_bits |