CortexA9.PrivateTimer.Mos 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. MODULE PrivateTimer;
  2. (**
  3. Author: Alexey Morozov, HighDim GmbH, 2013
  4. Purpose: implementation of the driver for ARM Cortex-A9 MPCore private timer
  5. *)
  6. IMPORT
  7. SYSTEM;
  8. CONST
  9. (* register offsets *)
  10. LoadOffset = 00H;
  11. CounterRegOffset = 04H;
  12. ControlRegOffset = 08H;
  13. IsrRegOffset = 00CH;
  14. (* control register masks *)
  15. ControlEnableMask = {0};
  16. ControlAutoReloadMask = {1};
  17. ControlIrqEnableMask = {2};
  18. ControlPrescalerMask = SYSTEM.VAL(SET,00000FF00H);
  19. TYPE
  20. (**
  21. Timer descriptor
  22. *)
  23. Timer* = RECORD
  24. baseAddr-: ADDRESS; (** timer base address *)
  25. END;
  26. (**
  27. Initialize a timer given a private timer bas address
  28. *)
  29. PROCEDURE Init*(VAR timer: Timer; baseAddress: ADDRESS);
  30. BEGIN
  31. timer.baseAddr := baseAddress;
  32. END Init;
  33. (**
  34. Get private timer counter value
  35. Remarks:
  36. counter value changes decrementally from the initial value set by LoadTimer
  37. *)
  38. PROCEDURE GetCounterValue*(CONST timer: Timer): LONGINT;
  39. BEGIN
  40. RETURN SYSTEM.GET32(timer.baseAddr+CounterRegOffset);
  41. END GetCounterValue;
  42. (**
  43. Load timer with a given 32-bit initial counter value
  44. *)
  45. PROCEDURE LoadTimer*(VAR timer: Timer; value: LONGINT);
  46. BEGIN
  47. SYSTEM.PUT32(timer.baseAddr+LoadOffset,value);
  48. END LoadTimer;
  49. (** Start timer *)
  50. PROCEDURE Start*(VAR timer: Timer);
  51. BEGIN
  52. SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))+ControlEnableMask);
  53. END Start;
  54. (** Stop timer *)
  55. PROCEDURE Stop*(VAR timer: Timer);
  56. BEGIN
  57. SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))-ControlEnableMask);
  58. END Stop;
  59. (** Enable/Disable auto reload of the timer counter *)
  60. PROCEDURE EnableAutoReload*(VAR timer: Timer; enable: BOOLEAN);
  61. BEGIN
  62. IF enable THEN
  63. SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))+ControlAutoReloadMask);
  64. ELSE
  65. SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))-ControlAutoReloadMask);
  66. END;
  67. END EnableAutoReload;
  68. (**
  69. Set 8-bit timer clock prescaler value
  70. *)
  71. PROCEDURE SetPrescaler*(VAR timer: Timer; value: LONGINT);
  72. VAR reg: LONGINT;
  73. BEGIN
  74. reg := SYSTEM.GET32(timer.baseAddr+ControlRegOffset);
  75. (* clear all prescaler control bits and set the prescaler value *)
  76. SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,reg)-ControlPrescalerMask+SYSTEM.VAL(SET,LSH(value,8)));
  77. END SetPrescaler;
  78. (**
  79. Get 8-bit timer clock prescaler value
  80. *)
  81. PROCEDURE GetPrescaler*(CONST timer: Timer): LONGINT;
  82. BEGIN
  83. RETURN LSH(SYSTEM.VAL(LONGINT,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset)) * ControlPrescalerMask),-8);
  84. END GetPrescaler;
  85. (** Enable/disable timer interrupt *)
  86. PROCEDURE EnableInterrupt*(VAR timer: Timer; enable: BOOLEAN);
  87. BEGIN
  88. IF enable THEN
  89. SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))+ControlIrqEnableMask);
  90. ELSE
  91. SYSTEM.PUT32(timer.baseAddr+ControlRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+ControlRegOffset))-ControlIrqEnableMask);
  92. END;
  93. END EnableInterrupt;
  94. (** Get timer interrupt status
  95. Remark:
  96. returned status value indicates the timer counter register has reached zero
  97. *)
  98. PROCEDURE GetInterruptStatus*(CONST timer: Timer): LONGINT;
  99. BEGIN
  100. RETURN SYSTEM.GET32(timer.baseAddr+IsrRegOffset);
  101. END GetInterruptStatus;
  102. (**
  103. Clear timer interrupt status
  104. *)
  105. PROCEDURE ClearInterruptStatus*(VAR timer: Timer);
  106. BEGIN
  107. SYSTEM.PUT32(timer.baseAddr+IsrRegOffset,SYSTEM.VAL(SET,SYSTEM.GET32(timer.baseAddr+IsrRegOffset)) - {0});
  108. END ClearInterruptStatus;
  109. END PrivateTimer.