/********************************************************************* * jl16-8.c - Demonstrate reading and writing to FLASH memory * * The program is based mostly on Freescale application note * AN2874 and is an example of using the ROM routines to read * and write to the processor's flash memory. * * This program stores one of three text strings in FLASH * memory and then reads it back and reports the results out the * RS-232 interface. * * If the button is not pressed it reads the string that is * currently in the FLASH memory. * If the button on PTA1 is pressed it reads the current string * from memory, then overwrites it with the next string, and * reads the new string back. * * * Revision History * Date Author Description * 04/22/11 A. Weber Initial release * 05/29/13 A. Weber Renamed CWJL-8.c to jl16-8.c *********************************************************************/ #include #include /* for EnableInterrupts macro */ #include "derivative.h" /* include peripheral declarations */ #include /* ROM Resident Routines Pointer Definitions */ #define ERARNGE 0xFCBE /* FLASH erase routine in internal ROM */ #define PRGRNGE 0xFC06 /* FLASH program routine in internal ROM */ #define LDRNGE 0xFF30 /* Load FLASH data into RAM data array */ void FLASHProgram(void); void FLASHErase(void); void FLASHLoad(void); /* RAM Data Block */ /* Note: putting this in zero-page memory did not work for some reason */ struct flashblock { unsigned char bspd; /* Value should equal 4x Bus speed */ unsigned char size; /* Number of bytes in data array (max 255) */ unsigned int addr; /* Start address of FLASH to manipulate */ unsigned char data[32]; /* Data to program into FLASH */ } fb; struct flashblock *flashptr; /* Address of RAM DATA Block */ void sci_init(unsigned char, unsigned char); void sci_out(unsigned char); void sci_outs(unsigned char *); /* Test strings to store in the EEPROM */ char *strs[] = { "1: EE459Lx jl16-8.c - 4/22/11", "2: ABCDEFGHIJKLMNOPQRSTUVWXYZ", "3: Testing the JL16 FLASH ROM" }; unsigned char ostr[80]; // Buffer for creating strings to go out SCI void main(void) { unsigned char one = 1; unsigned char n; CONFIG1_COPD = 1; // Disable COP reset //FLBPR = 0xFF; // FLASH Protection Register (unprotect ALL FLASH) PTAPUE_PTAPUE1 = 1; // Enable pull-up for switch on PTA1 DDRA_DDRA1 = 0; // Switch input on PTA1; /* Set SCI rate for 9600 baud. Assumes a 9.8304MHz clock */ sci_init(0, 2); // Initialize the SCI port /* RAM DATA Initialization */ fb.bspd = 10; // (9.830MHz / 4) * 4 = 10 fb.size = 32; // Data size to be programmed fb.addr = 0xEF00; // Address of where data is read/written in Flash flashptr = &fb; // Pointer to flash data block sci_outs("\r\njl16-8.c\r\n"); // Read the data at the address. Stored string should be 31 characters or less. (void) memset(&fb.data, 0, 32); FLASHLoad(); (void) sprintf(ostr, "Read \"%s\" from FLASH at %04x\r\n", &fb.data, fb.addr); sci_outs(ostr); if (PTA_PTA1 == 0) { // If button down, write data // Figure out which string is there now and write a different one n = fb.data[0] - '0' - 1; if (n < 3) { // Should be 0, 1 or 2 for the strings above n++; if (n >= 3) n = 0; (void) strncpy(&fb.data, strs[n], 32); } else (void) strncpy(&fb.data, strs[0], 32); // Write data at the address (void) sprintf(ostr, "Erasing FLASH at %04x\r\n", fb.addr); sci_outs(ostr); FLASHErase(); // Erase Page (void) sprintf(ostr, "Storing \"%s\" in FLASH at %04x\r\n", &fb.data, fb.addr); sci_outs(ostr); FLASHProgram(); // Program DATA Buffer into FLASH // Read back the data just written (void) memset(&fb.data, 0, 32); FLASHLoad(); (void) sprintf(ostr, "Read \"%s\" from FLASH at %04x\r\n", &fb.data, fb.addr); sci_outs(ostr); } else { (void) sprintf(ostr, "Bypassing storing data\r\n"); sci_outs(ostr); } while (one) { // Loop forever } } /* FLASHProgram: flashptr->size locations starting from flashptr->addr will be programmed. */ void FLASHProgram(void){ asm(LDHX flashptr); /* Load address of RAM Data Block to H:X */ asm(JSR PRGRNGE); /* Call PRGRNGE ROM Subroutine */ } /* FLASHErase: Erase a 64-byte page in FLASH specified by flashptr->addr */ void FLASHErase(void){ asm(LDHX flashptr); /* Load address of RAM Data Block to H:X */ asm(JSR ERARNGE); /* Call ERARNGE ROM Subroutine */ } /* FLASHLoad: Load flashptr->size locations from FLASH to flashptr->addr */ void FLASHLoad(void){ asm(LDHX flashptr); /* Load address of RAM Data Block to H:X */ asm(JSR LDRNGE); /* Call LDRNGE ROM Subroutine */ } /* ----------------------------------------------------------------------- */ /* sci_init - Initialize the SCI port */ void sci_init(unsigned char scp, unsigned char scr) { SCC1_ENSCI = 1; // Enable SCI SCBR_SCP = scp; // Baud rate prescaler SCBR_SCR = scr; // Baud rate divisor SCC2_TE = 1; // Enable transmitter } /* sci_out - Output a byte to SCI port */ void sci_out(unsigned char ch) { while (SCS1_SCTE == 0); SCDR = ch; } /* sci_outs - Print the contents of the character string "s" out the SCI port. The string must be terminated by a zero byte. */ void sci_outs(unsigned char *s) { unsigned char ch; while ((ch = *s++) != (unsigned char) NULL) sci_out(ch); }