[d09030d] | 1 | #include "at29c040.h"
|
---|
| 2 |
|
---|
[34c57e8] | 3 | #include <stdio.h>
|
---|
| 4 | #include <unistd.h>
|
---|
| 5 |
|
---|
| 6 |
|
---|
| 7 | AT29C040::AT29C040()
|
---|
| 8 | : Device()
|
---|
| 9 | {
|
---|
| 10 | }
|
---|
| 11 |
|
---|
| 12 | void AT29C040::power()
|
---|
| 13 | {
|
---|
| 14 | Device::write(CTRL, 0b10011111 | CTRLmask);
|
---|
| 15 | Device::write(VOLT, 0b11001000 | VOLTmask);
|
---|
[a6ae6ac] | 16 | outb(port + 2, NONE);
|
---|
[34c57e8] | 17 | }
|
---|
| 18 |
|
---|
| 19 | void Device::shutdown()
|
---|
| 20 | {
|
---|
| 21 | // All pins of the ROM are put either in high-Z, or 0V when it's not
|
---|
| 22 | // possible
|
---|
[a6ae6ac] | 23 | Device::write(CTRL, 0b01100010);
|
---|
| 24 | Device::write(VOLT, 0b01111111);
|
---|
[34c57e8] | 25 | outb(port + 2, NONE);
|
---|
| 26 | }
|
---|
| 27 |
|
---|
[d09030d] | 28 | void AT29C040::read(const char* filename)
|
---|
| 29 | {
|
---|
[34c57e8] | 30 | if (!checkId()) {
|
---|
| 31 | return;
|
---|
| 32 | }
|
---|
[d09030d] | 33 | }
|
---|
| 34 |
|
---|
| 35 | void AT29C040::write(const char* filename)
|
---|
| 36 | {
|
---|
[34c57e8] | 37 | if (!checkId()) {
|
---|
| 38 | return;
|
---|
| 39 | }
|
---|
[d09030d] | 40 | }
|
---|
| 41 |
|
---|
| 42 | void AT29C040::erase(void)
|
---|
| 43 | {
|
---|
[34c57e8] | 44 | if (!checkId()) {
|
---|
| 45 | return;
|
---|
| 46 | }
|
---|
| 47 |
|
---|
| 48 | puts("Perfomring chip erase...");
|
---|
| 49 | }
|
---|
| 50 |
|
---|
| 51 | bool AT29C040::checkId(void)
|
---|
| 52 | {
|
---|
| 53 | // Chip enable
|
---|
[a6ae6ac] | 54 | Device::write(CTRL, CTRLmask | WE | OE | CE | A17);
|
---|
[34c57e8] | 55 | // Address bits low, WE = 1, CE = 0, OE = 1
|
---|
| 56 | // TC and TD = 1
|
---|
| 57 | Device::write(VOLT, VOLTmask);
|
---|
| 58 | // D and A OE = 0
|
---|
| 59 | // VPP config ?
|
---|
| 60 | // TA, TB, TE, TF = ?
|
---|
| 61 |
|
---|
| 62 | wr16(0x5555, 0xAA);
|
---|
[a6ae6ac] | 63 | wr16(0xAAAA, 0x55);
|
---|
[34c57e8] | 64 | wr16(0x5555, 0x90);
|
---|
| 65 |
|
---|
| 66 | // clear DOE for reading
|
---|
| 67 | Device::write(VOLT, DOE | VOLTmask);
|
---|
| 68 |
|
---|
| 69 | usleep(10000);
|
---|
| 70 |
|
---|
| 71 | // Read the result now
|
---|
| 72 | Device::write(ADR0, 0x00);
|
---|
[a6ae6ac] | 73 | usleep(1000);
|
---|
| 74 | Device::write(ADR1, 0x00 ^ A13);
|
---|
| 75 | usleep(1000);
|
---|
| 76 | Device::write(CTRL, WE | A17 | CTRLmask);
|
---|
| 77 | usleep(1000);
|
---|
[34c57e8] | 78 | uint8_t manufacturer = Device::read();
|
---|
| 79 |
|
---|
| 80 |
|
---|
[a6ae6ac] | 81 | Device::write(CTRL, CE | OE | WE | A17 | CTRLmask);
|
---|
| 82 | usleep(1000);
|
---|
[34c57e8] | 83 | Device::write(ADR0, 0x01);
|
---|
[a6ae6ac] | 84 | usleep(1000);
|
---|
| 85 | Device::write(CTRL, WE | A17 | CTRLmask);
|
---|
| 86 | usleep(1000);
|
---|
[34c57e8] | 87 |
|
---|
| 88 | uint8_t product = Device::read();
|
---|
| 89 |
|
---|
[a6ae6ac] | 90 | Device::write(CTRL, CE | WE | OE | A17 | CTRLmask);
|
---|
| 91 | usleep(1000);
|
---|
[34c57e8] | 92 | // re enable DOE, we are going to write again...
|
---|
| 93 | Device::write(VOLT, VOLTmask);
|
---|
[a6ae6ac] | 94 | usleep(1000);
|
---|
[34c57e8] | 95 |
|
---|
| 96 | wr16(0x5555, 0xAA);
|
---|
[a6ae6ac] | 97 | wr16(0xAAAA, 0x55);
|
---|
[34c57e8] | 98 | wr16(0x5555, 0xF0);
|
---|
| 99 | usleep(10000);
|
---|
| 100 |
|
---|
| 101 | // Chip disable - we're done !
|
---|
| 102 | Device::write(CTRL, 0xFF | CTRLmask);
|
---|
[a6ae6ac] | 103 | usleep(1000);
|
---|
[34c57e8] | 104 |
|
---|
| 105 | bool ok = (manufacturer == 0x1F && product == 0xA4);
|
---|
| 106 |
|
---|
| 107 | if (!ok)
|
---|
| 108 | {
|
---|
| 109 | fprintf(stderr, "Chip ID %X:%X does not match expected %X:%X\n",
|
---|
| 110 | manufacturer, product, 0x1F, 0xA4);
|
---|
| 111 | } else {
|
---|
| 112 | fprintf(stderr, "AT29C040 detected successfully!\n");
|
---|
| 113 | }
|
---|
| 114 |
|
---|
| 115 | return ok;
|
---|
[d09030d] | 116 | }
|
---|