UNPKG

4.93 kBJavaScriptView Raw
1var Options = require("./board.options");
2
3var MODES = {
4 INPUT: 0x00,
5 OUTPUT: 0x01,
6 ANALOG: 0x02,
7 PWM: 0x03,
8 SERVO: 0x04
9};
10
11
12/**
13 * Pin Capability Signature Mapping
14 */
15
16var pinsToType = {
17 20: "UNO",
18 25: "LEONARDO",
19 70: "MEGA"
20};
21
22function Pins(board) {
23 if (!(this instanceof Pins)) {
24 return new Pins(board);
25 }
26
27 var io = board.io;
28 var pins = io.pins.slice();
29 var length = pins.length;
30 var type = pinsToType[length] || "OTHER";
31
32 board.type = type;
33
34 // Copy pin data to index
35 for (var i = 0; i < length; i++) {
36 this[i] = pins[i];
37 }
38
39 Object.defineProperties(this, {
40 type: {
41 value: type
42 },
43 length: {
44 value: length
45 }
46 });
47
48 // If an IO Plugin or Expander defines
49 // these, override the default
50 [
51 "isInput",
52 "isOutput",
53 "isAnalog",
54 "isPwm",
55 "isServo",
56 ].forEach(function(isType) {
57 if (io[isType]) {
58 this[isType] = io[isType];
59 }
60 }, this);
61}
62
63Object.keys(MODES).forEach(function(mode) {
64 Object.defineProperty(Pins, mode, {
65 value: MODES[mode]
66 });
67});
68
69function isFirmata(board) {
70 return board.io.name === "Firmata" || board.io.name === "Mock";
71}
72
73function hasPins(opts) {
74 return typeof opts.pin !== "undefined" ||
75 (typeof opts.pins !== "undefined" && opts.pins.length);
76}
77
78Pins.isFirmata = isFirmata;
79
80Pins.Error = function(opts) {
81 throw new Error(
82 "Pin Error: " + opts.pin +
83 " is not a valid " + opts.type +
84 " pin (" + opts.via + ")"
85 );
86};
87
88var normalizers = new Map();
89
90Pins.normalize = function(opts, board) {
91 var type = board.pins.type;
92 var isArduino = isFirmata(board);
93 var normalizer = normalizers.get(board);
94 var isNormalizing;
95
96 if (typeof opts === "string" ||
97 typeof opts === "number" ||
98 Array.isArray(opts)) {
99
100 opts = new Options(opts);
101 }
102
103 if (!normalizer) {
104 isNormalizing = board.io && typeof board.io.normalize === "function";
105
106 normalizer = function(pin) {
107 return isArduino ?
108 Pins.fromAnalog(Pins.translate(pin, type)) :
109 (isNormalizing ? board.io.normalize(pin) : pin);
110 };
111
112 normalizers.set(board, normalizer);
113 }
114
115 // Auto-normalize pin values, this reduces boilerplate code
116 // inside module constructors
117 if (hasPins(opts)) {
118
119 // When an array of pins is present, attempt to
120 // normalize them if necessary
121 if (opts.pins) {
122 opts.pins = opts.pins.map(normalizer);
123 } else {
124 opts.pin = normalizer(opts.pin);
125 }
126 }
127
128 return opts;
129};
130
131Pins.normalize.clear = function() {
132 normalizers.clear();
133};
134
135// Special kit-centric pin translations
136Pins.translations = {
137 UNO: {
138 dtoa: {
139 14: "A0",
140 15: "A1",
141 16: "A2",
142 17: "A3",
143 18: "A4",
144 19: "A5"
145 },
146
147 // TinkerKit
148 tinker: {
149 I0: "A0",
150 I1: "A1",
151 I2: "A2",
152 I3: "A3",
153 I4: "A4",
154 I5: "A5",
155
156 O0: 11,
157 O1: 10,
158 O2: 9,
159 O3: 6,
160 O4: 5,
161 O5: 3,
162
163 D13: 13,
164 D12: 12,
165 D8: 8,
166 D7: 7,
167 D4: 4,
168 D2: 2
169 }
170 },
171 MEGA: {
172 dtoa: {
173 54: "A0",
174 55: "A1",
175 56: "A2",
176 57: "A3",
177 58: "A4",
178 59: "A5",
179 60: "A6",
180 61: "A7",
181 62: "A8",
182 63: "A9"
183 },
184
185 // TinkerKit
186 tinker: {
187 I0: "A0",
188 I1: "A1",
189 I2: "A2",
190 I3: "A3",
191 I4: "A4",
192 I5: "A5",
193 I6: "A6",
194 I7: "A7",
195 I8: "A8",
196 I9: "A9",
197
198 O0: 11,
199 O1: 10,
200 O2: 9,
201 O3: 6,
202 O4: 5,
203 O5: 3,
204
205 D13: 13,
206 D12: 12,
207 D8: 8,
208 D7: 7,
209 D4: 4,
210 D2: 2
211 }
212 }
213};
214
215Pins.translations.LEONARDO = Pins.translations.UNO;
216
217Pins.translate = function(pin, type) {
218 var translations = Pins.translations[type.toUpperCase()];
219
220 if (!translations) {
221 return pin;
222 }
223
224 return Object.keys(translations).reduce(function(pin, map) {
225 return translations[map][pin] || pin;
226 }, pin);
227};
228
229Pins.fromAnalog = function(pin) {
230 if (typeof pin === "string" && pin[0] === "A") {
231 return parseInt(pin.slice(1), 10);
232 }
233 return pin;
234};
235
236Pins.identity = function(pins, needle) {
237 return [].findIndex.call(pins, function(pin) {
238 return pin.name === needle || pin.id === needle || pin.port === needle;
239 });
240};
241
242/**
243 * (generated methods)
244 *
245 * Pins.prototype.isInput
246 * Pins.prototype.isOutput
247 * Pins.prototype.isAnalog
248 * Pins.prototype.isPwm
249 * Pins.prototype.isServo
250 *
251 */
252Object.keys(MODES).forEach(function(key) {
253 var name = key[0] + key.slice(1).toLowerCase();
254
255 Pins.prototype["is" + name] = function(pin) {
256 var attrs = this[pin] || this[Pins.identity(this, pin)];
257
258 if (attrs && attrs.supportedModes.includes(MODES[key])) {
259 return true;
260 }
261 return false;
262 };
263});
264
265Pins.prototype.isDigital = function(pin) {
266 var attrs = this[pin] || this[Pins.identity(this, pin)];
267
268 if (attrs && attrs.supportedModes.length) {
269 return true;
270 }
271 return false;
272};
273
274module.exports = Pins;