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.