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
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
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]
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]
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]
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]
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]
193 #define OUT5_NEAR_GND 100 // [mV] lower values mean that connection 5 is shorted to ground
303 #include <asm/types.h>
304 #include <linux/time.h>
307 #define HW_ID_SUPPORT
309 #include "../../lms2012/source/lms2012.h"
310 #include "../../lms2012/source/am1808.h"
312 #ifdef DEBUG_D_ANALOG
362 #define INPUTADCPORTS 12
363 #define INPUTADCPOWERS 4
364 #define INPUTADC (INPUTADCPORTS + INPUTADCPOWERS)
366 #define NO_OF_INPUT_PORTS INPUTS
367 #define NO_OF_OUTPUT_PORTS OUTPUTS
369 static void InputPortFloat(
int Port);
387 static const UBYTE InputReadMap[
INPUTADC] = { 6,8,10,12,5,7,9,11,1,0,13,14,2,15,3,4 };
630 #ifndef ADC_BITBANGING
657 #define PUDisable iowrite32(ioread32(da8xx_syscfg1_base + 0x0C) & ~0xFFFFFFFF,da8xx_syscfg1_base + 0x0C)
664 [
EP2] = (
INPIN*)&EP2_InputPortPin[0],
670 [
FINAL] = FINAL_OutputPortPin[0],
671 [
FINALB] = FINALB_OutputPortPin[0],
672 [
EP2] = EP2_OutputPortPin[0],
678 [
FINAL] = FINAL_AdcPowerPin,
679 [
FINALB] = FINALB_AdcPowerPin,
680 [
EP2] = EP2_AdcPowerPin,
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
691 static int ModuleInit(
void);
692 static void ModuleExit(
void);
696 #include <linux/kernel.h>
697 #include <linux/fs.h>
699 #include <linux/sched.h>
703 #ifndef DISABLE_PREEMPTED_VM
704 #include <linux/slab.h>
706 #include <linux/mm.h>
707 #include <linux/hrtimer.h>
709 #include <linux/init.h>
710 #include <linux/uaccess.h>
711 #include <linux/debugfs.h>
713 #include <linux/ioport.h>
714 #include <asm/gpio.h>
716 #include <linux/module.h>
717 #include <linux/miscdevice.h>
718 #include <asm/uaccess.h>
733 static void __iomem *GpioBase;
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);
762 printk(
" ANALOG SPI FUNCTION 0x%08X and 0x%08X or 0x%08X\n",(
u32)Reg,
MuxRegMap[Tmp].Mask,
MuxRegMap[Tmp].Mode);
768 printk(
"* GP%d_%-2d ********* ERROR not found *********\n",(Pin >> 4),(Pin & 0x0F));
782 memcpy(InputPortPin,pInputPortPin[
Hw],
sizeof(EP2_InputPortPin));
783 if (memcmp((
const void*)InputPortPin,(
const void*)pInputPortPin[Hw],
sizeof(EP2_InputPortPin)) != 0)
785 printk(
"%s InputPortPin tabel broken!\n",
MODULE_NAME);
791 printk(
" Input port %d\n",Port + 1);
795 if (InputPortPin[Port][Pin].Pin >= 0)
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));
800 SetGpio(InputPortPin[Port][Pin].Pin);
805 printk(
" Adc spi\n");
809 AdcSpiPin[Pin].
pGpio = (
struct gpio_controller *__iomem)(GpioBase + ((AdcSpiPin[Pin].Pin >> 5) * 0x28) + 0x10);
810 AdcSpiPin[Pin].
Mask = (1 << (AdcSpiPin[Pin].
Pin & 0x1F));
814 memcpy(OutputPortPin,pOutputPortPin[Hw],
sizeof(EP2_OutputPortPin));
815 if (memcmp((
const void*)OutputPortPin,(
const void*)pOutputPortPin[Hw],
sizeof(EP2_OutputPortPin)) != 0)
817 printk(
"%s OutputPortPin tabel broken!\n",
MODULE_NAME);
822 printk(
" Output port %d\n",Port + 1);
826 if (OutputPortPin[Port][Pin].Pin >= 0)
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));
831 SetGpio(OutputPortPin[Port][Pin].Pin);
836 printk(
" Adc power\n");
838 memcpy(AdcPowerPin,pAdcPowerPin[Hw],
sizeof(EP2_AdcPowerPin));
839 if (memcmp((
const void*)AdcPowerPin,(
const void*)pAdcPowerPin[Hw],
sizeof(EP2_AdcPowerPin)) != 0)
841 printk(
"%s AdcPowerPin tabel broken!\n",
MODULE_NAME);
846 if (AdcPowerPin[Pin].Pin >= 0)
848 AdcPowerPin[Pin].
pGpio = (
struct gpio_controller *__iomem)(GpioBase + ((AdcPowerPin[Pin].Pin >> 5) * 0x28) + 0x10);
849 AdcPowerPin[Pin].
Mask = (1 << (AdcPowerPin[Pin].
Pin & 0x1F));
863 #define PINFloat(port,pin) {\
864 (*InputPortPin[port][pin].pGpio).dir |= InputPortPin[port][pin].Mask;\
868 #define PINRead(port,pin) ((*InputPortPin[port][pin].pGpio).in_data & InputPortPin[port][pin].Mask)
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;\
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;\
882 #define POUTFloat(port,pin) {\
883 (*OutputPortPin[port][pin].pGpio).dir |= OutputPortPin[port][pin].Mask;\
887 #define POUTRead(port,pin) ((*OutputPortPin[port][pin].pGpio).in_data & OutputPortPin[port][pin].Mask)
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;\
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;\
902 (*AdcPowerPin[ADCONIGEN].pGpio).set_data = AdcPowerPin[ADCONIGEN].Mask;\
903 (*AdcPowerPin[ADCONIGEN].pGpio).dir &= ~AdcPowerPin[ADCONIGEN].Mask;\
908 (*AdcPowerPin[ADCONIGEN].pGpio).clr_data = AdcPowerPin[ADCONIGEN].Mask;\
909 (*AdcPowerPin[ADCONIGEN].pGpio).dir &= ~AdcPowerPin[ADCONIGEN].Mask;\
913 (*AdcPowerPin[ADCBATEN].pGpio).set_data = AdcPowerPin[ADCBATEN].Mask;\
914 (*AdcPowerPin[ADCBATEN].pGpio).dir &= ~AdcPowerPin[ADCBATEN].Mask;\
919 (*AdcPowerPin[ADCBATEN].pGpio).clr_data = AdcPowerPin[ADCBATEN].Mask;\
920 (*AdcPowerPin[ADCBATEN].pGpio).dir &= ~AdcPowerPin[ADCBATEN].Mask;\
925 #ifdef DISABLE_OLD_COLOR
931 if ((Char >=
'0') && (Char <=
'9'))
937 if ((Char >=
'a') && (Char <=
'f'))
939 Hex = Char -
'a' + 10;
943 if ((Char >=
'A') && (Char <=
'F'))
945 Hex = Char -
'A' + 10;
957 #ifndef ADC_BITBANGING
959 #define SPI0_CLOCK 150000000
961 #define ADC_TIME 8 // [uS]
964 #define ADC_CLOCK (((ULONG)1000000 * (ULONG)16) / (ULONG)ADC_TIME)
965 #define CNVSPD (((ULONG)SPI0_CLOCK / (ULONG)ADC_CLOCK) - 1)
992 static volatile unsigned long *Spi0;
994 #define SPIRxempty (Spi0[SPIBUF] & 0x80000000)
995 #define SPITxfull (Spi0[SPIBUF] & 0x20000000)
998 Spi0[SPIGCR1] = 0x00000003; \
999 Spi0[SPIPC0] = 0x00000E08; \
1000 Spi0[SPIDAT1] = 0x0; \
1001 Spi0[SPIFMT0] = 0x00010010 | ((CNVSPD << 8) & 0xFF00);\
1002 Spi0[SPIDELAY] = 0x0A0A0A0A; \
1003 Spi0[SPIINT0] = 0x0; \
1004 Spi0[SPIDEF] = 0x00000008;\
1005 Spi0[SPIGCR1] = 0x01000003; \
1009 Spi0[SPIGCR1] = 0x00000103; \
1010 Spi0[SPIPC0] = 0x01010E01; \
1011 Spi0[SPIDAT1] = 0x003F0000; \
1012 Spi0[SPIFMT0] = 0x00010408 | ((CNVSPD << 8) & 0xFF00);\
1013 Spi0[SPIDELAY] = 0x00000000; \
1014 Spi0[SPIINT0] = 0x00000000; \
1015 Spi0[SPIDEF] = 0x0000003F;\
1058 if (request_mem_region(0x01C41000,0x68,
MODULE_NAME) >= 0)
1060 Spi0 = (
unsigned long*)ioremap(0x01C41000,0x68);
1064 printk(
" %s memory mapped from 0x%08lX\n",
DEVICE1_NAME,(
unsigned long)Spi0);
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]);
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]);
1120 (*AdcSpiPin[ADCMOSI].pGpio).set_data = AdcSpiPin[ADCMOSI].Mask;\
1125 (*AdcSpiPin[ADCMOSI].pGpio).clr_data = AdcSpiPin[ADCMOSI].Mask;\
1130 (*AdcSpiPin[ADCCLK].pGpio).set_data = AdcSpiPin[ADCCLK].Mask;\
1135 (*AdcSpiPin[ADCCLK].pGpio).clr_data = AdcSpiPin[ADCCLK].Mask;\
1140 (*AdcSpiPin[ADCCS].pGpio).set_data = AdcSpiPin[ADCCS].Mask;\
1145 (*AdcSpiPin[ADCCS].pGpio).clr_data = AdcSpiPin[ADCCS].Mask;\
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;\
1157 #define SOMIRead ((*AdcSpiPin[ADCMISO].pGpio).in_data & AdcSpiPin[ADCMISO].Mask)
1190 if (DataOut & 0x8000)
1218 static struct hrtimer Device1Timer;
1219 static ktime_t Device1Time;
1221 static UBYTE TestMode = 0;
1223 static ANALOG AnalogDefault;
1225 static ANALOG *pAnalog = &AnalogDefault;
1226 static UWORD *pInputs = (
UWORD*)&AnalogDefault;
1228 static UBYTE Device3State = 0;
1264 #ifndef DISABLE_OLD_COLOR
1301 #define SCHEMESIZE1 10
1303 static UBYTE MuxSetup1[SCHEMESIZE1] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x20,0x20 };
1305 static UBYTE Reading1[SCHEMESIZE1] = { 0x80,0x20,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 };
1307 static UBYTE NextTime1[SCHEMESIZE1] = { 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x01 };
1309 static ktime_t Time1[2];
1353 #define SCHEMESIZE2 15
1355 static UBYTE MuxSetup2[SCHEMESIZE2] = { 0x13,0x00,0x01,0x02,0x10,0x03,0x04,0x05,0x11,0x06,0x07,0x20,0x12,0x20,0x20 };
1357 static UBYTE Reading2[SCHEMESIZE2] = { 0x80,0x20,0x13,0x00,0x01,0x02,0x10,0x03,0x04,0x05,0x11,0x06,0x07,0x80,0x12 };
1359 static UBYTE ClockHigh2[SCHEMESIZE2] = { 0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00 };
1361 static UBYTE ClockLow2[SCHEMESIZE2] = { 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00 };
1363 static UBYTE NextTime2[SCHEMESIZE2] = { 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x01 };
1365 static ktime_t Time2[2];
1366 static ktime_t NextTime;
1368 static UBYTE InputPoint1 = 8;
1370 static UBYTE Color = 0;
1371 static UBYTE NxtPointer = 0;
1376 static UBYTE InputPoint2 = 0;
1380 static enum hrtimer_restart Device1TimerInterrupt1(
struct hrtimer *pTimer)
1388 hrtimer_forward_now(pTimer,NextTime);
1390 if (NxtPointer == 0)
1392 if (++InputPoint2 >=
INPUTS)
1396 #ifndef DISABLE_PREEMPTED_VM
1397 ((*pAnalog).PreemptMilliSeconds)++;
1407 if (MuxSetup1[NxtPointer] & 0x20)
1409 Input = (
UWORD)InputReadMap[InputPoint1];
1413 Input = (
UWORD)InputReadMap[MuxSetup1[NxtPointer] & 0x0F];
1416 if (Reading1[NxtPointer] & 0x20)
1418 pData = &pInputs[InputPoint1];
1426 if (!(Reading1[NxtPointer] & 0xF0))
1428 pData = &pInputs[Reading1[NxtPointer]];
1437 while ((NextTime1[NxtPointer - 1] == 0));
1439 NextTime = Time1[NextTime1[NxtPointer - 1] - 1];
1441 if (NxtPointer >= SCHEMESIZE1)
1453 if (MuxSetup2[NxtPointer] & 0x20)
1455 Input = (
UWORD)InputReadMap[InputPoint1];
1459 if (MuxSetup2[NxtPointer] & 0x10)
1461 Input = (
UWORD)InputReadMap[InputPoint2 +
INPUTS];
1465 Input = (
UWORD)InputReadMap[MuxSetup2[NxtPointer] & 0x0F];
1469 if (Reading2[NxtPointer] & 0x20)
1471 pData = &pInputs[InputPoint1];
1479 if (Reading2[NxtPointer] & 0x10)
1481 pData = (
UWORD*)&(*pAnalog).NxtCol[InputPoint2].ADRaw[(Reading2[NxtPointer] & 0x03)];
1485 if (!(Reading2[NxtPointer] & 0xF0))
1487 pData = &pInputs[Reading2[NxtPointer]];
1492 *pData = (
UWORD)
SpiUpdate((0x1840 | ((Input & 0x000F) << 7))) & 0xFFF;
1493 if (NxtcolorLatchedCmd[InputPoint2] == 0x0D)
1495 if (ClockHigh2[NxtPointer])
1497 if (Nxtcolor[InputPoint2])
1499 if (ClockHigh2[NxtPointer] == 0x01)
1509 if (ClockLow2[NxtPointer])
1511 if (Nxtcolor[InputPoint2])
1520 while ((NextTime2[NxtPointer - 1] == 0));
1522 NextTime = Time2[NextTime2[NxtPointer - 1] - 1];
1524 if (NxtPointer >= SCHEMESIZE2)
1530 if (NxtPointer == 0)
1533 for (Port = 0;Port <
INPUTS;Port++)
1535 #ifndef DISABLE_FAST_DATALOG_BUFFER
1536 if (NxtColorActive[Port])
1543 (*pAnalog).Pin1[Port][(*pAnalog).LogIn[Port]] = (*pAnalog).InPin1[Port];
1544 (*pAnalog).Pin6[Port][(*pAnalog).LogIn[Port]] = (*pAnalog).InPin6[Port];
1546 (*pAnalog).Actual[Port] = (*pAnalog).LogIn[Port];
1548 if (++((*pAnalog).LogIn[Port]) >= DEVICE_LOGBUF_SIZE)
1550 (*pAnalog).LogIn[Port] = 0;
1552 if ((*pAnalog).LogIn[Port] == (*pAnalog).LogOut[Port])
1554 if (++((*pAnalog).LogOut[Port]) >= DEVICE_LOGBUF_SIZE)
1556 (*pAnalog).LogOut[Port] = 0;
1560 Nxtcolor[Port] = NxtColorActive[Port];
1562 if (NxtColorActive[Port])
1566 Nxtcolor[Port] = NxtColorActive[Port];
1569 (*pAnalog).Updated[Port] = 1;
1571 NxtcolorLatchedCmd[InputPoint2] = NxtcolorCmd[InputPoint2];
1574 return (HRTIMER_RESTART);
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;
1588 static enum hrtimer_restart Device1TimerInterrupt1(
struct hrtimer *pTimer)
1593 InputScheme1[InputSchemeLng1] = InputScheme2[InputPoint2];
1594 if (++InputPoint2 >= InputSchemeLng2)
1601 while ((InputPoint1 < InputSchemeLng1) || ((InputPoint1 <= InputSchemeLng1) && (InputSchemeLng2)))
1603 InputLast = InputMid;
1604 InputMid = InputNext;
1605 InputNext = InputScheme1[InputPoint1];
1607 pInputs[InputLast] = (
UWORD)
SpiUpdate((0x1850 | (InputReadMap[InputNext] << 7))) & 0xFFF;
1609 #if (HARDWARE == ONE2ONE)
1610 if (InputLast == 15)
1612 pMuxData[MuxAddr] = pInputs[InputLast];
1618 SetMultiplexer(MuxAddr);
1623 for (Port = 0;Port <
INPUTS;Port++)
1625 (*pAnalog).Updated[Port] = 1;
1629 hrtimer_forward_now(pTimer,Device1Time);
1630 return (HRTIMER_RESTART);
1646 #ifndef DISABLE_OLD_COLOR
1667 "DCM_FLOATING_DELAY",
1669 "DCM_WAITING_FOR_PIN5_LOW",
1670 "DCM_WAITING_FOR_PIN6_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",
1680 "DCM_CONNECTED_WAITING_FOR_PIN2_HIGH",
1682 "DCM_CONNECTED_WAITING_FOR_PIN1_TO_FLOAT",
1685 "DCM_CONNECTED_WAITING_FOR_PIN5_HIGH",
1686 "DCM_CONNECTED_WAITING_FOR_PIN6_LOW",
1687 "DCM_CONNECTED_WAITING_FOR_PORT_OPEN"
1716 static void InputPortFloat(
int Port)
1726 static void OutputPortFloat(
int Port)
1737 UWORD Pins = 0x0000;
1738 UWORD Mask = 0x0001;
1756 UWORD Pins = 0x0000;
1757 UWORD Mask = 0x0001;
1773 static ssize_t Device1Write(
struct file *File,
const char *
Buffer,
size_t Count,loff_t *Data)
1796 static ssize_t Device1Read(
struct file *File,
char *Buffer,
size_t Count,loff_t *Offset)
1804 for (Point = 0;Point <
INPUTS;Point++)
1809 if ((Pins & 0x0001))
1811 Buffer[Lng++] =
'1';
1815 Buffer[Lng++] =
'0';
1822 if ((Pins & 0x0001))
1824 Buffer[Lng++] =
'1';
1828 Buffer[Lng++] =
'0';
1832 Buffer[Lng++] =
' ';
1835 Buffer[Lng++] =
'\r';
1837 Buffer[Lng++] = 0x1B;
1838 Buffer[Lng++] =
'[';
1839 Buffer[Lng++] =
'B';
1843 while ((Count > Tmp) && (Point <
INPUTADC))
1847 Tmp =
snprintf(&Buffer[Lng],6,
"%04u ",pInputs[Point]);
1851 Tmp =
snprintf(&Buffer[Lng],7,
"%04u\r",pInputs[Point]);
1858 Buffer[Lng++] = 0x1B;
1859 Buffer[Lng++] =
'[';
1860 Buffer[Lng++] =
'A';
1867 #define SHM_LENGTH (sizeof(AnalogDefault))
1868 #define NPAGES ((SHM_LENGTH + PAGE_SIZE - 1) / PAGE_SIZE)
1869 static void *kmalloc_ptr;
1871 static int Device1Mmap(
struct file *filp,
struct vm_area_struct *vma)
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);
1886 static const struct file_operations Device1Entries =
1888 .owner = THIS_MODULE,
1889 .read = Device1Read,
1890 .write = Device1Write,
1891 .mmap = Device1Mmap,
1895 static struct miscdevice Device1 =
1903 static int Device1Init(
void)
1910 Result = misc_register(&Device1);
1927 if ((kmalloc_ptr = kmalloc((
NPAGES + 2) * PAGE_SIZE, GFP_KERNEL)) !=
NULL)
1929 pTmp = (
UWORD*)((((
unsigned long)kmalloc_ptr) + PAGE_SIZE - 1) & PAGE_MASK);
1930 for (i = 0; i <
NPAGES * PAGE_SIZE; i += PAGE_SIZE)
1932 SetPageReserved(virt_to_page(((
unsigned long)pTmp) + i));
1934 pAnalog = (ANALOG*)pTmp;
1935 memset(pAnalog,0,
sizeof(ANALOG));
1938 for (Port = 0;Port <
INPUTS;Port++)
1940 (*pAnalog).InDcm[Port] = 0;
1941 (*pAnalog).InConn[Port] = 0;
1943 for (Port = 0;Port <
OUTPUTS;Port++)
1945 (*pAnalog).OutDcm[Port] = 0;
1946 (*pAnalog).OutConn[Port] = 0;
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);
1956 NextTime = Time1[0];
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);
1977 static void Device1Exit(
void)
1982 hrtimer_cancel(&Device1Timer);
1987 pInputs = (
UWORD*)&AnalogDefault;
1988 pAnalog = &AnalogDefault;
1991 for (i = 0; i <
NPAGES * PAGE_SIZE; i+= PAGE_SIZE)
1993 ClearPageReserved(virt_to_page(((
unsigned long)pTmp) + i));
1995 printk(
" %s memory page %d unmapped\n",
DEVICE1_NAME,i);
2000 misc_deregister(&Device1);
2009 #define BUFFER_LNG 16
2011 static int Device2Ioctl(
struct inode *pNode,
struct file *File,
unsigned int Request,
unsigned long Pointer)
2022 copy_from_user((
void*)&Tstpin,(
void*)Pointer,
sizeof(
TSTPIN));
2025 Lng = (int)Tstpin.
Length;
2034 for (Port = 0;Port <
INPUTS;Port++)
2038 for (Port = 0;Port <
OUTPUTS;Port++)
2050 for (Port = 0;Port <
INPUTS;Port++)
2052 InputPortFloat(Port);
2054 (*pAnalog).InConn[Port] = CONN_NONE;
2057 for (Port = 0;Port <
OUTPUTS;Port++)
2059 OutputPortFloat(Port);
2061 (*pAnalog).OutConn[Port] = CONN_NONE;
2075 if ((Port >= 0) && (Port < INPUTS))
2078 for (Tmp = 0;(Poi < Lng) && (Tmp < INPUT_PORT_PINS);Tmp++)
2080 if ((Pins & 0x0001))
2082 Tstpin.
String[Poi] =
'1';
2086 Tstpin.
String[Poi] =
'0';
2098 for (Tmp = 0;(Poi < Lng) && (Tmp < OUTPUT_PORT_PINS);Tmp++)
2100 if ((Pins & 0x0001))
2102 Tstpin.
String[Poi] =
'1';
2106 Tstpin.
String[Poi] =
'0';
2113 for (;Poi < Lng;Poi++)
2115 Tstpin.
String[Poi] =
' ';
2121 copy_to_user((
void*)Pointer,(
void*)&Tstpin,
sizeof(
TSTPIN));
2133 if ((Port >= 0) && (Port < INPUTS))
2135 for (Tmp = 0;(Poi < Lng) && (Tmp < INPUT_PORT_PINS);Tmp++)
2137 if (Tstpin.
String[Poi] ==
'0')
2141 if (Tstpin.
String[Poi] ==
'1')
2145 if ((Tstpin.
String[Poi] ==
'x') || (Tstpin.
String[Poi] ==
'X'))
2152 if (Port >= (INPUTS * CHAIN_DEPT))
2158 for (Tmp = 0;(Poi < Lng) && (Tmp < OUTPUT_PORT_PINS);Tmp++)
2160 if (Tstpin.
String[Poi] ==
'0')
2164 if (Tstpin.
String[Poi] ==
'1')
2168 if ((Tstpin.
String[Poi] ==
'x') || (Tstpin.
String[Poi] ==
'X'))
2185 static ssize_t Device2Write(
struct file *File,
const char *Buffer,
size_t Count,loff_t *Data)
2195 static ssize_t Device2Read(
struct file *File,
char *Buffer,
size_t Count,loff_t *Offset)
2202 if (Count >= (INPUTS * (INPUT_PORT_PINS + OUTPUT_PORT_PINS + 1) + 2))
2204 for (Port = 0;Port <
INPUTS;Port++)
2209 if ((Pins & 0x0001))
2211 Buffer[Lng++] =
'1';
2215 Buffer[Lng++] =
'0';
2222 if ((Pins & 0x0001))
2224 Buffer[Lng++] =
'1';
2228 Buffer[Lng++] =
'0';
2232 Buffer[Lng++] =
' ';
2235 Buffer[Lng++] =
'\r';
2243 static const struct file_operations Device2Entries =
2245 .owner = THIS_MODULE,
2246 .read = Device2Read,
2247 .write = Device2Write,
2248 .ioctl = Device2Ioctl
2252 static struct miscdevice Device2 =
2260 static int Device2Init(
void)
2264 Result = misc_register(&Device2);
2280 static void Device2Exit(
void)
2282 misc_deregister(&Device2);
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]
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]
2305 static struct hrtimer Device3Timer;
2306 static ktime_t Device3Time;
2308 static UWORD Device3StateTimer;
2311 #ifndef DISABLE_OLD_COLOR
2313 static struct hrtimer NxtColorTimer;
2314 static ktime_t NxtColorTime;
2315 #define NXTCOLOR_TIMER_RESOLUTION 200 // [uS]
2322 #define NXTCOLOR_BYTES (12 * 4 + 3 * 2)
2323 #define NXTCOLOR_BITS (NXTCOLOR_BYTES * 8)
2334 static UBYTE NxtColorBuffer[
INPUTS][NXTCOLOR_BYTES];
2339 static UBYTE NxtColorInitInUse;
2343 static enum hrtimer_restart NxtColorCommIntr(
struct hrtimer *pTimer)
2347 hrtimer_forward_now(pTimer,NxtColorTime);
2352 if (NxtColorState[Port])
2354 switch (NxtColorState[Port])
2359 NxtColorState[Port]++;
2367 if (NxtColorInitCnt[Port] == 0)
2370 NxtColorState[Port]++;
2374 NxtColorInitTimer[Port] = 0;
2375 NxtColorState[Port] += 2;
2381 NxtColorState[Port]++;
2389 if (++NxtColorInitCnt[Port] >= 2)
2391 NxtColorState[Port]++;
2395 NxtColorState[Port] = 1;
2403 if (++NxtColorInitTimer[Port] >= ((DCM_NXT_COLOR_INIT_DELAY * 1000) / NXTCOLOR_TIMER_RESOLUTION))
2405 NxtColorState[Port]++;
2412 NxtColorBuffer[Port][0] = NxtColorCmd[Port];
2413 NxtColorByteCnt[Port] = 1;
2414 NxtColorBytePnt[Port] = 0;
2415 NxtColorTx[Port] = 1;
2416 NxtColorState[Port]++;
2422 if ((NxtColorBitCnt[Port] == 0) && (NxtColorByteCnt[Port] == 0))
2424 NxtColorByteCnt[Port] = NXTCOLOR_BYTES;
2425 NxtColorBytePnt[Port] = 0;
2426 NxtColorTx[Port] = 0;
2427 NxtColorState[Port]++;
2434 if ((NxtColorBitCnt[Port] == 0) && (NxtColorByteCnt[Port] == 0))
2436 NxtColorState[Port]++;
2443 NxtColorState[Port] = 0;
2449 if (NxtColorBitCnt[Port])
2451 if (!NxtColorClkHigh[Port])
2453 if (NxtColorTx[Port])
2455 if (NxtColorByte[Port] & 1)
2463 NxtColorByte[Port] >>= 1;
2470 NxtColorClkHigh[Port] = 1;
2475 NxtColorBitCnt[Port]--;
2476 if (!NxtColorTx[Port])
2478 NxtColorByte[Port] >>= 1;
2481 NxtColorByte[Port] |= 0x80;
2485 NxtColorByte[Port] &= ~0x80;
2487 if (!NxtColorBitCnt[Port])
2489 NxtColorBuffer[Port][NxtColorBytePnt[Port]] = NxtColorByte[Port];
2490 NxtColorBytePnt[Port]++;
2494 NxtColorClkHigh[Port] = 0;
2499 if (NxtColorByteCnt[Port])
2501 if (NxtColorTx[Port])
2503 NxtColorByte[Port] = NxtColorBuffer[Port][NxtColorBytePnt[Port]];
2504 NxtColorBytePnt[Port]++;
2506 NxtColorBitCnt[Port] = 8;
2507 NxtColorByteCnt[Port]--;
2513 return (HRTIMER_RESTART);
2519 NxtColorState[Port] = 1;
2520 NxtColorInitCnt[Port] = 0;
2521 NxtColorBytePnt[Port] = 0;
2522 NxtColorByteCnt[Port] = 0;
2523 NxtColorBitCnt[Port] = 0;
2524 NxtColorCmd[Port] = Cmd;
2526 if (NxtColorInitInUse == 0)
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);
2533 NxtColorInitInUse |= (1 << Port);
2541 if (NxtColorState[Port] == 0)
2553 NxtColorInitInUse &= ~(1 << Port);
2555 if (NxtColorInitInUse == 0)
2557 hrtimer_cancel(&NxtColorTimer);
2559 NxtColorState[Port] = 0;
2566 static enum hrtimer_restart Device3TimerInterrupt1(
struct hrtimer *pTimer)
2571 #ifndef DISABLE_OLD_COLOR
2575 hrtimer_forward_now(pTimer,Device3Time);
2577 switch (Device3State)
2591 Device3StateTimer = 0;
2598 if (++Device3StateTimer >= (DCM_DEVICE_RESET_TIME / DCM_TIMER_RESOLUTION))
2611 switch (InputPort[Port].State)
2616 #ifndef DISABLE_OLD_COLOR
2617 NxtColorActive[Port] = 0;
2620 InputPortFloat(Port);
2622 (*pAnalog).InConn[Port] = CONN_NONE;
2623 InputPort[Port].
Timer = 0;
2624 InputPort[Port].
Event = 0;
2632 if (++(InputPort[Port].
Timer) >= (DCM_FLOAT_DELAY / DCM_TIMER_RESOLUTION))
2634 InputPort[Port].
Timer = 0;
2649 if ((*pAnalog).InPin1[Port] <
VtoC(IN1_NEAR_5V))
2664 if (InputPort[Port].Event != Event)
2668 printk(
"i ! %d Event = %02X Old = %02X\n",Port,Event,InputPort[Port].Event);
2670 InputPort[Port].
Event = Event;
2671 InputPort[Port].
Timer = 0;
2674 if (InputPort[Port].Event)
2677 if (++(InputPort[Port].Timer) >= (DCM_CONNECT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
2725 #ifndef DISABLE_FAST_DATALOG_BUFFER
2726 (*pAnalog).Actual[Port] = 0;
2727 (*pAnalog).LogIn[Port] = 0;
2728 (*pAnalog).LogOut[Port] = 0;
2736 InputPortFloat(Port);
2737 InputPort[Port].
Timer = 0;
2743 if ((*pAnalog).InPin1[Port] <
VtoC(IN1_NEAR_GND))
2747 #ifndef DISABLE_OLD_COLOR
2748 (*pAnalog).InConn[Port] = CONN_NXT_COLOR;
2751 (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2758 (*pAnalog).InConn[Port] = CONN_NXT_IIC;
2770 (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2775 (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2780 if ((*pAnalog).InPin1[Port] <
VtoC(IN1_NEAR_GND))
2784 #ifndef DISABLE_OLD_COLOR
2785 (*pAnalog).InConn[Port] = CONN_NXT_COLOR;
2788 (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2793 if ((*pAnalog).InPin1[Port] >
VtoC(IN1_NEAR_5V))
2797 (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2801 if (((*pAnalog).InPin1[Port] >
VtoC(IN1_TOUCH_LOW)) && ((*pAnalog).InPin1[Port] <
VtoC(IN1_TOUCH_HIGH)))
2804 InputPort[Port].
Timer = 0;
2805 InputPort[Port].
Value = (*pAnalog).InPin1[Port];
2812 (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2824 if (++(InputPort[Port].Timer) >= (DCM_TOUCH_DELAY / DCM_TIMER_RESOLUTION))
2827 if (((*pAnalog).InPin1[Port] > (InputPort[Port].
Value - 10)) && ((*pAnalog).InPin1[Port] < (InputPort[Port].
Value + 10)))
2831 (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2837 (*pAnalog).InConn[Port] = CONN_NXT_DUMB;
2843 #ifndef DISABLE_OLD_COLOR
2847 NxtcolorCmd[Port] = 0;
2850 InputPort[Port].
Timer = 0;
2857 if (NxtcolorCmd[Port] == NxtcolorLatchedCmd[Port])
2869 NxtcolorCmd[Port] = InputPort[Port].
Cmd;
2870 InputPort[Port].
Timer = 0;
2873 pData = (
UBYTE*)&((*pAnalog).NxtCol[Port]);
2875 for (Tmp = 0;Tmp < NXTCOLOR_BYTES;Tmp++)
2877 *pData = NxtColorBuffer[Port][Tmp];
2883 NxtColorActive[Port] = 1;
2885 if (++(InputPort[Port].Timer) > (DCM_NXT_COLOR_TIMEOUT / DCM_TIMER_RESOLUTION))
2888 printk(
"i ! %d NXT Color sensor timeout\n",Port);
2890 InputPort[Port].
Timer = 0;
2903 if (++(InputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
2911 InputPort[Port].
Timer = 0;
2918 if ((*pAnalog).InPin1[Port] >
VtoC(IN1_NEAR_PIN2))
2921 (*pAnalog).InConn[Port] = CONN_ERROR;
2925 if ((*pAnalog).InPin1[Port] <
VtoC(IN1_NEAR_GND))
2928 (*pAnalog).InConn[Port] = CONN_INPUT_UART;
2933 (*pAnalog).InConn[Port] = CONN_INPUT_DUMB;
2937 InputPort[Port].
Timer = 0;
2944 if ((*pAnalog).InPin1[Port] >
VtoC(IN1_NEAR_5V))
2947 if (++(InputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
2955 InputPort[Port].
Timer = 0;
2964 (*pAnalog).InConn[Port] = CONN_NXT_IIC;
2966 InputPort[Port].
Timer = 0;
2975 if (++(InputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
2983 InputPort[Port].
Timer = 0;
2991 (*pAnalog).InConn[Port] = CONN_ERROR;
2993 InputPort[Port].
Timer = 0;
3002 if (++(InputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
3010 InputPort[Port].
Timer = 0;
3023 if (InputPort[Port].OldState != InputPort[Port].State)
3027 printk(
"i %d %s\n",Port,DcmStateText[InputPort[Port].State]);
3038 switch (OutputPort[Port].State)
3043 OutputPortFloat(Port);
3045 (*pAnalog).OutConn[Port] = CONN_NONE;
3046 OutputPort[Port].
Timer = 0;
3047 OutputPort[Port].
Event = 0;
3055 if (++(OutputPort[Port].Timer) >= (DCM_FLOAT_DELAY / DCM_TIMER_RESOLUTION))
3057 OutputPort[Port].
Timer = 0;
3081 if (((*pAnalog).OutPin5[Port] <
VtoC(OUT5_BALANCE_LOW)) || ((*pAnalog).OutPin5[Port] >
VtoC(OUT5_BALANCE_HIGH)))
3087 if (OutputPort[Port].Event != Event)
3090 OutputPort[Port].
Event = Event;
3091 OutputPort[Port].
Timer = 0;
3094 if (OutputPort[Port].Event)
3097 if (++(OutputPort[Port].Timer) >= (DCM_CONNECT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
3102 OutputPort[Port].
Timer = 0;
3112 if (++(OutputPort[Port].Timer) >= (DCM_LOW_DELAY / DCM_TIMER_RESOLUTION))
3114 OutputPort[Port].
Value5Low =
CtoV((*pAnalog).OutPin5[Port]);
3129 if ((Tmp > (ADC_REF - 50)) && (Tmp < (ADC_REF + 50)))
3132 if ((OutputPort[Port].Value5Float >= OUT5_BALANCE_LOW) && (OutputPort[Port].Value5Float <= OUT5_BALANCE_HIGH) && (OutputPort[Port].Event & (0x01 <<
OUTPUT_PORT_PIN6)))
3136 (*pAnalog).OutConn[Port] = CONN_ERROR;
3141 if (OutputPort[Port].Value5Float < OUT5_NEAR_GND)
3145 (*pAnalog).OutConn[Port] = CONN_ERROR;
3150 if ((OutputPort[Port].Value5Float >= OUT5_LIGHT_LOW) && (OutputPort[Port].Value5Float <= OUT5_LIGHT_HIGH))
3154 (*pAnalog).OutConn[Port] = CONN_ERROR;
3159 if ((OutputPort[Port].Value5Float >= OUT5_IIC_LOW) && (OutputPort[Port].Value5Float <= OUT5_IIC_HIGH))
3163 (*pAnalog).OutConn[Port] = CONN_ERROR;
3168 if (OutputPort[Port].Value5Float < OUT5_BALANCE_LOW)
3170 if (OutputPort[Port].Value5Float > OUT5_MINITACHO_HIGH2)
3176 if (OutputPort[Port].Value5Float > OUT5_MINITACHO_LOW2)
3185 (*pAnalog).OutConn[Port] = CONN_OUTPUT_TACHO;
3202 if ((OutputPort[Port].Value5Low > OUT5_NEAR_GND) && (OutputPort[Port].Value5Low < OUT5_BALANCE_LOW))
3205 (*pAnalog).OutPin5Low[Port] = OutputPort[Port].
Value5Low;
3207 (*pAnalog).OutConn[Port] = CONN_OUTPUT_DUMB;
3213 (*pAnalog).OutConn[Port] = CONN_ERROR;
3218 OutputPort[Port].
Timer = 0;
3220 if (OutputPort[Port].Connected)
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);
3230 if (++(OutputPort[Port].Timer) >= (DCM_LOW_DELAY / DCM_TIMER_RESOLUTION))
3232 OutputPort[Port].
Value5Low =
CtoV((*pAnalog).OutPin5[Port]);
3235 (*pAnalog).OutConn[Port] = CONN_OUTPUT_TACHO;
3236 if (OutputPort[Port].Value5Low < OUT5_MINITACHO_LOW1)
3239 (*pAnalog).OutConn[Port] = CONN_ERROR;
3243 if (OutputPort[Port].Value5Low < OUT5_MINITACHO_HIGH1)
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);
3263 if (((*pAnalog).OutPin5[Port] <
VtoC(OUT5_BALANCE_LOW)) || ((*pAnalog).OutPin5[Port] >
VtoC(OUT5_BALANCE_HIGH)))
3266 OutputPort[Port].
Timer = 0;
3272 OutputPort[Port].
Timer = 0;
3278 OutputPort[Port].
Timer = 0;
3281 if (++(OutputPort[Port].Timer) >= (DCM_EVENT_STABLE_DELAY / DCM_TIMER_RESOLUTION))
3297 if (OutputPort[Port].OldState != OutputPort[Port].State)
3301 printk(
"o %d %s\n",Port,DcmStateText[OutputPort[Port].State]);
3311 return (HRTIMER_RESTART);
3315 static ssize_t Device3Write(
struct file *File,
const char *Buffer,
size_t Count,loff_t *Data)
3317 char Buf[INPUTS + 1];
3322 if (Count >= INPUTS)
3325 copy_from_user(Buf,Buffer,INPUTS);
3340 InputPortFloat(Port);
3346 if (InputPort[Port].Connected)
3348 if ((Char & 0xF8) ==
'0')
3371 #ifndef DISABLE_OLD_COLOR
3374 if ((Char >= 0x0D) && (Char <= 0x11))
3378 InputPort[Port].
Timer = 0;
3396 static ssize_t Device3Read(
struct file *File,
char *Buffer,
size_t Count,loff_t *Offset)
3402 while (Lng < NO_OF_INPUT_PORTS)
3404 Buffer[Lng] = (*pAnalog).InDcm[Lng];
3407 while (Lng < INPUTS)
3412 while (Lng < (INPUTS + NO_OF_OUTPUT_PORTS))
3414 Buffer[Lng] = (*pAnalog).OutDcm[Lng -
INPUTS];
3417 while (Lng < (INPUTS +
OUTPUTS))
3422 Buffer[Lng++] =
'\r';
3430 static const struct file_operations Device3Entries =
3432 .owner = THIS_MODULE,
3433 .read = Device3Read,
3434 .write = Device3Write
3438 static struct miscdevice Device3 =
3446 static int Device3Init(
void)
3451 Result = misc_register(&Device3);
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);
3485 static void Device3Exit(
void)
3489 hrtimer_cancel(&Device3Timer);
3492 InputPortFloat(Tmp);
3494 misc_deregister(&Device3);
3509 static int ModuleInit(
void)
3525 if (request_mem_region(DA8XX_GPIO_BASE,0xD8,
MODULE_NAME) >= 0)
3527 GpioBase = (
void*)ioremap(DA8XX_GPIO_BASE,0xD8);
3528 if (GpioBase !=
NULL)
3551 static void ModuleExit(
void)
Device is NXT sound sensor.
MODULE_SUPPORTED_DEVICE(DEVICE1_NAME)
INPIN OutputPortPin[NO_OF_OUTPUT_PORTS][OUTPUT_PORT_PINS]
#define POUTLow(port, pin)
INPIN InputPortPin[NO_OF_INPUT_PORTS][INPUT_PORT_PINS]
INPORT InputPort[NO_OF_INPUT_PORTS]
OUTPORT OutputPort[NO_OF_OUTPUT_PORTS]
#define POUTRead(port, pin)
#define EP2
Schematics revision D.
INPIN EP2_OutputPortPin[][OUTPUT_PORT_PINS]
Port empty or not available.
#define FINAL
Final prototype.
OUTPORT OutputPortDefault
MODULE_AUTHOR("The LEGO Group")
UWORD Device1GetInputPins(UBYTE Port)
void NxtColorCommStop(UBYTE Port)
DATA8 String[TST_PIN_LENGTH+1]
Device is a NXT ADC test sensor.
MODULE_DESCRIPTION(MODULE_NAME)
Port not empty but type has not been determined.
INPIN FINAL_OutputPortPin[][OUTPUT_PORT_PINS]
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
#define NO_OF_OUTPUT_PORTS
Device is NXT light sensor.
#define POUTFloat(port, pin)
UBYTE DataOut[DAISY_DEFAULT_MAX_EP_SIZE]
module_param(HwId, charp, 0)
Port not empty and type is invalid.
#define FINALB
Schematics revision B and C.
Device is NXT IIC sensor.
#define PINFloat(port, pin)
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
#define PINRead(port, pin)
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
#define POUTHigh(port, pin)
UWORD SpiUpdate(UWORD DataOut)
#define OUTPUTS
Number of output ports in the system.
char DcmStateText[DCM_STATES][50]
#define PINLow(port, pin)
Device is a mini tacho motor.
UBYTE NxtColorCommReady(UBYTE Port)
INPIN FINALB_OutputPortPin[][OUTPUT_PORT_PINS]
SBYTE DATA8
VM Type for 1 byte signed value.
Device is NXT color sensor.
#define NO_OF_INPUT_PORTS
Device is a new tacho motor.
#define INPUTS
Number of input ports in the system.
#define PINHigh(port, pin)
#define PLATFORM_END
Newest supported hardware (newer versions will use this)
UWORD Device1GetOutputPins(UBYTE Port)
#define CHAIN_DEPT
Number of bricks in the USB daisy chain (master + slaves)
INPIN AdcPowerPin[ADC_POWER_PINS]
void NxtColorCommStart(UBYTE Port, UBYTE Cmd)
Device is NXT touch sensor.
UBYTE DataIn[DAISY_DEFAULT_MAX_EP_SIZE]
#define PLATFORM_START
Oldest supported hardware (older versions will use this)