Guest User

EEPROM_Dumper_and_Programmer.ino

a guest
Feb 7th, 2020
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.15 KB | None | 0 0
  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(false);
  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() {}
Add Comment
Please, Sign In to add comment