📜 ⬆️ ⬇️

SPI Flash Programming with Arduino and SD Card

Prehistory


During the next cleaning, the extension cord was accidentally turned off, to which the working system unit and monitor were connected. The system unit consists of:


After switching on, the system man began to publish five nasty squeaks, which seems to correspond to a processor malfunction. The processor, judging by Yandex.Market, currently costs from 11,000 rubles. Buying quite expensive, but inexpensive, but weak do not want. In general, a little scared ...

Rummaged on the Internet, found out that the exact cause of the malfunction may be quite different. It gave little hope. But we must somehow find this very reason.
')
First of all, I connected another old power supply unit - the computer does not start.

For further checks brought home car comp. Composition:


It is good that the components are interchangeable.

I pulled out the processor from the car's computer, inserted it into the home computer - the computer does not start. But there is hope that the processor is still intact, and the motherboard is faulty, which is a bit cheaper (although the new ones on the chipsets are not H61 and H67 - the deficit).

Next, the home processor is inserted into the car computer - the computer has earned. Consequently, the processor is alive, and the problem is in the motherboard. Began to sin on the BIOS (Winbond 25Q64BVAIG).

Actually, programming


It is good that the BIOS chip is not soldered, but on the usual DIP-8 socket. I do not have a programmer, ordering in China and waiting a month is not an option. I decided to make the programmer out of my wife’s laptop and the Arduino Nano available. I rummaged through the Internet ... Everywhere, basically, the firmware is poured through the COM port, but I decided to flash it from the memory card (it seems to be much faster).

Sketched the wiring diagram:



I collected everything on the breadboard:



The type and size of the memory card, its formatting method, the file name must comply with the requirements of the SD Arduino library.

To begin with, I sketched a sketch that reads the contents of the SPI Flash and writes it to a file on a memory card, simultaneously calculating a checksum using the Checksum-32 method, i.e. simple summation.

ReadFlash_WriteSD.ino
/*  SPI-Flash: CS - D9 MOSI - D11 MISO - D12 CLK - D13  SD-Card Shield: CS - D10 MOSI - D11 MISO - D12 CLK - D13 */ #include <SD.h> #include <SPIFlash.h> #define Flash_CS 9 #define SD_CS 10 #define FILENAME "BIOS.ROM" File myFile; SPIFlash flash(Flash_CS); void setup() { Serial.begin(115200); while (!Serial) {} //     //  SD- Serial.println("Initializing SD card..."); if (!SD.begin(SD_CS)) { Serial.println("Initialization SD card failed!"); return; } Serial.println("Initialization done."); //   ,   Serial.print(FILENAME); if (SD.exists(FILENAME)) { Serial.println(" exists, removing..."); SD.remove(FILENAME); } else { Serial.println(" doesn't exist."); } //        Serial.print("Creating "); Serial.print(FILENAME); Serial.println("..."); myFile = SD.open(FILENAME, FILE_WRITE); //       -     if (myFile) { //  SPI Flash Serial.println("Initializing SPI Flash..."); flash.begin(); // / /  256  uint8_t data_buffer[256]; //   uint32_t maxPage = flash.getMaxPage(); // Checksum (32 bit) uint32_t checkSum = 0; for (int page = 0; page < maxPage; page++) { //    if ((page % 1000) == 0) { Serial.print(page + 1); Serial.print("/"); Serial.println(maxPage); } //   SPI Flash flash.readByteArray(page, 0, &data_buffer[0], 256); //        myFile.write(data_buffer, 256); //    for (int i = 0; i < 256; i++) { checkSum += data_buffer[i]; } } //      myFile.close(); //    Serial.print("Checksum-32: 0x"); Serial.println(checkSum, HEX); Serial.println("Done."); } else { //    ,      Serial.println("Error creating "); Serial.println(FILENAME); } } void loop() { //   } 


I started the sketch, the resulting file was compared with the original BIOS - it turned out about 140,000 mismatched bytes.

Then he wrote a sketch that reads a file from a memory card and writes it to SPI Flash, erasing the chip beforehand.

