├── README.md ├── Schematic_SPI-Based-EEPROM-Reader-Writer_Sheet-1_20190113165852.png ├── WINBOND_EEPROM_Programmer.ino ├── WINBOND_WWPROM_Programmer.ino ├── download_rom.py └── upload_rom.py /README.md: -------------------------------------------------------------------------------- 1 | # Read carefully before using this project 2 | 3 | 4 | ## Steps to download the content of EEPROM into a file: 5 | 6 | 1. First, make **download_rom()** function only active and flash the sketch into your arduino. 7 | 2. Configure **serial port** and **baud rate** in **download_rom.py** according to your arduino sketch. 8 | 3. Press **reset** button in your arduino. 9 | 4. Run **download_rom.py** by entering '**python2.7 download_rom.py**' in your terminal/cmd window. 10 | 5. Now press '**d**' and hit enter in the prompt in your terminal/cmd window and wait for finish. 11 | 12 | 13 | ## Steps to upload a file from computer to the EEPROM: 14 | 15 | 1. First, make **upload_rom()** function only active and flash the sketch into your arduino. 16 | 2. Configure **serial port** and **baud rate** in **upload_rom.py** according to your arduino sketch. 17 | 3. Run **upload_rom.py** by entering '**python2.7 upload_rom.py**' in your terminal/cmd window. 18 | 4. Press **reset** button in your arduino. 19 | 5. Enter the file path i.e. '**/path/to/the/file.rom**' and hit enter and wait for finish. 20 | 21 | ## Schematic 22 | Schematic can be found here: https://easyeda.com/arp14/spi-based-eeprom-reader-writer 23 | ![SPI-Based-EEPROM-Reader-Writer Schematic](https://raw.githubusercontent.com/Cyberster/SPI-Based-EEPROM-Reader-Writer/master/Schematic_SPI-Based-EEPROM-Reader-Writer_Sheet-1_20190113165852.png) 24 | 25 | ## Details about various functions with examples can be found here: 26 | https://w3epic.com/how-to-read-write-spi-based-serial-eeprom-using-arduino-uno-e-g-winbond-w25x80a/ -------------------------------------------------------------------------------- /Schematic_SPI-Based-EEPROM-Reader-Writer_Sheet-1_20190113165852.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cyberster/Arduino-SPI-EEPROM-Reader-Writer/ee3a001aca721c9140df64baf72d7bfed6bc0779/Schematic_SPI-Based-EEPROM-Reader-Writer_Sheet-1_20190113165852.png -------------------------------------------------------------------------------- /WINBOND_EEPROM_Programmer.ino: -------------------------------------------------------------------------------- 1 | /* Author: Arpan Das 2 | * Date: Fri Jan 11 12:16:59 2019 +0530 3 | * URL: https://github.com/Cyberster/SPI-Based-EEPROM-Reader-Writer */ 4 | 5 | // pin configurations 6 | #define CS_BAR 10 // SS EEPROM pin 1 7 | #define DO 11 // MOSI EEPROM pin 2 8 | #define DIO 12 // MISO EEPROM pin 5 9 | #define CLK 13 // SCK EEPROM pin 6 10 | 11 | // opcodes for winbond W25X10A, W25X20A, W25X40A, W25X80A EEPROMs 12 | #define WREN 0x06 // write enable 13 | #define WRDI 0x04 // write disable 14 | #define RDSR 0x05 // read status register 15 | #define WRSR 0x01 // write status register 16 | #define READ 0x03 // read from memory 17 | #define FREAD 0x0B // fast read from memory 18 | #define FREAD2 0x3B // fast read dual output from memory 19 | #define WRITE 0x02 // wribeginTransactionte to memory 20 | #define BERASE 0xD8 // block erase (64KB) 21 | #define SERASE 0x20 // sector erase (4KB) 22 | #define CERASE 0xC7 // chip erase (0xC7/0x60) 23 | #define PWRDWN 0xB9 // power down 24 | #define RELPWR 0xAB // block erase (64KB) 25 | #define INFO 0x90 // get manufacturer & device ID info 26 | #define JEDEC 0x9F // get JEDDEC ID 27 | 28 | byte clr; 29 | 30 | char spi_transfer(volatile char data) { 31 | SPDR = data; // Start the transmission 32 | // https://www.avrfreaks.net/forum/how-does-while-spsr-1 33 | while (!(SPSR & (1 << SPIF))) {}; // Wait the end of the transmission 34 | return SPDR; // return the received byte 35 | } 36 | 37 | void setup() { 38 | // Initialize serial and wait for port to open: 39 | // 1000000 working for upload, not working for download 40 | // 115200 working best for both upload and download 41 | Serial.begin(115200); 42 | // wait for serial port to connect. Needed for native USB port only 43 | while (!Serial); 44 | 45 | pinMode(DO, OUTPUT); 46 | pinMode(DIO, INPUT); 47 | pinMode(CLK, OUTPUT); 48 | pinMode(CS_BAR, OUTPUT); 49 | digitalWrite(CS_BAR, HIGH); // disable device 50 | // SPCR = 01010000 51 | //interrupt disabled,spi enabled,msb 1st,master,clk low when idle, 52 | //sample on leading edge of clk,system clock/4 rate (fastest) 53 | SPCR = (1 << SPE) | (1 << MSTR); 54 | clr = SPSR; 55 | clr = SPDR; 56 | delay(10); 57 | 58 | byte data = read_eeprom(0x0000FF); // 0x000000 to 0x100000 59 | Serial.println(data, HEX); 60 | 61 | // // read data, block_size columns (bytes) in a row, block_count rows 62 | // read_block(0x000000, 16, 10, true); 63 | 64 | // // download entier rom into a file 65 | // download_rom(true); 66 | 67 | // // write data to the EEPROM 68 | // byte buffer[256]; 69 | // for (int i = 0; i < 256; i++) { 70 | // buffer[i] = i; // filling buffer with 0-255 71 | // } 72 | // buffer size must be 1 to 256 73 | // EEPROM can only be written if empty i.e. filled with 1's 74 | // write_eeprom(0x000000, buffer, 256); 75 | 76 | // // erase 4kB from given address 77 | // sector_erase(0x000000); 78 | 79 | // // erase 64kB from given address 80 | // block_erase(0x000000); 81 | 82 | // // erase the entier EEPROM chip 83 | // chip_erase(); 84 | 85 | // // write data to eeprom 86 | // // fill buffer with data 87 | // byte buffer[256]; 88 | // for (int I = 0; I < 256; I++) { 89 | // buffer[I] = I; 90 | // } 91 | // write_eeprom(0x00010E, buffer, 256); 92 | 93 | // // upload data from file to the EEPROM 94 | // upload_rom(); 95 | 96 | // // read manufacturer id and device id 97 | // byte manufacturer_id; 98 | // byte device_id; 99 | // get_device_info(manufacturer_id, device_id); 100 | // Serial.println(manufacturer_id, HEX); 101 | // Serial.println(device_id, HEX); 102 | } 103 | 104 | // read data from EEPROM 105 | byte read_eeprom(long EEPROM_address) { 106 | byte data; 107 | digitalWrite(CS_BAR, LOW); // Write function 108 | spi_transfer(READ); //transmit read opcode 109 | spi_transfer((byte)((EEPROM_address >> 16) & 0x0000FF)); //send b2 address first 110 | spi_transfer((byte)((EEPROM_address >> 8) & 0x0000FF)); //send b1 address 111 | spi_transfer((byte)((EEPROM_address) & 0x0000FF)); //send b0 address last 112 | data = spi_transfer(0xFF); //get data byte 113 | digitalWrite(CS_BAR, HIGH); //release chip, signal end transfer 114 | return data; 115 | } 116 | 117 | // read manufacturer id and device id 118 | void get_device_info(byte &manufacturer_id, byte &device_id) { 119 | // read manufacturer id and device id 120 | digitalWrite(CS_BAR, LOW); 121 | spi_transfer(INFO); 122 | spi_transfer(0x00); 123 | spi_transfer(0x00); 124 | spi_transfer(0x00); 125 | manufacturer_id = spi_transfer(0xFF); //get data byte 126 | device_id = spi_transfer(0xFF); //get data byte 127 | digitalWrite(CS_BAR, HIGH); 128 | delay(10); 129 | } 130 | 131 | void read_block(long starting_address, int block_size, int block_count, boolean fastread) { 132 | // read data, block_size columns (bytes) in a row, block_count rows 133 | for (long i = starting_address; i < starting_address + (block_size * block_count); i += block_size) { 134 | digitalWrite(CS_BAR, LOW); 135 | if (fastread) 136 | spi_transfer(FREAD); 137 | else 138 | spi_transfer(READ); 139 | spi_transfer((byte)((i >> 16) & 0x0000FF)); 140 | spi_transfer((byte)((i >> 8) & 0x0000FF)); 141 | spi_transfer((byte)((i) & 0x0000FF)); 142 | if (fastread) 143 | spi_transfer(0xFF); // adding dummy clock for fast read 144 | 145 | byte data[block_size]; 146 | char buf[block_size * 4 + block_size + 8]; 147 | 148 | int length = 0; 149 | length += sprintf(buf + length, "%06lX\t ", i); 150 | 151 | for (int j = 0; j < block_size; j++) { 152 | data[j] = spi_transfer(0xFF); 153 | length += sprintf(buf + length, " %02X", data[j]); 154 | } 155 | length += sprintf(buf + length, "\t "); 156 | for (int j = 0; j < block_size; j++) { 157 | if (data[j] >= 32 && data[j] <= 127) 158 | length += sprintf(buf + length, "%c", (char)data[j]); 159 | else 160 | length += sprintf(buf + length, "."); 161 | } 162 | digitalWrite(CS_BAR, HIGH); 163 | 164 | Serial.println(buf); 165 | } 166 | } 167 | 168 | void download_rom(boolean fastread) { 169 | while (!Serial.available()) {} 170 | while (Serial.read() != 'd'); // waiting for handshaking 171 | 172 | // reading EEPROM 256 byte at a time for reliability 173 | for (long i = 0x000000; i <= 0xFF0000; i += 256) { 174 | Serial.write('W'); // response 1 byte of data write request 175 | while (Serial.read() != 'G'); // wait for computer grant write request 176 | 177 | // read EEPROM 178 | digitalWrite(CS_BAR, LOW); 179 | if (fastread) 180 | spi_transfer(FREAD); 181 | else 182 | spi_transfer(READ); 183 | spi_transfer((byte)((i >> 16) & 0x0000FF)); 184 | spi_transfer((byte)((i >> 8) & 0x0000FF)); 185 | spi_transfer((byte)((i) & 0x0000FF)); 186 | if (fastread) 187 | spi_transfer(0xFF); // adding dummy clock for fast read 188 | 189 | for (int j = 0; j < 256; j++) { 190 | byte data = spi_transfer(0xFF); 191 | Serial.write(data); 192 | } 193 | 194 | digitalWrite(CS_BAR, HIGH); 195 | delayMicroseconds(1000); 196 | } 197 | 198 | Serial.println("ROM downloaded successfully."); 199 | } 200 | 201 | // erase 4kB from given address 202 | void sector_erase(long address) { 203 | digitalWrite(CS_BAR, LOW); 204 | spi_transfer(WREN); //write enable 205 | digitalWrite(CS_BAR, HIGH); 206 | digitalWrite(CS_BAR, LOW); 207 | spi_transfer(SERASE); 208 | spi_transfer((byte) (address >> 16)); //send b2 address first 209 | spi_transfer((byte) (address >> 8)); //send b1 address 210 | spi_transfer((byte) address); //send b0 address last 211 | digitalWrite(CS_BAR, HIGH); 212 | delay(250); // tBE = 120-250ms 213 | digitalWrite(CS_BAR, LOW); 214 | spi_transfer(WRDI); //write disable 215 | digitalWrite(CS_BAR, HIGH); 216 | Serial.println("Operation SECTOR ERASE has been executed successfully."); 217 | } 218 | 219 | // erase 64kB from given address 220 | void block_erase(long address) { 221 | digitalWrite(CS_BAR, LOW); 222 | spi_transfer(WREN); //write enable 223 | digitalWrite(CS_BAR, HIGH); 224 | digitalWrite(CS_BAR, LOW); 225 | spi_transfer(BERASE); 226 | spi_transfer((byte) (address >> 16)); //send b2 address first 227 | spi_transfer((byte) (address >> 8)); //send b1 address 228 | spi_transfer((byte) address); //send b0 address last 229 | digitalWrite(CS_BAR, HIGH); 230 | delay(1000); // tBE = 0.4-1s 231 | digitalWrite(CS_BAR, LOW); 232 | spi_transfer(WRDI); //write disable 233 | digitalWrite(CS_BAR, HIGH); 234 | Serial.println("Operation BLOCK ERASE has been executed successfully."); 235 | } 236 | 237 | // erase the entire EEPROM chip 238 | void chip_erase() { 239 | digitalWrite(CS_BAR, LOW); 240 | spi_transfer(WREN); //write enable 241 | digitalWrite(CS_BAR, HIGH); 242 | digitalWrite(CS_BAR, LOW); 243 | spi_transfer(CERASE); 244 | digitalWrite(CS_BAR, HIGH); 245 | delay(10000); // tCE = 6-10s for W25X80A in our case. 246 | digitalWrite(CS_BAR, LOW); 247 | spi_transfer(WRDI); //write disable 248 | digitalWrite(CS_BAR, HIGH); 249 | Serial.println("Operation CHIP ERASE has been executed successfully."); 250 | } 251 | 252 | // write data to the EEPROM 253 | // max buffer size is 256 254 | void write_eeprom(long address, byte data[], int data_size) { 255 | digitalWrite(CS_BAR, LOW); 256 | spi_transfer(WREN); //write enable 257 | digitalWrite(CS_BAR, HIGH); 258 | delayMicroseconds(5); 259 | 260 | digitalWrite(CS_BAR, LOW); 261 | spi_transfer(WRITE); //write instruction 262 | spi_transfer((byte)((address >> 16) & 0x0000FF)); // send b2 address first 263 | spi_transfer((byte)((address >> 8) & 0x0000FF)); // send b1 address 264 | 265 | // send b0 address: 266 | // If an entire 256 byte page is to be programmed, the last address 267 | // byte (the 8 least significant address bits) should be set to 0. 268 | if (data_size == 256) 269 | spi_transfer(0x00); // as 0xFF 270 | else 271 | spi_transfer((byte)((address) & 0x0000FF)); // as it is 272 | 273 | for (int i = 0; i < data_size; i++) { 274 | spi_transfer(data[i]); //write data byte 275 | } 276 | 277 | digitalWrite(CS_BAR, HIGH); //release chip 278 | //wait for eeprom to finish writing 279 | delayMicroseconds(1500); // tpp = 1.5-3ms 280 | 281 | digitalWrite(CS_BAR, LOW); 282 | spi_transfer(WRDI); //write disable 283 | digitalWrite(CS_BAR, HIGH); 284 | } 285 | 286 | // upload data from file to the EEPROM 287 | void upload_rom() { 288 | while (!Serial.available()) {} 289 | while (Serial.read() != 'H'); // wait for handshake request from cmoputer 290 | 291 | byte buff[256]; 292 | 293 | // 1 page at a time where page size = 256 byte 294 | for (long address = 0; address <= 0x0FFFFF; address += 256) { //0x0FFFFF 295 | Serial.write('R'); // requests 256 bytes of data 296 | while (!Serial.available()); // wait for computer 297 | 298 | Serial.readBytes(buff, 256); 299 | write_eeprom(address, buff, 256); 300 | } 301 | 302 | // while (Serial.available()) { 303 | // byte data = (byte)Serial.read(); 304 | // Serial.readBytes(buff, 256); 305 | // 306 | // buff[i++] = data; 307 | // if (i == 256) { 308 | // write_eeprom(address, buff, 256); 309 | // address += 256; 310 | // i = 0; 311 | // } 312 | // } 313 | 314 | Serial.println("ROM uploaded successfully."); 315 | } 316 | 317 | void loop() {} 318 | -------------------------------------------------------------------------------- /WINBOND_WWPROM_Programmer.ino: -------------------------------------------------------------------------------- 1 | /* Author: Arpan Das 2 | * Date: Fri Jan 11 12:16:59 2019 +0530 3 | * URL: https://github.com/Cyberster/SPI-Based-EEPROM-Reader-Writer */ 4 | 5 | // pin configurations 6 | #define CS_BAR 10 // SS EEPROM pin 1 7 | #define DO 11 // MOSI EEPROM pin 2 8 | #define DIO 12 // MISO EEPROM pin 5 9 | #define CLK 13 // SCK EEPROM pin 6 10 | 11 | // opcodes for winbond W25X10A, W25X20A, W25X40A, W25X80A EEPROMs 12 | #define WREN 0x06 // write enable 13 | #define WRDI 0x04 // write disable 14 | #define RDSR 0x05 // read status register 15 | #define WRSR 0x01 // write status register 16 | #define READ 0x03 // read from memory 17 | #define FREAD 0x0B // fast read from memory 18 | #define FREAD2 0x3B // fast read dual output from memory 19 | #define WRITE 0x02 // write to memory 20 | #define BERASE 0xD8 // block erase (64KB) 21 | #define SERASE 0x20 // sector erase (4KB) 22 | #define CERASE 0xC7 // chip erase (0xC7/0x60) 23 | #define PWRDWN 0xB9 // power down 24 | #define RELPWR 0xAB // block erase (64KB) 25 | #define INFO 0x90 // get manufacturer & device ID info 26 | #define JEDEC 0x9F // get JEDDEC ID 27 | 28 | byte clr; 29 | 30 | char spi_transfer(volatile char data) { 31 | SPDR = data; // Start the transmission 32 | while (!(SPSR & (1<> 16)); //send b2 address first 93 | spi_transfer((char)(EEPROM_address >> 8)); //send b1 address 94 | spi_transfer((char)(EEPROM_address)); //send b0 address last 95 | data = spi_transfer(0xFF); //get data byte 96 | digitalWrite(CS_BAR, HIGH); //release chip, signal end transfer 97 | return data; 98 | } 99 | 100 | // functions for WINBOND EEPROM chips 101 | void get_device_info(byte &manufacturer_id, byte &device_id) { 102 | // read manufacturer id and device id 103 | digitalWrite(CS_BAR, LOW); 104 | spi_transfer(INFO); 105 | spi_transfer(0x00); 106 | spi_transfer(0x00); 107 | spi_transfer(0x00); 108 | manufacturer_id = spi_transfer(0xFF); //get data byte 109 | device_id = spi_transfer(0xFF); //get data byte 110 | digitalWrite(CS_BAR, HIGH); 111 | delay(10); 112 | } 113 | 114 | void read_block(long starting_address, int block_size, int block_count, boolean fastread) { 115 | // read data, block_size columns (bytes) in a row, block_count rows 116 | for (long i = starting_address; i < starting_address + (block_size * block_count); i += block_size) { 117 | digitalWrite(CS_BAR, LOW); 118 | if (fastread) 119 | spi_transfer(FREAD); 120 | else 121 | spi_transfer(READ); 122 | spi_transfer((byte)((i >> 16) & 0x0000FF)); 123 | spi_transfer((byte)((i >> 8) & 0x0000FF)); 124 | spi_transfer((byte)((i) & 0x0000FF)); 125 | if (fastread) 126 | spi_transfer(0xFF); // adding dummy clock for fast read 127 | 128 | byte data[block_size]; 129 | char buf[block_size * 4 + block_size + 8]; 130 | 131 | int length = 0; 132 | length += sprintf(buf + length, "%06lX\t ", i); 133 | 134 | for (int j = 0; j < block_size; j++) { 135 | data[j] = spi_transfer(0xFF); 136 | length += sprintf(buf + length, " %02X", data[j]); 137 | } 138 | length += sprintf(buf + length, "\t "); 139 | for (int j = 0; j < block_size; j++) { 140 | if (data[j] >= 32 && data[j] <= 127) 141 | length += sprintf(buf + length, "%c", (char)data[j]); 142 | else 143 | length += sprintf(buf + length, "."); 144 | } 145 | digitalWrite(CS_BAR, HIGH); 146 | 147 | Serial.println(buf); 148 | } 149 | } 150 | 151 | void download_rom(boolean fastread) { 152 | while (!Serial.available()) {} 153 | while (Serial.read() != 'd'); // waiting for handshaking 154 | 155 | // reading EEPROM 256 byte at a time for reliability 156 | for (long i = 0x000000; i <= 0xFF0000; i += 256) { 157 | Serial.write('W'); // response 1 byte of data write request 158 | while (Serial.read() != 'G'); // wait for computer grant write request 159 | 160 | // read EEPROM 161 | digitalWrite(CS_BAR, LOW); 162 | if (fastread) 163 | spi_transfer(FREAD); 164 | else 165 | spi_transfer(READ); 166 | spi_transfer((byte)((i >> 16) & 0x0000FF)); 167 | spi_transfer((byte)((i >> 8) & 0x0000FF)); 168 | spi_transfer((byte)((i) & 0x0000FF)); 169 | if (fastread) 170 | spi_transfer(0xFF); // adding dummy clock for fast read 171 | 172 | for (int j = 0; j < 256; j++) { 173 | byte data = spi_transfer(0xFF); 174 | Serial.write(data); 175 | } 176 | 177 | digitalWrite(CS_BAR, HIGH); 178 | delayMicroseconds(1000); 179 | } 180 | 181 | Serial.println("ROM downloaded successfully."); 182 | } 183 | 184 | // erase 4kB from given address 185 | void sector_erase(long address) { 186 | digitalWrite(CS_BAR, LOW); 187 | spi_transfer(WREN); //write enable 188 | digitalWrite(CS_BAR, HIGH); 189 | digitalWrite(CS_BAR, LOW); 190 | spi_transfer(SERASE); 191 | spi_transfer((byte) (address >> 16)); //send b2 address first 192 | spi_transfer((byte) (address >> 8)); //send b1 address 193 | spi_transfer((byte) address); //send b0 address last 194 | digitalWrite(CS_BAR, HIGH); 195 | delay(250); // tBE = 120-250ms 196 | digitalWrite(CS_BAR, LOW); 197 | spi_transfer(WRDI); //write disable 198 | digitalWrite(CS_BAR, HIGH); 199 | Serial.println("Operation SECTOR ERASE has been executed successfully."); 200 | } 201 | 202 | // erase 64kB from given address 203 | void block_erase(long address) { 204 | digitalWrite(CS_BAR, LOW); 205 | spi_transfer(WREN); //write enable 206 | digitalWrite(CS_BAR, HIGH); 207 | digitalWrite(CS_BAR, LOW); 208 | spi_transfer(BERASE); 209 | spi_transfer((byte) (address >> 16)); //send b2 address first 210 | spi_transfer((byte) (address >> 8)); //send b1 address 211 | spi_transfer((byte) address); //send b0 address last 212 | digitalWrite(CS_BAR, HIGH); 213 | delay(1000); // tBE = 0.4-1s 214 | digitalWrite(CS_BAR, LOW); 215 | spi_transfer(WRDI); //write disable 216 | digitalWrite(CS_BAR, HIGH); 217 | Serial.println("Operation BLOCK ERASE has been executed successfully."); 218 | } 219 | 220 | // erase the entier chip 221 | void chip_erase() { 222 | digitalWrite(CS_BAR, LOW); 223 | spi_transfer(WREN); //write enable 224 | digitalWrite(CS_BAR, HIGH); 225 | digitalWrite(CS_BAR, LOW); 226 | spi_transfer(CERASE); 227 | digitalWrite(CS_BAR, HIGH); 228 | delay(10000); // tCE = 6-10s for W25X80A in our case. 229 | digitalWrite(CS_BAR, LOW); 230 | spi_transfer(WRDI); //write disable 231 | digitalWrite(CS_BAR, HIGH); 232 | Serial.println("Operation CHIP ERASE has been executed successfully."); 233 | } 234 | 235 | // write data to the EEPROM 236 | // max buffer size is 256 237 | void write_eeprom(long address, byte data[], int data_size) { 238 | digitalWrite(CS_BAR, LOW); 239 | spi_transfer(WREN); //write enable 240 | digitalWrite(CS_BAR, HIGH); 241 | delayMicroseconds(5); 242 | 243 | digitalWrite(CS_BAR, LOW); 244 | spi_transfer(WRITE); //write instruction 245 | spi_transfer((byte)((address >> 16) & 0x0000FF)); // send b2 address first 246 | spi_transfer((byte)((address >> 8) & 0x0000FF)); // send b1 address 247 | 248 | // send b0 address: 249 | // If an entire 256 byte page is to be programmed, the last address 250 | // byte (the 8 least significant address bits) should be set to 0. 251 | if (data_size == 256) 252 | spi_transfer(0x00); // as 0xFF 253 | else 254 | spi_transfer((byte)((address) & 0x0000FF)); // as it is 255 | 256 | for (int i = 0; i < data_size; i++) { 257 | spi_transfer(data[i]); //write data byte 258 | } 259 | 260 | digitalWrite(CS_BAR, HIGH); //release chip 261 | //wait for eeprom to finish writing 262 | delayMicroseconds(1500); // tpp = 1.5-3ms 263 | 264 | digitalWrite(CS_BAR, LOW); 265 | spi_transfer(WRDI); //write disable 266 | digitalWrite(CS_BAR, HIGH); 267 | } 268 | 269 | // upload data from file to the EEPROM 270 | void upload_rom() { 271 | while (!Serial.available()) {} 272 | while (Serial.read() != 'H'); // wait for handshake request from cmoputer 273 | 274 | byte buff[256]; 275 | 276 | // 1 page at a time where page size = 256 byte 277 | for (long address = 0; address <= 0x0FFFFF; address += 256) { //0x0FFFFF 278 | Serial.write('R'); // requests 256 bytes of data 279 | while (!Serial.available()); // wait for computer 280 | 281 | Serial.readBytes(buff, 256); 282 | write_eeprom(address, buff, 256); 283 | } 284 | 285 | // while (Serial.available()) { 286 | // byte data = (byte)Serial.read(); 287 | // Serial.readBytes(buff, 256); 288 | // 289 | // buff[i++] = data; 290 | // if (i == 256) { 291 | // write_eeprom(address, buff, 256); 292 | // address += 256; 293 | // i = 0; 294 | // } 295 | // } 296 | 297 | Serial.println("ROM uploaded successfully."); 298 | } 299 | 300 | void loop() {} 301 | -------------------------------------------------------------------------------- /download_rom.py: -------------------------------------------------------------------------------- 1 | ## Author: Arpan Das 2 | ## Date: Fri Jan 11 12:16:59 2019 +0530 3 | ## URL: https://github.com/Cyberster/SPI-Based-EEPROM-Reader-Writer 4 | 5 | ## It listens to serial port and writes contents into a file 6 | ## requires pySerial to be installed 7 | import sys 8 | import serial 9 | import time 10 | start = time.time() 11 | 12 | MEMORY_SIZE = 1048576 # In bytes 13 | serial_port = '/dev/ttyACM0' 14 | baud_rate = 115200 # In arduino, Serial.begin(baud_rate) 15 | write_to_file_path = "dump.rom" 16 | 17 | output_file = open(write_to_file_path, "wb") 18 | ser = serial.Serial(serial_port, baud_rate) 19 | 20 | print("Press d for dump ROM else CTRL+C to exit.") 21 | ch = sys.stdin.read(1) 22 | 23 | if ch == 'd': 24 | ser.write('d') 25 | for i in range(4096): # i.e. MEMORY_SIZE / 256 26 | # wait until arduino response with 'W' i.e. 1 byte of data write request 27 | while (ser.read() != 'W'): continue 28 | ser.write('G') # sends back write request granted signal 29 | 30 | for j in range(256): 31 | byte = ser.read(1); 32 | output_file.write(byte); 33 | print(str(MEMORY_SIZE - (i * 256)) + " bytes remaining.") 34 | 35 | print '\nIt took', time.time()-start, ' seconds.' 36 | -------------------------------------------------------------------------------- /upload_rom.py: -------------------------------------------------------------------------------- 1 | ## Author: Arpan Das 2 | ## Date: Fri Jan 11 12:16:59 2019 +0530 3 | ## URL: https://github.com/Cyberster/SPI-Based-EEPROM-Reader-Writer 4 | 5 | ## It listens to serial port and send data to serial port 6 | ## requires pySerial to be installed 7 | import sys 8 | import serial 9 | import time 10 | 11 | MEMORY_SIZE = 1048576 # In bytes 12 | serial_port = '/dev/ttyACM0' 13 | baud_rate = 115200 # In arduino, Serial.begin(baud_rate) 14 | ser = serial.Serial(serial_port, baud_rate) 15 | 16 | fileName = raw_input("Please enter file name: ") 17 | 18 | with open(fileName, mode='rb') as file: # b is important -> binary 19 | start = time.time() 20 | #i = 0 21 | ser.write('H') # for handshake request 22 | 23 | # whole file at a time 24 | #fileContent = file.read() 25 | 26 | # 1 byte at a time 27 | for i in range(4096): # 4096 x 256 bytes = 1MB 28 | # wait until arduino requests 'R' i.e. 256 bytes of data 29 | while (ser.read() != 'R'): continue 30 | 31 | for j in range(256): 32 | byte_s = file.read(1) 33 | if not byte_s: break 34 | byte = byte_s[0] 35 | ser.write(byte) 36 | '''byte_s = file.read(256) 37 | if not byte_s: break 38 | ser.write(byte_s)''' 39 | print str((i + 1) * 256), 'bytes of', MEMORY_SIZE, 'bytes has been uploaded.' 40 | 41 | '''while 1: 42 | byte_s = file.read(1) 43 | if not byte_s: 44 | break 45 | byte = byte_s[0] 46 | ser.write(byte) 47 | print str(i + 1), 'bytes of', MEMORY_SIZE, 'bytes has been uploaded.' 48 | i += 1''' 49 | 50 | status = ser.readline() 51 | print(status) 52 | 53 | print '\nIt took', time.time()-start, 'seconds.' 54 | --------------------------------------------------------------------------------