git-svn-id: https://svn.code.sf.net/p/libusbjava/code/trunk@96 94ad28fe-ef68-46b1-9651-e7ae4fcf1c4c
370 lines
13 KiB
Plaintext
370 lines
13 KiB
Plaintext
|
|
MODULE Xo68x32AmdFlashs;
|
|
(** © ProXon/ED 7.10.97 / 20.10.98 / wm 9.00 / ED 18.12.00 / 27.6.02 | *)
|
|
(* Updated for 29F800 Bottom Boot Sector. Changes in dark-green. wm, 9.2000 *)
|
|
IMPORT
|
|
Log := StdLog, Dialog, Services,
|
|
UT := XdeUtilities, XE := XdeErrors, FlM := Xo68x32FlashMemories, BDI := UsbBDI332,
|
|
BDIMain := UsbBDI;
|
|
|
|
CONST
|
|
errPrefix = "Amd_";
|
|
TargetDefineMem = "Xo68x32ImcTarget.DefineMemory";
|
|
TargetInit = "Xo68x32ImcTarget.Init";
|
|
(*
|
|
thisMod="XdeAmdFlashs";
|
|
*)
|
|
|
|
CONST
|
|
nul = 0X; cr = 0DX; eol = cr; ht = 9X;
|
|
|
|
imageFileExt = ".Tim"; (** target image file extension: ".Tim" *)
|
|
|
|
VAR
|
|
Done-: BOOLEAN; eof-: BOOLEAN;
|
|
(** Done=TRUE: vorangegangene Operation wurde erfolgreich beendet.
|
|
eof = TRUE: das Ende des Files ist nun erreicht, oder ein ENDrecord wurde gelesen.
|
|
|
|
Done=TRUE und eot = TRUE: ENDrecord konnte noch erfolgreich gelesen werden.
|
|
*)
|
|
firstErr-: INTEGER; (** error list see CrossErrors.Text, search for Xo68x32AmdFlashs *)
|
|
|
|
PROCEDURE Error (errNr: SHORTINT);
|
|
BEGIN
|
|
IF Done THEN firstErr := firstErr; Done := FALSE END;
|
|
XE.Error("", errPrefix, errNr, TRUE)
|
|
END Error;
|
|
|
|
|
|
PROCEDURE LogHex (val: INTEGER);
|
|
BEGIN
|
|
Log.Char('0'); Log.IntForm(val, Log.hexadecimal, 1, ' ', Log.hideBase); Log.Char('H')
|
|
END LogHex;
|
|
|
|
|
|
PROCEDURE PutWord (adr, data: INTEGER);
|
|
BEGIN
|
|
data := data MOD 10000H; BDI.writeMem(adr, data, 2)
|
|
END PutWord;
|
|
|
|
PROCEDURE WaitByDataPoll (adr, expData: INTEGER);
|
|
VAR endTime: LONGINT; data: INTEGER;
|
|
BEGIN
|
|
endTime := Services.Ticks() + 5000;
|
|
REPEAT data := BDI.readMem(adr, 2) UNTIL (data = expData) OR (endTime < Services.Ticks());
|
|
IF data # expData THEN
|
|
Error(3); Log.Tab; Log.String("at loc "); LogHex(adr); Log.Ln
|
|
END
|
|
END WaitByDataPoll;
|
|
|
|
PROCEDURE LogWord (data: INTEGER; comment: ARRAY OF CHAR);
|
|
BEGIN
|
|
Log.Tab; Log.String(comment); Log.String(":"); Log.Tab; LogHex(data MOD 10000H); Log.Ln
|
|
END LogWord;
|
|
|
|
PROCEDURE InDeviceAdr (VAR devAdr: INTEGER);
|
|
VAR adr: INTEGER; scnr: UT.Scanner;
|
|
BEGIN
|
|
UT.GetScanner("!", scnr);
|
|
IF scnr.done THEN scnr.Int(adr) END;
|
|
IF ~scnr.done THEN
|
|
Error(1); devAdr := 0
|
|
ELSE
|
|
devAdr := adr DIV FlM.memDevice.deviceSize * FlM.memDevice.deviceSize
|
|
END
|
|
END InDeviceAdr;
|
|
|
|
PROCEDURE InSectorAdr (VAR sectorAdr: INTEGER);
|
|
VAR adr: INTEGER; scnr: UT.Scanner;
|
|
BEGIN
|
|
UT.GetScanner("!", scnr);
|
|
IF scnr.done THEN scnr.Int(adr) END;
|
|
IF ~scnr.done THEN
|
|
Error(1); sectorAdr := 0
|
|
ELSE
|
|
sectorAdr := adr DIV FlM.memDevice.sectorSize * FlM.memDevice.sectorSize
|
|
END
|
|
END InSectorAdr;
|
|
|
|
|
|
PROCEDURE GetChipIDsAm29F800 (devAdr: INTEGER);
|
|
VAR data: INTEGER; res, sector: INTEGER;
|
|
|
|
PROCEDURE GetSectorProtection (sector, sectAdr, sectSize: INTEGER);
|
|
BEGIN
|
|
data := BDI.readMem(sectAdr + 4, 2);
|
|
Log.Tab; Log.String("sector "); Log.Int(sector); Log.Tab; Log.String("adr: ");
|
|
Log.Tab; LogHex(sectAdr); Log.String("..."); LogHex(sectAdr + sectSize - 1);
|
|
Log.Tab;
|
|
IF data = 0 THEN Log.String("un") END; Log.String("protected")
|
|
END GetSectorProtection;
|
|
|
|
|
|
BEGIN
|
|
devAdr := devAdr DIV FlM.memDevice.deviceSize * FlM.memDevice.deviceSize;
|
|
Dialog.Call(TargetInit, "error calling " + TargetInit, res);
|
|
IF res # 0 THEN Error(2) END;
|
|
Log.Ln; Log.String("getting Am29F800B chip IDs:"); Log.Ln; Log.Tab; Log.String("address area:");
|
|
LogHex(devAdr); Log.String(" .. "); LogHex(devAdr + FlM.memDevice.deviceSize - 1); Log.Ln;
|
|
PutWord(devAdr + 0AAAH, 0AAAAH);
|
|
PutWord(devAdr + 0554H, 5555H);
|
|
PutWord(devAdr + 0AAAH, 9090H);
|
|
data := BDI.readMem(devAdr + 0, 2); LogWord(data, "manufacturer id");
|
|
data := BDI.readMem(devAdr + 2, 2); LogWord(data, "device id");
|
|
(* device id = 22D6h: top boot block, device id = 2258H: bottom boot block *)
|
|
|
|
Log.Tab; Log.String("sector protection:"); Log.Ln;
|
|
IF data = 22D6H THEN
|
|
FOR sector := 0 TO 14 DO
|
|
GetSectorProtection(sector, devAdr, FlM.memDevice.sectorSize);
|
|
INC(devAdr, FlM.memDevice.sectorSize); Log.Ln
|
|
END;
|
|
GetSectorProtection(15, devAdr, FlM.memDevice.sectorSize DIV 2);
|
|
INC(devAdr, FlM.memDevice.sectorSize DIV 2); Log.Ln;
|
|
GetSectorProtection(16, devAdr, FlM.memDevice.sectorSize DIV 8);
|
|
INC(devAdr, FlM.memDevice.sectorSize DIV 8); Log.Ln;
|
|
GetSectorProtection(17, devAdr, FlM.memDevice.sectorSize DIV 8);
|
|
INC(devAdr, FlM.memDevice.sectorSize DIV 8); Log.Ln;
|
|
GetSectorProtection(18, devAdr, FlM.memDevice.sectorSize DIV 4);
|
|
ELSIF data = 2258H THEN
|
|
GetSectorProtection(0, devAdr, FlM.memDevice.sectorSize DIV 4);
|
|
INC(devAdr, FlM.memDevice.sectorSize DIV 4); Log.Ln;
|
|
GetSectorProtection(1, devAdr, FlM.memDevice.sectorSize DIV 8);
|
|
INC(devAdr, FlM.memDevice.sectorSize DIV 8); Log.Ln;
|
|
GetSectorProtection(2, devAdr, FlM.memDevice.sectorSize DIV 8);
|
|
INC(devAdr, FlM.memDevice.sectorSize DIV 8); Log.Ln;
|
|
GetSectorProtection(3, devAdr, FlM.memDevice.sectorSize DIV 2);
|
|
INC(devAdr, FlM.memDevice.sectorSize DIV 2); Log.Ln;
|
|
FOR sector := 4 TO 18 DO
|
|
GetSectorProtection(sector, devAdr, FlM.memDevice.sectorSize);
|
|
INC(devAdr, FlM.memDevice.sectorSize); Log.Ln
|
|
END
|
|
ELSE Error(4) (* wrong device id *)
|
|
END;
|
|
PutWord(devAdr, 0F0F0H); Log.Ln
|
|
END GetChipIDsAm29F800;
|
|
|
|
PROCEDURE GetChipIDsAm29F040 (devAdr: INTEGER);
|
|
VAR data: INTEGER; res, sector: INTEGER;
|
|
|
|
PROCEDURE GetSectorProtection (sector, sectAdr, sectSize: INTEGER);
|
|
BEGIN
|
|
data := BDI.readMem(sectAdr + 4, 2);
|
|
Log.Tab; Log.String("sector "); Log.Int(sector); Log.Tab; Log.String("adr: ");
|
|
Log.Tab; LogHex(sectAdr); Log.String("..."); LogHex(sectAdr + sectSize - 1);
|
|
Log.Tab;
|
|
IF data = 0 THEN Log.String("un") END; Log.String("protected")
|
|
END GetSectorProtection;
|
|
|
|
|
|
BEGIN
|
|
devAdr := devAdr DIV FlM.memDevice.deviceSize * FlM.memDevice.deviceSize;
|
|
Dialog.Call(TargetInit, "error calling " + TargetInit, res);
|
|
IF res # 0 THEN Error(2) END;
|
|
Log.Ln; Log.String("getting Am29F040B chip IDs:"); Log.Tab; Log.String("address area:");
|
|
Log.Tab; LogHex(devAdr); Log.String(" .. "); LogHex(devAdr + FlM.memDevice.deviceSize - 1); Log.Ln;
|
|
PutWord(devAdr + 0AAAH, 0AAAAH);
|
|
PutWord(devAdr + 0554H, 5555H);
|
|
PutWord(devAdr + 0AAAH, 9090H);
|
|
data := BDI.readMem(devAdr + 0, 2); LogWord(data, "manufacturer id");
|
|
data := BDI.readMem(devAdr + 2, 2); LogWord(data, "device id");
|
|
(* device id = 22D6h: top boot block, device id = 2258H: bottom boot block *)
|
|
|
|
Log.Tab; Log.String("sector protection:"); Log.Ln;
|
|
FOR sector := 0 TO 7 DO
|
|
GetSectorProtection(sector, devAdr, FlM.memDevice.sectorSize);
|
|
INC(devAdr, FlM.memDevice.sectorSize); Log.Ln
|
|
END;
|
|
Log.Ln;
|
|
DEC(devAdr, FlM.memDevice.sectorSize);
|
|
PutWord(devAdr, 0F0F0H); Log.Ln
|
|
END GetChipIDsAm29F040;
|
|
|
|
PROCEDURE EraseDevice (adr: INTEGER);
|
|
CONST expData = 0FFFFH;
|
|
VAR devAdr: INTEGER;
|
|
BEGIN
|
|
devAdr := adr DIV FlM.memDevice.deviceSize * FlM.memDevice.deviceSize;
|
|
Log.Ln; Log.Tab; Log.String("erasing device(s): ");
|
|
LogHex(devAdr); Log.String(" .. "); LogHex(devAdr + FlM.memDevice.deviceSize - 1); Log.Ln;
|
|
|
|
PutWord(devAdr + 0AAAAH, 0AAAAH);
|
|
PutWord(devAdr + 05554H, 5555H);
|
|
PutWord(devAdr + 0AAAAH, 8080H);
|
|
PutWord(devAdr + 0AAAAH, 0AAAAH);
|
|
PutWord(devAdr + 05554H, 5555H);
|
|
PutWord(devAdr + 0AAAAH, 1010H);
|
|
|
|
WaitByDataPoll(devAdr, expData)
|
|
END EraseDevice;
|
|
|
|
PROCEDURE EraseSector (sectorAdr: INTEGER);
|
|
VAR devAdr: INTEGER;
|
|
BEGIN
|
|
sectorAdr := sectorAdr DIV FlM.memDevice.sectorSize * FlM.memDevice.sectorSize;
|
|
devAdr := sectorAdr DIV FlM.memDevice.deviceSize * FlM.memDevice.deviceSize;
|
|
Log.Ln; Log.Tab; Log.String("erasing sector: ");
|
|
LogHex(sectorAdr); Log.String(" .. "); LogHex(sectorAdr + FlM.memDevice.sectorSize - 1);
|
|
|
|
PutWord(devAdr + 0AAAAH, 0AAAAH);
|
|
PutWord(devAdr + 05554H, 5555H);
|
|
PutWord(devAdr + 0AAAAH, 8080H);
|
|
PutWord(devAdr + 0AAAAH, 0AAAAH);
|
|
PutWord(devAdr + 05554H, 5555H);
|
|
PutWord(sectorAdr, 3030H);
|
|
|
|
WaitByDataPoll(sectorAdr, 0FFFFH)
|
|
END EraseSector;
|
|
|
|
PROCEDURE EraseSectorAm29F800 (sectorAdr: INTEGER);
|
|
VAR devAdr: INTEGER;
|
|
|
|
PROCEDURE SetEraseMode;
|
|
BEGIN
|
|
PutWord(devAdr + 0AAAAH, 0AAAAH);
|
|
PutWord(devAdr + 05554H, 5555H);
|
|
PutWord(devAdr + 0AAAAH, 8080H);
|
|
PutWord(devAdr + 0AAAAH, 0AAAAH);
|
|
PutWord(devAdr + 05554H, 5555H)
|
|
END SetEraseMode;
|
|
|
|
|
|
BEGIN
|
|
sectorAdr := sectorAdr DIV FlM.memDevice.sectorSize * FlM.memDevice.sectorSize;
|
|
devAdr := sectorAdr DIV FlM.memDevice.deviceSize * FlM.memDevice.deviceSize;
|
|
Log.Ln; Log.Tab; Log.String("erasing sector: ");
|
|
LogHex(sectorAdr); Log.String(" .. "); LogHex(sectorAdr + FlM.memDevice.sectorSize - 1);
|
|
SetEraseMode;
|
|
PutWord(sectorAdr, 3030H); WaitByDataPoll(sectorAdr, 0FFFFH);
|
|
IF sectorAdr - devAdr <= 0FFFFH THEN (* erase bottom boot block *)
|
|
INC(sectorAdr, FlM.memDevice.sectorSize DIV 4);
|
|
SetEraseMode; PutWord(sectorAdr, 3030H); WaitByDataPoll(sectorAdr, 0FFFFH);
|
|
INC(sectorAdr, FlM.memDevice.sectorSize DIV 8);
|
|
SetEraseMode; PutWord(sectorAdr, 3030H); WaitByDataPoll(sectorAdr, 0FFFFH);
|
|
INC(sectorAdr, FlM.memDevice.sectorSize DIV 8);
|
|
SetEraseMode; PutWord(sectorAdr, 3030H); WaitByDataPoll(sectorAdr, 0FFFFH);
|
|
ELSIF sectorAdr - devAdr >= 0F0000H THEN (* erase top boot block *)
|
|
INC(sectorAdr, FlM.memDevice.sectorSize DIV 2);
|
|
SetEraseMode; PutWord(sectorAdr, 3030H); WaitByDataPoll(sectorAdr, 0FFFFH);
|
|
INC(sectorAdr, FlM.memDevice.sectorSize DIV 8);
|
|
SetEraseMode; PutWord(sectorAdr, 3030H); WaitByDataPoll(sectorAdr, 0FFFFH);
|
|
INC(sectorAdr, FlM.memDevice.sectorSize DIV 8);
|
|
SetEraseMode; PutWord(sectorAdr, 3030H); WaitByDataPoll(sectorAdr, 0FFFFH);
|
|
END
|
|
END EraseSectorAm29F800;
|
|
|
|
PROCEDURE ProgramLong (adr, data: INTEGER);
|
|
(* program one long at adr *)
|
|
VAR devAdr, word: INTEGER;
|
|
BEGIN
|
|
devAdr := adr DIV FlM.memDevice.deviceSize * FlM.memDevice.deviceSize;
|
|
|
|
(* high word *)
|
|
word := data DIV 10000H MOD 10000H;
|
|
PutWord(devAdr + 0AAAAH, 0AAAAH);
|
|
PutWord(devAdr + 05554H, 5555H);
|
|
PutWord(devAdr + 0AAAAH, 0A0A0H);
|
|
PutWord(adr, word);
|
|
WaitByDataPoll(adr, word);
|
|
|
|
(* low word *)
|
|
word := data MOD 10000H; INC(adr, 2);
|
|
PutWord(devAdr + 0AAAAH, 0AAAAH);
|
|
PutWord(devAdr + 05554H, 5555H);
|
|
PutWord(devAdr + 0AAAAH, 0A0A0H);
|
|
PutWord(adr, word);
|
|
WaitByDataPoll(adr, word)
|
|
END ProgramLong;
|
|
|
|
|
|
PROCEDURE ShowChipIDsAm29F040 * ;
|
|
(**
|
|
Syntax: XdeAmdFlashs.ShowChipIDsAm29F040B deviceAddress
|
|
|
|
Preconditions: Target.DefineMemory defines the memory device Am29F040B
|
|
target connected via BDI
|
|
Description: shows: manufacturer id, device id and sector protection
|
|
Postconditions: the device(s) is in normal reading array mode.
|
|
*)
|
|
VAR devAdr: INTEGER;
|
|
BEGIN
|
|
BDIMain.ConnectDevice;
|
|
FlM.LoadMemDevPar("Am29F040"); InDeviceAdr(devAdr); GetChipIDsAm29F040(devAdr)
|
|
END ShowChipIDsAm29F040;
|
|
|
|
|
|
PROCEDURE ShowChipIDsAm29F800 * ;
|
|
(**
|
|
Syntax: XdeAmdFlashs.ShowChipIDsAm29F800B deviceAddress
|
|
|
|
Preconditions: Target.DefineMemory defines the memory device Am29F800B
|
|
target connected via BDI
|
|
Description: shows: manufacturer id, device id and sector protection
|
|
Postconditions: the device(s) is in normal reading array mode.
|
|
*)
|
|
VAR devAdr: INTEGER;
|
|
BEGIN
|
|
BDIMain.ConnectDevice;
|
|
FlM.LoadMemDevPar("Am29F800"); InDeviceAdr(devAdr); GetChipIDsAm29F800(devAdr)
|
|
END ShowChipIDsAm29F800;
|
|
|
|
|
|
|
|
PROCEDURE EraseSectAm29F800 * ;
|
|
VAR sectAdr: INTEGER;
|
|
BEGIN
|
|
BDIMain.ConnectDevice;
|
|
FlM.LoadMemDevPar("Am29F800"); InSectorAdr(sectAdr); EraseSectorAm29F800(sectAdr)
|
|
END EraseSectAm29F800;
|
|
|
|
|
|
|
|
PROCEDURE LoadAm29F010 * ;
|
|
(** Preconditions: there is an image file Am29F010.Tim
|
|
if neccessary, click on CRSystem.Build to update all images
|
|
Description: the image in file Am29F010.Tim is loaded to the targets flash memory devices.
|
|
Postconditions: all flash memory device sectors, touched by the records in the imagefile,
|
|
are first erased and then programed.
|
|
*)
|
|
BEGIN
|
|
BDIMain.ConnectDevice;
|
|
Done := TRUE;
|
|
FlM.InstallDeviceProc(EraseDevice, EraseSector, ProgramLong);
|
|
FlM.Program("Am29F010", FALSE)
|
|
END LoadAm29F010;
|
|
|
|
|
|
PROCEDURE LoadAm29F040 * ;
|
|
(** Preconditions: there is an image file Am29F040.Tim
|
|
if neccessary, click on CRSystem.Build to update all images
|
|
Description: the image in file Am29F040.Tim is loaded to the targets flash memory devices.
|
|
Postconditions: all flash memory device sectors, touched by the records in the imagefile,
|
|
are first erased and then programed.
|
|
*)
|
|
BEGIN
|
|
BDIMain.ConnectDevice;
|
|
Done := TRUE;
|
|
FlM.InstallDeviceProc(EraseDevice, EraseSector, ProgramLong);
|
|
FlM.Program("Am29F040", FALSE)
|
|
END LoadAm29F040;
|
|
|
|
|
|
PROCEDURE LoadAm29F800 * ;
|
|
(** Preconditions: there is an image file Am29F800B.Tim
|
|
if neccessary, click on CRSystem.Build to update all images
|
|
Description: the image in file Am29F800B.Tim is loaded to the targets flash memory devices.
|
|
Postconditions: all flash memory device sectors, touched by the records in the imagefile,
|
|
are first erased and then programed.
|
|
*)
|
|
BEGIN
|
|
BDIMain.ConnectDevice;
|
|
Done := TRUE;
|
|
FlM.InstallDeviceProc(EraseDevice, EraseSectorAm29F800, ProgramLong);
|
|
FlM.Program("Am29F800", FALSE)
|
|
END LoadAm29F800;
|
|
|
|
|
|
|
|
BEGIN
|
|
END Xo68x32AmdFlashs.
|