ReadSD_WriteFlash.ino
 /*  SPI-Flash: CS - D9 MOSI - D11 MISO - D12 CLK - D13  SD-Card Shield: CS - D10 MOSI - D11 MISO - D12 CLK - D13 */ #include <SD.h> #include <SPIFlash.h> #define Flash_CS 9 #define SD_CS 10 #define FILENAME "B75PRO31.90" File myFile; SPIFlash flash(Flash_CS); void setup() { Serial.begin(115200); while (!Serial) {} //     //  SD- Serial.println("Initializing SD card..."); if (!SD.begin(SD_CS)) { Serial.println("Initialization SD card failed!"); return; } Serial.println("Initialization done."); if (!SD.exists(FILENAME)) { Serial.print(FILENAME); Serial.println(" doesn't exist."); return; } //     Serial.print("Opening "); Serial.print(FILENAME); Serial.println("..."); myFile = SD.open(FILENAME, FILE_READ); //     -     if (myFile) { Serial.print("File "); Serial.print(FILENAME); Serial.println(" is open."); //  SPI Flash Serial.println("Initializing SPI Flash..."); flash.begin(); //   if (flash.eraseChip()) { Serial.println("Chip erased."); } else { Serial.println("Error erasing chip."); return; } // / /  256  uint8_t data_buffer[256]; //   uint32_t maxPage = flash.getMaxPage(); // Checksum (32 bit) uint32_t checkSum = 0; for (int page = 0; page < maxPage; page++) { //    if ((page % 1000) == 0) { Serial.print(page + 1); Serial.print("/"); Serial.println(maxPage); } //      myFile.read(data_buffer, 256); //     SPI Flash flash.writeByteArray(page, 0, &data_buffer[0], 256); //    for (int i = 0; i < 256; i++) { checkSum += data_buffer[i]; } } //      myFile.close(); //    Serial.print("Checksum-32: 0x"); Serial.println(checkSum, HEX); Serial.println("Done."); } else { //     -     Serial.print("Error opening "); Serial.println(FILENAME); } } void loop() { //   } 


Launched, waited, the sketch brought the checksum, it coincided with the checksum of the original file. But this is the checksum of the file on the memory card, but I need the checksum of the SPI Flash contents.

It was possible to use the first sketch, but wrote a third one, which only counts the checksum of the SPI Flash content using the same algorithm.

ChecksumFlash.ino
 /*  SPI-Flash: CS - D9 MOSI - D11 MISO - D12 CLK - D13 */ #include <SPIFlash.h> #define Flash_CS 9 SPIFlash flash(Flash_CS); void setup() { Serial.begin(115200); while (!Serial) {} //     //   ,    SD- pinMode(10, OUTPUT); digitalWrite(10, HIGH); //  SPI Flash Serial.println("Initializing SPI Flash..."); flash.begin(); //    256  uint8_t data_buffer[256]; //   uint32_t maxPage = flash.getMaxPage(); // Checksum (32 bit) uint32_t checkSum = 0; for (int page = 0; page < maxPage; page++) { //    if ((page % 1000) == 0) { Serial.print(page + 1); Serial.print("/"); Serial.println(maxPage); } //   SPI Flash flash.readByteArray(page, 0, &data_buffer[0], 256); //    for (int i = 0; i < 256; i++) { checkSum += data_buffer[i]; } } //    Serial.print("Checksum-32: 0x"); Serial.println(checkSum, HEX); Serial.println("Done."); } void loop() { //   } 


The SPI Flash checksum matches the checksum of the original file.

After inserting the BIOS firmware into the home computer, it worked smoothly.

In the Arduino IDE, you need to install the SPIFlash library through library management.

Checksum calculated using HX-editor HxD.

PS: Initially, I used the following as an SD module:

But with him there were frequent glitches, the SD card was not initialized. The “hot” reconnection of the SD card itself, with the Arduino connected to the computer, helped.

PPS: Instead of resistors I tried to connect a bidirectional signal converter:

But the scheme did not work with him.

Source: https://habr.com/ru/post/318110/


All Articles