# HG changeset patch # User Heinz Junkes # Date 1441814819 -7200 # Node ID 7029db7ac3db4cc6ed2136d75fac02fc9e40fcd0 # Parent bd6bb22c65330f4b68db9cfd0e79248d000de7c0 Add adcPi device support diff -r bd6bb22c6533 -r 7029db7ac3db iocBoot/iockstm/Makefile --- a/iocBoot/iockstm/Makefile Fri Aug 14 11:30:43 2015 +0200 +++ b/iocBoot/iockstm/Makefile Wed Sep 09 18:06:59 2015 +0200 @@ -1,5 +1,5 @@ TOP = ../.. include $(TOP)/configure/CONFIG -ARCH = linux-x86_64 +ARCH = linux-arm TARGETS = envPaths include $(TOP)/configure/RULES.ioc diff -r bd6bb22c6533 -r 7029db7ac3db iocBoot/iockstm/st.cmd --- a/iocBoot/iockstm/st.cmd Fri Aug 14 11:30:43 2015 +0200 +++ b/iocBoot/iockstm/st.cmd Wed Sep 09 18:06:59 2015 +0200 @@ -53,12 +53,12 @@ # ASYN_TRACE_FLOW 0x0010 #asynSetTraceMask ${PGC2_MC_LINK} 0 8 -epicsEnvSet ("streamDebug","1") +#epicsEnvSet ("streamDebug","1") ## Load record instances dbLoadRecords("db/misc.db","P=FHI4KSTM, Q=MISC") -#dbLoadRecords("db/dht.db","P=FHI4KSTM, Q=DHT") +dbLoadRecords("db/dht.db","P=FHI4KSTM, Q=DHT") dbLoadTemplate("db/4kStmEuro.sub") @@ -67,6 +67,10 @@ dbLoadRecords("db/pgc2.db","PORT=PGC2_MC, P=FHI4KSTM, Q=PGC2_MC") dbLoadRecords("db/pgc2.db","PORT=PGC2_PC, P=FHI4KSTM, Q=PGC2_PC") +#dbLoadRecords("db/adcPi.db","P=FHI4KSTM:ADCPI:CH_1,C=1") +#dbLoadRecords("db/adcPi.db","P=FHI4KSTM:ADCPI:CH_2,C=2") +dbLoadRecords("db/adcPi.db","P=FHI4KSTM:ADCPI:CH_3,C=3") + iocInit() ## Start any sequence programs diff -r bd6bb22c6533 -r 7029db7ac3db kstmApp/Db/Makefile --- a/kstmApp/Db/Makefile Fri Aug 14 11:30:43 2015 +0200 +++ b/kstmApp/Db/Makefile Wed Sep 09 18:06:59 2015 +0200 @@ -13,7 +13,9 @@ #DB += xxx.db DB += dht.db DB += misc.db + DB += mtm.db +DB += mtm.proto DB += 4kStmEuro.sub DB += eurotherm2k.proto @@ -25,6 +27,8 @@ DB += M1900.db DB += M1900.proto +DB += adcPi.db + #---------------------------------------------------- # If .db template is not named *.template add # _template = diff -r bd6bb22c6533 -r 7029db7ac3db kstmApp/Db/adcPi.db --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kstmApp/Db/adcPi.db Wed Sep 09 18:06:59 2015 +0200 @@ -0,0 +1,9 @@ +record(ai,"$(P)"){ + field(DTYP,"AdcPi") + field(DESC,"ADC Pi") + field(SCAN,"$(SCAN=1 second)") + field(INP,"$(C)") + field(LINR,"LINEAR") + field (ESLO, "0.000154") + field(EGU,"V") +} diff -r bd6bb22c6533 -r 7029db7ac3db kstmApp/Db/dht.db --- a/kstmApp/Db/dht.db Fri Aug 14 11:30:43 2015 +0200 +++ b/kstmApp/Db/dht.db Wed Sep 09 18:06:59 2015 +0200 @@ -1,8 +1,14 @@ -record(sub,"$(P):$(Q):R_temp") +record(aSub,"$(P):$(Q):R_DHT") { - field(INAM,"dbSubReadDHTInit") - field(SNAM,"dbSubReadDHTProcess") - field(SCAN,"5 second") - field(INPA,"3") + field(DESC, "Reads DHT from GPIO def in A") + field(INAM,"aSubReadDHTInit") + field(SNAM,"aSubReadDHTProcess") + field(SCAN,"10 second") + field(INPA,"4") + field(FTA, "USHORT") +# Temperature in VALA + field(FTVA, "DOUBLE") +# Humidity in VALB + field(FTVB, "DOUBLE") } diff -r bd6bb22c6533 -r 7029db7ac3db kstmApp/src/Makefile --- a/kstmApp/src/Makefile Fri Aug 14 11:30:43 2015 +0200 +++ b/kstmApp/src/Makefile Wed Sep 09 18:06:59 2015 +0200 @@ -17,10 +17,12 @@ # Include dbd files from all support applications: #kstm_DBD += xxx.dbd -kstm_DBD += dbSubReadDHT.dbd +kstm_DBD += aSubReadDHT.dbd kstm_DBD += asyn.dbd kstm_DBD += drvAsynIPPort.dbd kstm_DBD += stream.dbd +kstm_DBD += adcPi.dbd + # Add all the support libraries needed by this IOC #kstm_LIBS += xxx @@ -34,8 +36,9 @@ kstm_SRCS += common_dht_read.c kstm_SRCS += pi_2_mmio.c kstm_SRCS += pi_2_dht_read.c -kstm_SRCS += dbSubReadDHT.c +kstm_SRCS += aSubReadDHT.c #kstm_SRCS += dbSubReadADC.c +kstm_SRCS += devadcpi.c # Build the main IOC entry point on workstation OSs. kstm_SRCS_DEFAULT += kstmMain.cpp diff -r bd6bb22c6533 -r 7029db7ac3db kstmApp/src/aSubReadDHT.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kstmApp/src/aSubReadDHT.c Wed Sep 09 18:06:59 2015 +0200 @@ -0,0 +1,60 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "pi_2_dht_read.h" + +#define USED_DHT_TYPE 22 +int aSubReadDHTDebug = 0; +unsigned short GPIOPin; + +static long aSubReadDHTInit(aSubRecord *precord) +{ +unsigned short *a; + + if (aSubReadDHTDebug) + printf("Record %s called aSubReadDHTInit(%p)\n", precord->name, (void*) precord); + + a = (unsigned short *)precord->a; + GPIOPin = a[0]; + + if (aSubReadDHTDebug) + printf("Record %s : GPIOPin = %d\n", precord->name, GPIOPin); + + return 0; +} + +static long aSubReadDHTProcess(aSubRecord *precord) +{ +float humidity, temperature; +int ret; +double *vala, *valb; + + if (aSubReadDHTDebug) + printf("Record %s called aSubRreadDHTProcess(%p)\n", precord->name, (void*) precord); + + ret = pi_2_dht_read(USED_DHT_TYPE, GPIOPin, &humidity, &temperature); + + if (aSubReadDHTDebug) + printf(" ret : %d, humidity = %f, temperature = %f\n", ret, humidity, temperature); + + if (!ret) { + vala = (double *)precord->vala; + valb = (double *)precord->valb; + vala[0] = (double)temperature; + valb[0] = (double)humidity; + } + return 0; +} + +/* Register these symbols for use by IOC code: */ + +epicsExportAddress(int, aSubReadDHTDebug); +epicsRegisterFunction(aSubReadDHTInit); +epicsRegisterFunction(aSubReadDHTProcess); + diff -r bd6bb22c6533 -r 7029db7ac3db kstmApp/src/aSubReadDHT.dbd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kstmApp/src/aSubReadDHT.dbd Wed Sep 09 18:06:59 2015 +0200 @@ -0,0 +1,3 @@ +variable(aSubReadDHTDebug) +function(aSubReadDHTInit) +function(aSubReadDHTProcess) diff -r bd6bb22c6533 -r 7029db7ac3db kstmApp/src/adcPi.dbd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kstmApp/src/adcPi.dbd Wed Sep 09 18:06:59 2015 +0200 @@ -0,0 +1,1 @@ +device(ai,CONSTANT,devAiAdcPi,"AdcPi") diff -r bd6bb22c6533 -r 7029db7ac3db kstmApp/src/devadcpi.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kstmApp/src/devadcpi.c Wed Sep 09 18:06:59 2015 +0200 @@ -0,0 +1,117 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +// ADCPi definitions +#define ADC_1 0x68 +#define ADC_2 0x69 +#define ADC_CHANNEL1 0x98 +#define ADC_CHANNEL2 0xB8 +#define ADC_CHANNEL3 0xD8 +#define ADC_CHANNEL4 0xF8 + + +static long init_record(aiRecord *pai); +static long read_ai(aiRecord *pai); + +struct adcPiChannel { + unsigned int channel; +}; + + +int getadc (int chn){ + unsigned int fh,dummy, adc, adc_channel; +// double val; + __u8 res[4]; +printf(" Read channel Nr: %d\n", chn); + switch (chn){ + case 1: { adc=ADC_1; adc_channel=ADC_CHANNEL1; }; break; + case 2: { adc=ADC_1; adc_channel=ADC_CHANNEL2; }; break; + case 3: { adc=ADC_1; adc_channel=ADC_CHANNEL3; }; break; + case 4: { adc=ADC_1; adc_channel=ADC_CHANNEL4; }; break; + case 5: { adc=ADC_2; adc_channel=ADC_CHANNEL1; }; break; + case 6: { adc=ADC_2; adc_channel=ADC_CHANNEL2; }; break; + case 7: { adc=ADC_2; adc_channel=ADC_CHANNEL3; }; break; + case 8: { adc=ADC_2; adc_channel=ADC_CHANNEL4; }; break; + default: { adc=ADC_1; adc_channel=ADC_CHANNEL1; }; break; + } + fh = open("/dev/i2c-1", O_RDWR); + ioctl(fh,I2C_SLAVE,adc); + i2c_smbus_write_byte (fh, adc_channel); + usleep (50000); + i2c_smbus_read_i2c_block_data(fh,adc_channel,4,res); + usleep(50000); + close (fh); + dummy = (res[0]<<8|res[1]); + if (dummy>=32768) dummy=65536-dummy; + //val = dummy * 0.000154; +// printf(" dummy = %d, val = %lf\n", dummy, val); + //return val; + return dummy; +} + +static long init_record(aiRecord *pai) +{ + struct adcPiChannel* priv; + unsigned long channel; + + priv=malloc(sizeof(struct adcPiChannel)); + if(!priv){ + recGblRecordError(S_db_noMemory, (void*)pai, + "devAoTimebase failed to allocate private struct"); + return S_db_noMemory; + } + + recGblInitConstantLink(&pai->inp,DBF_ULONG,&channel); + + priv->channel=channel; + pai->dpvt=priv; + + return 0; +} + + +static long read_ai(aiRecord *pai) +{ + struct adcPiChannel* priv=pai->dpvt; + + pai->rval = getadc(priv->channel); + + return 0; +} + +struct { + long num; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_ai; + DEVSUPFUN special_linconv; +} devAiAdcPi = { + 6, /* space for 6 functions */ + NULL, + NULL, + init_record, + NULL, + read_ai, + NULL +}; + +epicsExportAddress(dset,devAiAdcPi); + diff -r bd6bb22c6533 -r 7029db7ac3db kstmApp/src/pi_2_dht_read.c --- a/kstmApp/src/pi_2_dht_read.c Fri Aug 14 11:30:43 2015 +0200 +++ b/kstmApp/src/pi_2_dht_read.c Wed Sep 09 18:06:59 2015 +0200 @@ -21,6 +21,10 @@ #include #include +#include "epicsExit.h" +#include "epicsThread.h" +#include "iocsh.h" + #include "pi_2_dht_read.h" #include "pi_2_mmio.h" @@ -36,6 +40,11 @@ #define DHT_PULSES 41 int pi_2_dht_read(int type, int pin, float* humidity, float* temperature) { +int i; +volatile int j; +unsigned int defPrio; +epicsThreadId threadIdSelf; + // Validate humidity and temperature arguments and set them to zero. if (humidity == NULL || temperature == NULL) { return DHT_ERROR_ARGUMENT; @@ -56,7 +65,9 @@ pi_2_mmio_set_output(pin); // Bump up process priority and change scheduler to try to try to make process more 'real time'. - set_max_priority(); + defPrio = epicsThreadGetPrioritySelf(); + threadIdSelf = epicsThreadGetIdSelf(); + epicsThreadSetPriority( threadIdSelf , epicsThreadPriorityHigh); // Set pin high for ~500 milliseconds. pi_2_mmio_set_high(pin); @@ -72,28 +83,26 @@ // Set pin at input. pi_2_mmio_set_input(pin); // Need a very short delay before reading pins or else value is sometimes still low. -volatile int i; - for (i = 0; i < 50; ++i) { - } + for (j = 0; j < 50; ++j) { } // Wait for DHT to pull pin low. uint32_t count = 0; while (pi_2_mmio_input(pin)) { if (++count >= DHT_MAXCOUNT) { // Timeout waiting for response. - set_default_priority(); + epicsThreadSetPriority( threadIdSelf , defPrio); return DHT_ERROR_TIMEOUT; } } - // Record pulse widths for the expected result bits. - int j; - for ( j=0; j < DHT_PULSES*2; j+=2) { + + // Record pulse widths for the expected result bits. + for ( i=0; i < DHT_PULSES*2; i+=2) { // Count how long pin is low and store in pulseCounts[i] while (!pi_2_mmio_input(pin)) { if (++pulseCounts[i] >= DHT_MAXCOUNT) { // Timeout waiting for response. - set_default_priority(); + epicsThreadSetPriority( threadIdSelf , defPrio); return DHT_ERROR_TIMEOUT; } } @@ -101,23 +110,22 @@ while (pi_2_mmio_input(pin)) { if (++pulseCounts[i+1] >= DHT_MAXCOUNT) { // Timeout waiting for response. - set_default_priority(); + epicsThreadSetPriority( threadIdSelf , defPrio); return DHT_ERROR_TIMEOUT; } } } // Done with timing critical code, now interpret the results. - // Drop back to normal priority. - set_default_priority(); + // set_default_priority(); + epicsThreadSetPriority( threadIdSelf , defPrio); // Compute the average low pulse width to use as a 50 microsecond reference threshold. // Ignore the first two readings because they are a constant 80 microsecond pulse. uint32_t threshold = 0; - int k; - for (k=2; i < DHT_PULSES*2; k+=2) { - threshold += pulseCounts[k]; + for (i=2; i < DHT_PULSES*2; i+=2) { + threshold += pulseCounts[i]; } threshold /= DHT_PULSES-1; @@ -125,11 +133,10 @@ // If the count is less than 50us it must be a ~28us 0 pulse, and if it's higher // then it must be a ~70us 1 pulse. uint8_t data[5] = {0}; - int l; - for ( l=3; l < DHT_PULSES*2; l+=2) { - int index = (l-3)/16; + for ( i=3; i < DHT_PULSES*2; i+=2) { + int index = (i-3)/16; data[index] <<= 1; - if (pulseCounts[l] >= threshold) { + if (pulseCounts[i] >= threshold) { // One bit for long pulse. data[index] |= 1; }