ZynqFpgaProgrammer.Mos 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. MODULE ZynqFpgaProgrammer;
  2. (**
  3. AUTHOR Timothée Martiel, 01/2016
  4. PURPOSE FPGA programmer for Zynq-7000 SoC
  5. *)
  6. IMPORT
  7. SYSTEM, Platform, Caches, StreamReaders,
  8. EnetTiming,
  9. Programmer;
  10. CONST
  11. Timeout = 5000;
  12. TYPE
  13. Fpga * = POINTER TO FpgaDesc;
  14. FpgaDesc * = RECORD (Programmer.DestinationDesc)
  15. END;
  16. PROCEDURE ProgramFpga (CONST resource: Programmer.Resource; destination: Programmer.Destination);
  17. VAR
  18. timer: EnetTiming.Timer;
  19. res, i: LONGINT;
  20. start, size: ADDRESS;
  21. BEGIN
  22. start := resource.start;
  23. size := resource.size;
  24. Caches.CleanDCacheRange(start, size);
  25. EnetTiming.SetTimerMilli(timer, Timeout);
  26. IF size > 512 * Platform.M THEN Programmer.error := TRUE; Programmer.done := TRUE; RETURN END;
  27. Platform.devcfg.CTRL := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, Platform.devcfg.CTRL) - {25});
  28. (* Clear DMA_DONE and PL_PROGRAMMED interrupts *)
  29. Platform.devcfg.INT_STS := SYSTEM.VAL(LONGINT, {2, 13});
  30. (* Start DMA *)
  31. Platform.devcfg.DMA_SRC_ADDR := start + 1;
  32. Platform.devcfg.DMA_DST_ADDR := Platform.DevCfgDmaPlAdr;
  33. Platform.devcfg.DMA_SRC_LEN := (size) DIV 4;
  34. Platform.devcfg.DMA_DST_LEN := (size) DIV 4;
  35. (* Wait until DMA done and PL programmed *)
  36. EnetTiming.StartTimer(timer);
  37. REPEAT UNTIL ({2, 13} * SYSTEM.VAL(SET, Platform.devcfg.INT_STS) = {2, 13}) OR (EnetTiming.IsTimerExpired(timer));
  38. IF {2, 13} * SYSTEM.VAL(SET, Platform.devcfg.INT_STS) # {2, 13} THEN
  39. (* Programming failed *)
  40. Programmer.done := TRUE;
  41. Programmer.error := TRUE;
  42. RETURN
  43. END;
  44. Platform.slcr.SLCR_UNLOCK := Platform.SlcrUnlockKey;
  45. (* Bring PL out of reset ??? *)
  46. Platform.slcr.FPGA_RST_CTRL := {0 .. 3};
  47. (* Enable Level shifters *)
  48. Platform.slcr.LVL_SHFTR_EN := 0FH;
  49. Platform.slcr.SLCR_LOCK := Platform.SlcrLockKey;
  50. Programmer.done := TRUE;
  51. Programmer.error := FALSE
  52. END ProgramFpga;
  53. PROCEDURE Accept (destination: Programmer.Destination): BOOLEAN;
  54. BEGIN
  55. RETURN destination IS Fpga
  56. END Accept;
  57. PROCEDURE Factory (VAR args: StreamReaders.Reader): Programmer.Destination;
  58. VAR
  59. dest: Fpga;
  60. BEGIN
  61. NEW(dest);
  62. RETURN dest
  63. END Factory;
  64. BEGIN
  65. Programmer.RegisterProgrammer("ZynqFpga", ProgramFpga, Accept, Factory)
  66. END ZynqFpgaProgrammer.