Zynq.Gpio.Mod 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. MODULE Gpio; (** AUTHOR "Timothée Martiel"; PURPOSE "GPIO driver"; *)
  2. (*! TODO:
  3. - Interrupt configuration
  4. *)
  5. IMPORT Platform;
  6. CONST
  7. (** Direction: Input *)
  8. Input * = FALSE;
  9. (** Direction: Output *)
  10. Output * = TRUE;
  11. TYPE
  12. DataReg = POINTER {UNSAFE,UNTRACED} TO RECORD
  13. DATA: ARRAY 4 OF SET;
  14. DATA_RO: ARRAY 4 OF SET;
  15. END;
  16. BankCtrlReg = POINTER {UNSAFE,UNTRACED} TO RECORD
  17. DIRM, OEN, INT_MASK, INT_EN, INT_DIS, INT_STAT, INT_TYPE, INT_POLARITY, INT_ANY: SET;
  18. END;
  19. VAR
  20. bankCtrlRegs: ARRAY 4 OF BankCtrlReg;
  21. dataRegs: DataReg;
  22. i: LONGINT;
  23. (** Set the direction of 'gpio' to output if 'out' is TRUE and to input otherwise. *)
  24. PROCEDURE SetDirection * (gpio: LONGINT; out: BOOLEAN);
  25. VAR
  26. bank, ofs: LONGINT;
  27. BEGIN
  28. GetBankOfs(gpio, bank, ofs);
  29. IF (bank < 0) & (ofs < 0) THEN RETURN END;
  30. IF out THEN
  31. INCL(bankCtrlRegs[bank].DIRM, ofs)
  32. ELSE
  33. EXCL(bankCtrlRegs[bank].DIRM, ofs)
  34. END
  35. END SetDirection;
  36. (** If 'on' enable (if 'off' disable) output for 'gpio'. 'gpio' direction must be set to output prior to this call. *)
  37. PROCEDURE EnableOutput * (gpio: LONGINT; on: BOOLEAN);
  38. VAR
  39. bank, ofs: LONGINT;
  40. BEGIN
  41. GetBankOfs(gpio, bank, ofs);
  42. IF (bank < 0) & (ofs < 0) THEN RETURN END;
  43. IF on THEN
  44. INCL(bankCtrlRegs[bank].OEN, ofs)
  45. ELSE
  46. EXCL(bankCtrlRegs[bank].OEN, ofs)
  47. END
  48. END EnableOutput;
  49. (** Set the data of output GPIO 'gpio' to 'data' (TRUE for high, FALSE for low). *)
  50. PROCEDURE SetData * (gpio: LONGINT; data: BOOLEAN);
  51. VAR
  52. bank, ofs: LONGINT;
  53. BEGIN
  54. GetBankOfs(gpio, bank, ofs);
  55. IF (bank < 0) & (ofs < 0) THEN RETURN END;
  56. IF data THEN
  57. INCL(dataRegs.DATA[bank], ofs)
  58. ELSE
  59. EXCL(dataRegs.DATA[bank], ofs)
  60. END
  61. END SetData;
  62. (** Get data of input GPIO 'gpio': TRUE for high, FALSE for low. *)
  63. PROCEDURE GetData * (gpio: LONGINT): BOOLEAN;
  64. VAR
  65. bank, ofs: LONGINT;
  66. BEGIN
  67. GetBankOfs(gpio, bank, ofs);
  68. IF (bank < 0) & (ofs < 0) THEN HALT(100) END;
  69. RETURN ofs IN dataRegs.DATA_RO[bank]
  70. END GetData;
  71. PROCEDURE GetBankOfs (gpio: LONGINT; VAR bank, ofs: LONGINT);
  72. BEGIN
  73. IF gpio < 54 THEN
  74. bank := gpio DIV 32;
  75. ofs := gpio MOD 32
  76. ELSE
  77. (*! TODO: implement *)
  78. END;
  79. bank := -1;
  80. ofs := -1
  81. END GetBankOfs;
  82. BEGIN
  83. dataRegs := Platform.GpioData;
  84. FOR i := 0 TO Platform.GpioBankNb - 1 DO
  85. bankCtrlRegs[i] := Platform.GpioBank[i]
  86. END
  87. END Gpio.