Zynq.SdEnvironment.Mos 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. MODULE SdEnvironment;
  2. (**
  3. AUTHOR Timothée Martiel, 01/2016
  4. PURPOSE SD driver environment for Minos
  5. *)
  6. IMPORT
  7. Platform, Board, Trace, Caches, Interrupts, GlobalTimer;
  8. CONST
  9. MaxHandlers = 2;
  10. VAR
  11. Char *: PROCEDURE (c: CHAR);
  12. String *: PROCEDURE (CONST str: ARRAY OF CHAR);
  13. Int *: PROCEDURE (i: HUGEINT; w: LONGINT);
  14. Hex *: PROCEDURE (i: LONGINT; w: LONGINT);
  15. Address *: PROCEDURE (a: ADDRESS);
  16. Set *: PROCEDURE (s: SET);
  17. Boolean *: PROCEDURE (b: BOOLEAN);
  18. Ln *: PROCEDURE;
  19. FlushDCacheRange *,
  20. InvalidateDCacheRange *: PROCEDURE (adr: ADDRESS; size: SIZE);
  21. GetTimeCounter *: PROCEDURE (): Time;
  22. handlers: ARRAY MaxHandlers OF RECORD irq: LONGINT; handle: PROCEDURE END;
  23. TYPE
  24. Time * = HUGEINT;
  25. PROCEDURE InstallHandler * (handler: PROCEDURE; irq: LONGINT);
  26. VAR
  27. i: LONGINT;
  28. BEGIN
  29. i := 0;
  30. WHILE (i < MaxHandlers) & (handlers[i].handle # NIL) DO INC(i) END;
  31. ASSERT(i < MaxHandlers);
  32. handlers[i].irq := irq;
  33. handlers[i].handle := handler;
  34. Interrupts.InstallHandler(InterruptHandler, irq)
  35. END InstallHandler;
  36. PROCEDURE Enable * (sd: LONGINT): BOOLEAN;
  37. VAR
  38. enable: BOOLEAN;
  39. BEGIN
  40. CASE sd OF
  41. 0: enable := Board.SdEnable0
  42. |1: enable := Board.SdEnable1
  43. END;
  44. RETURN enable
  45. END Enable;
  46. PROCEDURE HcClock * (sd: LONGINT): LONGINT;
  47. VAR
  48. reg, div, base: LONGINT;
  49. BEGIN
  50. div := LSH(Platform.slcr.SDIO_CLK_CTRL, -8) MOD 40H;
  51. CASE LSH(Platform.slcr.SDIO_CLK_CTRL, -4) MOD 4 OF
  52. 0:
  53. reg := Platform.slcr.IO_PLL_CTRL;
  54. base := Board.PsRefClockHz
  55. |2:
  56. reg := Platform.slcr.ARM_PLL_CTRL;
  57. base := Board.CpuClockHz DIV 2
  58. |3:
  59. reg := Platform.slcr.DDR_PLL_CTRL;
  60. Trace.StringLn("ERROR: DDR PLL clock source for SD not supported")
  61. END;
  62. base := base * (LSH(reg, -12) MOD 80H);
  63. RETURN base DIV div
  64. END HcClock;
  65. (** Convert microseconds to time counts *)
  66. PROCEDURE FromMicro*(us: Time): Time;
  67. BEGIN
  68. RETURN us * ENTIERH(0.5D0+Board.CpuClockHz/2.0D6);
  69. END FromMicro;
  70. (** Convert time counts to microseconds *)
  71. PROCEDURE ToMicro*(time: Time): Time;
  72. BEGIN
  73. RETURN ENTIERH((0.5D0 + time) / (LONGREAL(Board.CpuClockHz)) * 2.0D6)
  74. END ToMicro;
  75. (** Convert milliseconds to time counts *)
  76. PROCEDURE FromMilli*(ms: Time): Time;
  77. BEGIN
  78. RETURN ms * ENTIERH(0.5D0+Board.CpuClockHz/2.0D3);
  79. END FromMilli;
  80. (** Convert time counts to milliseconds *)
  81. PROCEDURE ToMilli*(time: Time): Time;
  82. BEGIN
  83. RETURN ENTIERH((0.5D0 + time) / (LONGREAL(Board.CpuClockHz)) * 2.0D3)
  84. END ToMilli;
  85. PROCEDURE GetLock * (VAR acq, rel: PROCEDURE {DELEGATE});
  86. END GetLock;
  87. PROCEDURE InterruptHandler (irq: LONGINT);
  88. VAR
  89. i: LONGINT;
  90. BEGIN
  91. FOR i := 0 TO MaxHandlers - 1 DO
  92. IF handlers[i].irq = irq THEN
  93. handlers[i].handle
  94. END
  95. END
  96. END InterruptHandler;
  97. BEGIN
  98. GlobalTimer.EnableTimer;
  99. Char := Trace.Char;
  100. String := Trace.String;
  101. Int := Trace.HInt;
  102. Hex := Trace.Hex;
  103. Address := Trace.Address;
  104. Set := Trace.Set;
  105. Boolean := Trace.Boolean;
  106. Ln := Trace.Ln;
  107. FlushDCacheRange := Caches.CleanDCacheRange;
  108. InvalidateDCacheRange := Caches.InvalidateDCacheRange;
  109. GetTimeCounter := GlobalTimer.GetTime;
  110. END SdEnvironment.