Algún cambio en la forma de leer los datos y algo mas ordenado.
Código:
// Flaspi-Beta-03; del tipo de flaps pero para ir directamente a la S25FL016A.
//
// Default is Compile for Linux (both #define's below should be commented out)
// #define WINDOWS_VERSION // descomentar esta linea para compilar en Windows
// #define __FreeBSD__ // uncomment only this for FreeBSD
#ifdef WINDOWS_VERSION
#include <windows.h> // Only for Windows Compile
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define OUT_PORT _outp(p_base, data)
#define IN_PORT data_read = (unsigned char)_inp(p_base + 1)
#endif
#ifndef WINDOWS_VERSION
#include <unistd.h>
#include <sys/ioctl.h>
#define OUT_PORT ioctl(pfd, PPWDATA, &data)
#define IN_PORT ioctl(pfd, PPRSTATUS, &data_read)
#ifdef __FreeBSD__
#include <dev/ppbus/ppi.h>
#include <dev/ppbus/ppbconf.h>
#define PPWDATA PPISDATA
#define PPRSTATUS PPIGSTATUS
#else
#include <linux/ppdev.h>
#endif
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
/*
* The followint table shows the pin assignment of 25-pin Parallel Printer Port.
* please refer to IEEE 1284 standard for detailed description.
* data port (Out) (0x378) status port (In) (0x379)
* bit[7] -- pin9 (Out) bit[7] -- pin11 (In), busy (Hardware Inverted)
* bit[6] -- pin8 (Out) bit[6] -- pin10 (In), Ack
* bit[5] -- pin7 (Out) bit[5] -- pin12 (In), Paper out
* bit[4] -- pin6 (Out) bit[4] -- pin13 (In), Select
* bit[3] -- pin5 (Out) bit[3] -- pin15 (In), Error
* bit[2] -- pin4 (Out) bit[2] -- IRQ(Not)
* bit[1] -- pin3 (Out) bit[1] -- Reserved
* bit[0] -- pin2 (Out) bit[0] -- Reserved
*/
// --- Cable ---
#define SI 2 // Pin4
#define SCK 1 // Pin3
#define CS 0 // Pin2
#define SO 4 // Pin13
// ---- Comands S25FL016A ----
#define READ 0x03
#define FAST_READ 0x0B
#define RDID 0x9F
#define WREN 0x06
#define WRDI 0x04
#define SE 0xD8
#define PP 0x02
#define RDSR 0x05
#define WRSR 0x01
#define DP 0xB9
#define RES 0xAB
// ---- Mask Status register bits S25FL016A ----
#define SRWD 0x80
#define BP2 0x10
#define BP1 0x08
#define BP0 0x04
#define WEL 0x02
#define WIP 0x01
int pfd;
int p_base = 0x378;
unsigned int start = 0x00;
unsigned int length = 0x10000;
char filename[] = "FILE";
int bit = 0;
int block_total = 32;
// -----------------------------------------
// ---- Start of Compiler Specific Code ----
// -----------------------------------------
void lpt_openport(void)
{
#ifdef WINDOWS_VERSION // ---- Compiler Specific Code ----
HANDLE h;
h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(h == INVALID_HANDLE_VALUE) { printf("Couldn't access giveio device\n"); CloseHandle(h); exit(0); }
CloseHandle(h);
#else // ---- Compiler Specific Code ----
#ifdef __FreeBSD__ // ---- Compiler Specific Code ----
pfd = open("/dev/ppi0", O_RDWR);
if (pfd < 0) { perror("Failed to open /dev/ppi0"); exit(0); }
if ((ioctl(pfd, PPEXCL) < 0) || (ioctl(pfd, PPCLAIM) < 0)) { perror("Failed to lock /dev/ppi0"); close(pfd); exit(0); }
#else // ---- Compiler Specific Code ----
pfd = open("/dev/parport0", O_RDWR);
if (pfd < 0) { perror("Failed to open /dev/parport0"); exit(0); }
if ((ioctl(pfd, PPEXCL) < 0) || (ioctl(pfd, PPCLAIM) < 0)) { perror("Failed to lock /dev/parport0"); close(pfd); exit(0); }
#endif
#endif
}
void lpt_closeport(void)
{
#ifndef WINDOWS_VERSION // ---- Compiler Specific Code ----
#ifndef __FreeBSD__ // ---- Compiler Specific Code ----
if (ioctl(pfd, PPRELEASE) < 0) { perror("Failed to release /dev/parport0"); close(pfd); exit(0); }
#endif
close(pfd);
#endif
}
// ---------------------------------------
// ---- End of Compiler Specific Code ----
// ---------------------------------------
static unsigned char clockin(int si)
{
unsigned char data, data_read;
si = si ? 1 : 0;
data = (0 << SCK) | (0 << CS) | (si << SI); OUT_PORT; // SCK Down
IN_PORT; data_read >>=SO; data_read &= 1;
data = (1 << SCK) | (0 << CS) | (si << SI); OUT_PORT; // SCK Up
//usleep(1);
return data_read;
}
void init_port(void)
{
unsigned char data;
data = 0 | (1 << CS); OUT_PORT;
}
static unsigned int ReadWriteByte(unsigned int in_data)
{
int i;
unsigned int out_data = 0;
unsigned char out_bit;
for(i = 0 ; i < 8 ; i++)
{
out_bit = clockin(((in_data << i) & 0x80));
out_data = out_data | (out_bit << (7-i));
}
return out_data;
}
void WriteData(unsigned int in_data)
{
ReadWriteByte(in_data);
}
static unsigned int ReadData(void)
{
return ReadWriteByte(0x00);
}
void flash_erase_area(unsigned int start, unsigned int length)
{
unsigned int addr0, addr1,addr2, data;
int cur_block;
int tot_blocks, block_addr;
unsigned int reg_start;
unsigned int reg_end;
reg_start = start;
reg_end = reg_start + length;
tot_blocks = (((length-1 ) >> 16) & 0xff) +1;
printf("Total Blocks to Erase: %d\n\n", tot_blocks);
for (cur_block = 0; cur_block < tot_blocks; cur_block++)
{
block_addr = start + (cur_block << 16);
printf("Erasing block: %d (addr = %08x)...",block_addr >> 16 , block_addr); fflush(stdout);
addr0 = (block_addr & 0xff);
addr1 = (block_addr >> 8 & 0xff);
addr2 = (block_addr >> 16 & 0xff);
WriteData(WREN);
data = (1 << CS) ; OUT_PORT; //CS => Up
WriteData(SE);
WriteData(addr2);
WriteData(addr1);
WriteData(addr0);
WriteData(RDSR);
while ( (ReadData() & WIP) != WIP ); //Espera a que se termine la escritura
printf("Done\n"); fflush(stdout);
}
WriteData(WRDI);
data = (1 << CS) ; OUT_PORT; //CS => Up
}
void flash_read( unsigned int start, unsigned int length)
{
unsigned int addr, addr0, addr1,addr2, data;
FILE *fd;
int counter = 0;
int percent_complete = 0;
char newfilename[128] = "";
time_t start_time = time(0);
time_t end_time, elapsed_seconds;
struct tm* lt = localtime(&start_time);
char time_str[15];
sprintf(time_str, "%04d%02d%02d_%02d%02d%02d",
lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday,
lt->tm_hour, lt->tm_min, lt->tm_sec
);
printf("*** You Selected to Backup the %s ***\n\n",filename);
strcpy(newfilename,filename);
strcat(newfilename,".SAVED");
/*if (issue_timestamp)
{
strcat(newfilename,"_");
strcat(newfilename,time_str);
} */
fd = fopen(newfilename, "wb" );
if (fd<=0)
{
fprintf(stderr,"Could not open %s for writing\n", newfilename);
exit(1);
}
printf("=========================\n");
printf("Backup Routine Started\n");
printf("=========================\n");
printf("\nSaving %s to Disk...\n",newfilename);
addr0 = (start & 0xff);
addr1 = (start >> 8 & 0xff);
addr2 = (start >> 16 & 0xff);
WriteData(READ);
WriteData(addr2);
WriteData(addr1);
WriteData(addr0);
for(addr=start; addr<(start+length); addr++)
{
counter++;
percent_complete = (counter * 100 / length);
if ((addr&0xF) == 0) printf("[%3d%% Backed Up] %08x: ", percent_complete, addr);
data = ReadData(); // leemos byte de la memoria
fwrite( (unsigned char*) &data, 1, 1, fd); // Lo escribimos en el archivo
printf("%02x%c", data, (addr&0xF)==(0xf)?'\n':' '); // Presentamos en pantalla
fflush(stdout);
}
data = (1 << CS) ; OUT_PORT; //CS => Up
fclose(fd);
printf("Done (%s saved to Disk OK)\n\n",newfilename);
printf("bytes written: %d\n", counter);
printf("=========================\n");
printf("Backup Routine Complete\n");
printf("=========================\n");
time(&end_time);
elapsed_seconds = difftime(end_time, start_time);
printf("elapsed time: %d seconds\n", (int)elapsed_seconds);
}
void flash_write(unsigned int start, unsigned int length)
{
unsigned int addr, addr0, addr1,addr2, data, index;
FILE *fd ;
int counter = 0;
int percent_complete = 0;
time_t start_time = time(0);
time_t end_time, elapsed_seconds;
char newfilename[128] = "";
strcpy(newfilename,filename);
strcat(newfilename,".BIN");
printf("*** You Selected to Flash the %s ***\n\n", newfilename);
fd=fopen(newfilename, "rb" );
if (fd<=0)
{
fprintf(stderr,"Could not open %s for reading\n", newfilename);
exit(1);
}
printf("=========================\n");
printf("Flashing Routine Started\n");
printf("=========================\n");
printf("\nLoading %s to Flash Memory...\n",newfilename);
WriteData(WREN);
data = (1 << CS) ; OUT_PORT; //CS => hig
for(addr=start; addr<(start+length); addr += 256)
{
addr0 = (start & 0xff);
addr1 = (start >> 8 & 0xff);
addr2 = (start >> 16 & 0xff);
WriteData(PP);
WriteData(addr2);
WriteData(addr1);
WriteData(addr0);
for(index=0; index < 256; index++)
{
counter++;
percent_complete = (counter * 100 / length);
// if (!silent_mode)
if ((index&0xF) == 0) printf("[%3d%% Flashed ] %08x: ", percent_complete, addr+index);
fread( (unsigned char*) &data, 1, 1, fd);
printf("%02x%c", data&0xFF, (index&0xf)==(0xf)?'\n':' ');
WriteData(data);
}
data = (1 << CS) ; OUT_PORT; //CS => hig
WriteData(RDSR);
while ( (ReadData() & WIP) != WIP ); //Espera a que se termine la escritura de la pagina
printf("\n");
}
WriteData(WRDI);
fclose(fd);
printf("Done (%s loaded into Flash Memory OK)\n\n",newfilename);
printf("=========================\n");
printf("Flashing Routine Complete\n");
printf("=========================\n");
time(&end_time);
elapsed_seconds = difftime(end_time, start_time);
printf("elapsed time: %d seconds\n", (int)elapsed_seconds);
}
int main(int argc, char** argv)
{
char choice[128];
lpt_openport();
init_port();
printf("\n");
printf("===========================================\n");
printf("FLASPI s25fl016a Flash Utility BETA-0.3\n");
printf("===========================================\n\n");
if (argc < 2)
{ printf("\n\n *** LOS COMANDOS SON: -erase -write -read ***\n\n");
exit(1);
}
strcpy(choice,argv[1]);
if (strcasecmp(choice,"-erase")==0)
{ flash_erase_area(start, length);
exit(0);
}
if (strcasecmp(choice,"-read")==0)
{ flash_read(start, length);;
exit(0);
}
if (strcasecmp(choice,"-write")==0)
{ flash_erase_area(start, length);
flash_write(start, length);;
exit(0);
}
printf("\n\n *** NO HA INTRODUCIDO UNA OPCION VALIDA ***\n\n");
lpt_closeport();
return 0;
}
// **************************************************************************
// End of File
// **************************************************************************