/* FLSHEXMP.C * * * (c) 1998 Micro/sys, Inc. * Glendale, CA * All rights reserved * * Routines for accessing the 8k parameter block of the Intel Boot Block * flash on the SBC1190 * * Characteristics: * * Erased when EXE * Blk size Address Range file is loaded? * -------- ------------- --------------- * 8k E000:0-E000:1FFF No * * Note: These routines assume that the flash is visible in the * memory map. In order to do this, the chip-select for the flash * is programmed to access 128k starting at address E000:0000. * * The 8k block is accessed between E000:0000 and E000:1FFF. * Do not attempt to program any block outside of this range. * If a memory-mapped card is installed in the range of E000:0000 to * E000:FFFF, it will be inaccessible while the chip-selects * are reprogrammed. * * The characteristics of flash memory are such that each bit can be * programmed from a 1 (erased) to a 0 (programmed), but the only way * to return a bit to a 1 is to erase the entire block. Another * important thing to remember is that flash memory has a limited number * of write/erase cycles. A lifetime of at least 100,000 cycles is * a large number if the only write/erase cycles occur during program * downloads, but it is a short lifetime if a program is constantly * writing to and erasing the same locations. * * */ #include #include #include #include #define PCB 0x0FF00 /* default base address after reset */ #define GCS5SP PCB+0x096 #define UCSST PCB+0x0A4 /* flash */ #define P1LTCH PCB+0x056 /* input/output port unit register */ #ifdef __TURBOC__ #ifndef _enable #define _enable enable #endif #ifndef _disable #define _disable disable #endif #ifndef outpw #define outpw outport #endif #ifndef inpw #define inpw inport #endif #endif #define VPPDISABLE 0x20 #define VPPENABLE (~VPPDISABLE) /* ------------------------------------------------------------------------------ Flash Command Definitions These commands are written to the flash device to run the internal state machine. ------------------------------------------------------------------------------ */ #define C_PROG 0x40 /* enter program state */ #define C_ERASSUSP 0xB0 /* erase suspend */ #define C_ERASSET 0x20 /* erase setup */ #define C_ERASCONF 0xD0 /* erase confirm */ #define C_CLRSTAT 0x50 /* clear status register */ #define C_RDSTATUS 0x70 /* read status register */ #define C_READ 0xFF /* enter read state */ #define C_ID 0x90 /* enter ID state */ /* ------------------------------------------------------------------------------ Flash Status Register Definitions The status register bits show the status of various operations ------------------------------------------------------------------------------ */ #define WRSTATE 0x80 /* write state machine status */ #define ERSUSPSTAT 0x40 /* erase suspend status */ #define ERASESTAT 0x20 /* erase status */ #define PROGSTAT 0x10 /* program status */ #define VPPSTATUS 0x08 /* Vpp status */ /* ------------------------------------------------------------------------------ Flash Program/Erase Errors Error return values for program or erase routines ------------------------------------------------------------------------------ */ #define E_VPPLOW -50 #define E_CMD -51 #define E_BLKERAS -52 #define E_BYTEPROG -53 #define NOERROR 0 /* ------------------------------------------------------------------------------ Flash Memory IDs ID number ------------------------------------------------------------------------------ */ #define FL28F200 0x8974 #define FL28F400 0x8970 #define SEG1START 0x8000 #define SEG2START 0xA000 #define SEG3START 0xC000 /* ------------------------------------------------------------------------------ Vpp On/Off ------------------------------------------------------------------------------ */ #define VPPON 1 #define VPPOFF 0 /* --------------------------------------------------------------------- WATCHDOG TIMER PORT --------------------------------------------------------------------- */ #define WDTMR 0xFE4C /* write only */ /*--------------------------------------------------------------------------- * int Vpp(int vppstate) * * This routine enables writes to the flash. * * * On entry: vppstate is 0 to disable writes to the flash or * 1 to enable writes to the flash. * * On exit: - * * Returns: - * *--------------------------------------------------------------------------*/ int Vpp(int vppstate) { if (vppstate == VPPON) { outp(P1LTCH, inp(P1LTCH) & VPPENABLE); } else outp(P1LTCH, inp(P1LTCH) | VPPDISABLE); return 0; } /*--------------------------------------------------------------------------- * unsigned GetFlashID(unsigned flshblkseg) * * This routine gets the manufacturer ID of the flash device. * * * On entry: flshblkseg is the segment at which the flash resides. * * On exit: - * * Returns: the flash ID * *--------------------------------------------------------------------------*/ unsigned GetFlashID(unsigned flshblkseg) { unsigned char mfg, device; unsigned int id; unsigned char far *EPROM; EPROM =(unsigned char far *)((unsigned long)flshblkseg<<16); _disable(); /* disable interrupts */ Vpp(VPPON); /* writes must be enabled to send commands */ *(EPROM+3) = C_ID; /* send the command to read the ID */ mfg = *EPROM; /* read the manufacturer code */ *(EPROM+3) = C_ID; /* send the command to read the ID */ device = *(EPROM+2); /* read the device type */ id = ((unsigned int)mfg<<8) + (unsigned int)device; *EPROM = C_READ; /* put flash back in read mode */ Vpp(VPPOFF); /* disable writes to protect the flash */ _enable(); /* enable interrupts */ return(id); /* get flash ID */ } /*--------------------------------------------------------------------------- * int EraseBlock(unsigned flshblkseg) * * This routine erases a block in the flash. * * * On entry: flshblkseg is the segment of the flash block that should * be erased. * * On exit: - * * Returns: 0 if no error * an error code if an error occurs * *--------------------------------------------------------------------------*/ int EraseBlock(unsigned flshblkseg) { unsigned char status; unsigned char far *flshblk; int error, n; flshblk =(unsigned char far *)((unsigned long)flshblkseg<<16); Vpp(VPPON); _disable(); /* disable interrupts */ *flshblk = C_ERASSET; /* erase setup */ *flshblk = C_ERASCONF; /* erase confirm */ for(n=0;;n++) { outp(WDTMR, 0); /* strobe watchdog timer */ status = *flshblk; /* read the status */ if (status & WRSTATE) /* keep polling register until done */ { #ifdef DEBUG printf("status = %02X, n=%d\n", status, n); #endif break; } } if (status & VPPSTATUS) error = E_VPPLOW; else if ((status & PROGSTAT) &&(status & ERASESTAT)) error = E_CMD; else if (status & ERASESTAT) error = E_BLKERAS; else error = NOERROR; if (error) *flshblk = C_CLRSTAT; /* clear status register if needed */ *flshblk = C_READ; /* put flash back in read mode */ _enable(); /* enable interrupts */ Vpp(VPPOFF); return(error); } /*--------------------------------------------------------------------------- * int ProgFlash(unsigned char *datablk, unsigned flshblkseg, int numbytes) * * This routine programs a block of data into the flash. * * * On entry: datablk is a pointer to an array of data to program into * the flash. * flshblkseg is the segment of the flash into which * the data should be programmed. * numbytes is the number of bytes of data that should * be programmed. * * On exit: - * * Returns: 0 if no error * an error code if an error occurs * *--------------------------------------------------------------------------*/ int ProgFlash(unsigned char *datablk, unsigned flshblkseg, int numbytes) { unsigned char status; unsigned char far *flshaddr; int error, n, m; Vpp(VPPON); flshaddr =(unsigned char far *)((unsigned long)flshblkseg<<16); _disable(); /* disable interrupts */ for (n=0; n