硬件:树莓派2B+、BIOS烧录夹、杜邦线若干、东芝笔记本Satelite L50-AT11W1(BIOS是W25Q64FVSIG)
环境:树莓派装PiLFS(其他系统也行)、WiringPI
网上下载了笔记本的对应BIOS,改了开机logo,用fptw64刷不了,只能用烧录夹刷。
W25Q64是SPI接口,可以用树莓派的GPIO模拟,测试代码如下:
-
#include<wiringPi.h>
-
#include<stdio.h>
-
#include<time.h>
-
//1 /CS GPIO.9(3)
-
//2 DO GPIO.13(9)
-
//3 /WP GPIO.28(20)
-
//4 GND GND
-
//5 DI GPIO.12(10)
-
//6 CLK GPIO.14(11)
-
//7 /HOLD GPIO.40(21)
-
//8 VCC GPIO.8(2)
-
-
#define VCC 2
-
#define CS 3
-
#define DI 10
-
#define DO 9
-
#define CLK 11
-
#define WP 20
-
#define HOLD 21
-
-
void delay_x(int i){
-
int j;
-
for(j=0;j<i;j++);
-
}
-
-
void delay_ms(int i){
-
delay(i);
-
}
-
-
unsigned int spi_read_byte(){
-
int i,data;
-
data=0;
-
for(i=0;i<8;i++){
-
digitalWrite(CLK,0);
-
delay_x(1000);
-
digitalWrite(CLK,1);
-
delay_x(1000);
-
if(digitalRead(DO)){
-
data|=1<<(7-i);
-
}
-
}
-
return data;
-
}
-
-
void spi_write_byte(unsigned int data){
-
int i;
-
for(i=0;i<8;i++){
-
if(data&(1<<(7-i))){
-
digitalWrite(DI,1);
-
}else{
-
digitalWrite(DI,0);
-
}
-
digitalWrite(CLK,0);
-
delay_x(1000);
-
digitalWrite(CLK,1);
-
delay_x(1000);
-
}
-
}
-
-
void spi_id_read(){
-
digitalWrite(CS,0);
-
spi_write_byte(0x9f);
-
printf("%X\n",spi_read_byte());
-
printf("%X\n",spi_read_byte());
-
printf("%X\n",spi_read_byte());
-
digitalWrite(CS,1);
-
}
-
-
void spi_id_read1(){
-
digitalWrite(CS,0);
-
spi_write_byte(0x90);
-
spi_write_byte(0x00);
-
spi_write_byte(0x00);
-
spi_write_byte(0x00);
-
printf("%X\n",spi_read_byte());
-
printf("%X\n",spi_read_byte());
-
digitalWrite(CS,1);
-
}
-
-
void spi_reg_read(){
-
digitalWrite(CS,0);
-
spi_write_byte(0x05);
-
printf("%X\n",spi_read_byte());
-
digitalWrite(CS,1);
-
}
-
-
void spi_reg_read1(){
-
digitalWrite(CS,0);
-
spi_write_byte(0x35);
-
printf("%X\n",spi_read_byte());
-
digitalWrite(CS,1);
-
}
-
-
unsigned int spi_data_read(unsigned int addr){
-
int data;
-
digitalWrite(CS,0);
-
spi_write_byte(0x03);
-
spi_write_byte((addr>>16)&0xff);
-
spi_write_byte((addr>>8)&0xff);
-
spi_write_byte(addr&0xff);
-
data=spi_read_byte();
-
digitalWrite(CS,1);
-
return data;
-
}
-
-
void spi_data_write(unsigned int addr,unsigned int data){
-
digitalWrite(CS,0);
-
spi_write_byte(0x06);
-
digitalWrite(CS,1);
-
delay_ms(1);
-
digitalWrite(CS,0);
-
spi_write_byte(0x02);
-
spi_write_byte((addr>>16)&0xff);
-
spi_write_byte((addr>>8)&0xff);
-
spi_write_byte(addr&0xff);
-
spi_write_byte(data);
-
digitalWrite(CS,1);
-
delay_ms(1);
-
}
-
-
void spi_chip_erase(){
-
digitalWrite(CS,0);
-
spi_write_byte(0x06);
-
digitalWrite(CS,1);
-
delay_ms(1);
-
digitalWrite(CS,0);
-
spi_write_byte(0x60);
-
digitalWrite(CS,1);
-
delay_ms(20000);
-
}
-
-
void spi_reg_clear(){
-
digitalWrite(CS,0);
-
spi_write_byte(0x06);
-
digitalWrite(CS,1);
-
delay_ms(1);
-
digitalWrite(CS,0);
-
spi_write_byte(0x01);
-
spi_write_byte(0x00);
-
spi_write_byte(0x02);
-
digitalWrite(CS,1);
-
delay_ms(1000);
-
}
-
-
int main(){
-
wiringPiSetupGpio();
-
pinMode(VCC,OUTPUT);
-
pinMode(CS,OUTPUT);
-
pinMode(DI,OUTPUT);
-
pinMode(DO,INPUT);
-
pinMode(CLK,OUTPUT);
-
pinMode(WP,OUTPUT);
-
pinMode(HOLD,OUTPUT);
-
-
digitalWrite(VCC,1);
-
digitalWrite(CS,1);
-
digitalWrite(WP,1);
-
digitalWrite(HOLD,1);
-
-
spi_id_read();
-
spi_id_read1();
-
-
spi_reg_read();
-
spi_reg_read1();
-
-
spi_reg_clear();
-
-
return 0;
-
}
编译:
gcc testspi.c -lwiringPi
烧录夹夹上之后,直接读W25Q64的ID发现读出来的都是0x00(试了很多次都是这样),若主板插上电源后再读,读出来的都是0xFF,过几分钟把电源去掉,读出来就正常了(可能是外部电路导致VCC供电不足)。
正式代码如下(刷了几十分钟):
-
#include<wiringPi.h>
-
#include<stdio.h>
-
#include<time.h>
-
#include<string.h>
-
//1 /CS GPIO.9(3)
-
//2 DO GPIO.13(9)
-
//3 /WP GPIO.28(20)
-
//4 GND GND
-
//5 DI GPIO.12(10)
-
//6 CLK GPIO.14(11)
-
//7 /HOLD GPIO.40(21)
-
//8 VCC GPIO.8(2)
-
-
#define VCC 2
-
#define CS 3
-
#define DI 10
-
#define DO 9
-
#define CLK 11
-
#define WP 20
-
#define HOLD 21
-
-
void delay_x(int i){
-
int j;
-
for(j=0;j<i;j++);
-
}
-
-
void delay_ms(int i){
-
delay(i);
-
}
-
-
unsigned int spi_read_byte(){
-
int i,data;
-
data=0;
-
for(i=0;i<8;i++){
-
digitalWrite(CLK,0);
-
delay_x(1000);
-
digitalWrite(CLK,1);
-
delay_x(1000);
-
if(digitalRead(DO)){
-
data|=1<<(7-i);
-
}
-
}
-
return data;
-
}
-
-
void spi_write_byte(unsigned int data){
-
int i;
-
for(i=0;i<8;i++){
-
if(data&(1<<(7-i))){
-
digitalWrite(DI,1);
-
}else{
-
digitalWrite(DI,0);
-
}
-
digitalWrite(CLK,0);
-
delay_x(1000);
-
digitalWrite(CLK,1);
-
delay_x(1000);
-
}
-
}
-
-
unsigned int spi_data_read(unsigned int addr){
-
int data;
-
digitalWrite(CS,0);
-
spi_write_byte(0x03);
-
spi_write_byte((addr>>16)&0xff);
-
spi_write_byte((addr>>8)&0xff);
-
spi_write_byte(addr&0xff);
-
data=spi_read_byte();
-
digitalWrite(CS,1);
-
return data;
-
}
-
-
void spi_data_write(unsigned int addr,unsigned int data){
-
digitalWrite(CS,0);
-
spi_write_byte(0x06);
-
digitalWrite(CS,1);
-
delay_ms(1);
-
digitalWrite(CS,0);
-
spi_write_byte(0x02);
-
spi_write_byte((addr>>16)&0xff);
-
spi_write_byte((addr>>8)&0xff);
-
spi_write_byte(addr&0xff);
-
spi_write_byte(data);
-
digitalWrite(CS,1);
-
}
-
-
void spi_data_read_x(unsigned int addr,unsigned char *data,int size){
-
int i;
-
digitalWrite(CS,0);
-
spi_write_byte(0x03);
-
spi_write_byte((addr>>16)&0xff);
-
spi_write_byte((addr>>8)&0xff);
-
spi_write_byte(addr&0xff);
-
for(i=0;i<size;i++){
-
data[i]=spi_read_byte();
-
}
-
digitalWrite(CS,1);
-
}
-
-
void spi_data_write_x(unsigned int addr,unsigned char *data,int size){
-
int i;
-
digitalWrite(CS,0);
-
spi_write_byte(0x06);
-
digitalWrite(CS,1);
-
delay_ms(1);
-
digitalWrite(CS,0);
-
spi_write_byte(0x02);
-
spi_write_byte((addr>>16)&0xff);
-
spi_write_byte((addr>>8)&0xff);
-
spi_write_byte(addr&0xff);
-
for(i=0;i<size;i++){
-
spi_write_byte(data[i]);
-
}
-
digitalWrite(CS,1);
-
delay_ms(1);
-
}
-
-
void spi_chip_erase(){
-
digitalWrite(CS,0);
-
spi_write_byte(0x06);
-
digitalWrite(CS,1);
-
delay_ms(1);
-
digitalWrite(CS,0);
-
spi_write_byte(0x60);
-
digitalWrite(CS,1);
-
delay_ms(20000);
-
}
-
-
int main(){
-
wiringPiSetupGpio();
-
pinMode(VCC,OUTPUT);
-
pinMode(CS,OUTPUT);
-
pinMode(DI,OUTPUT);
-
pinMode(DO,INPUT);
-
pinMode(CLK,OUTPUT);
-
pinMode(WP,OUTPUT);
-
pinMode(HOLD,OUTPUT);
-
-
digitalWrite(VCC,1);
-
digitalWrite(CS,1);
-
digitalWrite(WP,1);
-
digitalWrite(HOLD,1);
-
-
printf("start\n");
-
-
spi_chip_erase();
-
-
int i,j,l;
-
char data[256],data1[256];
-
FILE *fp;
-
fp=fopen("x.bin","rb");
-
fseek(fp,0,2);
-
l=ftell(fp);
-
printf("file size: %d\n",l);
-
-
fseek(fp,0,0);
-
for(i=0;i<l;i+=256){
-
j=(l-i<256)?(l-i):256;
-
fread(data,1,j,fp);
-
spi_data_write_x(i,data,j);
-
spi_data_read_x(i,data1,j);
-
if(memcmp(data,data1,j)!=0){
-
break;
-
}
-
printf("%d\n",i/256);
-
}
-
-
printf("%s\n",i<l?"wa":"ac");
-
fclose(fp);
-
-
return 0;
-
}
编译:
gcc testspi_bios.c -lwiringPi
这里的代码仅供参考,若笔记本变砖了概不负责(笔记本变砖了不保修)。
阅读(3960) | 评论(0) | 转发(0) |