/* ----------------------------------------------------------------------------- * Copyright (c) 2014 ARM Ltd. * * This software is provided 'as-is', without any express or implied warranty. * In no event will the authors be held liable for any damages arising from * the use of this software. Permission is granted to anyone to use this * software for any purpose, including commercial applications, and to alter * it and redistribute it freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software in * a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source distribution. * * * $Date: 15. April 2014 * $Revision: V1.00 * * Project: Flash Programming Functions for Micron M29W640Fx * --------------------------------------------------------------------------- */ /* History: * Version 1.00 * Initial release */ #include "..\FlashOS.H" // FlashOS Structures #define M8(adr) (*((volatile unsigned char *) (adr))) #define M16(adr) (*((volatile unsigned short *) (adr))) #define M32(adr) (*((volatile unsigned long *) (adr))) #define STACK_SIZE 64 // Stack Size union fsreg { // Flash Status Register struct b { unsigned int q0:1; unsigned int q1:1; unsigned int q2:1; // alternative toggle bit unsigned int q3:1; // erase timer bit unsigned int q4:1; unsigned int q5:1; // error bit unsigned int q6:1; // toggle bit unsigned int q7:1; // data polling bit } b; unsigned int v; } fsr; unsigned long base_adr; /* * Check if Program/Erase completed using the toggle bit * Parameter: adr: Block Start Address * Return Value: 0 - OK, 1 - Failed */ int Polling (unsigned long adr) { unsigned int q6; fsr.v = M16(adr); q6 = fsr.b.q6; do { fsr.v = M16(adr); if (fsr.b.q6 == q6) return (0); // Done q6 = fsr.b.q6; // if (fsr.b.q3 == 1) break; // VPP not high enough } while (fsr.b.q5 == 0); // Check for Timeout fsr.v = M16(adr); q6 = fsr.b.q6; fsr.v = M16(adr); if (fsr.b.q6 == q6) return (0); // Done M16(adr) = 0xF0; // Reset Device return (1); // Failed } /* * Initialize Flash Programming Functions * Parameter: adr: Device Base Address * clk: Clock Frequency (Hz) * fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify) * Return Value: 0 - OK, 1 - Failed */ int Init (unsigned long adr, unsigned long clk, unsigned long fnc) { base_adr = adr; return (0); } /* * De-Initialize Flash Programming Functions * Parameter: fnc: Function Code (1 - Erase, 2 - Program, 3 - Verify) * Return Value: 0 - OK, 1 - Failed */ int UnInit (unsigned long fnc) { return (0); } /* * Erase complete Flash Memory * Return Value: 0 - OK, 1 - Failed */ int EraseChip (void) { // Start Chip Erase Command M16(base_adr + (0x0555 << 1)) = 0xAA; M16(base_adr + (0x0AAA << 1)) = 0x55; M16(base_adr + (0x0555 << 1)) = 0x80; M16(base_adr + (0x0555 << 1)) = 0xAA; M16(base_adr + (0x0AAA << 1)) = 0x55; M16(base_adr + (0x0555 << 1)) = 0x10; return (Polling(base_adr)); // Wait until Erase completed } /* * Erase Sector in Flash Memory * Parameter: adr: Sector Address * Return Value: 0 - OK, 1 - Failed */ int EraseSector (unsigned long adr) { // Start Erase Sector Command M16(base_adr + (0x0555 << 1)) = 0xAA; M16(base_adr + (0x0AAA << 1)) = 0x55; M16(base_adr + (0x0555 << 1)) = 0x80; M16(base_adr + (0x0555 << 1)) = 0xAA; M16(base_adr + (0x0AAA << 1)) = 0x55; M16(adr) = 0x30; return (Polling(adr)); // Wait until Erase completed } /* * Program Page in Flash Memory * Parameter: adr: Page Start Address * sz: Page Size * buf: Page Data * Return Value: 0 - OK, 1 - Failed */ int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) { int i; for (i = 0; i < ((sz+1)/2); i++) { // Start Program Command M16(base_adr + (0x0555 << 1)) = 0xAA; M16(base_adr + (0x0AAA << 1)) = 0x55; M16(base_adr + (0x0555 << 1)) = 0xA0; M16(adr) = *((unsigned short *) buf); if (Polling(adr) != 0) return (1); buf += 2; adr += 2; } return (0); }