PageRenderTime 67ms CodeModel.GetById 39ms RepoModel.GetById 0ms app.codeStats 0ms

/Main/GadgeteerCore/Gadgeteer43/Socket.SocketInterfaces.cs

#
C# | 222 lines | 162 code | 10 blank | 50 comment | 61 complexity | 9df6e7335afbdb2d0322312680488e6a MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4. using Gadgeteer.Modules;
  5. using Microsoft.SPOT;
  6. using Microsoft.SPOT.Hardware;
  7. using System;
  8. namespace Gadgeteer
  9. {
  10. partial class Socket
  11. {
  12. /// <summary>
  13. /// This static class contains interfaces used by mainboards to provide functionalities on sockets to Gadgeteer.
  14. /// End users do not need to use this class directly and should normally use GTM.Modules to access functionality.
  15. /// Module developers do not need to use this class directly and should normally use GT.Socket and GT.Interfaces to access the required functionality.
  16. /// </summary>
  17. public static partial class SocketInterfaces
  18. {
  19. /// <summary>
  20. /// Creates a new <see cref="Socket" /> object specifying the socket number.
  21. /// </summary>
  22. /// <remarks>
  23. /// This should be used by the mainboard's constructor to create socket instances,
  24. /// which should then configure the socket properties as appropriate, and then call <see cref="RegisterSocket" />
  25. /// NB the socket name is fixed to be the same as the socket number.
  26. /// </remarks>
  27. /// <param name="socketNumber">The mainboard socket number</param>
  28. public static Socket CreateNumberedSocket(int socketNumber)
  29. {
  30. return new Socket(socketNumber, socketNumber.ToString());
  31. }
  32. /// <summary>
  33. /// Creates a new <see cref="Socket" /> object specifying the socket name.
  34. /// </summary>
  35. /// <remarks>
  36. /// This should be used by module constructors to create socket instances if they provide sockets to other modules.
  37. /// The module constructor should then configure the socket properties as appropriate, and then call <see cref="RegisterSocket" />
  38. /// A socketNumber is auto-assigned.
  39. /// </remarks>
  40. /// <param name="name">The socket's name</param>
  41. public static Socket CreateUnnumberedSocket(String name)
  42. {
  43. int socketNumber;
  44. lock (Socket._sockets)
  45. {
  46. while (Socket.GetSocket(autoSocketNumber, false, null, null) != null) autoSocketNumber--;
  47. socketNumber = autoSocketNumber;
  48. autoSocketNumber--;
  49. }
  50. return new Socket(socketNumber, name);
  51. }
  52. private static int autoSocketNumber = -10;
  53. private static bool DoRegistrationChecks = true;
  54. private static void SocketRegistrationError(Socket socket, string message)
  55. {
  56. Debug.Print("Warning: socket " + socket + " is not compliant with Gadgeteer : " + message);
  57. }
  58. private static void TestPinsPresent(Socket socket, int[] pins, char type)
  59. {
  60. for (int i = 0; i < pins.Length; i++)
  61. {
  62. if (socket.CpuPins[pins[i]] == Socket.UnspecifiedPin) SocketRegistrationError(socket, "Cpu pin " + pins[i] + " must be specified for socket of type " + type);
  63. }
  64. }
  65. /// <summary>
  66. /// Registers a socket. Should be used by mainboards and socket-providing modules during initialization.
  67. /// </summary>
  68. /// <param name="socket">The socket to register</param>
  69. public static void RegisterSocket(Socket socket)
  70. {
  71. if (DoRegistrationChecks)
  72. {
  73. if (socket.CpuPins == null || socket.CpuPins.Length != 11) SocketRegistrationError(socket, "CpuPins array must be of length 11");
  74. if (socket.SupportedTypes == null || socket.SupportedTypes.Length == 0) SocketRegistrationError(socket, "SupportedTypes list is null/empty");
  75. foreach (char type in socket.SupportedTypes)
  76. {
  77. switch (type)
  78. {
  79. case 'A':
  80. TestPinsPresent(socket, new int[] { 3, 4, 5, 6 }, type);
  81. if (socket.AnalogInputIndirector == null)
  82. {
  83. if (socket.AnalogInput3 == Cpu.AnalogChannel.ANALOG_NONE || socket.AnalogInput4 == Cpu.AnalogChannel.ANALOG_NONE || socket.AnalogInput5 == Cpu.AnalogChannel.ANALOG_NONE) SocketRegistrationError(socket, "Socket of type A must support analog input functionality on pins 3, 4 and 5");
  84. if (socket.AnalogInputScale == double.MinValue || socket.AnalogInputOffset == double.MinValue || socket.AnalogInputPrecisionInBits == int.MinValue) SocketRegistrationError(socket, "Socket of type A must provide analog input scale/offset through calling SocketInterfaces.SetAnalogInputFactors");
  85. }
  86. break;
  87. case 'C':
  88. TestPinsPresent(socket, new int[] { 3, 4, 5, 6 }, type);
  89. break;
  90. case 'D':
  91. TestPinsPresent(socket, new int[] { 3, 6, 7 }, type);
  92. break;
  93. case 'E':
  94. TestPinsPresent(socket, new int[] { 6, 7, 8, 9 }, type);
  95. break;
  96. case 'F':
  97. TestPinsPresent(socket, new int[] { 3, 4, 5, 6, 7, 8, 9 }, type);
  98. break;
  99. case 'H':
  100. TestPinsPresent(socket, new int[] { 3 }, type);
  101. break;
  102. case 'I':
  103. TestPinsPresent(socket, new int[] { 3, 6, 8, 9 }, type);
  104. break;
  105. case 'K':
  106. TestPinsPresent(socket, new int[] { 3, 4, 5, 6, 7 }, type);
  107. if (socket.SerialIndirector == null)
  108. {
  109. if (socket.SerialPortName == null) SocketRegistrationError(socket, "Socket of type K must specify serial port name");
  110. }
  111. break;
  112. case 'O':
  113. TestPinsPresent(socket, new int[] { 3, 4, 5 }, type);
  114. if (socket.AnalogOutputIndirector == null)
  115. {
  116. if (socket.AnalogOutput5 == Cpu.AnalogOutputChannel.ANALOG_OUTPUT_NONE) SocketRegistrationError(socket, "Socket of type O must support analog output functionality");
  117. if (socket.AnalogOutputScale == double.MinValue || socket.AnalogOutputOffset == double.MinValue || socket.AnalogOutputPrecisionInBits == int.MinValue) SocketRegistrationError(socket, "Socket of type O must provide analog output scale/offset through calling SocketInterfaces.SetAnalogOutputFactors");
  118. }
  119. break;
  120. case 'P':
  121. TestPinsPresent(socket, new int[] { 3, 6, 7, 8, 9 }, type);
  122. if (socket.PwmOutputIndirector == null)
  123. {
  124. if (socket.PWM7 == Cpu.PWMChannel.PWM_NONE || socket.PWM8 == Cpu.PWMChannel.PWM_NONE || socket.PWM9 == Cpu.PWMChannel.PWM_NONE) SocketRegistrationError(socket, "Socket of type P must support PWM functionality");
  125. }
  126. break;
  127. case 'S':
  128. TestPinsPresent(socket, new int[] { 3, 4, 5, 6, 7, 8, 9 }, type);
  129. if (socket.SpiIndirector == null)
  130. {
  131. if (socket.SPIModule == Socket.SocketInterfaces.SPIMissing) SocketRegistrationError(socket, "Socket of type S must specify SPI module number");
  132. }
  133. break;
  134. case 'T':
  135. TestPinsPresent(socket, new int[] { 4, 5, 6, 7 }, type);
  136. break;
  137. case 'U':
  138. TestPinsPresent(socket, new int[] { 3, 4, 5, 6 }, type);
  139. if (socket.SerialIndirector == null)
  140. {
  141. if (socket.SerialPortName == null) SocketRegistrationError(socket, "Socket of type U must specify serial port name");
  142. }
  143. break;
  144. case 'R':
  145. TestPinsPresent(socket, new int[] { 3, 4, 5, 6, 7, 8, 9 }, type);
  146. break;
  147. case 'G':
  148. TestPinsPresent(socket, new int[] { 3, 4, 5, 6, 7, 8, 9 }, type);
  149. break;
  150. case 'B':
  151. TestPinsPresent(socket, new int[] { 3, 4, 5, 6, 7, 8, 9 }, type);
  152. break;
  153. case 'X':
  154. TestPinsPresent(socket, new int[] { 3, 4, 5 }, type);
  155. break;
  156. case 'Y':
  157. TestPinsPresent(socket, new int[] { 3, 4, 5, 6, 7, 8, 9 }, type);
  158. break;
  159. case 'Z':
  160. // manufacturer specific socket - no tests
  161. break;
  162. case '*':
  163. // * is a special case - daisylink modules don't actually declare their new socket in code, instead reusing the mainboard socket number
  164. // so we don't need the below, but it doesnt hurt to leave it in
  165. TestPinsPresent(socket, new int[] { 3, 4, 5 }, type);
  166. break;
  167. default:
  168. SocketRegistrationError(socket, "Socket type '" + type + "' is not supported by Gadgeteer");
  169. break;
  170. }
  171. }
  172. }
  173. lock (Socket._sockets)
  174. {
  175. if (Socket.GetSocket(socket.SocketNumber, false, null, null) != null) throw new Socket.InvalidSocketException("Cannot register socket - socket number " + socket.SocketNumber + " already used");
  176. Socket._sockets.Add(socket);
  177. socket._registered = true;
  178. }
  179. }
  180. /// <summary>
  181. /// Set the scale and offset used by <see cref="Microsoft.SPOT.Hardware.AnalogInput.Read" /> to transform the raw value into a voltage between 0 and 3.3V, and the precision in bits.
  182. /// </summary>
  183. /// <param name="scale">The multiplicative scale factor.</param>
  184. /// <param name="offset">The additive offset.</param>
  185. /// <param name="precisionInBits">The number of bits precision by this analog input socket.</param>
  186. /// <param name="socket">The socket being configured.</param>
  187. public static void SetAnalogInputFactors(Socket socket, double scale, double offset, int precisionInBits)
  188. {
  189. socket.AnalogInputScale = scale;
  190. socket.AnalogInputOffset = offset;
  191. socket.AnalogInputPrecisionInBits = precisionInBits;
  192. }
  193. /// <summary>
  194. /// Set the scale and offset used by <see cref="Microsoft.SPOT.Hardware.AnalogInput.Read" /> to transform the raw value into a voltage between 0 and 3.3V, and the precision in bits.
  195. /// </summary>
  196. /// <param name="scale">The multiplicative scale factor.</param>
  197. /// <param name="offset">The additive offset.</param>
  198. /// <param name="precisionInBits">The number of bits precision by this analog input socket.</param>
  199. /// <param name="socket">The socket being configured.</param>
  200. public static void SetAnalogOutputFactors(Socket socket, double scale, double offset, int precisionInBits)
  201. {
  202. socket.AnalogOutputScale = scale;
  203. socket.AnalogOutputOffset = offset;
  204. socket.AnalogOutputPrecisionInBits = precisionInBits;
  205. }
  206. /// <summary>
  207. /// A value indicating that a socket has no associated SPI bus
  208. /// </summary>
  209. public static readonly SPI.SPI_module SPIMissing = (SPI.SPI_module)(-1);
  210. }
  211. }
  212. }