//--------------------------------------------------------- // Spansion S29GLxxxM MirrorBit Flash: XJEase device file // S29GLxxxM.xje Revision: 1.21 // (c)2001-2008 XJTAG Limited // // Disclaimer: XJTAG makes no guarantees whatsoever // about this code. You use it at your own risk ... // This code requires XJTAG version 1.4 or later. // // This file tests Non-JTAG Flash using TestNonDestructive()(INT result) // TestDestructive()(INT result) //--------------------------------------------------------- // This file covers the whole S29GLxxxM family of Flash // devices. Select all the appropriate package options // for your device before running the code. //--------------------------------------------------------- DEVICE NAME := "S29GLxxxM" PINS /* // 40-pin TSOP ADDR := 29, 38, 37, 13, 40, 1, 2, 3, 4, 5, 6, 36, 7, 8, 14, 15, 16, 17, 18, 19, 20, 21; DATA := 35, 34, 33, 32, 28, 27, 26, 25; NWE := 9; NCE := 22; NOE := 24; RDY := 12; NRESET := 10; // 48-pin TSOP // word mode ADDR := 13, 10, 9, 16, 17, 48, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24, 25; DATA := 45, 43, 41, 39, 36, 34, 32, 30, 44, 42, 40, 38, 35, 33, 31, 29; // byte mode : remember to set NYBTE low and change to byte mode commands. //ADDR := 13, 10, 9, 16, 17, 48, 1, 2, 3, 4, 5, 6, 7, 8, 18, 19, 20, 21, 22, 23, 24, 25, 45; //DATA := 44, 42, 40, 38, 35, 33, 31, 29; NWE := 11; NCE := 26; NOE := 28; RDY := 15; NRESET := 12; BYTE := 47; // 48-pin TSOP (model R0) ADDR := 2, 35, 44, 43, 15, 46, 3, 4, 5, 6, 7, 8, 42, 9, 10, 16, 17, 18, 19, 20, 21, 22, 27; DATA := 41, 40, 39, 38, 34, 33, 32, 31; NWE := 11; NCE := 28; NOE := 30; RDY := 14; NRESET := 12; // 56-pin TSOP // word mode ADDR := 1, 2, 15, 12, 11, 18, 19, 54, 3, 4, 5, 6, 7, 8, 9, 10, 20, 21, 22, 23, 24, 25, 26, 31; DATA := 51, 49, 47, 45, 42, 40, 38, 36, 50, 48, 46, 44, 41, 39, 37, 35; // byte mode : remember to set NYBTE low and change to byte mode commands. //ADDR := 1, 2, 15, 12, 11, 18, 19, 54, 3, 4, 5, 6, 7, 8, 9, 10, 20, 21, 22, 23, 24, 25, 26, 31, 51; //DATA := 50, 48, 46, 44, 41, 39, 37, 35; NWE := 13; NCE := 32; NOE := 34; RDY := 17; NRESET := 14; BYTE := 53; */ // 64-ball fortified BGA // word mode ADDR := C8, B8, C5, D4, D5, C4, B3, E7, D7, C7, A7, B7, D6, C6, A6, B6, A3, C3, D3, B2, A2, C2, D2, E2; DATA := G7, F6, G6, F5, G4, F4, G3, F3, E6, H6, E5, H5, H4, E4, H3, E3; // byte mode : remember to set NYBTE low and change to byte mode commands. //ADDR := C8, B8, C5, D4, D5, C4, B3, E7, D7, C7, A7, B7, D6, C6, A6, B6, A3, C3, D3, B2, A2, C2, D2, E2, G7; //DATA := E6, H6, E5, H5, H4, E4, H3, E3; NWE := A5; NCE := F2; NOE := G2; RDY := A4; NRESET := B5; BYTE := F7; /* // 63-ball fine-pitch BGA // word mode ADDR := E5, F4, F5, E4, D3, G7, F7, E7, C7, D7, F6, E6, C6, D6, C3, E3, F3, D2, C2, E2, F2, G2; DATA := J7, H6, J6, H5, J4, H4, J3, H3, G6, K6, G5, K5, K4, G4, K3, G3; // byte mode : remember to set NYBTE low and change to byte mode commands. //ADDR := E5, F4, F5, E4, D3, G7, F7, E7, C7, D7, F6, E6, C6, D6, C3, E3, F3, D2, C2, E2, F2, G2, J7; //DATA := G6, K6, G5, K5, K4, G4, K3, G3; NWE := C5; NCE := H2; NOE := J2; RDY := C4; NRESET := D5; BYTE := H7; // 48 ball fine-pitch BGA // word mode ADDR := B2, E6, D6, C6, A6, B6, D5, C5, A5, B5, A2, C2, D2, B1, A1, C1, D1, E1; DATA := G6, F5, G5, F4, G3, F3, G2, F2, E5, H5, E4, H4, H3, E3, H2, E2; // byte mode : remember to set NYBTE low and change to byte mode commands. //ADDR := B2, E6, D6, C6, A6, B6, D5, C5, A5, B5, A2, C2, D2, B1, A1, C1, D1, E1, G6; //DATA := E5, H5, E4, H4, H3, E3, H2, E2; NWE := A4; NCE := F1; NOE := G1; RDY := A3; NRESET := B4; BYTE := F6; // 48 ball fine-pitch BGA (model R0) ADDR := E6, D6, C6, A6, B6, D5, C5, F5, A5, B5, A2, C2, D2, B1, A1, C1, D1, E1; DATA := H5, G5, E4, H4, F3, E3, H2, E2; NWE := A4; NCE := F1; NOE := G1; RDY := A3; NRESET := B4; */ END; DISABLE DEVICE NCE := 1; NOE := 1; END; TEST COVERAGE ADDR := OPEN SHORTS LO HI; DATA := OPEN SHORTS LO HI; NWE := OPEN LO HI; NCE := OPEN LO HI; NOE := OPEN LO HI; END; // Additional files FILES "memtestFlash.xje"; //"DataReader.xje"; END; END; /* // Commands: x8 INT ADDR_UNLOCK_1 := 0xAAA; INT ADDR_UNLOCK_2 := 0x555; INT ADDR_AUTOSELECT := 0xAAA; INT ADDR_PROGRAM := 0xAAA; INT ADDR_ERASE_SETUP := 0xAAA; INT ADDR_ERASE := 0xAAA; INT ADDR_ABORT_PROG := 0xAAA; INT ADDR_DEV_ID0 := 0x02; INT ADDR_DEV_ID1 := 0x1C; INT ADDR_DEV_ID2 := 0x1E; */ // Commands: x16 INT ADDR_UNLOCK_1 := 0x555; INT ADDR_UNLOCK_2 := 0x2AA; INT ADDR_AUTOSELECT := 0x555; INT ADDR_PROGRAM := 0x555; INT ADDR_ERASE_SETUP := 0x555; INT ADDR_ERASE := 0x555; INT ADDR_ABORT_PROG := 0x555; INT ADDR_DEV_ID0 := 0x01; INT ADDR_DEV_ID1 := 0x0E; INT ADDR_DEV_ID2 := 0x0F; // Commands: x8 and x16 INT DATA_UNLOCK_1 := 0xAA; INT DATA_UNLOCK_2 := 0x55; INT DATA_AUTOSELECT := 0x90; INT DATA_PROGRAM := 0xA0; INT DATA_ERASE_SETUP := 0x80; INT DATA_ERASE_ALL := 0x10; INT DATA_ERASE_SEC := 0x30; INT ADDR_MAN_ID := 0x00; INT DATA_WRITETOBUF := 0x25; INT DATA_PROGBUF := 0x29; INT ABORT_PROGBUF := 0xF0; //INT MANUFACTURER_ID := 0x0001; // Spansion INT MANUFACTURER_ID := 0x0020; // ST // M29W128FX IDs: x8 //INT DEVICE_ID := 0x7E128A; // M29W128FH //INT DEVICE_ID := 0x7E128B; // M29W128FL // M29W128FX IDs: x16 //INT DEVICE_ID := 0x227E2212228A; // M29W128FH INT DEVICE_ID := 0x227E2212228B; // M29W128FL /* // S29GLxxxM IDs: x8 INT DEVICE_ID := 0x7E1C00; // S26GL032M R0 //INT DEVICE_ID := 0x7E1D00; // S26GL032M R1, R2 //INT DEVICE_ID := 0x7E1A00; // S26GL032M R4 //INT DEVICE_ID := 0x7E1A01; // S26GL032M R3 //INT DEVICE_ID := 0x7E1C00; // S26GL032M R6 //INT DEVICE_ID := 0x7E1C01; // S26GL032M R5 //INT DEVICE_ID := 0x7E1300; // S26GL064M R0 //INT DEVICE_ID := 0x7E0C01; // S26GL064M R1, R2, R8, R9 //INT DEVICE_ID := 0x7E1000; // S26GL064M R4 //INT DEVICE_ID := 0x7E1001; // S26GL064M R3 //INT DEVICE_ID := 0x7E1301; // S26GL064M R5, R6, R7 //INT DEVICE_ID := 0x7E1200; // S26GL128M //INT DEVICE_ID := 0x7E1201; // S26GL256M */ // S29GLxxxM IDs: x16 //INT DEVICE_ID := 0x227E221C2200; // S26GL032M R0 //INT DEVICE_ID := 0x227E221D2200; // S26GL032M R1, R2 //INT DEVICE_ID := 0x227E221A2200; // S26GL032M R4 //INT DEVICE_ID := 0x227E221A2201; // S26GL032M R3 //INT DEVICE_ID := 0x227E221C2200; // S26GL032M R6 //INT DEVICE_ID := 0x227E221C2201; // S26GL032M R5 //INT DEVICE_ID := 0x227E22132200; // S26GL064M R0 //INT DEVICE_ID := 0x227E220C2201; // S26GL064M R1, R2, R8, R9 //INT DEVICE_ID := 0x227E22102200; // S26GL064M R4 //INT DEVICE_ID := 0x227E22102201; // S26GL064M R3 //INT DEVICE_ID := 0x227E22132201; // S26GL064M R5, R6, R7 //INT DEVICE_ID := 0x227E22122200; // S26GL128M //INT DEVICE_ID := 0x227E22122201; // S26GL256M CONST INT BUFFER_LENGTH := 0x10; // double if 8 bit wide data bus ? CONST INT ADDR_BUS_WIDTH := WIDTHOF(ADDR); CONST INT DATA_BUS_WIDTH := WIDTHOF(DATA); CONST INT BLOCK_LENGTH := (0x10000/DATA_BUS_WIDTH)*8; // For boot sector devices, use larger block size CONST INT FLASH_SIZE := (1<<ADDR_BUS_WIDTH)*DATA_BUS_WIDTH; CONST INT FLASH_PROG_LEVEL_NONE := 0; // Flash erased everywhere CONST INT FLASH_PROG_LEVEL_SOME := 1; // Flash programmed enough to verify data/addr bus for opens/stucks and data bus // for shorts. Ie. Data written to a single block, or small number of blocks. CONST INT FLASH_PROG_LEVEL_LOTS := 2; // Flash programmed enough to data/addr bus for opens/stucks and shorts. // Ie. Data written to a large number of blocks. //------------------------------------------------------------------------ // The higher this level is set, the more test coverage will be attained. // The aim is to set the highest level possible with the test still passing. // If the flash is totally erased, the test will only pass if this variable // is set to FLASH_PROG_LEVEL_NONE. //------------------------------------------------------------------------ CONST INT FLASH_PROG_LEVEL := FLASH_PROG_LEVEL_NONE; CONST INT RESULT_PASS := FALSE; CONST INT RESULT_FAIL := TRUE; // Globals INT DEBUG := FALSE; INT ALL_ONES WIDTH FLASH_SIZE := ~0[(FLASH_SIZE-1)..0]; INT dataSet WIDTH FLASH_SIZE; //------------------------------------------------------------------------ // Includes Read ID test and optional Readonly Data and Address bus tests. // The optional test only be used if the flash has been sufficiently // programmed (by setting FlASH_PROGRAMMED to TRUE). // Much quicker alternative to Destructive test. //------------------------------------------------------------------------ TestNonDestructive()(INT result) INT tempResult; result := RESULT_PASS; IF (WRITEABLE(BYTE)) THEN SET BYTE := 1; END; IF (WRITEABLE(NRESET)) THEN SET NRESET := 0; SET NRESET := 1; END; PRINT("\n\nStarting Read ID test...\n"); ReadIDtest()(result); IF (FLASH_PROG_LEVEL > FLASH_PROG_LEVEL_NONE) THEN PRINT("\nStarting Non-Destructive memory test\n"); MemTestNonDestructive()(tempResult); IF tempResult = RESULT_FAIL THEN result := RESULT_FAIL; END; ELSE PRINT("FLASH_PROG_LEVEL currently set to FLASH_PROG_LEVEL_NONE\nAlthough the ReadID test excersises the data/addr bus and control lines,\na more comprehensive test can be done by changing FLASH_PROG_LEVEL\nThis can only be done if the flash is progammed (see device file for more information).\n\n"); END; IF result = RESULT_FAIL THEN PRINT("Non Destructive Memory Test FAILED...\n\n"); ELSE PRINT("Non Destructive Memory Test PASSED...\n\n"); END; END; //------------------------------------------------------------------------ // Includes Read ID test, and optimised destructive memory test. // Slower than non destructive test, but more reliable. //------------------------------------------------------------------------ TestDestructive()(INT result) INT tempResult; result := RESULT_PASS; IF (WRITEABLE(BYTE)) THEN SET BYTE := 1; END; IF (WRITEABLE(NRESET)) THEN SET NRESET := 0; SET NRESET := 1; END; PRINT("\n\nStarting Read ID test...\n"); ReadIDtest()(result); PRINT("\nStarting Destructive memory test\n"); IF (result = RESULT_PASS) THEN MemTestDestructive()(tempResult); IF tempResult = RESULT_FAIL THEN result := RESULT_FAIL; END; ELSE TestDetail(TRUE)(); END; IF ((result = RESULT_PASS) && WRITEABLE(NCE)) THEN PRINT("\nTesting Chip Enable\n"); TestChipEnable()(result); IF result = RESULT_FAIL THEN PRINT("Chip Enable - pin: ",PINNUM(NCE)," stuck low\n"); END; END; IF result = RESULT_FAIL THEN PRINT("Destructive Memory Test FAILED...\n"); ELSE PRINT("Destructive Memory Test PASSED...\n"); END; END; //------------------------------------------------------ // ReadIDTest //------------------------------------------------------ ReadIDtest()(INT result) INT manufacturer; INT device; PRINT ("Checking Flash ", DEVICE_REF, " ID codes...\n "); ResetFlash()(); result := RESULT_FAIL; // Read Flash IDs. ReadID()(manufacturer, device); ResetFlash()(); manufacturer := manufacturer[7..0]; IF DEBUG THEN PRINT("Manufacturer ID = 0x", HEX(manufacturer), ", "); PRINT("Device ID = 0x", HEX(device), ", \n"); END; // Check the IDs. IF ((manufacturer != MANUFACTURER_ID) || (device != DEVICE_ID)) THEN PRINT("Read Manufacturer ID : 0x", HEX(manufacturer), ", expected to read 0x",HEX(MANUFACTURER_ID),"\n"); PRINT("Read Device ID = 0x", HEX(device), ", expected to read 0x", HEX(DEVICE_ID),"\n"); PRINT("failed.\n"); result := RESULT_FAIL; RETURN; END; PRINT("Flash IDs verified\n"); result := RESULT_PASS; END; //------------------------------------------------------ // Checks the chip enable pin isn't stuck low //------------------------------------------------------ TestChipEnable()(INT result) INT data; INT temp; result := RESULT_PASS; EraseBlock(0)(temp); WriteCycle(ADDR_UNLOCK_1, DATA_UNLOCK_1); WriteCycle(ADDR_UNLOCK_2, DATA_UNLOCK_2); WriteCycle(ADDR_PROGRAM, DATA_PROGRAM); // try programming with nCE held high SET ADDR := 0; SET NWE := 0, NCE := 1, NOE := 1, DATA := 0; SET NCE := 1, NOE := 1, DATA := I, NWE := 1; WaitReady(0, 0, 100)(temp); ReadWord(0)(data); IF data = 0 THEN result := RESULT_FAIL; END; END; //------------------------------------------------------ // EraseAll //------------------------------------------------------ EraseAll()(INT result) IF DEBUG THEN PRINT("Erasing all flash contents.\n"); END; ResetFlash()(); // Two unlock cycles WriteCycle(ADDR_UNLOCK_1, DATA_UNLOCK_1); WriteCycle(ADDR_UNLOCK_2, DATA_UNLOCK_2); // Set-up command WriteCycle(ADDR_ERASE_SETUP, DATA_ERASE_SETUP); // Two unlock write cycles WriteCycle(ADDR_UNLOCK_1, DATA_UNLOCK_1); WriteCycle(ADDR_UNLOCK_2, DATA_UNLOCK_2); // Chip erase command WriteCycle(ADDR_ERASE, DATA_ERASE_ALL); // Poll for erase complete WaitReady(0x00, 0x80, 0xffffffff)(result); IF (result != RESULT_PASS) THEN PRINT("Flash not ready after EraseAll\n"); RETURN; END; ResetFlash()(); result := RESULT_PASS; IF DEBUG THEN PRINT("Erased all OK\n"); END; END; //------------------------------------------------------ // EraseBlock //------------------------------------------------------ EraseBlock(INT address)(INT result) result := RESULT_FAIL; IF DEBUG THEN PRINT ("Erase flash block at 0x", HEX(address), "\n"); END; // Two unlock cycles WriteCycle(ADDR_UNLOCK_1, DATA_UNLOCK_1); WriteCycle(ADDR_UNLOCK_2, DATA_UNLOCK_2); // Set-up command WriteCycle(ADDR_ERASE_SETUP, DATA_ERASE_SETUP); // Two unlock write cycles WriteCycle(ADDR_UNLOCK_1, DATA_UNLOCK_1); WriteCycle(ADDR_UNLOCK_2, DATA_UNLOCK_2); // Chip erase command WriteCycle(address, DATA_ERASE_SEC); WaitReady(address, 0xFFFF, 5000)(result); // data is effectively FF, since erasing sets to 1s IF (result != RESULT_PASS) THEN PRINT("Flash not ready after erase.\n"); RETURN; END; result := RESULT_PASS; IF DEBUG THEN PRINT("Block erased.\n"); END; END; //------------------------------------------------------ // ProgramWord // Write a word to the flash //------------------------------------------------------ ProgramWord(INT address, INT data)(INT result) INT read_data; IF DEBUG THEN PRINT ("Program 0x", HEX(data), " to 0x", HEX(address), "\n"); END; WriteCycle(ADDR_UNLOCK_1, DATA_UNLOCK_1); WriteCycle(ADDR_UNLOCK_2, DATA_UNLOCK_2); WriteCycle(ADDR_PROGRAM, DATA_PROGRAM); WriteCycle(address, data); WaitReady(address, data, 100)(result); IF (result != RESULT_PASS) THEN PRINT("Flash not ready after program byte.\n"); RETURN; END; result := RESULT_PASS; IF DEBUG THEN PRINT("Word programmed OK.\n"); END; END; //------------------------------------------------------ // ReadWord // Read a word from the flash //------------------------------------------------------ ReadWord(INT address)(INT data) ResetFlash()(); ReadCycle(address)(data); IF DEBUG THEN PRINT ("Read addr 0x", HEX(address), " = 0x", HEX(data), "\n"); END; END; //------------------------------------------------------ // ResetFlash //------------------------------------------------------ ResetFlash()() WriteCycle(0, 0xF0); // Reset and switch to read array mode. END; //------------------------------------------------------ // ReadID // Read the manufacturer and device IDs. //------------------------------------------------------ ReadID()(INT manufacturer, INT device) INT timeout, read; // Go into autoselect mode. WriteCycle(ADDR_UNLOCK_1, DATA_UNLOCK_1); WriteCycle(ADDR_UNLOCK_2, DATA_UNLOCK_2); WriteCycle(ADDR_AUTOSELECT, DATA_AUTOSELECT); // Read the manufacturer ID. ReadCycle(ADDR_MAN_ID)(manufacturer); // Read the device ID. ReadCycle(ADDR_DEV_ID0)(read); device := read; ReadCycle(ADDR_DEV_ID1)(read); device := device:read; ReadCycle(ADDR_DEV_ID2)(read); device := device:read; END; //------------------------------------------------------ // WaitReady // waits until DQ[7] matches passed data[7] or times out // when DQ[5] goes high // also times out after user defined time incase a more // serious failure //------------------------------------------------------ WaitReady (INT address, INT data, INT delay)(INT result) INT status; INT timeout := NOW() + delay; result := RESULT_FAIL; DO ReadCycle(address)(status); IF (status[7] = data[7]) THEN result := RESULT_PASS; RETURN; END; WHILE (status[5] != 1) IF delay != 0 THEN IF NOW() > timeout THEN PRINT("\n Timeout waiting for flash ready ***\n"); RETURN; END; END; END; ReadCycle(address)(status); IF (status[7] != data[7]) THEN PRINT("\n*** Timeout waiting for flash ready ***\n"); RETURN; END; result := RESULT_PASS; END; //------------------------------------------------------ // WriteCycle // Address latched on falling edge of nWE or nCE // Data latched on rising edge of nWE //------------------------------------------------------ WriteCycle(INT address, INT code)() SET ADDR := address[ADDR_BUS_WIDTH-1..0]; SET NWE := 0, NCE := 0, NOE := 1, DATA := code[DATA_BUS_WIDTH-1..0]; SET NCE := 1, NOE := 1, DATA := I, NWE := 1; END; //------------------------------------------------------ // ReadCycle // Address latched on falling edge of NCE // Data latched on rising edge of nCE //------------------------------------------------------ ReadCycle(INT address)(INT result) SET ADDR := address[ADDR_BUS_WIDTH-1..0], DATA := I; SET NWE := 1, NCE := 0, NOE := 0; SET result := DATA, NCE := 1, NOE := 1, NWE := 1; END; //---------------------------------------------------------------------------------- // Functions required for use of device file with memtestFlash.xje //---------------------------------------------------------------------------------- PrintData(INT i)() PRINT(PINNUM(DATA[i])); END; PrintAddr(INT i)() PRINT(PINNUM(ADDR[i])); END; /*********************FLASH PROGRAMMING*********************************** //------------------------------------------------------ // ProgramFromSRecordFile // Program the flash from an S Record file //------------------------------------------------------ ProgramFromSRecordFile(STRING fileName)(INT result) INT addrLow; INT addrHigh; INT address; PRINT("\n\nStarting flash programming from file ",fileName,"\n"); dataSet := ALL_ONES; ReadSRecordFile(fileName, 0, 0, 16, DATA_BUS_WIDTH)(dataSet, addrLow, addrHigh, result); ProgramFlash(addrLow, addrHigh - addrLow, dataSet)(result); // optional verification of memory written to flash // VerifyFlash(dataSet, addrLow, addrHigh - addrLow)(result); END; //------------------------------------------------------ // ProgramFromHexFile // Program the flash from a HEX file //------------------------------------------------------ ProgramFromHexFile(STRING fileName)(INT result) INT addrLow; INT addrHigh; INT address; dataSet := ALL_ONES; ReadHEXFile(fileName, 0, 0, 16, DATA_BUS_WIDTH)(dataSet, addrLow, addrHigh, result); ProgramFlash(addrLow, addrHigh - addrLow, dataSet)(result); // optional verification of memory written to flash // VerifyFlash(dataSet, addrLow, addrHigh - addrLow)(result); END; //------------------------------------------------------ // ProgramFromBinFile // Program the flash from a BIN file //------------------------------------------------------ ProgramFromBINFile(STRING fileName)(INT result) INT addrLow; INT addrHigh; INT address; dataSet := ALL_ONES; ReadBINFile(fileName, 0, 16, DATA_BUS_WIDTH)(dataSet, addrLow, addrHigh, result); ProgramFlash(addrLow, addrHigh - addrLow, dataSet)(result); // optional verification of memory written to flash // VerifyFlash(dataSet, addrLow, addrHigh - addrLow)(result); END; //----------------------------------------------------------------------------- ProgramFlash (INT startAddress, INT length, INT dataSet)(INT result) //----------------------------------------------------------------------------- INT address := startAddress; INT endAddress := address + length; INT data; INT byteNum; INT value; INT count := 0; INT tempCount :=0; ResetFlash(); IF DEBUG THEN PRINT("Programming from address 0x", HEX(startAddress), " for length 0x", HEX(length), "\n"); END; DO WHILE (address < endAddress) // Two unlock cycles WriteCycle(ADDR_UNLOCK_1, DATA_UNLOCK_1); WriteCycle(ADDR_UNLOCK_2, DATA_UNLOCK_2); WriteCycle(address, DATA_WRITETOBUF); // Write to buffer command value := (BUFFER_LENGTH-1)[DATA_BUS_WIDTH-1..0]; WriteCycle(address, value); // Length of buffer FOR byteNum := 0 FOR BUFFER_LENGTH data := dataSet[(address+1)*DATA_BUS_WIDTH -1..address*DATA_BUS_WIDTH]; WriteCycle(address, data); // Write data address := address + 1; END; WriteCycle(address-1, DATA_PROGBUF); // Program WaitReady(address-1, data, 500)(result); IF (result != RESULT_PASS) THEN PRINT("Flash not ready after program buffer.\n"); AbortProgramBuffer()(); RETURN; END; tempCount := ((address - startAddress)*100)/length; IF (tempCount != count && tempCount%5 = 0) THEN PRINT(tempCount, " percent programming complete\r"); count := tempCount; END; END; ResetFlash(); PRINT("Programming complete. \n"); END; //----------------------------------------------------------------- AbortProgramBuffer()() //----------------------------------------------------------------- WriteCycle(ADDR_UNLOCK_1, DATA_UNLOCK_1); WriteCycle(ADDR_UNLOCK_2, DATA_UNLOCK_2); WriteCycle(ADDR_ABORT_PROG, ABORT_PROGBUF); END; //----------------------------------------------------------------- // VerifyFlash with a given dataSet //----------------------------------------------------------------- VerifyFlash(INT dataSet, INT addrLow, INT numAddresses)(INT result) //----------------------------------------------------------------- INT data WIDTH DATA_BUS_WIDTH; INT expectedData WIDTH DATA_BUS_WIDTH; INT address; INT count := 0; INT tempCount :=0; result := RESULT_FAIL; PRINT("Attempting to verify programmed data\n"); ResetFlash()(); FOR address := addrLow FOR numAddresses ReadCycle(address)(data); expectedData := dataSet[(address+1)*DATA_BUS_WIDTH-1..address*DATA_BUS_WIDTH]; IF (expectedData != data) THEN result := RESULT_FAIL; PRINT("\n*** Verify error at address 0x", HEX(address), ", data=0x", HEX(data), ", expected data=0x", HEX(expectedData), " ***\n"); RETURN; END; tempCount := ((address - addrLow)*100)/numAddresses; IF (tempCount != count && tempCount%5 = 0) THEN PRINT(tempCount, " percent verifying complete\r"); count := tempCount; END; END; PRINT("Verified OK. \n"); result := RESULT_PASS; END; //------------------------------------------------------ // Verify flash from a BIN file //------------------------------------------------------ VerifyFlashFromBINFile(STRING fileName)(INT result) //------------------------------------------------------ INT addrLow; INT addrHigh; result := RESULT_FAIL; dataSet := ALL_ONES; ReadBINFile(fileName, 0, 16, DATA_BUS_WIDTH)(dataSet, addrLow, addrHigh, result); IF (result = RESULT_FAIL) THEN PRINT("BIN file failed to be read\n"); END; VerifyFlash(dataSet, addrLow, addrHigh - addrLow)(result); END; //------------------------------------------------------ // Verify flash from a HEX file //------------------------------------------------------ VerifyFlashFromHEXFile(STRING fileName)(INT result) //------------------------------------------------------ INT addrLow; INT addrHigh; result := RESULT_FAIL; dataSet := ALL_ONES; ReadHEXFile(fileName, 0, 0, 16, DATA_BUS_WIDTH)(dataSet, addrLow, addrHigh, result); IF (result = RESULT_FAIL) THEN PRINT("HEX file failed to be read\n"); END; VerifyFlash(dataSet, addrLow, addrHigh - addrLow)(result); END; //------------------------------------------------------ // Verify flash from an S Record file //------------------------------------------------------ VerifyFlashFromSRecordFile(STRING fileName)(INT result) //------------------------------------------------------ INT addrLow; INT addrHigh; result := RESULT_FAIL; dataSet := ALL_ONES; ReadSRecordFile(fileName, 0, 0, 16, DATA_BUS_WIDTH)(dataSet, addrLow, addrHigh, result); IF (result = RESULT_FAIL) THEN PRINT("S-Record file failed to be read\n"); END; VerifyFlash(dataSet, addrLow, addrHigh - addrLow)(result); END; //------------------------------------------------------ // ReadFlash // Read the flash and write contents in binary // format to an open file //------------------------------------------------------ ReadFlash(FILE fp, INT address, INT length)(INT result) INT endAddress := address + length; INT data; IF DEBUG THEN PRINT("Reading Flash\n"); END; ResetFlash()(); result := RESULT_FAIL; DO WHILE address <= endAddress ReadCycle(address)(data); FWRITE(fp, data[0..(DATA_BUS_WIDTH-1)])(); address := address + 1; END; result := RESULT_PASS; IF DEBUG THEN PRINT("Read completed OK\n"); END; END; //*************************************************************************/