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