LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
d_analog.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 
64 #define IN_CONNECT_STEADY_TIME 350 // [mS] time needed to be sure that the connection is steady
65 #define IN_DISCONNECT_STEADY_TIME 100 // [mS] time needed to be sure that the disconnection is steady
66 
67 #define IN1_NEAR_5V 4800 // [mV] higher values mean that connection 1 is floating
68 #define IN1_NEAR_PIN2 3100 // [mV] higher values mean that connection 1 is shorted to connection 2 (5000 * 18K / (18K + 10k))
69 #define IN1_TOUCH_HIGH 950 // [mV] values in between these limits means that an old touch sensor is connected
70 #define IN1_TOUCH_LOW 850 // [mV]
71 #define IN1_NEAR_GND 100 // [mV] lower values mean that connection 1 is shorted to connection 3
72 #define IN6_NEAR_GND 150 // [mV] lower values mean that connection 6 is floating
73 
74 /*
75 
76 INPUT
77 *********************************************************************************************************************************************************************************************************************
78 
79 MICRO CIRCUIT CONNECTION NEW UART DEVICE NEW DUMB SENSOR OLD SENSOR TACHO MOTOR NEW DUMP ACTUATOR
80 ---------------------- ---------------------------------- ---------- --------------------- ------------------------ -------------------- ---------------- -----------------
81 Analogue I 10K pull up to ADC_REF 1 Short circuit to ground ID resistor to ground Analogue value Motor + Motor +
82 
83 Digital I 6K4 impedance to NEAR_PIN2 voltage 2 Open Open Short to ground Motor - Motor -
84 
85 Ground Ground 3 Ground Ground Ground Ground ?
86 
87 Supply Supply 4 Supply Supply Supply Supply ?
88 
89 Digital I/O (float) 100K pull up to 3.3V 5 RXD (float) Short to ground ? Tacho A ID resistor to 5
90 
91 Analogue I + Digital I/O (float) 220K pull down to ground 6 TXD (low) Analogue value ? Tacho B ID resistor to 6
92 
93 *********************************************************************************************************************************************************************************************************************
94 
95 
96 
97 ID VALUE ON CONNECTION 1:
98 
99  ADC_REF -----
100  IN1_NEAR_5V -----
101  |
102  |
103  | TACHO MOTOR and NEW DUMB ACTUATOR
104  |
105  |
106  IN1_NEAR_PIN2 -----
107  |
108  |
109  |
110  |
111  |
112  |
113  |
114  | NEW SENSOR ID's
115  |
116  |
117  |
118  |
119  |
120  |
121  | NEW UART SENSOR
122  0.0V -----
123 
124 
125 
126 IMPLEMENTED DETECTION RULES (sequence matters):
127 
128 I. Connection 2 low
129  1. Connection 5 and 6 high -> NXT IIC DEVICE
130  2. Connection 5 low -> NXT LIGHT SENSOR
131  3. Connection 1 lower than IN1_NEAR_GND -> NXT COLOR SENSOR
132  4. Connection 1 higher than IN1_NEAR_5V -> NXT TOUCH SENSOR
133  5. Connection 1 between IN1_TOUCH_HIGH and IN1_TOUCH_LOW -> NXT TOUCH SENSOR
134  6. else -> NXT SOUND SENSOR
135 
136 
137 II. Connection 1 loaded
138  1. Connection 1 higher than IN1_NEAR_PIN2 -> ERROR
139  2. Connection 1 lower than IN1_NEAR_GND -> NEW UART DEVICE
140  3. else (value on connection 1 is ID) -> NEW DUMB DEVICE
141 
142 
143 III. Connection 6 high -> NXT IIC TEMP SENSOR
144 
145 
146 IV. Connection 5 low -> ERROR
147 
148 
149 
150 NEW ID's:
151 
152 The range from 0mV to just beneath the voltage on connection 2 is free to be used for the new sensor ID's - recommendations:
153 
154 I. Use a short circuit to ground to identify the UART device.
155 
156 \endverbatim
157  *
158  * \n
159  */
160 
178 #define OUT5_IIC_HIGH 3700 // [mV] values in between these limits means that an old IIC sensor or color sensor is connected
179 #define OUT5_IIC_LOW 2800 // [mV]
180 
181 #define OUT5_MINITACHO_HIGH1 2000 // [mV] values in between these limits means that a mini tacho motor is pulling high when pin5 is pulling low
182 #define OUT5_MINITACHO_LOW1 1600 // [mV]
183 
184 #define OUT5_BALANCE_HIGH 2600 // [mV] values in between these limits means that connection 5 is floating
185 #define OUT5_BALANCE_LOW 2400 // [mV]
186 
187 #define OUT5_LIGHT_HIGH 850 // [mV] values in between these limits means that an old light sensor is connected
188 #define OUT5_LIGHT_LOW 650 // [mV]
189 
190 #define OUT5_MINITACHO_HIGH2 450 // [mV] values in between these limits means that a mini tacho motor is pulling low when pin5 floats
191 #define OUT5_MINITACHO_LOW2 250 // [mV]
192 
193 #define OUT5_NEAR_GND 100 // [mV] lower values mean that connection 5 is shorted to ground
194 
195 /*
196 
197 
198 OUTPUT
199 *********************************************************************************************************************************************************************************************************************
200 
201 MICRO CIRCUIT CONNECTION NEW UART DEVICE NEW DUMB SENSOR OLD SENSOR TACHO MOTOR NEW DUMP ACTUATOR
202 ---------------------- ------------------------------- ---------- --------------------- ------------------------ -------------------- ---------------- -----------------
203 Motor driver + Connected to motor driver 1 ID resistor to ground ID resistor to ground Analogue value Motor + Motor +
204 
205 Motor driver - 100K pull up to ADC_REF 2 Open Open Short to ground Motor - Motor -
206 
207 Ground Ground 3 Ground Ground Ground Ground ?
208 
209 Supply Supply 4 Supply Supply Supply Supply ?
210 
211 Analogue I + Digital I/O 50K impedance to OUT5_BALANCE 5 RXD (float) Short to ground ? Tacho A ID resistor to 5
212 
213 Digital I/O (low) 100K pull up to connection 2 6 TXD (low) Analogue value ? Tacho B ID resistor to 6
214 
215 *********************************************************************************************************************************************************************************************************************
216 
217 
218 
219 ID VALUE ON CONNECTION 5:
220 
221  Connection 6 floating Connection 6 low and value on connection 5 changed
222  --------------------------------------------------------------------------------------- --------------------------------------------------
223 
224  ADC_REF -------------------------------------------------------------------------------------------------
225  NEAR_5V ----- |
226  | |
227  | |
228  3.3 - | - - - - - - - - - - - - - - - - - - - - - - | - - - - - - - - - - - - - - - - - - - - - - - - 2014 ADC reference voltage
229  | LARGE TACHO MOTOR -
230  | MINI TACHO MOTOR, NEW DUMB MOTOR - OLD TACHO MOTOR
231  | NEW TACHO MOTOR -
232  OUT5_IIC_HIGH ----- |
233  | OLD IIC SENSOR -
234  OUT5_IIC_LOW ----- |
235  | |
236  OUT5_BALANCE_HIGH ----- |
237  | OPEN -
238  OUT5_BALANCE_LOW ----- |
239  | | -----
240  | | |
241  | | |
242  | | | NEW ACTUATOR ID's
243  | | |
244  | | |
245  | | -----
246  OUT5_LIGHT_HIGH ----- |
247  | OLD LIGHT SENSOR -
248  OUT5_LIGHT_LOW ----- |
249  | NEW TACHO MOTOR -
250  | MINI TACHO MOTOR -
251  | LARGE TACHO MOTOR -
252  OUT5_NEAR_GND ----- -----
253  | NEW DUMB SENSOR
254  0.0V -------------------------------------------------------------------------------------------------
255 
256 When something is connected: the value on connection 5 is stored as Value5Float. Connection 6 is driven low and the value on connection 5 is then stored as Value5Low.
257 Connection 6 is set floating again.
258 The two stored values is used to determine the type of the attached device.
259 
260 
261 IMPLEMENTED DETECTION RULES (sequence matters):
262 
263 I. Value5Float is equal to Value5Low
264  1. Value5Float is between OUT5_BALANCE_LOW and OUT5_BALANCE_HIGH and Connection 6 is low -> ERROR (NXT TOUCH SENSOR, NXT SOUND SENSOR, NEW UART SENSOR)
265  2. Value5Float is lower than OUT5_NEAR_GND -> ERROR (NEW DUMP SENSOR)
266  3. Value5Float is between OUT5_LIGHT_LOW and OUT5_LIGHT_HIGH -> ERROR (OLD IIC SENSOR)
267  4. Value5Float is between OUT5_IIC_LOW and OUT5_IIC_HIGH -> ERROR (OLD TEMP SENSOR)
268  5. Value5Float is lower than OUT5_BALANCE_LOW
269  Value5Float is higher than OUT5_MINITACHO_HIGH2 -> NEW TACHO
270  Value5Float is higher than OUT5_MINITACHO_LOW2 -> MINI TACHO (NEW MINI TACHO MOTOR)
271  else -> TACHO MOTOR
272  6. Set connection 5 low and measure new Value5Low
273  7. VALUE5Low is lower than OUT5_MINITACHO_LOW1 -> NEW TACHO (NEW MINI TACHO MOTOR)
274  VALUE5Low is lower than OUT5_MINITACHO_HIGH1 -> MINI TACHO (NEW MINI TACHO MOTOR)
275  else -> TACHO MOTOR
276 
277 II. Value5Float is NOT equal to Value5Low
278  1. Value5Low is between OUT5_NEAR_GND and OUT5_BALANCE_LOW -> NEW DUMP ACTUATOR (ID is Value5Low)
279  2. else -> ERROR
280 
281 
282 
283 NEW ID's:
284 
285 The range from 800mV to OUT5_BALANCE_LOW is free to be used for the new sensor ID's - recommendations:
286 
287 I. Use a short circuit between connection 5 and connection 6 to identify the cheapest device
288 
289 II. Remember to reserve one id for the smart actuator (maybe the highest resistance = 500K)
290 
291 III. Remember that the ID resistor must get connection 5 out of balance
292 
293 IV. Remember the voltage on pin 1 when connected to an input port
294 
295 
296 \endverbatim
297  *
298  * \n
299  */
300 
301 
302 #ifndef PCASM
303 #include <asm/types.h>
304 #include <linux/time.h>
305 #endif
306 
307 #define HW_ID_SUPPORT
308 
309 #include "../../lms2012/source/lms2012.h"
310 #include "../../lms2012/source/am1808.h"
311 
312 #ifdef DEBUG_D_ANALOG
313 #define DEBUG
314 #endif
315 
316 
317 int Hw = 0;
318 
319 
321 {
329 };
330 
331 
333 {
339 };
340 
341 
343 {
351 };
352 
353 
355 {
359 };
360 
361 
362 #define INPUTADCPORTS 12
363 #define INPUTADCPOWERS 4
364 #define INPUTADC (INPUTADCPORTS + INPUTADCPOWERS)
365 
366 #define NO_OF_INPUT_PORTS INPUTS
367 #define NO_OF_OUTPUT_PORTS OUTPUTS
368 
369 static void InputPortFloat(int Port);
370 
372 
374 
376 
377 
387 static const UBYTE InputReadMap[INPUTADC] = { 6,8,10,12,5,7,9,11,1,0,13,14,2,15,3,4 };
388 
389 /* \endverbatim
390  * \n
391  */
392 
393 
402 // EP2
403 
404 
405 INPIN EP2_InputPortPin[][INPUT_PORT_PINS] =
406 {
407  { // Input port 1
408  { GP8_10 , NULL, 0 }, // Pin 1 - I_ONA - 9V enable (high)
409  { GP2_2 , NULL, 0 }, // Pin 2 - LEGDETA - Digital input pulled up
410  { GP0_2 , NULL, 0 }, // Pin 5 - DIGIA0 - Digital input/output
411  { GP0_15 , NULL, 0 }, // Pin 6 - DIGIA1 - Digital input/output
412  { GP8_11 , NULL, 0 }, // Buffer disable
413  },
414  { // Input port 2
415  { GP8_12 , NULL, 0 }, // Pin 1 - I_ONB - 9V enable (high)
416  { GP8_15 , NULL, 0 }, // Pin 2 - LEGDETB - Digital input pulled up
417  { GP0_14 , NULL, 0 }, // Pin 5 - DIGIB0 - Digital input/output
418  { GP0_13 , NULL, 0 }, // Pin 6 - DIGIB1 - Digital input/output
419  { GP8_14 , NULL, 0 }, // Buffer disable
420  },
421  { // Input port 3
422  { GP8_9 , NULL, 0 }, // Pin 1 - I_ONC - 9V enable (high)
423  { GP7_11 , NULL, 0 }, // Pin 2 - LEGDETC - Digital input pulled up
424  { GP0_12 , NULL, 0 }, // Pin 5 - DIGIC0 - Digital input/output
425  { GP1_14 , NULL, 0 }, // Pin 6 - DIGIC1 - Digital input/output
426  { GP7_9 , NULL, 0 }, // Buffer disable
427  },
428  { // Input port 4
429  { GP6_4 , NULL, 0 }, // Pin 1 - I_OND - 9V enable (high)
430  { GP7_8 , NULL, 0 }, // Pin 2 - LEGDETD - Digital input pulled up
431  { GP0_1 , NULL, 0 }, // Pin 5 - DIGID0 - Digital input/output
432  { GP1_15 , NULL, 0 }, // Pin 6 - DIGID1 - Digital input/output
433  { GP7_10 , NULL, 0 }, // Buffer disable
434  },
435 };
436 
437 
439 {
440  { // Output port 1
441  { GP3_15 , NULL, 0 }, // Pin 1 - MAIN0
442  { GP3_6 , NULL, 0 }, // Pin 2 - MAIN1
443  { GP5_4 , NULL, 0 }, // Pin 5 - DETA0 TP18
444  { GP5_11 , NULL, 0 }, // Pin 5 - INTA0
445  { GP0_4 , NULL, 0 }, // Pin 6 - DIRA
446  },
447  { // Output port 2
448  { GP0_3 , NULL, 0 }, // Pin 1 - MBIN0
449  { GP2_1 , NULL, 0 }, // Pin 2 - MBIN1
450  { GP2_5 , NULL, 0 }, // Pin 5 - DETB0 TP19
451  { GP5_8 , NULL, 0 }, // Pin 5 - INTB0
452  { GP2_9 , NULL, 0 }, // Pin 6 - DIRB
453  },
454  { // Output port 3
455  { GP6_8 , NULL, 0 }, // Pin 1 - MCIN0
456  { GP5_9 , NULL, 0 }, // Pin 2 - MCIN1
457  { GP3_8 , NULL, 0 }, // Pin 5 - DETC0 TP20
458  { GP5_13 , NULL, 0 }, // Pin 5 - INTC0
459  { GP3_14 , NULL, 0 }, // Pin 6 - DIRC
460  },
461  { // Output port 4
462  { GP5_10 , NULL, 0 }, // Pin 1 - MDIN0
463  { GP5_3 , NULL, 0 }, // Pin 2 - MDIN1
464  { GP5_15 , NULL, 0 }, // Pin 5 - DETD0 TP21
465  { GP6_9 , NULL, 0 }, // Pin 5 - INTD0
466  { GP2_8 , NULL, 0 }, // Pin 6 - DIRD
467  },
468 };
469 
470 
471 INPIN EP2_AdcPowerPin[ADC_POWER_PINS] =
472 {
473  { GP6_14 , NULL, 0 }, // 5VONIGEN
474  { GP0_6 , NULL, 0 }, // ADCBATEN
475 };
476 
477 
478 // FINALB
479 
480 
481 INPIN FINALB_InputPortPin[][INPUT_PORT_PINS] =
482 {
483  { // Input port 1
484  { GP8_10 , NULL, 0 }, // Pin 1 - I_ONA - 9V enable (high)
485  { GP2_2 , NULL, 0 }, // Pin 2 - LEGDETA - Digital input pulled up
486  { GP0_2 , NULL, 0 }, // Pin 5 - DIGIA0 - Digital input/output
487  { GP0_15 , NULL, 0 }, // Pin 6 - DIGIA1 - Digital input/output
488  { GP8_11 , NULL, 0 }, // Buffer disable
489  },
490  { // Input port 2
491  { GP8_12 , NULL, 0 }, // Pin 1 - I_ONB - 9V enable (high)
492  { GP8_15 , NULL, 0 }, // Pin 2 - LEGDETB - Digital input pulled up
493  { GP0_14 , NULL, 0 }, // Pin 5 - DIGIB0 - Digital input/output
494  { GP0_13 , NULL, 0 }, // Pin 6 - DIGIB1 - Digital input/output
495  { GP8_14 , NULL, 0 }, // Buffer disable
496  },
497  { // Input port 3
498  { GP8_9 , NULL, 0 }, // Pin 1 - I_ONC - 9V enable (high)
499  { GP7_11 , NULL, 0 }, // Pin 2 - LEGDETC - Digital input pulled up
500  { GP0_12 , NULL, 0 }, // Pin 5 - DIGIC0 - Digital input/output
501  { GP1_14 , NULL, 0 }, // Pin 6 - DIGIC1 - Digital input/output
502  { GP7_9 , NULL, 0 }, // Buffer disable
503  },
504  { // Input port 4
505  { GP6_4 , NULL, 0 }, // Pin 1 - I_OND - 9V enable (high)
506  { GP7_8 , NULL, 0 }, // Pin 2 - LEGDETD - Digital input pulled up
507  { GP1_13 , NULL, 0 }, // Pin 5 - DIGID0 - Digital input/output
508  { GP1_15 , NULL, 0 }, // Pin 6 - DIGID1 - Digital input/output
509  { GP7_10 , NULL, 0 }, // Buffer disable
510  },
511 };
512 
513 
515 {
516  { // Output port 1
517  { GP0_3 , NULL, 0 }, // Pin 1 - MAIN0
518  { GP4_12 , NULL, 0 }, // Pin 2 - MAIN1
519  { GP5_4 , NULL, 0 }, // Pin 5 - DETA0 TP18
520  { GP5_11 , NULL, 0 }, // Pin 5 - INTA0
521  { GP0_4 , NULL, 0 }, // Pin 6 - DIRA
522  },
523  { // Output port 2
524  { GP3_15 , NULL, 0 }, // Pin 1 - MBIN0
525  { GP3_6 , NULL, 0 }, // Pin 2 - MBIN1
526  { GP2_5 , NULL, 0 }, // Pin 5 - DETB0 TP19
527  { GP5_8 , NULL, 0 }, // Pin 5 - INTB0
528  { GP2_9 , NULL, 0 }, // Pin 6 - DIRB
529  },
530  { // Output port 3
531  { GP5_10 , NULL, 0 }, // Pin 1 - MCIN0
532  { GP5_3 , NULL, 0 }, // Pin 2 - MCIN1
533  { GP3_2 , NULL, 0 }, // Pin 5 - DETC0 TP20
534  { GP5_13 , NULL, 0 }, // Pin 5 - INTC0
535  { GP3_14 , NULL, 0 }, // Pin 6 - DIRC
536  },
537  { // Output port 4
538  { GP6_8 , NULL, 0 }, // Pin 1 - MDIN0
539  { GP5_9 , NULL, 0 }, // Pin 2 - MDIN1
540  { GP5_15 , NULL, 0 }, // Pin 5 - DETD0 TP21
541  { GP6_9 , NULL, 0 }, // Pin 5 - INTD0
542  { GP2_8 , NULL, 0 }, // Pin 6 - DIRD
543  },
544 };
545 
546 
547 INPIN FINALB_AdcPowerPin[ADC_POWER_PINS] =
548 {
549  { GP6_14 , NULL, 0 }, // 5VONIGEN
550  { GP0_6 , NULL, 0 }, // ADCBATEN
551 };
552 
553 
554 // FINAL
555 
556 
557 INPIN FINAL_InputPortPin[][INPUT_PORT_PINS] =
558 {
559  { // Input port 1
560  { GP8_10 , NULL, 0 }, // Pin 1 - I_ONA - 9V enable (high)
561  { GP2_2 , NULL, 0 }, // Pin 2 - LEGDETA - Digital input pulled up
562  { GP0_2 , NULL, 0 }, // Pin 5 - DIGIA0 - Digital input/output
563  { GP0_15 , NULL, 0 }, // Pin 6 - DIGIA1 - Digital input/output
564  { GP8_11 , NULL, 0 }, // Buffer disable
565  },
566  { // Input port 2
567  { GP8_12 , NULL, 0 }, // Pin 1 - I_ONB - 9V enable (high)
568  { GP8_15 , NULL, 0 }, // Pin 2 - LEGDETB - Digital input pulled up
569  { GP0_14 , NULL, 0 }, // Pin 5 - DIGIB0 - Digital input/output
570  { GP0_13 , NULL, 0 }, // Pin 6 - DIGIB1 - Digital input/output
571  { GP8_14 , NULL, 0 }, // Buffer disable
572  },
573  { // Input port 3
574  { GP8_9 , NULL, 0 }, // Pin 1 - I_ONC - 9V enable (high)
575  { GP7_11 , NULL, 0 }, // Pin 2 - LEGDETC - Digital input pulled up
576  { GP0_12 , NULL, 0 }, // Pin 5 - DIGIC0 - Digital input/output
577  { GP1_14 , NULL, 0 }, // Pin 6 - DIGIC1 - Digital input/output
578  { GP7_9 , NULL, 0 }, // Buffer disable
579  },
580  { // Input port 4
581  { GP6_4 , NULL, 0 }, // Pin 1 - I_OND - 9V enable (high)
582  { GP7_8 , NULL, 0 }, // Pin 2 - LEGDETD - Digital input pulled up
583  { GP1_13 , NULL, 0 }, // Pin 5 - DIGID0 - Digital input/output
584  { GP1_15 , NULL, 0 }, // Pin 6 - DIGID1 - Digital input/output
585  { GP7_10 , NULL, 0 }, // Buffer disable
586  },
587 };
588 
589 
591 {
592  { // Output port 1
593  { GP0_3 , NULL, 0 }, // Pin 1 - MAIN0
594  { GP4_12 , NULL, 0 }, // Pin 2 - MAIN1
595  { GP5_4 , NULL, 0 }, // Pin 5 - DETA0 TP18
596  { GP5_11 , NULL, 0 }, // Pin 5 - INTA0
597  { GP0_4 , NULL, 0 }, // Pin 6 - DIRA
598  },
599  { // Output port 2
600  { GP3_15 , NULL, 0 }, // Pin 1 - MBIN0
601  { GP3_6 , NULL, 0 }, // Pin 2 - MBIN1
602  { GP2_5 , NULL, 0 }, // Pin 5 - DETB0 TP19
603  { GP5_8 , NULL, 0 }, // Pin 5 - INTB0
604  { GP2_9 , NULL, 0 }, // Pin 6 - DIRB
605  },
606  { // Output port 3
607  { GP5_10 , NULL, 0 }, // Pin 1 - MCIN0
608  { GP5_3 , NULL, 0 }, // Pin 2 - MCIN1
609  { GP3_2 , NULL, 0 }, // Pin 5 - DETC0 TP20
610  { GP5_13 , NULL, 0 }, // Pin 5 - INTC0
611  { GP3_14 , NULL, 0 }, // Pin 6 - DIRC
612  },
613  { // Output port 4
614  { GP6_8 , NULL, 0 }, // Pin 1 - MDIN0
615  { GP5_9 , NULL, 0 }, // Pin 2 - MDIN1
616  { GP5_15 , NULL, 0 }, // Pin 5 - DETD0 TP21
617  { GP6_9 , NULL, 0 }, // Pin 5 - INTD0
618  { GP2_8 , NULL, 0 }, // Pin 6 - DIRD
619  },
620 };
621 
622 
623 INPIN FINAL_AdcPowerPin[ADC_POWER_PINS] =
624 {
625  { GP6_14 , NULL, 0 }, // 5VONIGEN
626  { GP0_6 , NULL, 0 }, // ADCBATEN
627 };
628 
629 
630 #ifndef ADC_BITBANGING
631 
632 INPIN AdcSpiPin[ADC_SPI_PINS] =
633 {
634  { SPI0_MOSI , NULL, 0 }, // ADCMOSI
635  { SPI0_MISO , NULL, 0 }, // ADCMISO
636  { SPI0_SCL , NULL, 0 }, // ADCCLK
637  { SPI0_CS , NULL, 0 } // ADCCS
638 };
639 
640 #else
641 
642 INPIN AdcSpiPin[ADC_SPI_PINS] =
643 {
644  { GP8_5 , NULL, 0 }, // ADCMOSI
645  { GP8_6 , NULL, 0 }, // ADCMISO
646  { GP1_8 , NULL, 0 }, // ADCCLK
647  { GP8_2 , NULL, 0 } // ADCCS
648 };
649 
650 #endif
651 
652 
653 /* \endverbatim
654  * \n
655  */
656 
657 #define PUDisable iowrite32(ioread32(da8xx_syscfg1_base + 0x0C) & ~0xFFFFFFFF,da8xx_syscfg1_base + 0x0C)
658 
659 
661 {
662  [FINAL] = (INPIN*)&FINAL_InputPortPin[0], // FINAL platform
663  [FINALB] = (INPIN*)&FINALB_InputPortPin[0], // FINALB platform
664  [EP2] = (INPIN*)&EP2_InputPortPin[0], // EP2 platform
665 };
666 
667 
669 {
670  [FINAL] = FINAL_OutputPortPin[0], // FINAL platform
671  [FINALB] = FINALB_OutputPortPin[0], // FINALB platform
672  [EP2] = EP2_OutputPortPin[0], // EP2 platform
673 };
674 
675 
677 {
678  [FINAL] = FINAL_AdcPowerPin, // FINAL platform
679  [FINALB] = FINALB_AdcPowerPin, // FINALB platform
680  [EP2] = EP2_AdcPowerPin, // EP2 platform
681 };
682 
683 
684 //*****************************************************************************
685 
686 #define MODULE_NAME "analog_module"
687 #define DEVICE1_NAME ANALOG_DEVICE
688 #define DEVICE2_NAME TEST_PIN_DEVICE
689 #define DEVICE3_NAME DCM_DEVICE
690 
691 static int ModuleInit(void);
692 static void ModuleExit(void);
693 
694 #define __USE_POSIX
695 
696 #include <linux/kernel.h>
697 #include <linux/fs.h>
698 
699 #include <linux/sched.h>
700 
701 
702 #ifndef PCASM
703 #ifndef DISABLE_PREEMPTED_VM
704 #include <linux/slab.h>
705 #endif
706 #include <linux/mm.h>
707 #include <linux/hrtimer.h>
708 
709 #include <linux/init.h>
710 #include <linux/uaccess.h>
711 #include <linux/debugfs.h>
712 
713 #include <linux/ioport.h>
714 #include <asm/gpio.h>
715 #include <asm/io.h>
716 #include <linux/module.h>
717 #include <linux/miscdevice.h>
718 #include <asm/uaccess.h>
719 
720 MODULE_LICENSE("GPL");
721 MODULE_AUTHOR("The LEGO Group");
724 
725 module_init(ModuleInit);
726 module_exit(ModuleExit);
727 
728 #else
729 // Keep Eclipse happy
730 #endif
731 
732 
733 static void __iomem *GpioBase;
734 
735 void SetGpio(int Pin)
736 {
737  int Tmp = 0;
738  void __iomem *Reg;
739 
740  if (Pin >= 0)
741  {
742  while ((MuxRegMap[Tmp].Pin != -1) && (MuxRegMap[Tmp].Pin != Pin))
743  {
744  Tmp++;
745  }
746  if (MuxRegMap[Tmp].Pin == Pin)
747  {
748  Reg = da8xx_syscfg0_base + 0x120 + (MuxRegMap[Tmp].MuxReg << 2);
749 
750  *(u32*)Reg &= MuxRegMap[Tmp].Mask;
751  *(u32*)Reg |= MuxRegMap[Tmp].Mode;
752 
753  if (Pin < NO_OF_GPIOS)
754  {
755  #ifdef DEBUG
756  printk(" GP%d_%-2d 0x%08X and 0x%08X or 0x%08X\n",(Pin >> 4),(Pin & 0x0F),(u32)Reg, MuxRegMap[Tmp].Mask, MuxRegMap[Tmp].Mode);
757  #endif
758  }
759  else
760  {
761  #ifdef DEBUG
762  printk(" ANALOG SPI FUNCTION 0x%08X and 0x%08X or 0x%08X\n",(u32)Reg, MuxRegMap[Tmp].Mask, MuxRegMap[Tmp].Mode);
763  #endif
764  }
765  }
766  else
767  {
768  printk("* GP%d_%-2d ********* ERROR not found *********\n",(Pin >> 4),(Pin & 0x0F));
769  }
770  }
771 }
772 
773 
774 void InitGpio(void)
775 {
776  int Port;
777  int Pin;
778 
779  // unlock
780  REGUnlock;
781 
782  memcpy(InputPortPin,pInputPortPin[Hw],sizeof(EP2_InputPortPin));
783  if (memcmp((const void*)InputPortPin,(const void*)pInputPortPin[Hw],sizeof(EP2_InputPortPin)) != 0)
784  {
785  printk("%s InputPortPin tabel broken!\n",MODULE_NAME);
786  }
787 
788  for (Port = 0;Port < NO_OF_INPUT_PORTS;Port++)
789  {
790 #ifdef DEBUG
791  printk(" Input port %d\n",Port + 1);
792 #endif
793  for (Pin = 0;Pin < INPUT_PORT_PINS;Pin++)
794  {
795  if (InputPortPin[Port][Pin].Pin >= 0)
796  {
797  InputPortPin[Port][Pin].pGpio = (struct gpio_controller *__iomem)(GpioBase + ((InputPortPin[Port][Pin].Pin >> 5) * 0x28) + 0x10);
798  InputPortPin[Port][Pin].Mask = (1 << (InputPortPin[Port][Pin].Pin & 0x1F));
799 
800  SetGpio(InputPortPin[Port][Pin].Pin);
801  }
802  }
803  }
804 #ifdef DEBUG
805  printk(" Adc spi\n");
806 #endif
807  for (Pin = 0;Pin < ADC_SPI_PINS;Pin++)
808  {
809  AdcSpiPin[Pin].pGpio = (struct gpio_controller *__iomem)(GpioBase + ((AdcSpiPin[Pin].Pin >> 5) * 0x28) + 0x10);
810  AdcSpiPin[Pin].Mask = (1 << (AdcSpiPin[Pin].Pin & 0x1F));
811 
812  SetGpio(AdcSpiPin[Pin].Pin);
813  }
814  memcpy(OutputPortPin,pOutputPortPin[Hw],sizeof(EP2_OutputPortPin));
815  if (memcmp((const void*)OutputPortPin,(const void*)pOutputPortPin[Hw],sizeof(EP2_OutputPortPin)) != 0)
816  {
817  printk("%s OutputPortPin tabel broken!\n",MODULE_NAME);
818  }
819  for (Port = 0;Port < NO_OF_OUTPUT_PORTS;Port++)
820  {
821 #ifdef DEBUG
822  printk(" Output port %d\n",Port + 1);
823 #endif
824  for (Pin = 0;Pin < OUTPUT_PORT_PINS;Pin++)
825  {
826  if (OutputPortPin[Port][Pin].Pin >= 0)
827  {
828  OutputPortPin[Port][Pin].pGpio = (struct gpio_controller *__iomem)(GpioBase + ((OutputPortPin[Port][Pin].Pin >> 5) * 0x28) + 0x10);
829  OutputPortPin[Port][Pin].Mask = (1 << (OutputPortPin[Port][Pin].Pin & 0x1F));
830 
831  SetGpio(OutputPortPin[Port][Pin].Pin);
832  }
833  }
834  }
835 #ifdef DEBUG
836  printk(" Adc power\n");
837 #endif
838  memcpy(AdcPowerPin,pAdcPowerPin[Hw],sizeof(EP2_AdcPowerPin));
839  if (memcmp((const void*)AdcPowerPin,(const void*)pAdcPowerPin[Hw],sizeof(EP2_AdcPowerPin)) != 0)
840  {
841  printk("%s AdcPowerPin tabel broken!\n",MODULE_NAME);
842  }
843 
844  for (Pin = 0;Pin < ADC_POWER_PINS;Pin++)
845  {
846  if (AdcPowerPin[Pin].Pin >= 0)
847  {
848  AdcPowerPin[Pin].pGpio = (struct gpio_controller *__iomem)(GpioBase + ((AdcPowerPin[Pin].Pin >> 5) * 0x28) + 0x10);
849  AdcPowerPin[Pin].Mask = (1 << (AdcPowerPin[Pin].Pin & 0x1F));
850 
851  SetGpio(AdcPowerPin[Pin].Pin);
852  }
853  }
854 
855  // Disable pull up/down
856  PUDisable;
857 
858  // lock
859  REGLock;
860 }
861 
862 
863 #define PINFloat(port,pin) {\
864  (*InputPortPin[port][pin].pGpio).dir |= InputPortPin[port][pin].Mask;\
865  }
866 
867 
868 #define PINRead(port,pin) ((*InputPortPin[port][pin].pGpio).in_data & InputPortPin[port][pin].Mask)
869 
870 
871 #define PINHigh(port,pin) {\
872  (*InputPortPin[port][pin].pGpio).set_data = InputPortPin[port][pin].Mask;\
873  (*InputPortPin[port][pin].pGpio).dir &= ~InputPortPin[port][pin].Mask;\
874  }
875 
876 #define PINLow(port,pin) {\
877  (*InputPortPin[port][pin].pGpio).clr_data = InputPortPin[port][pin].Mask;\
878  (*InputPortPin[port][pin].pGpio).dir &= ~InputPortPin[port][pin].Mask;\
879  }
880 
881 
882 #define POUTFloat(port,pin) {\
883  (*OutputPortPin[port][pin].pGpio).dir |= OutputPortPin[port][pin].Mask;\
884  }
885 
886 
887 #define POUTRead(port,pin) ((*OutputPortPin[port][pin].pGpio).in_data & OutputPortPin[port][pin].Mask)
888 
889 
890 #define POUTHigh(port,pin) {\
891  (*OutputPortPin[port][pin].pGpio).set_data = OutputPortPin[port][pin].Mask;\
892  (*OutputPortPin[port][pin].pGpio).dir &= ~OutputPortPin[port][pin].Mask;\
893  }
894 
895 
896 #define POUTLow(port,pin) {\
897  (*OutputPortPin[port][pin].pGpio).clr_data = OutputPortPin[port][pin].Mask;\
898  (*OutputPortPin[port][pin].pGpio).dir &= ~OutputPortPin[port][pin].Mask;\
899  }
900 
901 #define IGENOn {\
902  (*AdcPowerPin[ADCONIGEN].pGpio).set_data = AdcPowerPin[ADCONIGEN].Mask;\
903  (*AdcPowerPin[ADCONIGEN].pGpio).dir &= ~AdcPowerPin[ADCONIGEN].Mask;\
904  }
905 
906 
907 #define IGENOff {\
908  (*AdcPowerPin[ADCONIGEN].pGpio).clr_data = AdcPowerPin[ADCONIGEN].Mask;\
909  (*AdcPowerPin[ADCONIGEN].pGpio).dir &= ~AdcPowerPin[ADCONIGEN].Mask;\
910  }
911 
912 #define BATENOn {\
913  (*AdcPowerPin[ADCBATEN].pGpio).set_data = AdcPowerPin[ADCBATEN].Mask;\
914  (*AdcPowerPin[ADCBATEN].pGpio).dir &= ~AdcPowerPin[ADCBATEN].Mask;\
915  }
916 
917 
918 #define BATENOff {\
919  (*AdcPowerPin[ADCBATEN].pGpio).clr_data = AdcPowerPin[ADCBATEN].Mask;\
920  (*AdcPowerPin[ADCBATEN].pGpio).dir &= ~AdcPowerPin[ADCBATEN].Mask;\
921  }
922 
923 
924 
925 #ifdef DISABLE_OLD_COLOR
926 
927 static UBYTE CtoH(UBYTE Char)
928 {
929  UBYTE Hex = 0;
930 
931  if ((Char >= '0') && (Char <= '9'))
932  {
933  Hex = Char - '0';
934  }
935  else
936  {
937  if ((Char >= 'a') && (Char <= 'f'))
938  {
939  Hex = Char - 'a' + 10;
940  }
941  else
942  {
943  if ((Char >= 'A') && (Char <= 'F'))
944  {
945  Hex = Char - 'A' + 10;
946  }
947  }
948  }
949 
950  return (Hex);
951 }
952 
953 #endif
954 
955 // SW SPI *********************************************************************
956 
957 #ifndef ADC_BITBANGING
958 
959 #define SPI0_CLOCK 150000000
960 
961 #define ADC_TIME 8 // [uS]
962 
963 
964 #define ADC_CLOCK (((ULONG)1000000 * (ULONG)16) / (ULONG)ADC_TIME)
965 #define CNVSPD (((ULONG)SPI0_CLOCK / (ULONG)ADC_CLOCK) - 1)
966 
967 /* SPI Register number */
968 #define SPIGCR0 0
969 #define SPIGCR1 1
970 #define SPIINT0 2
971 #define SPILVL 3
972 #define SPIFLG 4
973 #define SPIPC0 5
974 #define SPIPC1 6
975 #define SPIPC2 7
976 #define SPIPC3 8
977 #define SPIPC4 9
978 #define SPIPC5 10
979 #define SPIDAT0 14
980 #define SPIDAT1 15
981 #define SPIBUF 16
982 #define SPIEMU 17
983 #define SPIDELAY 18
984 #define SPIDEF 19
985 #define SPIFMT0 20
986 #define SPIFMT1 21
987 #define SPIFMT2 22
988 #define SPIFMT3 23
989 #define INTVEC1 25
990 
991 
992 static volatile unsigned long *Spi0;
993 
994 #define SPIRxempty (Spi0[SPIBUF] & 0x80000000)
995 #define SPITxfull (Spi0[SPIBUF] & 0x20000000)
996 
997 #define SPIInit {\
998  Spi0[SPIGCR1] = 0x00000003; /* Master enable */\
999  Spi0[SPIPC0] = 0x00000E08; /* */\
1000  Spi0[SPIDAT1] = 0x0; /* Format 0 is selected */\
1001  Spi0[SPIFMT0] = 0x00010010 | ((CNVSPD << 8) & 0xFF00);\
1002  Spi0[SPIDELAY] = 0x0A0A0A0A; /* Delays = 10 */\
1003  Spi0[SPIINT0] = 0x0; /* Interrupts disabled */\
1004  Spi0[SPIDEF] = 0x00000008;\
1005  Spi0[SPIGCR1] = 0x01000003; /* Enable bit */\
1006  }
1007 
1008 #define SPIExit {\
1009  Spi0[SPIGCR1] = 0x00000103; /* Master enable */\
1010  Spi0[SPIPC0] = 0x01010E01; /* */\
1011  Spi0[SPIDAT1] = 0x003F0000; /* Format 0 is selected */\
1012  Spi0[SPIFMT0] = 0x00010408 | ((CNVSPD << 8) & 0xFF00);\
1013  Spi0[SPIDELAY] = 0x00000000; /* Delays = 10 */\
1014  Spi0[SPIINT0] = 0x00000000; /* Interrupts disabled */\
1015  Spi0[SPIDEF] = 0x0000003F;\
1016  }
1017 
1018 
1019 
1028 
1029 
1030 void SpiSaveReg(void)
1031 {
1032  SpiSave0 = Spi0[SPIGCR0];
1033  SpiSave1 = Spi0[SPIGCR1];
1034  SpiSave2 = Spi0[SPIPC0];
1035  SpiSave3 = Spi0[SPIDAT1];
1036  SpiSave4 = Spi0[SPIFMT0];
1037  SpiSave5 = Spi0[SPIDELAY];
1038  SpiSave6 = Spi0[SPIINT0];
1039  SpiSave7 = Spi0[SPIDEF];
1040 }
1041 
1042 
1043 void SpiRestoreReg(void)
1044 {
1045  Spi0[SPIGCR0] = SpiSave0;
1046  Spi0[SPIGCR1] = SpiSave1;
1047  Spi0[SPIPC0] = SpiSave2;
1048  Spi0[SPIDAT1] = SpiSave3;
1049  Spi0[SPIFMT0] = SpiSave4;
1050  Spi0[SPIDELAY] = SpiSave5;
1051  Spi0[SPIINT0] = SpiSave6;
1052  Spi0[SPIDEF] = SpiSave7;
1053 }
1054 
1055 
1056 void SpiInit(void)
1057 {
1058  if (request_mem_region(0x01C41000,0x68,MODULE_NAME) >= 0)
1059  {
1060  Spi0 = (unsigned long*)ioremap(0x01C41000,0x68);
1061  if (Spi0 != NULL)
1062  {
1063  #ifdef DEBUG
1064  printk(" %s memory mapped from 0x%08lX\n",DEVICE1_NAME,(unsigned long)Spi0);
1065  #endif
1066  }
1067 
1068 #ifdef DEBUG
1069  printk("SPIGCR0 = 0x%08lX\n",Spi0[SPIGCR0]);
1070  printk("SPIGCR1 = 0x%08lX\n",Spi0[SPIGCR1]);
1071  printk("SPIPC0 = 0x%08lX\n",Spi0[SPIPC0]);
1072  printk("SPIDAT1 = 0x%08lX\n",Spi0[SPIDAT1]);
1073  printk("SPIFMT0 = 0x%08lX\n",Spi0[SPIFMT0]);
1074  printk("SPIDELAY = 0x%08lX\n",Spi0[SPIDELAY]);
1075  printk("SPIINT0 = 0x%08lX\n",Spi0[SPIINT0]);
1076  printk("SPIDEF = 0x%08lX\n",Spi0[SPIDEF]);
1077 #endif
1078  SpiSaveReg();
1079  SPIInit;
1080  }
1081 }
1082 
1083 
1084 void SpiExit(void)
1085 {
1086  SpiRestoreReg();
1087 #ifdef DEBUG
1088  printk("SPIGCR0 = 0x%08lX\n",Spi0[SPIGCR0]);
1089  printk("SPIGCR1 = 0x%08lX\n",Spi0[SPIGCR1]);
1090  printk("SPIPC0 = 0x%08lX\n",Spi0[SPIPC0]);
1091  printk("SPIDAT1 = 0x%08lX\n",Spi0[SPIDAT1]);
1092  printk("SPIFMT0 = 0x%08lX\n",Spi0[SPIFMT0]);
1093  printk("SPIDELAY = 0x%08lX\n",Spi0[SPIDELAY]);
1094  printk("SPIINT0 = 0x%08lX\n",Spi0[SPIINT0]);
1095  printk("SPIDEF = 0x%08lX\n",Spi0[SPIDEF]);
1096 #endif
1097  iounmap(Spi0);
1098 }
1099 
1100 
1102 {
1103 #ifndef DISABLE_ADC
1104  while (SPITxfull);
1105 
1106  Spi0[SPIDAT0] = (ULONG)DataOut;
1107 
1108  while (SPIRxempty);
1109 
1110  return ((UWORD)(Spi0[SPIBUF] & 0x0000FFFF));
1111 #else
1112  return(0);
1113 #endif
1114 }
1115 
1116 
1117 #else
1118 
1119 #define SIMOHigh {\
1120  (*AdcSpiPin[ADCMOSI].pGpio).set_data = AdcSpiPin[ADCMOSI].Mask;\
1121  }
1122 
1123 
1124 #define SIMOLow {\
1125  (*AdcSpiPin[ADCMOSI].pGpio).clr_data = AdcSpiPin[ADCMOSI].Mask;\
1126  }
1127 
1128 
1129 #define CLKHigh {\
1130  (*AdcSpiPin[ADCCLK].pGpio).set_data = AdcSpiPin[ADCCLK].Mask;\
1131  }
1132 
1133 
1134 #define CLKLow {\
1135  (*AdcSpiPin[ADCCLK].pGpio).clr_data = AdcSpiPin[ADCCLK].Mask;\
1136  }
1137 
1138 
1139 #define SCSHigh {\
1140  (*AdcSpiPin[ADCCS].pGpio).set_data = AdcSpiPin[ADCCS].Mask;\
1141  }
1142 
1143 
1144 #define SCSLow {\
1145  (*AdcSpiPin[ADCCS].pGpio).clr_data = AdcSpiPin[ADCCS].Mask;\
1146  }
1147 
1148 
1149 #define SOMIFloat {\
1150  (*AdcSpiPin[ADCMISO].pGpio).dir |= AdcSpiPin[ADCMISO].Mask;\
1151  (*AdcSpiPin[ADCMOSI].pGpio).dir &= ~AdcSpiPin[ADCMOSI].Mask;\
1152  (*AdcSpiPin[ADCCLK].pGpio).dir &= ~AdcSpiPin[ADCCLK].Mask;\
1153  (*AdcSpiPin[ADCCS].pGpio).dir &= ~AdcSpiPin[ADCCS].Mask;\
1154  }
1155 
1156 
1157 #define SOMIRead ((*AdcSpiPin[ADCMISO].pGpio).in_data & AdcSpiPin[ADCMISO].Mask)
1158 
1159 
1160 
1161 
1162 void SpiInit(void)
1163 {
1164  SCSHigh;
1165  CLKLow;
1166  SIMOLow;
1167  SOMIFloat;
1168 }
1169 
1170 
1171 void SpiExit(void)
1172 {
1173  SCSHigh;
1174  CLKLow;
1175  SIMOLow;
1176  SOMIFloat;
1177 }
1178 
1179 
1181 {
1182  UWORD DataIn = 0;
1183  UBYTE Bit = 16;
1184 
1185 
1186  SCSLow;
1187 
1188  while (Bit--)
1189  {
1190  if (DataOut & 0x8000)
1191  {
1192  SIMOHigh;
1193  }
1194  else
1195  {
1196  SIMOLow;
1197  }
1198  CLKHigh;
1199  DataOut <<= 1;
1200  DataIn <<= 1;
1201  if (SOMIRead)
1202  {
1203  DataIn |= 1;
1204  }
1205  CLKLow;
1206  }
1207 
1208  SCSHigh;
1209 
1210  return (DataIn);
1211 }
1212 
1213 #endif
1214 
1215 
1216 // DEVICE1 ********************************************************************
1217 
1218 static struct hrtimer Device1Timer;
1219 static ktime_t Device1Time;
1220 
1221 static UBYTE TestMode = 0;
1222 
1223 static ANALOG AnalogDefault;
1224 
1225 static ANALOG *pAnalog = &AnalogDefault;
1226 static UWORD *pInputs = (UWORD*)&AnalogDefault;
1227 
1228 static UBYTE Device3State = 0;
1229 
1230 
1231 typedef struct
1232 {
1240 }
1241 INPORT;
1242 
1243 
1245 
1246 
1247 typedef struct
1248 {
1258 }
1259 OUTPORT;
1260 
1261 
1263 
1264 #ifndef DISABLE_OLD_COLOR
1265 
1266 /*
1267 
1268  NO NXT COLOR SENSOR ATTACHED
1269 
1270  |---------------------------------------------------------------------------------------------------|
1271  100uS
1272  |---------|
1273 
1274 
1275 Clock ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1276 
1277 
1278 INTR | | |
1279 
1280 SPI R/W |||| |||| ||
1281 
1282 PIN 1 ||||
1283 
1284 PIN 6 ||||
1285 
1286 Other ||
1287 
1288 MuxSetup 0123 4567 xx
1289 
1290 Converting x012 3456 7x
1291 
1292 Reading -x01 2345 67
1293 
1294 Time 0001 0002 01
1295 
1296 1 = 200uS
1297 2 = 600uS
1298 
1299 */
1300 
1301 #define SCHEMESIZE1 10
1302 
1303 static UBYTE MuxSetup1[SCHEMESIZE1] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x20,0x20 };
1304 
1305 static UBYTE Reading1[SCHEMESIZE1] = { 0x80,0x20,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 };
1306 
1307 static UBYTE NextTime1[SCHEMESIZE1] = { 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x01 };
1308 
1309 static ktime_t Time1[2];
1310 
1311 
1312 /*
1313 
1314  ONE OR MORE NXT COLOR SENSOR ATTACHED
1315 
1316  |---------------------------------------------------------------------------------------------------|
1317  100uS
1318  |---------|
1319 
1320  ,---------, ,---------,
1321 Clock | | | |
1322  --' '---------' '-------------------------------------------------------------------
1323 
1324 INTR | | | |
1325 
1326 Colour convert || | | ||
1327 
1328 SPI R/W |||| |||| |||| |||
1329 
1330 PIN 1 || | |
1331 
1332 PIN 6 | | ||
1333 
1334 Other |
1335 
1336 MuxSetup e012 r345 g67x bee
1337 
1338 Converting ee01 2r34 5g67 xbe
1339 
1340 Reading --e0 12r3 45g6 7xb
1341 
1342 ClockHigh 0100 0000 0100 000
1343 
1344 ClockLow 0000 0100 0000 010
1345 
1346 NextTime 0001 0001 0002 001
1347 
1348 1 = 200uS
1349 2 = 400uS
1350 
1351 */
1352 
1353 #define SCHEMESIZE2 15
1354 
1355 static UBYTE MuxSetup2[SCHEMESIZE2] = { 0x13,0x00,0x01,0x02,0x10,0x03,0x04,0x05,0x11,0x06,0x07,0x20,0x12,0x20,0x20 };
1356 
1357 static UBYTE Reading2[SCHEMESIZE2] = { 0x80,0x20,0x13,0x00,0x01,0x02,0x10,0x03,0x04,0x05,0x11,0x06,0x07,0x80,0x12 };
1358 
1359 static UBYTE ClockHigh2[SCHEMESIZE2] = { 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00 };
1360 
1361 static UBYTE ClockLow2[SCHEMESIZE2] = { 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00 };
1362 
1363 static UBYTE NextTime2[SCHEMESIZE2] = { 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x01 };
1364 
1365 static ktime_t Time2[2];
1366 static ktime_t NextTime;
1367 
1368 static UBYTE InputPoint1 = 8;
1369 
1370 static UBYTE Color = 0;
1371 static UBYTE NxtPointer = 0;
1372 static UBYTE NxtColorActive[INPUTS];
1373 static UBYTE Nxtcolor[INPUTS];
1374 static UBYTE NxtcolorCmd[INPUTS];
1375 static UBYTE NxtcolorLatchedCmd[INPUTS];
1376 static UBYTE InputPoint2 = 0;
1377 
1378 
1379 
1380 static enum hrtimer_restart Device1TimerInterrupt1(struct hrtimer *pTimer)
1381 {
1382  UBYTE Port;
1383  UWORD *pData;
1384  UWORD Data;
1385  UWORD Input;
1386 
1387  // restart timer
1388  hrtimer_forward_now(pTimer,NextTime);
1389 
1390  if (NxtPointer == 0)
1391  {
1392  if (++InputPoint2 >= INPUTS)
1393  {
1394  InputPoint2 = 0;
1395  }
1396 #ifndef DISABLE_PREEMPTED_VM
1397  ((*pAnalog).PreemptMilliSeconds)++;
1398 #endif
1399  }
1400 
1401  if (!Color)
1402  { // No NXT color sensor attached -> use scheme 1
1403 
1404  do
1405  {
1406  pData = &Data;
1407  if (MuxSetup1[NxtPointer] & 0x20)
1408  {
1409  Input = (UWORD)InputReadMap[InputPoint1];
1410  }
1411  else
1412  {
1413  Input = (UWORD)InputReadMap[MuxSetup1[NxtPointer] & 0x0F];
1414  }
1415 
1416  if (Reading1[NxtPointer] & 0x20)
1417  {
1418  pData = &pInputs[InputPoint1];
1419  if (++InputPoint1 >= INPUTADC)
1420  {
1421  InputPoint1 = 8;
1422  }
1423  }
1424  else
1425  {
1426  if (!(Reading1[NxtPointer] & 0xF0))
1427  {
1428  pData = &pInputs[Reading1[NxtPointer]];
1429  }
1430  }
1431 
1432  *pData = (UWORD)SpiUpdate((0x1840 | ((Input & 0x000F) << 7)));
1433  *pData &= 0x0FFF;
1434 
1435  NxtPointer++;
1436  }
1437  while ((NextTime1[NxtPointer - 1] == 0));
1438 
1439  NextTime = Time1[NextTime1[NxtPointer - 1] - 1];
1440 
1441  if (NxtPointer >= SCHEMESIZE1)
1442  {
1443  NxtPointer = 0;
1444  }
1445  }
1446  else
1447  { // One or more NXT color sensors attached -> use scheme 2
1448 
1449  do
1450  {
1451 
1452  pData = &Data;
1453  if (MuxSetup2[NxtPointer] & 0x20)
1454  {
1455  Input = (UWORD)InputReadMap[InputPoint1];
1456  }
1457  else
1458  {
1459  if (MuxSetup2[NxtPointer] & 0x10)
1460  {
1461  Input = (UWORD)InputReadMap[InputPoint2 + INPUTS];
1462  }
1463  else
1464  {
1465  Input = (UWORD)InputReadMap[MuxSetup2[NxtPointer] & 0x0F];
1466  }
1467  }
1468 
1469  if (Reading2[NxtPointer] & 0x20)
1470  {
1471  pData = &pInputs[InputPoint1];
1472  if (++InputPoint1 >= INPUTADC)
1473  {
1474  InputPoint1 = 8;
1475  }
1476  }
1477  else
1478  {
1479  if (Reading2[NxtPointer] & 0x10)
1480  {
1481  pData = (UWORD*)&(*pAnalog).NxtCol[InputPoint2].ADRaw[(Reading2[NxtPointer] & 0x03)];
1482  }
1483  else
1484  {
1485  if (!(Reading2[NxtPointer] & 0xF0))
1486  {
1487  pData = &pInputs[Reading2[NxtPointer]];
1488  }
1489  }
1490  }
1491 
1492  *pData = (UWORD)SpiUpdate((0x1840 | ((Input & 0x000F) << 7))) & 0xFFF;
1493  if (NxtcolorLatchedCmd[InputPoint2] == 0x0D)
1494  {
1495  if (ClockHigh2[NxtPointer])
1496  {
1497  if (Nxtcolor[InputPoint2])
1498  {
1499  if (ClockHigh2[NxtPointer] == 0x01)
1500  {
1501  PINHigh(InputPoint2,INPUT_PORT_PIN5);
1502  }
1503  else
1504  {
1505  PINFloat(InputPoint2,INPUT_PORT_PIN5);
1506  }
1507  }
1508  }
1509  if (ClockLow2[NxtPointer])
1510  {
1511  if (Nxtcolor[InputPoint2])
1512  {
1513  PINLow(InputPoint2,INPUT_PORT_PIN5);
1514  }
1515  }
1516  }
1517 
1518  NxtPointer++;
1519  }
1520  while ((NextTime2[NxtPointer - 1] == 0));
1521 
1522  NextTime = Time2[NextTime2[NxtPointer - 1] - 1];
1523 
1524  if (NxtPointer >= SCHEMESIZE2)
1525  {
1526  NxtPointer = 0;
1527  }
1528  }
1529 
1530  if (NxtPointer == 0)
1531  {
1532  Color = 0;
1533  for (Port = 0;Port < INPUTS;Port++)
1534  {
1535 #ifndef DISABLE_FAST_DATALOG_BUFFER
1536  if (NxtColorActive[Port])
1537  {
1538  Color = 1;
1539  }
1540  else
1541  { // Buffer for fast data logging
1542 
1543  (*pAnalog).Pin1[Port][(*pAnalog).LogIn[Port]] = (*pAnalog).InPin1[Port];
1544  (*pAnalog).Pin6[Port][(*pAnalog).LogIn[Port]] = (*pAnalog).InPin6[Port];
1545 
1546  (*pAnalog).Actual[Port] = (*pAnalog).LogIn[Port];
1547 
1548  if (++((*pAnalog).LogIn[Port]) >= DEVICE_LOGBUF_SIZE)
1549  {
1550  (*pAnalog).LogIn[Port] = 0;
1551  }
1552  if ((*pAnalog).LogIn[Port] == (*pAnalog).LogOut[Port])
1553  {
1554  if (++((*pAnalog).LogOut[Port]) >= DEVICE_LOGBUF_SIZE)
1555  {
1556  (*pAnalog).LogOut[Port] = 0;
1557  }
1558  }
1559  }
1560  Nxtcolor[Port] = NxtColorActive[Port];
1561 #else
1562  if (NxtColorActive[Port])
1563  {
1564  Color = 1;
1565  }
1566  Nxtcolor[Port] = NxtColorActive[Port];
1567 #endif
1568 
1569  (*pAnalog).Updated[Port] = 1;
1570  }
1571  NxtcolorLatchedCmd[InputPoint2] = NxtcolorCmd[InputPoint2];
1572  }
1573 
1574  return (HRTIMER_RESTART);
1575 }
1576 
1577 
1578 #else
1579 
1580 static UBYTE InputScheme1[INPUTADC + 1];
1581 static UBYTE InputScheme2[INPUTADC + 1];
1582 static UBYTE InputPoint1 = 0;
1583 static UBYTE InputPoint2 = 0;
1584 static UBYTE InputLast = 0;
1585 static UBYTE InputMid = 0;
1586 static UBYTE InputNext = 0;
1587 
1588 static enum hrtimer_restart Device1TimerInterrupt1(struct hrtimer *pTimer)
1589 {
1590  DATA8 Port;
1591 
1592  // find next channel from scheme 2 to convert
1593  InputScheme1[InputSchemeLng1] = InputScheme2[InputPoint2];
1594  if (++InputPoint2 >= InputSchemeLng2)
1595  {
1596  InputPoint2 = 0;
1597  }
1598 
1599  // do the scheme
1600  InputPoint1 = 0;
1601  while ((InputPoint1 < InputSchemeLng1) || ((InputPoint1 <= InputSchemeLng1) && (InputSchemeLng2)))
1602  {
1603  InputLast = InputMid;
1604  InputMid = InputNext;
1605  InputNext = InputScheme1[InputPoint1];
1606 
1607  pInputs[InputLast] = (UWORD)SpiUpdate((0x1850 | (InputReadMap[InputNext] << 7))) & 0xFFF;
1608  InputPoint1++;
1609 #if (HARDWARE == ONE2ONE)
1610  if (InputLast == 15)
1611  {
1612  pMuxData[MuxAddr] = pInputs[InputLast];
1613 
1614  if (++MuxAddr >= 8)
1615  {
1616  MuxAddr = 0;
1617  }
1618  SetMultiplexer(MuxAddr);
1619  }
1620 #endif
1621  }
1622 
1623  for (Port = 0;Port < INPUTS;Port++)
1624  {
1625  (*pAnalog).Updated[Port] = 1;
1626  }
1627 
1628  // restart timer
1629  hrtimer_forward_now(pTimer,Device1Time);
1630  return (HRTIMER_RESTART);
1631 }
1632 
1633 #endif
1634 
1635 
1637 {
1646 #ifndef DISABLE_OLD_COLOR
1651 #endif
1661 };
1662 
1663 
1665 {
1666  "DCM_INIT",
1667  "DCM_FLOATING_DELAY",
1668  "DCM_FLOATING\n",
1669  "DCM_WAITING_FOR_PIN5_LOW",
1670  "DCM_WAITING_FOR_PIN6_LOW",
1671  "DCM_CONNECTION",
1672  "DCM_PIN2_LOW",
1673  "DCM_NXT_TOUCH_CHECK",
1674 #ifndef DISABLE_OLD_COLOR
1675  "DCM_NXT_COLOR_INIT",
1676  "DCM_NXT_COLOR_WAIT",
1677  "DCM_NXT_COLOR_START",
1678  "DCM_NXT_COLOR_BUSY",
1679 #endif
1680  "DCM_CONNECTED_WAITING_FOR_PIN2_HIGH",
1681  "DCM_PIN1_LOADED",
1682  "DCM_CONNECTED_WAITING_FOR_PIN1_TO_FLOAT",
1683  "DCM_PIN6_HIGH",
1684  "DCM_PIN5_LOW",
1685  "DCM_CONNECTED_WAITING_FOR_PIN5_HIGH",
1686  "DCM_CONNECTED_WAITING_FOR_PIN6_LOW",
1687  "DCM_CONNECTED_WAITING_FOR_PORT_OPEN"
1688 };
1689 
1690 
1692 {
1693  0,
1694  0,
1695  DCM_INIT,
1696  -1,
1697  0,
1698  0
1699 };
1700 
1701 
1703 {
1704  0,
1705  0,
1706  0,
1707  0,
1708  0,
1709  DCM_INIT,
1710  -1,
1711  0,
1712  0,
1713 };
1714 
1715 
1716 static void InputPortFloat(int Port)
1717 {
1718  PINLow(Port,INPUT_PORT_PIN1);
1719  PINFloat(Port,INPUT_PORT_PIN2);
1720  PINFloat(Port,INPUT_PORT_PIN5);
1721  PINFloat(Port,INPUT_PORT_PIN6);
1722  PINHigh(Port,INPUT_PORT_BUF);
1723 }
1724 
1725 
1726 static void OutputPortFloat(int Port)
1727 {
1728  POUTLow(Port,OUTPUT_PORT_PIN1);
1729  POUTLow(Port,OUTPUT_PORT_PIN2);
1730  POUTLow(Port,OUTPUT_PORT_PIN5W);
1732 }
1733 
1734 
1736 {
1737  UWORD Pins = 0x0000;
1738  UWORD Mask = 0x0001;
1739  UBYTE Tmp;
1740 
1741  for (Tmp = 0;Tmp < INPUT_PORT_PINS;Tmp++)
1742  {
1743  if (PINRead(Port,Tmp))
1744  {
1745  Pins |= Mask;
1746  }
1747  Mask <<= 1;
1748  }
1749 
1750  return (Pins);
1751 }
1752 
1753 
1755 {
1756  UWORD Pins = 0x0000;
1757  UWORD Mask = 0x0001;
1758  UBYTE Tmp;
1759 
1760  for (Tmp = 0;Tmp < OUTPUT_PORT_PINS;Tmp++)
1761  {
1762  if (POUTRead(Port,Tmp))
1763  {
1764  Pins |= Mask;
1765  }
1766  Mask <<= 1;
1767  }
1768 
1769  return (Pins);
1770 }
1771 
1772 
1773 static ssize_t Device1Write(struct file *File,const char *Buffer,size_t Count,loff_t *Data)
1774 {
1775  int Lng = 0;
1776 
1777 
1778 
1779  return (Lng);
1780 }
1781 
1782 
1796 static ssize_t Device1Read(struct file *File,char *Buffer,size_t Count,loff_t *Offset)
1797 {
1798 
1799  int Lng = 0;
1800  int Tmp;
1801  int Point;
1802  UWORD Pins;
1803 
1804  for (Point = 0;Point < INPUTS;Point++)
1805  {
1806  Pins = Device1GetInputPins(Point);
1807  for (Tmp = 0;Tmp < INPUT_PORT_PINS;Tmp++)
1808  {
1809  if ((Pins & 0x0001))
1810  {
1811  Buffer[Lng++] = '1';
1812  }
1813  else
1814  {
1815  Buffer[Lng++] = '0';
1816  }
1817  Pins >>= 1;
1818  }
1819  Pins = Device1GetOutputPins(Point);
1820  for (Tmp = 0;Tmp < OUTPUT_PORT_PINS;Tmp++)
1821  {
1822  if ((Pins & 0x0001))
1823  {
1824  Buffer[Lng++] = '1';
1825  }
1826  else
1827  {
1828  Buffer[Lng++] = '0';
1829  }
1830  Pins >>= 1;
1831  }
1832  Buffer[Lng++] = ' ';
1833  }
1834 
1835  Buffer[Lng++] = '\r';
1836 
1837  Buffer[Lng++] = 0x1B;
1838  Buffer[Lng++] = '[';
1839  Buffer[Lng++] = 'B';
1840 
1841  Point = 0;
1842  Tmp = 5;
1843  while ((Count > Tmp) && (Point < INPUTADC))
1844  {
1845  if (Point != (INPUTADC - 1))
1846  {
1847  Tmp = snprintf(&Buffer[Lng],6,"%04u ",pInputs[Point]);
1848  }
1849  else
1850  {
1851  Tmp = snprintf(&Buffer[Lng],7,"%04u\r",pInputs[Point]);
1852  }
1853  Lng += Tmp;
1854  Count -= Tmp;
1855  Point++;
1856  }
1857 
1858  Buffer[Lng++] = 0x1B;
1859  Buffer[Lng++] = '[';
1860  Buffer[Lng++] = 'A';
1861 
1862 
1863 
1864  return (Lng);
1865 }
1866 
1867 #define SHM_LENGTH (sizeof(AnalogDefault))
1868 #define NPAGES ((SHM_LENGTH + PAGE_SIZE - 1) / PAGE_SIZE)
1869 static void *kmalloc_ptr;
1870 
1871 static int Device1Mmap(struct file *filp, struct vm_area_struct *vma)
1872 {
1873  int ret;
1874 
1875  ret = remap_pfn_range(vma,vma->vm_start,virt_to_phys((void*)((unsigned long)pAnalog)) >> PAGE_SHIFT,vma->vm_end-vma->vm_start,PAGE_SHARED);
1876 
1877  if (ret != 0)
1878  {
1879  ret = -EAGAIN;
1880  }
1881 
1882  return (ret);
1883 }
1884 
1885 
1886 static const struct file_operations Device1Entries =
1887 {
1888  .owner = THIS_MODULE,
1889  .read = Device1Read,
1890  .write = Device1Write,
1891  .mmap = Device1Mmap,
1892 };
1893 
1894 
1895 static struct miscdevice Device1 =
1896 {
1897  MISC_DYNAMIC_MINOR,
1898  DEVICE1_NAME,
1899  &Device1Entries
1900 };
1901 
1902 
1903 static int Device1Init(void)
1904 {
1905  int Result = -1;
1906  UWORD *pTmp;
1907  int i;
1908  DATA8 Port;
1909 
1910  Result = misc_register(&Device1);
1911  if (Result)
1912  {
1913  printk(" %s device register failed\n",DEVICE1_NAME);
1914  }
1915  else
1916  {
1917  SpiInit();
1918 
1919  SpiUpdate(0x400F);
1920  SpiUpdate(0x400F);
1921  SpiUpdate(0x400F);
1922  SpiUpdate(0x400F);
1923  SpiUpdate(0x400F);
1924  SpiUpdate(0x400F);
1925 
1926  // allocate kernel shared memory for analog values (pAnalog)
1927  if ((kmalloc_ptr = kmalloc((NPAGES + 2) * PAGE_SIZE, GFP_KERNEL)) != NULL)
1928  {
1929  pTmp = (UWORD*)((((unsigned long)kmalloc_ptr) + PAGE_SIZE - 1) & PAGE_MASK);
1930  for (i = 0; i < NPAGES * PAGE_SIZE; i += PAGE_SIZE)
1931  {
1932  SetPageReserved(virt_to_page(((unsigned long)pTmp) + i));
1933  }
1934  pAnalog = (ANALOG*)pTmp;
1935  memset(pAnalog,0,sizeof(ANALOG));
1936  pInputs = pTmp;
1937 
1938  for (Port = 0;Port < INPUTS;Port++)
1939  {
1940  (*pAnalog).InDcm[Port] = 0;
1941  (*pAnalog).InConn[Port] = 0;
1942  }
1943  for (Port = 0;Port < OUTPUTS;Port++)
1944  {
1945  (*pAnalog).OutDcm[Port] = 0;
1946  (*pAnalog).OutConn[Port] = 0;
1947  }
1948 
1949  // setup analog update timer interrupt
1950 
1951  Time1[0] = ktime_set(0,200000);
1952  Time1[1] = ktime_set(0,600000);
1953  Time2[0] = ktime_set(0,200000);
1954  Time2[1] = ktime_set(0,400000);
1955 
1956  NextTime = Time1[0];
1957 
1958  Device1Time = ktime_set(0,DEVICE_UPDATE_TIME);
1959  hrtimer_init(&Device1Timer,CLOCK_MONOTONIC,HRTIMER_MODE_REL);
1960  Device1Timer.function = Device1TimerInterrupt1;
1961  hrtimer_start(&Device1Timer,Device1Time,HRTIMER_MODE_REL);
1962 
1963 #ifdef DEBUG
1964  printk(" %s device register succes\n",DEVICE1_NAME);
1965 #endif
1966  }
1967  else
1968  {
1969  printk(" %s kmalloc failed !!\n",DEVICE1_NAME);
1970  }
1971  }
1972 
1973  return (Result);
1974 }
1975 
1976 
1977 static void Device1Exit(void)
1978 {
1979  UWORD *pTmp;
1980  int i;
1981 
1982  hrtimer_cancel(&Device1Timer);
1983 
1984  SpiExit();
1985 
1986  pTmp = pInputs;
1987  pInputs = (UWORD*)&AnalogDefault;
1988  pAnalog = &AnalogDefault;
1989 
1990  // free shared memory
1991  for (i = 0; i < NPAGES * PAGE_SIZE; i+= PAGE_SIZE)
1992  {
1993  ClearPageReserved(virt_to_page(((unsigned long)pTmp) + i));
1994 #ifdef DEBUG
1995  printk(" %s memory page %d unmapped\n",DEVICE1_NAME,i);
1996 #endif
1997  }
1998  kfree(kmalloc_ptr);
1999 
2000  misc_deregister(&Device1);
2001 #ifdef DEBUG
2002  printk(" %s device unregistered\n",DEVICE1_NAME);
2003 #endif
2004 }
2005 
2006 
2007 // DEVICE2 ********************************************************************
2008 
2009 #define BUFFER_LNG 16
2010 
2011 static int Device2Ioctl(struct inode *pNode, struct file *File, unsigned int Request, unsigned long Pointer)
2012 {
2013  int Result = 0;
2014  TSTPIN Tstpin;
2015  int Poi;
2016  int Lng;
2017  UWORD Pins;
2018  UBYTE Port;
2019  UBYTE Tmp;
2020 
2021 
2022  copy_from_user((void*)&Tstpin,(void*)Pointer,sizeof(TSTPIN));
2023 
2024  Port = Tstpin.Port;
2025  Lng = (int)Tstpin.Length;
2026 
2027  switch (Request)
2028  {
2029  case TST_PIN_OFF :
2030  { // Normal mode
2031 
2032  Device3State = 0;
2033  TestMode = 0;
2034  for (Port = 0;Port < INPUTS;Port++)
2035  {
2036  InputPort[Port].State = DCM_INIT;
2037  }
2038  for (Port = 0;Port < OUTPUTS;Port++)
2039  {
2040  OutputPort[Port].State = DCM_INIT;
2041  }
2042  }
2043  break;
2044 
2045  case TST_PIN_ON :
2046  { // Test mode
2047 
2048  Device3State = 0;
2049  TestMode = 1;
2050  for (Port = 0;Port < INPUTS;Port++)
2051  {
2052  InputPortFloat(Port);
2053  (*pAnalog).InDcm[Port] = TYPE_NONE;
2054  (*pAnalog).InConn[Port] = CONN_NONE;
2055  }
2056 
2057  for (Port = 0;Port < OUTPUTS;Port++)
2058  {
2059  OutputPortFloat(Port);
2060  (*pAnalog).OutDcm[Port] = TYPE_NONE;
2061  (*pAnalog).OutConn[Port] = CONN_NONE;
2062  }
2063  }
2064  break;
2065 
2066  case TST_PIN_READ :
2067  { // Read pins
2068 
2069  Poi = 0;
2070 
2071  if (Lng)
2072  {
2073  Lng--;
2074 
2075  if ((Port >= 0) && (Port < INPUTS))
2076  {
2077  Pins = Device1GetInputPins(Port);
2078  for (Tmp = 0;(Poi < Lng) && (Tmp < INPUT_PORT_PINS);Tmp++)
2079  {
2080  if ((Pins & 0x0001))
2081  {
2082  Tstpin.String[Poi] = '1';
2083  }
2084  else
2085  {
2086  Tstpin.String[Poi] = '0';
2087  }
2088  Pins >>= 1;
2089  Poi++;
2090  }
2091  }
2092  if (Port >= (INPUTS * CHAIN_DEPT))
2093  {
2094  Port -= (INPUTS * CHAIN_DEPT);
2095  if (Port < OUTPUTS)
2096  {
2097  Pins = Device1GetOutputPins(Port);
2098  for (Tmp = 0;(Poi < Lng) && (Tmp < OUTPUT_PORT_PINS);Tmp++)
2099  {
2100  if ((Pins & 0x0001))
2101  {
2102  Tstpin.String[Poi] = '1';
2103  }
2104  else
2105  {
2106  Tstpin.String[Poi] = '0';
2107  }
2108  Pins >>= 1;
2109  Poi++;
2110  }
2111  }
2112  }
2113  for (;Poi < Lng;Poi++)
2114  {
2115  Tstpin.String[Poi] = ' ';
2116  }
2117  Tstpin.String[Poi] = 0;
2118  Poi++;
2119  }
2120 
2121  copy_to_user((void*)Pointer,(void*)&Tstpin,sizeof(TSTPIN));
2122  }
2123  break;
2124 
2125  case TST_PIN_WRITE :
2126  { // Write pins
2127 
2128  Poi = 0;
2129 
2130  if ((Lng > 0) && (Lng < BUFFER_LNG))
2131  {
2132 
2133  if ((Port >= 0) && (Port < INPUTS))
2134  {
2135  for (Tmp = 0;(Poi < Lng) && (Tmp < INPUT_PORT_PINS);Tmp++)
2136  {
2137  if (Tstpin.String[Poi] == '0')
2138  {
2139  PINLow(Port,Tmp);
2140  }
2141  if (Tstpin.String[Poi] == '1')
2142  {
2143  PINHigh(Port,Tmp);
2144  }
2145  if ((Tstpin.String[Poi] == 'x') || (Tstpin.String[Poi] == 'X'))
2146  {
2147  PINFloat(Port,Tmp);
2148  }
2149  Poi++;
2150  }
2151  }
2152  if (Port >= (INPUTS * CHAIN_DEPT))
2153  {
2154  Port -= (INPUTS * CHAIN_DEPT);
2155  if (Port < OUTPUTS)
2156  {
2157  Pins = Device1GetOutputPins(Port);
2158  for (Tmp = 0;(Poi < Lng) && (Tmp < OUTPUT_PORT_PINS);Tmp++)
2159  {
2160  if (Tstpin.String[Poi] == '0')
2161  {
2162  POUTLow(Port,Tmp);
2163  }
2164  if (Tstpin.String[Poi] == '1')
2165  {
2166  POUTHigh(Port,Tmp);
2167  }
2168  if ((Tstpin.String[Poi] == 'x') || (Tstpin.String[Poi] == 'X'))
2169  {
2170  POUTFloat(Port,Tmp);
2171  }
2172  Poi++;
2173  }
2174  }
2175  }
2176  }
2177  }
2178  break;
2179  }
2180 
2181  return (Result);
2182 }
2183 
2184 
2185 static ssize_t Device2Write(struct file *File,const char *Buffer,size_t Count,loff_t *Data)
2186 {
2187  int Lng = 0;
2188 
2189 
2190 
2191  return (Lng);
2192 }
2193 
2194 
2195 static ssize_t Device2Read(struct file *File,char *Buffer,size_t Count,loff_t *Offset)
2196 {
2197  int Lng = 0;
2198  UWORD Pins;
2199  UBYTE Port;
2200  UBYTE Tmp;
2201 
2202  if (Count >= (INPUTS * (INPUT_PORT_PINS + OUTPUT_PORT_PINS + 1) + 2))
2203  {
2204  for (Port = 0;Port < INPUTS;Port++)
2205  {
2206  Pins = Device1GetInputPins(Port);
2207  for (Tmp = 0;Tmp < INPUT_PORT_PINS;Tmp++)
2208  {
2209  if ((Pins & 0x0001))
2210  {
2211  Buffer[Lng++] = '1';
2212  }
2213  else
2214  {
2215  Buffer[Lng++] = '0';
2216  }
2217  Pins >>= 1;
2218  }
2219  Pins = Device1GetOutputPins(Port);
2220  for (Tmp = 0;Tmp < OUTPUT_PORT_PINS;Tmp++)
2221  {
2222  if ((Pins & 0x0001))
2223  {
2224  Buffer[Lng++] = '1';
2225  }
2226  else
2227  {
2228  Buffer[Lng++] = '0';
2229  }
2230  Pins >>= 1;
2231  }
2232  Buffer[Lng++] = ' ';
2233  }
2234 
2235  Buffer[Lng++] = '\r';
2236  Buffer[Lng++] = 0;
2237  }
2238 
2239  return (Lng);
2240 }
2241 
2242 
2243 static const struct file_operations Device2Entries =
2244 {
2245  .owner = THIS_MODULE,
2246  .read = Device2Read,
2247  .write = Device2Write,
2248  .ioctl = Device2Ioctl
2249 };
2250 
2251 
2252 static struct miscdevice Device2 =
2253 {
2254  MISC_DYNAMIC_MINOR,
2255  DEVICE2_NAME,
2256  &Device2Entries
2257 };
2258 
2259 
2260 static int Device2Init(void)
2261 {
2262  int Result = -1;
2263 
2264  Result = misc_register(&Device2);
2265  if (Result)
2266  {
2267  printk(" %s device register failed\n",DEVICE2_NAME);
2268  }
2269  else
2270  {
2271 #ifdef DEBUG
2272  printk(" %s device register succes\n",DEVICE2_NAME);
2273 #endif
2274  }
2275 
2276  return (Result);
2277 }
2278 
2279 
2280 static void Device2Exit(void)
2281 {
2282  misc_deregister(&Device2);
2283 #ifdef DEBUG
2284  printk(" %s device unregistered\n",DEVICE2_NAME);
2285 #endif
2286 }
2287 
2288 
2289 // DEVICE3 ********************************************************************
2290 
2291 #define DCM_TIMER_RESOLUTION 10 // [mS]
2292 #define DCM_DEVICE_RESET_TIME 2000 // [mS]
2293 #define DCM_FLOAT_DELAY 20 // [mS]
2294 #define DCM_LOW_DELAY 20 // [mS]
2295 #define DCM_TOUCH_DELAY 20 // [mS]
2296 #define DCM_CONNECT_STABLE_DELAY IN_CONNECT_STEADY_TIME // [mS]
2297 #define DCM_EVENT_STABLE_DELAY IN_DISCONNECT_STEADY_TIME // [mS]
2298 
2299 #ifndef DISABLE_OLD_COLOR
2300 #define DCM_NXT_COLOR_TIMEOUT 500 // [mS]
2301 #define DCM_NXT_COLOR_INIT_DELAY 100 // [mS]
2302 #define DCM_NXT_COLOR_HIGH_TIME 20 // [mS]
2303 #endif
2304 
2305 static struct hrtimer Device3Timer;
2306 static ktime_t Device3Time;
2307 
2308 static UWORD Device3StateTimer;
2309 
2310 
2311 #ifndef DISABLE_OLD_COLOR
2312 
2313 static struct hrtimer NxtColorTimer;
2314 static ktime_t NxtColorTime;
2315 #define NXTCOLOR_TIMER_RESOLUTION 200 // [uS]
2316 
2317 
2318 
2319 
2320 
2321 
2322 #define NXTCOLOR_BYTES (12 * 4 + 3 * 2)
2323 #define NXTCOLOR_BITS (NXTCOLOR_BYTES * 8)
2324 
2325 static UBYTE NxtColorCmd[INPUTS];
2326 static UBYTE NxtColorByte[INPUTS];
2327 static UBYTE NxtColorTx[INPUTS];
2328 static UBYTE NxtColorClkHigh[INPUTS];
2329 
2330 static UBYTE NxtColorState[INPUTS] = { 0,0,0,0 };
2331 static UBYTE NxtColorBytePnt[INPUTS];
2332 static UBYTE NxtColorByteCnt[INPUTS];
2333 static UBYTE NxtColorBitCnt[INPUTS];
2334 static UBYTE NxtColorBuffer[INPUTS][NXTCOLOR_BYTES];
2335 
2336 static UWORD NxtColorInitTimer[INPUTS];
2337 static UBYTE NxtColorInitCnt[INPUTS];
2338 
2339 static UBYTE NxtColorInitInUse;
2340 
2341 
2342 
2343 static enum hrtimer_restart NxtColorCommIntr(struct hrtimer *pTimer)
2344 {
2345  UBYTE Port;
2346 
2347  hrtimer_forward_now(pTimer,NxtColorTime);
2348 
2349  for (Port = 0;Port < NO_OF_INPUT_PORTS;Port++)
2350  { // look at one port at a time
2351 
2352  if (NxtColorState[Port])
2353  {
2354  switch (NxtColorState[Port])
2355  {
2356  case 1 :
2357  {
2359  NxtColorState[Port]++;
2360  }
2361  break;
2362 
2363  case 2 :
2364  {
2365  if (PINRead(Port,INPUT_PORT_PIN5))
2366  {
2367  if (NxtColorInitCnt[Port] == 0)
2368  {
2369  PINHigh(Port,INPUT_PORT_PIN5);
2370  NxtColorState[Port]++;
2371  }
2372  else
2373  {
2374  NxtColorInitTimer[Port] = 0;
2375  NxtColorState[Port] += 2;
2376  }
2377  }
2378  else
2379  {
2380  PINHigh(Port,INPUT_PORT_PIN5);
2381  NxtColorState[Port]++;
2382  }
2383  }
2384  break;
2385 
2386  case 3 :
2387  {
2388  PINLow(Port,INPUT_PORT_PIN5);
2389  if (++NxtColorInitCnt[Port] >= 2)
2390  {
2391  NxtColorState[Port]++;
2392  }
2393  else
2394  {
2395  NxtColorState[Port] = 1;
2396  }
2397  }
2398  break;
2399 
2400  case 4 :
2401  {
2402  PINLow(Port,INPUT_PORT_PIN5);
2403  if (++NxtColorInitTimer[Port] >= ((DCM_NXT_COLOR_INIT_DELAY * 1000) / NXTCOLOR_TIMER_RESOLUTION))
2404  {
2405  NxtColorState[Port]++;
2406  }
2407  }
2408  break;
2409 
2410  case 5 :
2411  {
2412  NxtColorBuffer[Port][0] = NxtColorCmd[Port];
2413  NxtColorByteCnt[Port] = 1;
2414  NxtColorBytePnt[Port] = 0;
2415  NxtColorTx[Port] = 1;
2416  NxtColorState[Port]++;
2417  }
2418  break;
2419 
2420  case 6 :
2421  {
2422  if ((NxtColorBitCnt[Port] == 0) && (NxtColorByteCnt[Port] == 0))
2423  {
2424  NxtColorByteCnt[Port] = NXTCOLOR_BYTES;
2425  NxtColorBytePnt[Port] = 0;
2426  NxtColorTx[Port] = 0;
2427  NxtColorState[Port]++;
2428  }
2429  }
2430  break;
2431 
2432  case 7 :
2433  {
2434  if ((NxtColorBitCnt[Port] == 0) && (NxtColorByteCnt[Port] == 0))
2435  {
2436  NxtColorState[Port]++;
2437  }
2438  }
2439  break;
2440 
2441  default :
2442  {
2443  NxtColorState[Port] = 0;
2444  }
2445  break;
2446 
2447  }
2448 
2449  if (NxtColorBitCnt[Port])
2450  {
2451  if (!NxtColorClkHigh[Port])
2452  {
2453  if (NxtColorTx[Port])
2454  {
2455  if (NxtColorByte[Port] & 1)
2456  {
2457  PINHigh(Port,INPUT_PORT_PIN6);
2458  }
2459  else
2460  {
2461  PINLow(Port,INPUT_PORT_PIN6);
2462  }
2463  NxtColorByte[Port] >>= 1;
2464  }
2465  else
2466  {
2467  PINFloat(Port,INPUT_PORT_PIN6);
2468  }
2469  PINHigh(Port,INPUT_PORT_PIN5);
2470  NxtColorClkHigh[Port] = 1;
2471  }
2472  else
2473  {
2474 
2475  NxtColorBitCnt[Port]--;
2476  if (!NxtColorTx[Port])
2477  {
2478  NxtColorByte[Port] >>= 1;
2479  if (PINRead(Port,INPUT_PORT_PIN6))
2480  {
2481  NxtColorByte[Port] |= 0x80;
2482  }
2483  else
2484  {
2485  NxtColorByte[Port] &= ~0x80;
2486  }
2487  if (!NxtColorBitCnt[Port])
2488  {
2489  NxtColorBuffer[Port][NxtColorBytePnt[Port]] = NxtColorByte[Port];
2490  NxtColorBytePnt[Port]++;
2491  }
2492  }
2493  PINLow(Port,INPUT_PORT_PIN5);
2494  NxtColorClkHigh[Port] = 0;
2495  }
2496  }
2497  else
2498  {
2499  if (NxtColorByteCnt[Port])
2500  {
2501  if (NxtColorTx[Port])
2502  {
2503  NxtColorByte[Port] = NxtColorBuffer[Port][NxtColorBytePnt[Port]];
2504  NxtColorBytePnt[Port]++;
2505  }
2506  NxtColorBitCnt[Port] = 8;
2507  NxtColorByteCnt[Port]--;
2508  }
2509  }
2510  }
2511  }
2512 
2513  return (HRTIMER_RESTART);
2514 }
2515 
2516 
2518 {
2519  NxtColorState[Port] = 1;
2520  NxtColorInitCnt[Port] = 0;
2521  NxtColorBytePnt[Port] = 0;
2522  NxtColorByteCnt[Port] = 0;
2523  NxtColorBitCnt[Port] = 0;
2524  NxtColorCmd[Port] = Cmd;
2525 
2526  if (NxtColorInitInUse == 0)
2527  {
2528  NxtColorTime = ktime_set(0,NXTCOLOR_TIMER_RESOLUTION * 1000);
2529  hrtimer_init(&NxtColorTimer,CLOCK_MONOTONIC,HRTIMER_MODE_REL);
2530  NxtColorTimer.function = NxtColorCommIntr;
2531  hrtimer_start(&NxtColorTimer,NxtColorTime,HRTIMER_MODE_REL);
2532  }
2533  NxtColorInitInUse |= (1 << Port);
2534 }
2535 
2536 
2538 {
2539  UBYTE Result = 0;
2540 
2541  if (NxtColorState[Port] == 0)
2542  {
2543  Result = 1;
2544  }
2545 
2546  return (Result);
2547 }
2548 
2549 
2551 {
2552 
2553  NxtColorInitInUse &= ~(1 << Port);
2554 
2555  if (NxtColorInitInUse == 0)
2556  {
2557  hrtimer_cancel(&NxtColorTimer);
2558  }
2559  NxtColorState[Port] = 0;
2560 }
2561 
2562 
2563 #endif
2564 
2565 
2566 static enum hrtimer_restart Device3TimerInterrupt1(struct hrtimer *pTimer)
2567 {
2568  UBYTE Port;
2569  UBYTE Event;
2570  UWORD Tmp;
2571 #ifndef DISABLE_OLD_COLOR
2572  UBYTE *pData;
2573 #endif
2574 
2575  hrtimer_forward_now(pTimer,Device3Time);
2576 
2577  switch (Device3State)
2578  {
2579  case 0 :
2580  {
2581  if (TestMode == 0)
2582  {
2583  Device3State = 1;
2584  }
2585  }
2586  break;
2587 
2588  case 1 :
2589  {
2590 // IGENOff;
2591  Device3StateTimer = 0;
2592  Device3State++;
2593  }
2594  break;
2595 
2596  case 2 :
2597  {
2598  if (++Device3StateTimer >= (DCM_DEVICE_RESET_TIME / DCM_TIMER_RESOLUTION))
2599  {
2600 // IGENOn;
2601  Device3State++;
2602  }
2603  }
2604  break;
2605 
2606  default :
2607  {
2608  for (Port = 0;Port < NO_OF_INPUT_PORTS;Port++)
2609  { // look at one port at a time
2610 
2611  switch (InputPort[Port].State)
2612  {
2613  case DCM_INIT :
2614  { // set input port inactive
2615 
2616 #ifndef DISABLE_OLD_COLOR
2617  NxtColorActive[Port] = 0;
2618  NxtColorCommStop(Port);
2619 #endif
2620  InputPortFloat(Port);
2621  (*pAnalog).InDcm[Port] = TYPE_NONE;
2622  (*pAnalog).InConn[Port] = CONN_NONE;
2623  InputPort[Port].Timer = 0;
2624  InputPort[Port].Event = 0;
2625  InputPort[Port].State = DCM_FLOATING_DELAY;
2626  }
2627  break;
2628 
2629  case DCM_FLOATING_DELAY :
2630  { // wait for port pins to float
2631 
2632  if (++(InputPort[Port].Timer) >= (DCM_FLOAT_DELAY / DCM_TIMER_RESOLUTION))
2633  {
2634  InputPort[Port].Timer = 0;
2635  InputPort[Port].State = DCM_FLOATING;
2636  }
2637  }
2638  break;
2639 
2640  case DCM_FLOATING :
2641  { // pins floating - check and for connection event
2642 
2643  Event = 0;
2644  if (!(PINRead(Port,INPUT_PORT_PIN2)))
2645  { // pin 2 low
2646 
2647  Event |= (0x01 << INPUT_PORT_PIN2);
2648  }
2649  if ((*pAnalog).InPin1[Port] < VtoC(IN1_NEAR_5V))
2650  { // pin 1 loaded
2651 
2652  Event |= (0x01 << INPUT_PORT_VALUE);
2653  }
2654  if (!(PINRead(Port,INPUT_PORT_PIN5)))
2655  { // pin 5 low
2656 
2657  Event |= (0x01 << INPUT_PORT_PIN5);
2658  }
2659  if ((PINRead(Port,INPUT_PORT_PIN6)))
2660  { // pin 6 high
2661 
2662  Event |= (0x01 << INPUT_PORT_PIN6);
2663  }
2664  if (InputPort[Port].Event != Event)
2665  { // pins has changed - reset timer
2666 
2667 #ifdef DEBUG
2668  printk("i ! %d Event = %02X Old = %02X\n",Port,Event,InputPort[Port].Event);
2669 #endif
2670  InputPort[Port].Event = Event;
2671  InputPort[Port].Timer = 0;
2672  }
2673 
2674  if (InputPort[Port].Event)
2675  { // some event
2676 
2677  if (++(InputPort[Port].Timer) >= (DCM_CONNECT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
2678  {
2679  // some event is stable
2680 
2681  InputPort[Port].State = DCM_CONNECTION;
2682  }
2683  }
2684 
2685  }
2686  break;
2687 
2688  case DCM_CONNECTION :
2689  { // something is connected - try to evaluate
2690 
2691  if (InputPort[Port].Event & (0x01 << INPUT_PORT_PIN2))
2692  { // pin 2 is low
2693 
2694  InputPort[Port].State = DCM_PIN2_LOW;
2695  }
2696  else
2697  {
2698  if (InputPort[Port].Event & (0x01 << INPUT_PORT_VALUE))
2699  { // pin 1 is loaded
2700 
2701  InputPort[Port].State = DCM_PIN1_LOADED;
2702  }
2703  else
2704  {
2705  if (InputPort[Port].Event & (0x01 << INPUT_PORT_PIN6))
2706  { // pin 6 is high
2707 
2708  InputPort[Port].State = DCM_PIN6_HIGH;
2709  }
2710  else
2711  {
2712  if (InputPort[Port].Event & (0x01 << INPUT_PORT_PIN6))
2713  { // pin 5 is low
2714 
2715  InputPort[Port].State = DCM_PIN5_LOW;
2716  }
2717  else
2718  { // ?
2719 
2720  InputPort[Port].State = DCM_INIT;
2721  }
2722  }
2723  }
2724  }
2725 #ifndef DISABLE_FAST_DATALOG_BUFFER
2726  (*pAnalog).Actual[Port] = 0;
2727  (*pAnalog).LogIn[Port] = 0;
2728  (*pAnalog).LogOut[Port] = 0;
2729 #endif
2730  }
2731  break;
2732 
2733  case DCM_PIN2_LOW :
2734  {
2735  InputPort[Port].Connected = 1;
2736  InputPortFloat(Port);
2737  InputPort[Port].Timer = 0;
2738  InputPort[Port].State = DCM_CONNECTED_WAITING_FOR_PIN2_HIGH;
2739 
2740  if ((!(InputPort[Port].Event & (0x01 << INPUT_PORT_PIN5))) && (InputPort[Port].Event & (0x01 << INPUT_PORT_PIN6)))
2741  { // pin 5 and 6 is high
2742 
2743  if ((*pAnalog).InPin1[Port] < VtoC(IN1_NEAR_GND))
2744  { // nxt color sensor
2745 
2746  (*pAnalog).InDcm[Port] = TYPE_NXT_COLOR;
2747 #ifndef DISABLE_OLD_COLOR
2748  (*pAnalog).InConn[Port] = CONN_NXT_COLOR;
2749  InputPort[Port].State = DCM_NXT_COLOR_INIT;
2750 #else
2751  (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2752 #endif
2753  }
2754  else
2755  { // nxt IIC sensor
2756 
2757  (*pAnalog).InDcm[Port] = TYPE_NXT_IIC;
2758  (*pAnalog).InConn[Port] = CONN_NXT_IIC;
2759  }
2760  }
2761  else
2762  {
2763  if (InputPort[Port].Event & (0x01 << INPUT_PORT_PIN5))
2764  { // nxt light sensor
2765 
2766  if (InputPort[Port].Event & (0x01 << INPUT_PORT_PIN6))
2767  { // nxt test sensor
2768 
2769  (*pAnalog).InDcm[Port] = TYPE_NXT_TEST;
2770  (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2771  }
2772  else
2773  {
2774  (*pAnalog).InDcm[Port] = TYPE_NXT_LIGHT;
2775  (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2776  }
2777  }
2778  else
2779  {
2780  if ((*pAnalog).InPin1[Port] < VtoC(IN1_NEAR_GND))
2781  { // nxt color sensor
2782 
2783  (*pAnalog).InDcm[Port] = TYPE_NXT_COLOR;
2784 #ifndef DISABLE_OLD_COLOR
2785  (*pAnalog).InConn[Port] = CONN_NXT_COLOR;
2786  InputPort[Port].State = DCM_NXT_COLOR_INIT;
2787 #else
2788  (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2789 #endif
2790  }
2791  else
2792  {
2793  if ((*pAnalog).InPin1[Port] > VtoC(IN1_NEAR_5V))
2794  { // nxt touch sensor
2795 
2796  (*pAnalog).InDcm[Port] = TYPE_NXT_TOUCH;
2797  (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2798  }
2799  else
2800  {
2801  if (((*pAnalog).InPin1[Port] > VtoC(IN1_TOUCH_LOW)) && ((*pAnalog).InPin1[Port] < VtoC(IN1_TOUCH_HIGH)))
2802  { // nxt touch sensor
2803 
2804  InputPort[Port].Timer = 0;
2805  InputPort[Port].Value = (*pAnalog).InPin1[Port];
2806  InputPort[Port].State = DCM_NXT_TOUCH_CHECK;
2807  }
2808  else
2809  { // nxt sound sensor
2810 
2811  (*pAnalog).InDcm[Port] = TYPE_NXT_SOUND;
2812  (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2813  }
2814  }
2815 
2816  }
2817  }
2818  }
2819  }
2820  break;
2821 
2822  case DCM_NXT_TOUCH_CHECK :
2823  {
2824  if (++(InputPort[Port].Timer) >= (DCM_TOUCH_DELAY / DCM_TIMER_RESOLUTION))
2825  {
2826  InputPort[Port].State = DCM_CONNECTED_WAITING_FOR_PIN2_HIGH;
2827  if (((*pAnalog).InPin1[Port] > (InputPort[Port].Value - 10)) && ((*pAnalog).InPin1[Port] < (InputPort[Port].Value + 10)))
2828  { // nxt touch sensor
2829 
2830  (*pAnalog).InDcm[Port] = TYPE_NXT_TOUCH;
2831  (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2832  }
2833  else
2834  { // nxt sound sensor
2835 
2836  (*pAnalog).InDcm[Port] = TYPE_NXT_SOUND;
2837  (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2838  }
2839  }
2840  }
2841  break;
2842 
2843 #ifndef DISABLE_OLD_COLOR
2844 
2845  case DCM_NXT_COLOR_INIT :
2846  {
2847  NxtcolorCmd[Port] = 0;
2848  NxtColorCommStop(Port);
2849 
2850  InputPort[Port].Timer = 0;
2851  InputPort[Port].State = DCM_NXT_COLOR_WAIT;
2852  }
2853  break;
2854 
2855  case DCM_NXT_COLOR_WAIT :
2856  {
2857  if (NxtcolorCmd[Port] == NxtcolorLatchedCmd[Port])
2858  {
2859  NxtColorCommStart(Port,InputPort[Port].Cmd);
2860  InputPort[Port].State = DCM_NXT_COLOR_BUSY;
2861  }
2862  }
2863  break;
2864 
2865  case DCM_NXT_COLOR_BUSY :
2866  {
2867  if (NxtColorCommReady(Port))
2868  {
2869  NxtcolorCmd[Port] = InputPort[Port].Cmd;
2870  InputPort[Port].Timer = 0;
2871  InputPort[Port].State = DCM_CONNECTED_WAITING_FOR_PIN2_HIGH;
2872 
2873  pData = (UBYTE*)&((*pAnalog).NxtCol[Port]);
2874 
2875  for (Tmp = 0;Tmp < NXTCOLOR_BYTES;Tmp++)
2876  {
2877  *pData = NxtColorBuffer[Port][Tmp];
2878  pData++;
2879  }
2880 
2881  NxtColorCommStop(Port);
2882 
2883  NxtColorActive[Port] = 1;
2884  }
2885  if (++(InputPort[Port].Timer) > (DCM_NXT_COLOR_TIMEOUT / DCM_TIMER_RESOLUTION))
2886  {
2887 #ifdef DEBUG
2888  printk("i ! %d NXT Color sensor timeout\n",Port);
2889 #endif
2890  InputPort[Port].Timer = 0;
2891  InputPort[Port].State = DCM_CONNECTED_WAITING_FOR_PIN2_HIGH;
2892  NxtColorCommStop(Port);
2893  }
2894  }
2895  break;
2896 
2897 #endif
2898 
2900  {
2901  if (PINRead(Port,INPUT_PORT_PIN2))
2902  {
2903  if (++(InputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
2904  {
2905  InputPort[Port].Connected = 0;
2906  InputPort[Port].State = DCM_INIT;
2907  }
2908  }
2909  else
2910  {
2911  InputPort[Port].Timer = 0;
2912  }
2913  }
2914  break;
2915 
2916  case DCM_PIN1_LOADED :
2917  {
2918  if ((*pAnalog).InPin1[Port] > VtoC(IN1_NEAR_PIN2))
2919  {
2920  (*pAnalog).InDcm[Port] = TYPE_ERROR;
2921  (*pAnalog).InConn[Port] = CONN_ERROR;
2922  }
2923  else
2924  {
2925  if ((*pAnalog).InPin1[Port] < VtoC(IN1_NEAR_GND))
2926  {
2927  (*pAnalog).InDcm[Port] = TYPE_UNKNOWN;
2928  (*pAnalog).InConn[Port] = CONN_INPUT_UART;
2929  }
2930  else
2931  {
2932  (*pAnalog).InDcm[Port] = TYPE_UNKNOWN;
2933  (*pAnalog).InConn[Port] = CONN_INPUT_DUMB;
2934  }
2935  }
2936  InputPort[Port].Connected = 1;
2937  InputPort[Port].Timer = 0;
2939  }
2940  break;
2941 
2943  {
2944  if ((*pAnalog).InPin1[Port] > VtoC(IN1_NEAR_5V))
2945  { // pin 1 floating
2946 
2947  if (++(InputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
2948  {
2949  InputPort[Port].Connected = 0;
2950  InputPort[Port].State = DCM_INIT;
2951  }
2952  }
2953  else
2954  {
2955  InputPort[Port].Timer = 0;
2956  }
2957  }
2958  break;
2959 
2960  case DCM_PIN6_HIGH :
2961  { // nxt IIC sensor
2962 
2963  (*pAnalog).InDcm[Port] = TYPE_NXT_IIC;
2964  (*pAnalog).InConn[Port] = CONN_NXT_IIC;
2965  InputPort[Port].Connected = 1;
2966  InputPort[Port].Timer = 0;
2967  InputPort[Port].State = DCM_CONNECTED_WAITING_FOR_PIN6_LOW;
2968  }
2969  break;
2970 
2972  {
2973  if (!(PINRead(Port,INPUT_PORT_PIN6)))
2974  {
2975  if (++(InputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
2976  {
2977  InputPort[Port].Connected = 0;
2978  InputPort[Port].State = DCM_INIT;
2979  }
2980  }
2981  else
2982  {
2983  InputPort[Port].Timer = 0;
2984  }
2985  }
2986  break;
2987 
2988  case DCM_PIN5_LOW :
2989  {
2990  (*pAnalog).InDcm[Port] = TYPE_ERROR;
2991  (*pAnalog).InConn[Port] = CONN_ERROR;
2992  InputPort[Port].Connected = 1;
2993  InputPort[Port].Timer = 0;
2994  InputPort[Port].State = DCM_CONNECTED_WAITING_FOR_PIN5_HIGH;
2995  }
2996  break;
2997 
2999  {
3000  if (!(PINRead(Port,INPUT_PORT_PIN5)))
3001  {
3002  if (++(InputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
3003  {
3004  InputPort[Port].Connected = 0;
3005  InputPort[Port].State = DCM_INIT;
3006  }
3007  }
3008  else
3009  {
3010  InputPort[Port].Timer = 0;
3011  }
3012  }
3013  break;
3014 
3015  default :
3016  {
3017  InputPort[Port].State = DCM_INIT;
3018  }
3019  break;
3020 
3021  }
3022 #ifdef DEBUG
3023  if (InputPort[Port].OldState != InputPort[Port].State)
3024  {
3025  InputPort[Port].OldState = InputPort[Port].State;
3026 
3027  printk("i %d %s\n",Port,DcmStateText[InputPort[Port].State]);
3028  }
3029 #endif
3030 
3031  }
3032 
3033  //*****************************************************************************
3034 
3035  for (Port = 0;Port < NO_OF_OUTPUT_PORTS;Port++)
3036  { // look at one port at a time
3037 
3038  switch (OutputPort[Port].State)
3039  {
3040  case DCM_INIT :
3041  { // set output port inactive
3042 
3043  OutputPortFloat(Port);
3044  (*pAnalog).OutDcm[Port] = TYPE_NONE;
3045  (*pAnalog).OutConn[Port] = CONN_NONE;
3046  OutputPort[Port].Timer = 0;
3047  OutputPort[Port].Event = 0;
3048  OutputPort[Port].State = DCM_FLOATING_DELAY;
3049  }
3050  break;
3051 
3052  case DCM_FLOATING_DELAY :
3053  { // wait for port pins to float
3054 
3055  if (++(OutputPort[Port].Timer) >= (DCM_FLOAT_DELAY / DCM_TIMER_RESOLUTION))
3056  {
3057  OutputPort[Port].Timer = 0;
3058  OutputPort[Port].State = DCM_FLOATING;
3059  }
3060  }
3061  break;
3062 
3063  case DCM_FLOATING :
3064  { // pins floating - check and for connection event
3065 
3066  Event = 0;
3067 
3068 #ifdef FINALB
3069  if ((POUTRead(Port,OUTPUT_PORT_PIN6)))
3070  { // pin 6 low
3071 
3072  Event |= (0x01 << OUTPUT_PORT_PIN6);
3073  }
3074 #else
3075  if (!(POUTRead(Port,OUTPUT_PORT_PIN6)))
3076  { // pin 6 low
3077 
3078  Event |= (0x01 << OUTPUT_PORT_PIN6);
3079  }
3080 #endif
3081  if (((*pAnalog).OutPin5[Port] < VtoC(OUT5_BALANCE_LOW)) || ((*pAnalog).OutPin5[Port] > VtoC(OUT5_BALANCE_HIGH)))
3082  { // pin 5 out of balance
3083 
3084  Event |= (0x01 << OUTPUT_PORT_VALUE);
3085  }
3086 
3087  if (OutputPort[Port].Event != Event)
3088  { // pins has changed - reset timer
3089 
3090  OutputPort[Port].Event = Event;
3091  OutputPort[Port].Timer = 0;
3092  }
3093 
3094  if (OutputPort[Port].Event)
3095  { // some event
3096 
3097  if (++(OutputPort[Port].Timer) >= (DCM_CONNECT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
3098  {
3099  // some event is stable - store value on connection 5
3100 
3101  OutputPort[Port].Value5Float = CtoV((*pAnalog).OutPin5[Port]);
3102  OutputPort[Port].Timer = 0;
3103  POUTLow(Port,OUTPUT_PORT_PIN6);
3104  OutputPort[Port].State = DCM_WAITING_FOR_PIN6_LOW;
3105  }
3106  }
3107  }
3108  break;
3109 
3111  {
3112  if (++(OutputPort[Port].Timer) >= (DCM_LOW_DELAY / DCM_TIMER_RESOLUTION))
3113  {
3114  OutputPort[Port].Value5Low = CtoV((*pAnalog).OutPin5[Port]);
3115  OutputPort[Port].State = DCM_CONNECTION;
3117  }
3118  }
3119  break;
3120 
3121  case DCM_CONNECTION :
3122  { // something is connected - try to evaluate
3123 
3124  OutputPort[Port].State = DCM_CONNECTED_WAITING_FOR_PORT_OPEN;
3125  Tmp = ADC_REF;
3126  Tmp += OutputPort[Port].Value5Float;
3127  Tmp -= OutputPort[Port].Value5Low;
3128 
3129  if ((Tmp > (ADC_REF - 50)) && (Tmp < (ADC_REF + 50)))
3130  { // Value5Float is equal to Value5Low
3131 
3132  if ((OutputPort[Port].Value5Float >= OUT5_BALANCE_LOW) && (OutputPort[Port].Value5Float <= OUT5_BALANCE_HIGH) && (OutputPort[Port].Event & (0x01 << OUTPUT_PORT_PIN6)))
3133  { // NXT TOUCH SENSOR, NXT SOUND SENSOR or NEW UART SENSOR
3134 
3135  (*pAnalog).OutDcm[Port] = TYPE_ERROR;
3136  (*pAnalog).OutConn[Port] = CONN_ERROR;
3137  OutputPort[Port].Connected = 1;
3138  }
3139  else
3140  {
3141  if (OutputPort[Port].Value5Float < OUT5_NEAR_GND)
3142  { // NEW DUMB SENSOR
3143 
3144  (*pAnalog).OutDcm[Port] = TYPE_ERROR;
3145  (*pAnalog).OutConn[Port] = CONN_ERROR;
3146  OutputPort[Port].Connected = 1;
3147  }
3148  else
3149  {
3150  if ((OutputPort[Port].Value5Float >= OUT5_LIGHT_LOW) && (OutputPort[Port].Value5Float <= OUT5_LIGHT_HIGH))
3151  { // NXT LIGHT SENSOR
3152 
3153  (*pAnalog).OutDcm[Port] = TYPE_ERROR;
3154  (*pAnalog).OutConn[Port] = CONN_ERROR;
3155  OutputPort[Port].Connected = 1;
3156  }
3157  else
3158  {
3159  if ((OutputPort[Port].Value5Float >= OUT5_IIC_LOW) && (OutputPort[Port].Value5Float <= OUT5_IIC_HIGH))
3160  { // NXT IIC SENSOR
3161 
3162  (*pAnalog).OutDcm[Port] = TYPE_ERROR;
3163  (*pAnalog).OutConn[Port] = CONN_ERROR;
3164  OutputPort[Port].Connected = 1;
3165  }
3166  else
3167  {
3168  if (OutputPort[Port].Value5Float < OUT5_BALANCE_LOW)
3169  {
3170  if (OutputPort[Port].Value5Float > OUT5_MINITACHO_HIGH2)
3171  {
3172  (*pAnalog).OutDcm[Port] = TYPE_NEWTACHO;
3173  }
3174  else
3175  {
3176  if (OutputPort[Port].Value5Float > OUT5_MINITACHO_LOW2)
3177  {
3178  (*pAnalog).OutDcm[Port] = TYPE_MINITACHO;
3179  }
3180  else
3181  {
3182  (*pAnalog).OutDcm[Port] = TYPE_TACHO;
3183  }
3184  }
3185  (*pAnalog).OutConn[Port] = CONN_OUTPUT_TACHO;
3186  OutputPort[Port].Connected = 1;
3187  }
3188  else
3189  {
3191  OutputPort[Port].State = DCM_WAITING_FOR_PIN5_LOW;
3192  }
3193  }
3194  }
3195  }
3196  }
3197 
3198  }
3199  else
3200  { // Value5Float is NOT equal to Value5Low
3201 
3202  if ((OutputPort[Port].Value5Low > OUT5_NEAR_GND) && (OutputPort[Port].Value5Low < OUT5_BALANCE_LOW))
3203  { // NEW ACTUATOR
3204 
3205  (*pAnalog).OutPin5Low[Port] = OutputPort[Port].Value5Low;
3206  (*pAnalog).OutDcm[Port] = TYPE_UNKNOWN;
3207  (*pAnalog).OutConn[Port] = CONN_OUTPUT_DUMB;
3208  OutputPort[Port].Connected = 1;
3209  }
3210  else
3211  {
3212  (*pAnalog).OutDcm[Port] = TYPE_ERROR;
3213  (*pAnalog).OutConn[Port] = CONN_ERROR;
3214  OutputPort[Port].Connected = 1;
3215  }
3216 
3217  }
3218  OutputPort[Port].Timer = 0;
3219 #ifdef DEBUG
3220  if (OutputPort[Port].Connected)
3221  {
3222  printk("\r\no %d Type = %c, Float = %u, Low = %u\r\n",Port,(char)(*pAnalog).OutDcm[Port],(unsigned int)OutputPort[Port].Value5Float,(unsigned int)OutputPort[Port].Value5Low);
3223  }
3224 #endif
3225  }
3226  break;
3227 
3229  {
3230  if (++(OutputPort[Port].Timer) >= (DCM_LOW_DELAY / DCM_TIMER_RESOLUTION))
3231  {
3232  OutputPort[Port].Value5Low = CtoV((*pAnalog).OutPin5[Port]);
3233  OutputPort[Port].State = DCM_CONNECTION;
3234  POUTLow(Port,OUTPUT_PORT_PIN5W);
3235  (*pAnalog).OutConn[Port] = CONN_OUTPUT_TACHO;
3236  if (OutputPort[Port].Value5Low < OUT5_MINITACHO_LOW1)
3237  {
3238  (*pAnalog).OutDcm[Port] = TYPE_ERROR;
3239  (*pAnalog).OutConn[Port] = CONN_ERROR;
3240  }
3241  else
3242  {
3243  if (OutputPort[Port].Value5Low < OUT5_MINITACHO_HIGH1)
3244  {
3245  (*pAnalog).OutDcm[Port] = TYPE_MINITACHO;
3246  }
3247  else
3248  {
3249  (*pAnalog).OutDcm[Port] = TYPE_TACHO;
3250  }
3251  }
3252  OutputPort[Port].Connected = 1;
3253 #ifdef DEBUG
3254  printk("\r\no %d Type = %03u, Float = %u, Low = %u\r\n",Port,(char)(*pAnalog).OutDcm[Port],(unsigned int)OutputPort[Port].Value5Float,(unsigned int)OutputPort[Port].Value5Low);
3255 #endif
3256  OutputPort[Port].State = DCM_CONNECTED_WAITING_FOR_PORT_OPEN;
3257  }
3258  }
3259  break;
3260 
3262  {
3263  if (((*pAnalog).OutPin5[Port] < VtoC(OUT5_BALANCE_LOW)) || ((*pAnalog).OutPin5[Port] > VtoC(OUT5_BALANCE_HIGH)))
3264  { // connection 5 out of balance
3265 
3266  OutputPort[Port].Timer = 0;
3267  }
3268 #ifdef FINALB
3269  if ((POUTRead(Port,OUTPUT_PORT_PIN6)))
3270  { // pin 6 low
3271 
3272  OutputPort[Port].Timer = 0;
3273  }
3274 #else
3275  if (!(POUTRead(Port,OUTPUT_PORT_PIN6)))
3276  { // pin 6 low
3277 
3278  OutputPort[Port].Timer = 0;
3279  }
3280 #endif
3281  if (++(OutputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
3282  {
3283  OutputPort[Port].Connected = 0;
3284  OutputPort[Port].State = DCM_INIT;
3285  }
3286  }
3287  break;
3288 
3289  default :
3290  {
3291  OutputPort[Port].State = DCM_INIT;
3292  }
3293  break;
3294 
3295  }
3296 #ifdef DEBUG
3297  if (OutputPort[Port].OldState != OutputPort[Port].State)
3298  {
3299  OutputPort[Port].OldState = OutputPort[Port].State;
3300 
3301  printk("o %d %s\n",Port,DcmStateText[OutputPort[Port].State]);
3302  }
3303 #endif
3304 
3305  }
3306  }
3307  break;
3308 
3309  }
3310 
3311  return (HRTIMER_RESTART);
3312 }
3313 
3314 
3315 static ssize_t Device3Write(struct file *File,const char *Buffer,size_t Count,loff_t *Data)
3316 {
3317  char Buf[INPUTS + 1];
3318  UBYTE Port;
3319  UBYTE Char;
3320  int Lng = 0;
3321 
3322  if (Count >= INPUTS)
3323  {
3324  Lng = Count;
3325  copy_from_user(Buf,Buffer,INPUTS);
3326 
3327  for (Port = 0;Port < NO_OF_INPUT_PORTS;Port++)
3328  {
3329  Char = Buf[Port];
3330  switch (Char)
3331  {
3332  case '-' :
3333  { // do nothing
3334  }
3335  break;
3336 
3337  case 'f' :
3338  { // float
3339 
3340  InputPortFloat(Port);
3341  }
3342  break;
3343 
3344  default :
3345  {
3346  if (InputPort[Port].Connected)
3347  {
3348  if ((Char & 0xF8) == '0')
3349  { // 0,1,2,3,4,5,6,7
3350 
3351 
3352  if (Char & 0x01)
3353  { // pin 1
3354 
3355  PINHigh(Port,INPUT_PORT_PIN1)
3356  }
3357  else
3358  {
3359  PINLow(Port,INPUT_PORT_PIN1)
3360  }
3361  if (Char & 0x02)
3362  { // pin 5
3363 
3364  PINHigh(Port,INPUT_PORT_PIN5)
3365  }
3366  else
3367  {
3368  PINLow(Port,INPUT_PORT_PIN5)
3369  }
3370  }
3371 #ifndef DISABLE_OLD_COLOR
3372  else
3373  {
3374  if ((Char >= 0x0D) && (Char <= 0x11))
3375  { // NXT color sensor setup
3376 
3377  InputPort[Port].Cmd = Char;
3378  InputPort[Port].Timer = 0;
3379  InputPort[Port].State = DCM_NXT_COLOR_INIT;
3380 
3381  }
3382  }
3383 #endif
3384  }
3385  }
3386  break;
3387 
3388  }
3389  }
3390  }
3391 
3392  return (Lng);
3393 }
3394 
3395 
3396 static ssize_t Device3Read(struct file *File,char *Buffer,size_t Count,loff_t *Offset)
3397 {
3398  int Lng = 0;
3399 
3400  if (Count > 9)
3401  {
3402  while (Lng < NO_OF_INPUT_PORTS)
3403  {
3404  Buffer[Lng] = (*pAnalog).InDcm[Lng];
3405  Lng++;
3406  }
3407  while (Lng < INPUTS)
3408  {
3409  Buffer[Lng] = TYPE_NONE;
3410  Lng++;
3411  }
3412  while (Lng < (INPUTS + NO_OF_OUTPUT_PORTS))
3413  {
3414  Buffer[Lng] = (*pAnalog).OutDcm[Lng - INPUTS];
3415  Lng++;
3416  }
3417  while (Lng < (INPUTS + OUTPUTS))
3418  {
3419  Buffer[Lng] = TYPE_NONE;
3420  Lng++;
3421  }
3422  Buffer[Lng++] = '\r';
3423  Buffer[Lng++] = 0;
3424  }
3425 
3426  return (Lng);
3427 }
3428 
3429 
3430 static const struct file_operations Device3Entries =
3431 {
3432  .owner = THIS_MODULE,
3433  .read = Device3Read,
3434  .write = Device3Write
3435 };
3436 
3437 
3438 static struct miscdevice Device3 =
3439 {
3440  MISC_DYNAMIC_MINOR,
3441  DEVICE3_NAME,
3442  &Device3Entries
3443 };
3444 
3445 
3446 static int Device3Init(void)
3447 {
3448  int Result = -1;
3449  int Tmp;
3450 
3451  Result = misc_register(&Device3);
3452  if (Result)
3453  {
3454  printk(" %s device register failed\n",DEVICE3_NAME);
3455  }
3456  else
3457  {
3458  for (Tmp = 0;Tmp < NO_OF_INPUT_PORTS;Tmp++)
3459  {
3460  InputPort[Tmp] = InputPortDefault;
3461  }
3462  for (Tmp = 0;Tmp < NO_OF_OUTPUT_PORTS;Tmp++)
3463  {
3464  OutputPort[Tmp] = OutputPortDefault;
3465  }
3466 
3467  Device3State = 0;
3468  TestMode = 0;
3469 
3470 
3471  Device3Time = ktime_set(0,DCM_TIMER_RESOLUTION * 1000000);
3472  hrtimer_init(&Device3Timer,CLOCK_MONOTONIC,HRTIMER_MODE_REL);
3473  Device3Timer.function = Device3TimerInterrupt1;
3474  hrtimer_start(&Device3Timer,Device3Time,HRTIMER_MODE_REL);
3475 
3476 #ifdef DEBUG
3477  printk(" %s device register succes\n",DEVICE3_NAME);
3478 #endif
3479  }
3480 
3481  return (Result);
3482 }
3483 
3484 
3485 static void Device3Exit(void)
3486 {
3487  int Tmp;
3488 
3489  hrtimer_cancel(&Device3Timer);
3490  for (Tmp = 0;Tmp < NO_OF_INPUT_PORTS;Tmp++)
3491  {
3492  InputPortFloat(Tmp);
3493  }
3494  misc_deregister(&Device3);
3495 #ifdef DEBUG
3496  printk(" %s device unregistered\n",DEVICE3_NAME);
3497  printk(" %s memory unmapped\n",DEVICE3_NAME);
3498 #endif
3499 }
3500 
3501 
3502 // MODULE *********************************************************************
3503 
3504 
3505 #ifndef PCASM
3506 module_param (HwId, charp, 0);
3507 #endif
3508 
3509 static int ModuleInit(void)
3510 {
3511  Hw = HWID;
3512 
3513  if (Hw < PLATFORM_START)
3514  {
3515  Hw = PLATFORM_START;
3516  }
3517  if (Hw > PLATFORM_END)
3518  {
3519  Hw = PLATFORM_END;
3520  }
3521 
3522 #ifdef DEBUG
3523  printk("%s init started\n",MODULE_NAME);
3524 #endif
3525  if (request_mem_region(DA8XX_GPIO_BASE,0xD8,MODULE_NAME) >= 0)
3526  {
3527  GpioBase = (void*)ioremap(DA8XX_GPIO_BASE,0xD8);
3528  if (GpioBase != NULL)
3529  {
3530 #ifdef DEBUG
3531  printk("%s gpio address mapped\n",MODULE_NAME);
3532 #endif
3533 
3534  InitGpio();
3535 
3536 // IGENOn;
3537  BATENOn;
3538 
3539  Device1Init();
3540  Device2Init();
3541  Device3Init();
3542 
3543 
3544  }
3545  }
3546 
3547  return (0);
3548 }
3549 
3550 
3551 static void ModuleExit(void)
3552 {
3553 #ifdef DEBUG
3554  printk("%s exit started\n",MODULE_NAME);
3555 #endif
3556 
3557  BATENOff;
3558 
3561 
3562  Device3Exit();
3563  Device2Exit();
3564  Device1Exit();
3565 
3566  iounmap(GpioBase);
3567 }
3568 
3569 
Device is NXT sound sensor.
Definition: lms2012.h:568
MODULE_SUPPORTED_DEVICE(DEVICE1_NAME)
Definition: am1808.h:35
INPIN OutputPortPin[NO_OF_OUTPUT_PORTS][OUTPUT_PORT_PINS]
Definition: d_analog.c:373
Definition: am1808.h:41
#define REGLock
Definition: am1808.h:235
Definition: am1808.h:38
#define SPITxfull
Definition: d_analog.c:995
DATA8 Port
Definition: lms2012.h:1178
#define POUTLow(port, pin)
Definition: d_analog.c:896
char Char
Definition: tistdtypes.h:54
Definition: am1808.h:35
Definition: am1808.h:33
#define TST_PIN_ON
Definition: lms2012.h:1184
#define snprintf
Definition: c_input.c:141
#define SPIDEF
Definition: d_analog.c:984
Definition: am1808.h:39
UBYTE Event
Definition: d_analog.c:1256
Definition: am1808.h:38
#define SPIDELAY
Definition: d_analog.c:983
INPIN InputPortPin[NO_OF_INPUT_PORTS][INPUT_PORT_PINS]
Definition: d_analog.c:371
Definition: am1808.h:35
MRM MuxRegMap[]
Definition: am1808.h:59
Definition: am1808.h:33
INPORT InputPort[NO_OF_INPUT_PORTS]
Definition: d_analog.c:1244
void SpiRestoreReg(void)
Definition: d_analog.c:1043
OUTPORT OutputPort[NO_OF_OUTPUT_PORTS]
Definition: d_analog.c:1262
GPIOC pGpio
Definition: am1808.h:225
INPORT InputPortDefault
Definition: d_analog.c:1691
#define REGUnlock
Definition: am1808.h:230
Definition: am1808.h:39
UBYTE Timer
Definition: d_analog.c:1239
ULONG SpiSave4
Definition: d_analog.c:1024
#define VtoC(V)
Definition: lms2012.h:549
Definition: am1808.h:33
#define SPIGCR0
Definition: d_analog.c:968
Definition: am1808.h:41
Definition: am1808.h:222
#define TST_PIN_OFF
Definition: lms2012.h:1185
#define POUTRead(port, pin)
Definition: d_analog.c:887
#define EP2
Schematics revision D.
Definition: lms2012.h:99
#define PUDisable
Definition: d_analog.c:657
INPIN EP2_OutputPortPin[][OUTPUT_PORT_PINS]
Definition: d_pwm.c:343
ULONG SpiSave3
Definition: d_analog.c:1023
Definition: am1808.h:40
Port empty or not available.
Definition: lms2012.h:585
#define FINAL
Final prototype.
Definition: lms2012.h:101
OUTPORT OutputPortDefault
Definition: d_analog.c:1702
MODULE_AUTHOR("The LEGO Group")
InputPortPins
Definition: d_analog.c:320
OutputPortPins
Definition: d_analog.c:342
UBYTE Event
Definition: d_analog.c:1238
#define BATENOff
Definition: d_analog.c:918
#define DEVICE2_NAME
Definition: d_analog.c:688
Definition: am1808.h:41
UWORD Device1GetInputPins(UBYTE Port)
Definition: d_analog.c:1735
Definition: am1808.h:39
#define DEVICE1_NAME
Definition: d_analog.c:687
AdcPowerPins
Definition: d_analog.c:354
#define SPIRxempty
Definition: d_analog.c:994
#define TST_PIN_WRITE
Definition: lms2012.h:1187
#define SPIInit
Definition: d_analog.c:997
Definition: am1808.h:40
u16 MuxReg
Definition: am1808.h:53
Definition: am1808.h:38
#define TST_PIN_READ
Definition: lms2012.h:1186
UBYTE State
Definition: d_analog.c:1236
void NxtColorCommStop(UBYTE Port)
Definition: d_analog.c:2550
DATA8 String[TST_PIN_LENGTH+1]
Definition: lms2012.h:1180
Device is a NXT ADC test sensor.
Definition: lms2012.h:580
Definition: am1808.h:33
Definition: am1808.h:36
MODULE_DESCRIPTION(MODULE_NAME)
Port not empty but type has not been determined.
Definition: lms2012.h:584
Definition: am1808.h:39
#define Timer
Definition: am1808.h:38
ULONG SpiSave2
Definition: d_analog.c:1022
Definition: am1808.h:38
INPIN FINAL_OutputPortPin[][OUTPUT_PORT_PINS]
Definition: d_pwm.c:426
module_exit(ModuleExit)
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
Definition: lmstypes.h:31
UBYTE OldState
Definition: d_analog.c:1237
Definition: am1808.h:35
Definition: am1808.h:36
UBYTE Connected
Definition: d_analog.c:1251
Definition: am1808.h:34
INPIN * pAdcPowerPin[]
Definition: d_analog.c:676
#define NO_OF_OUTPUT_PORTS
Definition: d_analog.c:367
#define DEVICE3_NAME
Definition: d_analog.c:689
Definition: am1808.h:41
void SetGpio(int Pin)
Definition: d_analog.c:735
void SpiSaveReg(void)
Definition: d_analog.c:1030
Device is NXT light sensor.
Definition: lms2012.h:567
Definition: am1808.h:36
#define POUTFloat(port, pin)
Definition: d_analog.c:882
int Pin
Definition: am1808.h:224
INPIN * pInputPortPin[]
Definition: d_analog.c:660
#define CtoV(C)
Definition: lms2012.h:550
Definition: am1808.h:41
UBYTE DataOut[DAISY_DEFAULT_MAX_EP_SIZE]
Definition: c_daisy.c:85
UBYTE Cmd
Definition: d_analog.c:1235
UBYTE State
Definition: d_analog.c:1254
module_param(HwId, charp, 0)
#define BUFFER_LNG
Definition: d_uart_mod.c:3998
Definition: am1808.h:34
Port not empty and type is invalid.
Definition: lms2012.h:586
#define SPIINT0
Definition: d_analog.c:970
Definition: am1808.h:40
UBYTE Type
Definition: d_analog.c:1253
#define FINALB
Schematics revision B and C.
Definition: lms2012.h:100
UWORD Value5Low
Definition: d_analog.c:1250
UWORD Value5Float
Definition: d_analog.c:1249
#define INPUTADC
Definition: d_analog.c:364
Definition: am1808.h:37
ULONG SpiSave1
Definition: d_analog.c:1021
Definition: am1808.h:40
#define SPIDAT0
Definition: d_analog.c:979
UBYTE Timer
Definition: d_analog.c:1257
Device is a tacho motor.
Definition: lms2012.h:571
Definition: am1808.h:33
Device is NXT IIC sensor.
Definition: lms2012.h:582
#define SPIPC0
Definition: d_analog.c:973
Definition: am1808.h:33
#define PINFloat(port, pin)
Definition: d_analog.c:863
module_init(ModuleInit)
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
Definition: lmstypes.h:29
Definition: am1808.h:36
#define PINRead(port, pin)
Definition: d_analog.c:868
void InitGpio(void)
Definition: d_analog.c:774
Definition: am1808.h:41
Definition: am1808.h:38
u32 Mask
Definition: am1808.h:226
ULONG SpiSave7
Definition: d_analog.c:1027
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
Definition: lmstypes.h:30
#define POUTHigh(port, pin)
Definition: d_analog.c:890
char Buffer[1024]
Definition: c_wifi.c:102
DATA8 Length
Definition: lms2012.h:1179
UWORD SpiUpdate(UWORD DataOut)
Definition: d_analog.c:1101
Definition: am1808.h:41
#define OUTPUTS
Number of output ports in the system.
Definition: lms2012.h:191
Definition: am1808.h:34
Definition: am1808.h:41
char DcmStateText[DCM_STATES][50]
Definition: d_analog.c:1664
#define PINLow(port, pin)
Definition: d_analog.c:876
Definition: am1808.h:34
#define SPIDAT1
Definition: d_analog.c:980
UBYTE OldState
Definition: d_analog.c:1255
UBYTE Code
Definition: d_analog.c:1252
Definition: am1808.h:36
INPIN * pOutputPortPin[]
Definition: d_analog.c:668
void SpiExit(void)
Definition: d_analog.c:1084
UBYTE Connected
Definition: d_analog.c:1234
Device is a mini tacho motor.
Definition: lms2012.h:572
MODULE_LICENSE("GPL")
Definition: am1808.h:38
UBYTE NxtColorCommReady(UBYTE Port)
Definition: d_analog.c:2537
INPIN FINALB_OutputPortPin[][OUTPUT_PORT_PINS]
Definition: d_pwm.c:385
#define SPIFMT0
Definition: d_analog.c:985
Definition: am1808.h:33
SBYTE DATA8
VM Type for 1 byte signed value.
Definition: lmstypes.h:61
Definition: am1808.h:33
Definition: am1808.h:33
Definition: am1808.h:38
Device is NXT color sensor.
Definition: lms2012.h:569
uint32_t u32
Definition: common.h:158
#define NO_OF_INPUT_PORTS
Definition: d_analog.c:366
Definition: am1808.h:44
#define SPIBUF
Definition: d_analog.c:981
DCM_STATE
Definition: d_analog.c:1636
ULONG SpiSave0
Definition: d_analog.c:1020
Device is a new tacho motor.
Definition: lms2012.h:573
ULONG SpiSave5
Definition: d_analog.c:1025
#define BATENOn
Definition: d_analog.c:912
#define INPUTS
Number of input ports in the system.
Definition: lms2012.h:192
Definition: am1808.h:35
Definition: am1808.h:41
#define PINHigh(port, pin)
Definition: d_analog.c:871
#define PLATFORM_END
Newest supported hardware (newer versions will use this)
Definition: lms2012.h:105
InputSpiPins
Definition: d_analog.c:332
#define SPIGCR1
Definition: d_analog.c:969
void SpiInit(void)
Definition: d_analog.c:1056
UWORD Device1GetOutputPins(UBYTE Port)
Definition: d_analog.c:1754
#define CHAIN_DEPT
Number of bricks in the USB daisy chain (master + slaves)
Definition: lms2012.h:206
INPIN AdcPowerPin[ADC_POWER_PINS]
Definition: d_analog.c:375
void NxtColorCommStart(UBYTE Port, UBYTE Cmd)
Definition: d_analog.c:2517
Device is NXT touch sensor.
Definition: lms2012.h:566
UWORD Value
Definition: d_analog.c:1233
UBYTE DataIn[DAISY_DEFAULT_MAX_EP_SIZE]
Definition: c_daisy.c:84
#define MODULE_NAME
Definition: d_analog.c:686
int Hw
Definition: d_analog.c:317
#define PLATFORM_START
Oldest supported hardware (older versions will use this)
Definition: lms2012.h:104
#define NPAGES
Definition: d_analog.c:95
ULONG SpiSave6
Definition: d_analog.c:1026
#define NULL