MODULE XoppcAmdFlashs; (** © ProXon/ED 7.10.97 / 20.10.98 / wm 9.00 / ED 18.12.00 / 27.6.02 | *) (* changes: 22.10.04 UG adapted for ppc *) IMPORT Log := StdLog, Dialog, Services, UT := XdeUtilities, XE := XdeErrors, FlM := XoppcFlashMemories , BDI := UsbBDI555, TMAM := XoppcTargetMemAndMods, S := SYSTEM, XSYS := XoppcSystem, TextModels; CONST errPrefix = "Amd_"; TargetDefineMem = "Xo68x32ImcTarget.DefineMemory"; TargetInit = "Xo68x32ImcTarget.Init"; (* thisMod="XdeAmdFlashs"; *) CONST nul = 0X; cr = 0DX; eol = cr; ht = 9X; nyd = "<>"; (*not yet defined (number)*) 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 *) (*cs*) VAR Am29LV160DSegment : TMAM.Segment; Am29LV160DDevice: TMAM.Device; configT: TextModels.Model; CONST configText = "TargetConfig.odc"; 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 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 PutInt (adr, data: INTEGER); BEGIN BDI.writeMem(adr, data, 4); END PutInt; PROCEDURE mirrorReadIntData (data : INTEGER): INTEGER; VAR i: INTEGER; ds, datas: SET; BEGIN ds := {}; datas := S.VAL(SET, data); FOR i := 0 TO 31 DO IF i IN datas THEN INCL(ds, 31 - i) END; END; RETURN S.VAL(INTEGER, ds); END mirrorReadIntData; 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 Am29LV160DSegment.size * Am29LV160DSegment.size ; END END InDeviceAdr; PROCEDURE GetChipIDsAm29LV160D (devAdr: INTEGER); VAR data: INTEGER; res, sector: INTEGER; VAR locSgmt: TMAM.Segment; locSgmtNr: INTEGER; PROCEDURE GetSectorProtection (sector, sectAdr, sectSize: INTEGER); BEGIN data := BDI.readMem(sectAdr + 2 * 4, 4); Log.Tab; Log.String("adr: "); Log.Tab; LogHex(sectAdr); Log.String("..."); LogHex(sectAdr + sectSize - 1); Log.Tab; IF mirrorReadIntData(data) = 0 THEN Log.String("un") END; Log.String("protected") END GetSectorProtection; BEGIN devAdr := devAdr DIV Am29LV160DSegment.size * Am29LV160DSegment.size ; Log.Ln; Log.String("getting Am29LV160D chip IDs:"); Log.Tab; Log.String("address area:"); Log.Tab; LogHex(devAdr); Log.String(" .. "); LogHex(devAdr + Am29LV160DSegment.size - 1); Log.Ln; PutInt(devAdr + 01554H, 055005500H); PutInt(devAdr + 0AA8H, 0AA00AA00H); PutInt(devAdr + 01554H, 009000900H); data := BDI.readMem(devAdr + 0, 4); LogWord(mirrorReadIntData(data), "manufacturer id"); (*01*) data := BDI.readMem(devAdr + 4, 4); LogWord(mirrorReadIntData(data), "device id"); Log.String("Sectorname:"); Log.Tab; Log.String("Sectorbaseadress:"); Log.Tab; Log.String("Sectorsize:"); Log.Tab; Log.String("Sectorused:"); Log.Tab; Log.String("Sectorattributs:"); Log.Tab; Log.String("Sectoradressrange:"); Log.Tab; Log.Tab; Log.String("sector protection:"); Log.Ln; locSgmt := Am29LV160DSegment.local; locSgmtNr := 0; WHILE locSgmt # NIL DO IF locSgmt.name = "" THEN Log.Int(locSgmtNr) ELSE Log.String(locSgmt.name) END; Log.Tab; Log.Tab; IF locSgmt.base < 0 THEN Log.String(nyd) ELSE LogHex(locSgmt.base) END; Log.Tab; IF locSgmt.size < 0 THEN Log.String(nyd) ELSE LogHex(locSgmt.size) END; Log.Tab; LogHex(locSgmt.used); Log.Tab; Log.Set(locSgmt.attrs); GetSectorProtection(locSgmtNr, devAdr, locSgmt.size); INC(devAdr, locSgmt.size DIV Am29LV160DSegment.width); Log.Ln; locSgmt := locSgmt.next; INC(locSgmtNr) END; PutInt(devAdr + 01554H, 0F000F00H); Log.Ln (*Reset*) END GetChipIDsAm29LV160D; PROCEDURE ShowChipIDsAm29LV160D * ; (** Syntax: XdeAmdFlashs.ShowChipIDsAm29LV160D deviceAddress Preconditions: Target.DefineMemory defines the memory device Am29FLV160DB 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 InDeviceAdr(devAdr); GetChipIDsAm29LV160D(devAdr); END ShowChipIDsAm29LV160D; PROCEDURE GetSectorAdress (sectName : TMAM.Name; VAR sectSize : INTEGER ): INTEGER; VAR locSgmt: TMAM.Segment; locSgmtNr, adr: INTEGER; BEGIN locSgmt := Am29LV160DSegment.local; locSgmtNr := 0; adr := 0; WHILE locSgmt # NIL DO adr := adr DIV locSgmt.size * locSgmt.size; IF locSgmt.name = "" THEN Log.Int(locSgmtNr) ELSE Log.String(locSgmt.name) END; IF locSgmt.name = sectName THEN sectSize := locSgmt.size DIV Am29LV160DSegment.width ; RETURN adr ELSE adr := adr + locSgmt.size DIV Am29LV160DSegment.width; END; locSgmt := locSgmt.next; INC(locSgmtNr) END; END GetSectorAdress; PROCEDURE InSectorAdr (VAR sectorAdr, sectSize : INTEGER); VAR scnr: UT.Scanner; sectName : TMAM.Name; BEGIN UT.GetScanner("!", scnr); IF scnr.done THEN scnr.CharSequence(sectName) END; Log.String("Readed sector name: "); Log.String(sectName); Log.Tab; IF ~scnr.done THEN Error(1); sectorAdr := 0 ELSE sectorAdr := GetSectorAdress(sectName, sectSize); Log.String("Sectoradress: "); LogHex(sectorAdr); Log.Ln; END END InSectorAdr; PROCEDURE InDumpStartAndEndAdr (VAR startAdr, endAdr: 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); startAdr := 0 ELSE startAdr := adr END; Log.Ln; Log.String("read start adress to dump: "); LogHex(startAdr); IF scnr.done THEN scnr.Int(adr) END; IF ~scnr.done THEN Error(1); endAdr := 0 ELSE endAdr := adr END; Log.Ln; Log.String("read end adress to dump: "); LogHex(endAdr); Log.Ln; END InDumpStartAndEndAdr; PROCEDURE InSectorAdr2 (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 END; LogHex(sectorAdr); END InSectorAdr2; PROCEDURE WaitByDataPollInt (adr, expData, timeOut: INTEGER); VAR endTime: LONGINT; data: INTEGER; BEGIN endTime := Services.Ticks() + timeOut; REPEAT data := BDI.readMem(adr, 4) 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 WaitByDataPollInt; PROCEDURE EraseSectorAm29LV160D (sectorAdr: INTEGER); VAR devAdr: INTEGER; PROCEDURE SetEraseMode; BEGIN PutInt(devAdr + 01554H, 055005500H); PutInt(devAdr + 0AA8H, 0AA00AA00H); PutInt(devAdr + 01554H, 01000100H); PutInt(devAdr + 01554H, 055005500H); PutInt(devAdr + 0AA8H, 0AA00AA00H) END SetEraseMode; BEGIN (* Log.String("AmdFlashs-Erase, sector adress "); LogHex(sectorAdr); Log.Tab;*) devAdr := Am29LV160DSegment.base ; (* LogHex(devAdr);*) sectorAdr := sectorAdr - devAdr; (* Log.Ln; Log.Tab; Log.String("erasing sector: "); LogHex(devAdr + sectorAdr); Log.String(" .. ");*) SetEraseMode; PutInt(devAdr + sectorAdr , 0C000C00H); WaitByDataPollInt(devAdr + sectorAdr , 0FFFFFFFFH, 5000); END EraseSectorAm29LV160D; PROCEDURE EraseSectAm29LV160D * ; VAR sectAdr, sectSize: INTEGER; BEGIN InSectorAdr2(sectAdr); EraseSectorAm29LV160D(sectAdr); END EraseSectAm29LV160D; PROCEDURE EraseDeviceAm29LV160D * (adr: INTEGER); CONST expData = 0FFFFFFFFH; VAR devAdr: INTEGER; BEGIN devAdr := Am29LV160DSegment.base ; adr := adr - devAdr; Log.Ln; Log.Tab; Log.String("erasing device(s): "); LogHex(devAdr); Log.String(" .. "); LogHex(devAdr + Am29LV160DDevice.size - 1); Log.Ln; PutInt(devAdr + 01554H, 055005500H); PutInt(devAdr + 0AA8H, 0AA00AA00H); PutInt(devAdr + 01554H, 01000100H); PutInt(devAdr + 01554H, 055005500H); PutInt(devAdr + 0AA8H, 0AA00AA00H); PutInt(devAdr + 01554H, 08000800H); WaitByDataPollInt(devAdr, expData, 30000); Log.Tab; Log.String("device erased! "); END EraseDeviceAm29LV160D; PROCEDURE EraseDeviceAm29LV160DCmd * ; VAR sectAdr, sectSize: INTEGER; BEGIN InDeviceAdr(sectAdr); EraseDeviceAm29LV160D(sectAdr); END EraseDeviceAm29LV160DCmd; PROCEDURE ProgramIntAm29LV160D (adr, data: INTEGER); (* program one int at adr *) VAR devAdr: INTEGER; BEGIN devAdr := Am29LV160DSegment.base ; PutInt(devAdr + 01554H, 055005500H); PutInt(devAdr + 0AA8H, 0AA00AA00H); PutInt(devAdr + 01554H, 05000500H); PutInt(adr, data); WaitByDataPollInt(adr , data, 5000); END ProgramIntAm29LV160D; PROCEDURE LoadAm29LV160D * ; (** Preconditions: there is an image fileAm29LV160DB.Tim if neccessary, click on XoppcSystem.Build to update all images Description: the image in file fileAm29LV160DB.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 Done := TRUE; Am29LV160DSegment := TMAM.GetSegment(NIL, "ExternalFlashAm29LV160D"); Am29LV160DDevice := TMAM.GetDevice("Am29LV160D"); FlM.LoadMemDevPar(Am29LV160DDevice, Am29LV160DSegment); FlM.InstallDeviceProc(EraseDeviceAm29LV160D, EraseSectorAm29LV160D, ProgramIntAm29LV160D); XSYS.ResetTarget; IF ~BDI.Done THEN Error(40); RETURN END; FlM.Program("Am29LV160D", FALSE) END LoadAm29LV160D; PROCEDURE DumpIntAm29LV160D * ; VAR startAdr, endAdr : INTEGER; data, i : INTEGER; BEGIN InDumpStartAndEndAdr(startAdr, endAdr); FOR i := startAdr TO (endAdr) BY 4 DO data := BDI.readMem(i , 4); Log.String("Readed INT value at Adress "); LogHex(i); Log.String(" : "); LogHex(data); Log.Ln; END; END DumpIntAm29LV160D; PROCEDURE Init * ; BEGIN XSYS.ResetTarget; IF ~BDI.Done THEN Error(40); RETURN END; Log.Tab; Log.String("controller reset and initialised"); Log.Ln; TMAM.InitRegs; END Init; BEGIN Init; END XoppcAmdFlashs.