2
0

Zynq.PsSerials.Mod 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. MODULE PsSerials; (** AUTHOR "Timothée Martiel, 11/2017"; PURPOSE "Serial interface for Zynq PS UARTs"; *)
  2. IMPORT Platform, BootConfig, Modules, Strings, PsUartMin, PsUart, Serials, Objects, Machine;
  3. TYPE
  4. Port = OBJECT (Serials.Port)
  5. VAR
  6. uart: PsUart.UartController;
  7. sendCharLock := FALSE : BOOLEAN;
  8. PROCEDURE & Init (id: LONGINT);
  9. BEGIN
  10. uart := PsUart.GetUart(id);
  11. ASSERT(uart # NIL);
  12. END Init;
  13. PROCEDURE Open (bps, data, parity, stop : LONGINT; VAR res: LONGINT);
  14. BEGIN{EXCLUSIVE}
  15. PsUart.Open(uart, bps, data, parity, stop, res);
  16. END Open;
  17. PROCEDURE Close;
  18. BEGIN{EXCLUSIVE}
  19. PsUart.Close(uart);
  20. END Close;
  21. PROCEDURE Yield(VAR res: LONGINT): BOOLEAN;
  22. BEGIN
  23. IF uart.open THEN
  24. Objects.Yield;
  25. RETURN TRUE;
  26. ELSE
  27. res := Serials.Closed;
  28. RETURN FALSE;
  29. END;
  30. END Yield;
  31. PROCEDURE Yield0(VAR res: LONGINT): BOOLEAN;
  32. BEGIN
  33. IF uart.open THEN
  34. RETURN TRUE;
  35. ELSE
  36. res := Serials.Closed;
  37. RETURN FALSE;
  38. END;
  39. END Yield0;
  40. PROCEDURE SendChar(char: CHAR; VAR res: LONGINT);
  41. BEGIN
  42. Machine.AcquireObject(sendCharLock);
  43. (*! use Yield0 method to make sure no low-level lock is acquired here - required when used as trace output *)
  44. PsUart.SendChar(uart, char, TRUE, Yield0, res);
  45. FINALLY
  46. Machine.ReleaseObject(sendCharLock);
  47. END SendChar;
  48. PROCEDURE Send(CONST buf: ARRAY OF CHAR; ofs, len: LONGINT; propagate: BOOLEAN; VAR res: LONGINT);
  49. BEGIN
  50. PsUart.Send(uart, buf, ofs, len, propagate, Yield, res);
  51. END Send;
  52. PROCEDURE ReceiveChar(VAR char: CHAR; VAR res: LONGINT);
  53. BEGIN
  54. char := PsUart.ReceiveChar(uart, Yield, res);
  55. END ReceiveChar;
  56. PROCEDURE Receive(VAR buf: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT);
  57. BEGIN
  58. PsUart.Receive(uart, buf, ofs, size, min, len, Yield, res);
  59. END Receive;
  60. PROCEDURE Available(): LONGINT;
  61. BEGIN
  62. RETURN PsUart.Available(uart);
  63. END Available;
  64. PROCEDURE GetPortState(VAR openstat : BOOLEAN; VAR bps, data, parity, stop : LONGINT);
  65. BEGIN{EXCLUSIVE}
  66. openstat := uart.open;
  67. bps := uart.bps;
  68. data := uart.data;
  69. parity := uart.parity;
  70. stop := uart.stop;
  71. END GetPortState;
  72. END Port;
  73. VAR
  74. ports: ARRAY 2 OF Port;
  75. PROCEDURE Init;
  76. VAR
  77. i, clk, res: LONGINT;
  78. name, desc: ARRAY 32 OF CHAR;
  79. tracePort: LONGINT;
  80. BEGIN
  81. clk := BootConfig.GetIntValue("UartInputClockHz");
  82. FOR i := 0 TO LEN(Platform.UartBase,0)-1 DO
  83. PsUart.Install(i, Platform.UartBase[i], clk, res);
  84. END;
  85. (* if one of PS UART's is used for tracing, make the corresponding port open to allow trace output via PsUartMin *)
  86. tracePort := BootConfig.GetIntValue("TracePort");
  87. IF (tracePort >= 1) & (tracePort <= LEN(Platform.UartBase,0)) THEN
  88. PsUart.Open(PsUart.GetUart(tracePort-1), BootConfig.GetIntValue("TraceBPS"),PsUartMin.DefaultDataBits,PsUartMin.DefaultParity,PsUartMin.DefaultStop, res);
  89. ELSE tracePort := -1;
  90. END;
  91. FOR i := 0 TO LEN(ports) - 1 DO
  92. NEW(ports[i], i);
  93. name := "UART";
  94. Strings.AppendInt(name, i+1);
  95. desc := "Zynq PS UART";
  96. Strings.AppendInt(desc, i);
  97. Serials.RegisterOnboardPort(i+1, ports[i], name, desc);
  98. END;
  99. IF tracePort >= 0 THEN
  100. (* switch from PsUartMin to port-based trace output *)
  101. Serials.SetTracePort(tracePort, BootConfig.GetIntValue("TraceBPS"),PsUartMin.DefaultDataBits,PsUartMin.DefaultParity,PsUartMin.DefaultStop, res);
  102. END;
  103. Modules.InstallTermHandler(Cleanup)
  104. END Init;
  105. PROCEDURE Cleanup;
  106. VAR i: LONGINT;
  107. BEGIN
  108. FOR i := 0 TO LEN(ports) - 1 DO
  109. IF ports[i] # NIL THEN Serials.UnRegisterPort(ports[i]) END
  110. END
  111. END Cleanup;
  112. BEGIN
  113. Init
  114. END PsSerials.