diff options
author | Marty Fouts <mfouts@sta.samsung.com> | 2011-06-27 22:40:40 -0700 |
---|---|---|
committer | Arve Hjønnevåg <arve@android.com> | 2011-06-29 18:53:02 -0700 |
commit | fd62ef4c2d6e912b0a9a5354e82560f515b0c20c (patch) | |
tree | 2490fbde5fa0903c22b853415b964c7d3b0f9729 /libsensors | |
parent | a4116db3002715e73ba8d48fbefabd15b91c92a2 (diff) | |
download | device_samsung_tuna-fd62ef4c2d6e912b0a9a5354e82560f515b0c20c.zip device_samsung_tuna-fd62ef4c2d6e912b0a9a5354e82560f515b0c20c.tar.gz device_samsung_tuna-fd62ef4c2d6e912b0a9a5354e82560f515b0c20c.tar.bz2 |
tuna: sensors: add light, proximity, pressure sensors
NOTE:
- light sensor ADC values need to be calibrated.
Change-Id: Iba75dc62a922bbcd0d1e273566f9089c4da450fb
Signed-off-by: Marty Fouts <mfouts@sta.samsung.com>
Diffstat (limited to 'libsensors')
-rw-r--r-- | libsensors/Android.mk | 6 | ||||
-rw-r--r-- | libsensors/LightSensor.cpp | 68 | ||||
-rw-r--r-- | libsensors/LightSensor.h | 44 | ||||
-rw-r--r-- | libsensors/PressureSensor.cpp | 45 | ||||
-rw-r--r-- | libsensors/PressureSensor.h | 43 | ||||
-rw-r--r-- | libsensors/ProximitySensor.cpp | 70 | ||||
-rw-r--r-- | libsensors/ProximitySensor.h | 51 | ||||
-rw-r--r-- | libsensors/SamsungSensorBase.cpp | 179 | ||||
-rw-r--r-- | libsensors/SamsungSensorBase.h | 59 | ||||
-rw-r--r-- | libsensors/sensors.cpp | 49 | ||||
-rw-r--r-- | libsensors/sensors.h | 3 |
11 files changed, 613 insertions, 4 deletions
diff --git a/libsensors/Android.mk b/libsensors/Android.mk index 5fe88f4..d936b2f 100644 --- a/libsensors/Android.mk +++ b/libsensors/Android.mk @@ -31,7 +31,11 @@ LOCAL_CFLAGS := -DLOG_TAG=\"Sensors\" LOCAL_C_INCLUDES += vendor/invensense/libsensors LOCAL_SRC_FILES := \ sensors.cpp \ - InputEventReader.cpp + InputEventReader.cpp \ + LightSensor.cpp \ + ProximitySensor.cpp \ + PressureSensor.cpp \ + SamsungSensorBase.cpp LOCAL_SHARED_LIBRARIES := libinvensense_hal libcutils libutils libdl diff --git a/libsensors/LightSensor.cpp b/libsensors/LightSensor.cpp new file mode 100644 index 0000000..067654f --- /dev/null +++ b/libsensors/LightSensor.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2011 Samsung + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <fcntl.h> +#include <errno.h> +#include <math.h> +#include <poll.h> +#include <unistd.h> +#include <dirent.h> +#include <sys/select.h> +#include <cutils/log.h> +#include <pthread.h> + +#include "LightSensor.h" + +LightSensor::LightSensor() + : SamsungSensorBase(NULL, "lightsensor-level", ABS_MISC) +{ + mPendingEvent.sensor = ID_L; + mPendingEvent.type = SENSOR_TYPE_LIGHT; + mPreviousLight = -1; +} + +bool LightSensor::handleEvent(input_event const *event) { + mPendingEvent.light = indexToValue(event->value); + if (mPendingEvent.light != mPreviousLight) { + mPreviousLight = mPendingEvent.light; + return true; + } + return false; +} + +float LightSensor::indexToValue(size_t index) const { + /* Driver gives a rolling average adc value. We convert it lux levels. */ + static const struct adcToLux { + size_t adc_value; + float lux_value; + } adcToLux[] = { + { 150, 10.0 }, /* from 0 - 150 adc, we map to 10.0 lux */ + { 800, 160.0 }, /* from 151 - 800 adc, we map to 160.0 lux */ + { 900, 225.0 }, /* from 801 - 900 adc, we map to 225.0 lux */ + { 1000, 320.0 }, /* from 901 - 1000 adc, we map to 320.0 lux */ + { 1200, 640.0 }, /* from 1001 - 1200 adc, we map to 640.0 lux */ + { 1400, 1280.0 }, /* from 1201 - 1400 adc, we map to 1280.0 lux */ + { 1600, 2600.0 }, /* from 1401 - 1600 adc, we map to 2600.0 lux */ + { 4095, 10240.0 }, /* from 1601 - 4095 adc, we map to 10240.0 lux */ + }; + size_t i; + for (i = 0; i < ARRAY_SIZE(adcToLux); i++) { + if (index < adcToLux[i].adc_value) { + return adcToLux[i].lux_value; + } + } + return adcToLux[ARRAY_SIZE(adcToLux)-1].lux_value; +} diff --git a/libsensors/LightSensor.h b/libsensors/LightSensor.h new file mode 100644 index 0000000..ed639f4 --- /dev/null +++ b/libsensors/LightSensor.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2011 Samsung + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_LIGHT_SENSOR_H +#define ANDROID_LIGHT_SENSOR_H + +#include <stdint.h> +#include <errno.h> +#include <sys/cdefs.h> +#include <sys/types.h> + +#include "sensors.h" +#include "SamsungSensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +class LightSensor:public SamsungSensorBase { + + float mPreviousLight; + virtual bool handleEvent(input_event const * event); + float indexToValue(size_t index) const; +public: + LightSensor(); +}; + +/*****************************************************************************/ + +#endif /* ANDROID_LIGHT_SENSOR_H */ diff --git a/libsensors/PressureSensor.cpp b/libsensors/PressureSensor.cpp new file mode 100644 index 0000000..dc34b95 --- /dev/null +++ b/libsensors/PressureSensor.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2011 Samsung + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <fcntl.h> +#include <errno.h> +#include <math.h> +#include <poll.h> +#include <unistd.h> +#include <dirent.h> +#include <sys/select.h> +#include <cutils/log.h> +#include <pthread.h> + +#include "PressureSensor.h" + +/* + * The BMP driver gives pascal values. + * It needs to be changed into hectoPascal + */ +#define PRESSURE_HECTO (1.0f/100.0f) + +PressureSensor::PressureSensor() + : SamsungSensorBase(NULL, "barometer", ABS_PRESSURE) +{ + mPendingEvent.sensor = ID_PR; + mPendingEvent.type = SENSOR_TYPE_PRESSURE; +} + +bool PressureSensor::handleEvent(input_event const *event) { + mPendingEvent.pressure = event->value * PRESSURE_HECTO; + return true; +} diff --git a/libsensors/PressureSensor.h b/libsensors/PressureSensor.h new file mode 100644 index 0000000..183bfd3 --- /dev/null +++ b/libsensors/PressureSensor.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 Samsung + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PRESSURE_SENSOR_H +#define ANDROID_PRESSURE_SENSOR_H + +#include <stdint.h> +#include <errno.h> +#include <sys/cdefs.h> +#include <sys/types.h> + +#include "sensors.h" +#include "SamsungSensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + +struct input_event; + +class PressureSensor:public SamsungSensorBase { + virtual bool handleEvent(input_event const * event); + +public: + PressureSensor(); +}; + +/*****************************************************************************/ + +#endif /* ANDROID_PRESSURE_SENSOR_H */ + diff --git a/libsensors/ProximitySensor.cpp b/libsensors/ProximitySensor.cpp new file mode 100644 index 0000000..4e1ec9d --- /dev/null +++ b/libsensors/ProximitySensor.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2011 Samsung + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <fcntl.h> +#include <errno.h> +#include <math.h> +#include <poll.h> +#include <unistd.h> +#include <dirent.h> +#include <sys/select.h> +#include <pthread.h> + +#include <cutils/log.h> + +#include "ProximitySensor.h" + +/*****************************************************************************/ + +ProximitySensor::ProximitySensor() + : SamsungSensorBase(NULL, "proximity", ABS_DISTANCE) +{ + mPendingEvent.sensor = ID_P; + mPendingEvent.type = SENSOR_TYPE_PROXIMITY; +} + +int ProximitySensor::setDelay(int32_t handle, int64_t ns) +{ + return -1; +} + +float ProximitySensor::indexToValue(size_t index) const +{ + return index * PROXIMITY_THRESHOLD_GP2A; +} + +bool ProximitySensor::hasPendingEvents() const { + return mHasPendingEvent; +} + +int ProximitySensor::handleEnable(int en) { + if (!en) + return 0; + + struct input_absinfo absinfo; + if (!ioctl(data_fd, EVIOCGABS(ABS_DISTANCE), &absinfo)) { + mHasPendingEvent = true; + mPendingEvent.distance = indexToValue(absinfo.value); + return 0; + } else { + return -1; + } +} + +bool ProximitySensor::handleEvent(input_event const *event) { + mPendingEvent.distance = indexToValue(event->value); + return true; +} diff --git a/libsensors/ProximitySensor.h b/libsensors/ProximitySensor.h new file mode 100644 index 0000000..36b79d1 --- /dev/null +++ b/libsensors/ProximitySensor.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011 Samsung + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_PROXIMITY_SENSOR_H +#define ANDROID_PROXIMITY_SENSOR_H + +#include <stdint.h> +#include <errno.h> +#include <sys/cdefs.h> +#include <sys/types.h> + +#include "sensors.h" +#include "SamsungSensorBase.h" +#include "InputEventReader.h" + +/* the GP2A is a binary proximity sensor that triggers around 5 cm on + * this hardware */ +#define PROXIMITY_THRESHOLD_GP2A 5.0f + +/*****************************************************************************/ + +struct input_event; + +class ProximitySensor:public SamsungSensorBase { + + virtual int handleEnable(int en); + virtual bool handleEvent(input_event const * event); + + float indexToValue(size_t index) const; +public: + ProximitySensor(); + virtual int setDelay(int32_t handle, int64_t ns); + virtual bool hasPendingEvents() const; +}; + +/*****************************************************************************/ + +#endif /* ANDROID_PROXIMITY_SENSOR_H */ diff --git a/libsensors/SamsungSensorBase.cpp b/libsensors/SamsungSensorBase.cpp new file mode 100644 index 0000000..ab8f9d6 --- /dev/null +++ b/libsensors/SamsungSensorBase.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2011 Samsung + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <fcntl.h> +#include <errno.h> +#include <math.h> +#include <poll.h> +#include <fcntl.h> +#include <unistd.h> +#include <dirent.h> +#include <sys/select.h> +#include <cutils/log.h> +#include <pthread.h> + +#include "SamsungSensorBase.h" + +char *SamsungSensorBase::makeSysfsName(const char *input_name, + const char *file_name) { + char *name; + int length = strlen("/sys/class/input/") + + strlen(input_name) + + strlen("/device/") + + strlen(file_name); + + name = new char[length + 1]; + if (name) { + strcpy(name, "/sys/class/input/"); + strcat(name, input_name); + strcat(name, "/device/"); + strcat(name, file_name); + } + + return name; +} + +bool SamsungSensorBase::handleEvent(input_event const * event) { + return true; +} + +int SamsungSensorBase::handleEnable(int en) { + return 0; +} + +SamsungSensorBase::SamsungSensorBase(const char *dev_name, + const char *data_name, + int sensor_code) + : SensorBase(dev_name, data_name), + mEnabled(true), + mHasPendingEvent(false), + mInputReader(4), + mSensorCode(sensor_code), + mLock(PTHREAD_MUTEX_INITIALIZER) +{ + mPendingEvent.version = sizeof(sensors_event_t); + memset(mPendingEvent.data, 0, sizeof(mPendingEvent.data)); + if (!data_fd) + return; + mInputSysfsEnable = makeSysfsName(input_name, "enable"); + if (!mInputSysfsEnable) { + LOGE("%s: unable to allocate mem for %s:enable", __func__, + data_name); + return; + } + mInputSysfsPollDelay = makeSysfsName(input_name, "poll_delay"); + if (!mInputSysfsPollDelay) { + LOGE("%s: unable to allocate mem for %s:poll_delay", __func__, + data_name); + return; + } + + int flags = fcntl(data_fd, F_GETFL, 0); + fcntl(data_fd, F_SETFL, flags | O_NONBLOCK); + + enable(0, 0); +} + +SamsungSensorBase::~SamsungSensorBase() { + if (mEnabled) { + enable(0, 0); + } + delete[] mInputSysfsEnable; + delete[] mInputSysfsPollDelay; +} + +int SamsungSensorBase::enable(int32_t handle, int en) +{ + int err = 0; + pthread_mutex_lock(&mLock); + if (en != mEnabled) { + int fd; + fd = open(mInputSysfsEnable, O_RDWR); + if (fd >= 0) { + err = write(fd, en ? "1" : "0", 2); + close(fd); + if (err < 0) { + goto cleanup; + } + mEnabled = en; + err = handleEnable(en); + } else { + err = -1; + } + } +cleanup: + pthread_mutex_unlock(&mLock); + return err; +} + +int SamsungSensorBase::setDelay(int32_t handle, int64_t ns) +{ + int fd; + int result = 0; + char buf[21]; + pthread_mutex_lock(&mLock); + fd = open(mInputSysfsPollDelay, O_RDWR); + if (fd < 0) { + result = -1; + goto done; + } + sprintf(buf, "%lld", ns); + write(fd, buf, strlen(buf)+1); + close(fd); +done: + pthread_mutex_unlock(&mLock); + return result; +} + +int SamsungSensorBase::readEvents(sensors_event_t* data, int count) +{ + if (count < 1) + return -EINVAL; + + pthread_mutex_lock(&mLock); + int numEventReceived = 0; + + if (!mEnabled) + goto done; + + if (mHasPendingEvent) { + mHasPendingEvent = false; + mPendingEvent.timestamp = getTimestamp(); + *data = mPendingEvent; + numEventReceived++; + goto done; + } + + input_event const* event; + while (count && mInputReader.readEvent(data_fd, &event)) { + if (event->type == EV_ABS) { + if (event->code == mSensorCode) { + if (handleEvent(event)) { + mPendingEvent.timestamp = timevalToNano(event->time); + *data++ = mPendingEvent; + count--; + numEventReceived++; + } + } + } + mInputReader.next(); + } + +done: + pthread_mutex_unlock(&mLock); + return numEventReceived; + +} diff --git a/libsensors/SamsungSensorBase.h b/libsensors/SamsungSensorBase.h new file mode 100644 index 0000000..c989c71 --- /dev/null +++ b/libsensors/SamsungSensorBase.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2011 Samsung + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SAMSUNG_SENSORBASE_H +#define SAMSUNG_SENSORBASE_H + +#include <stdint.h> +#include <errno.h> +#include <sys/cdefs.h> +#include <sys/types.h> + +#include "sensors.h" +#include "SensorBase.h" +#include "SamsungSensorBase.h" +#include "InputEventReader.h" + +/*****************************************************************************/ + +class SamsungSensorBase:public SensorBase { +protected: + bool mEnabled; + bool mHasPendingEvent; + InputEventCircularReader mInputReader; + sensors_event_t mPendingEvent; + char *mInputSysfsEnable; + char *mInputSysfsPollDelay; + int mSensorCode; + pthread_mutex_t mLock; + + char *makeSysfsName(const char *input_name, + const char *input_file); + + virtual int handleEnable(int en); + virtual bool handleEvent(input_event const * event); + +public: + SamsungSensorBase(const char* dev_name, + const char* data_name, + int sensor_code); + + virtual ~SamsungSensorBase(); + virtual int enable(int32_t handle, int en); + virtual int setDelay(int32_t handle, int64_t ns); + virtual int readEvents(sensors_event_t *data, int count); +}; +#endif /* SAMSUNG_SENSORBASE_H */ diff --git a/libsensors/sensors.cpp b/libsensors/sensors.cpp index f9dd0ef..ab2c571 100644 --- a/libsensors/sensors.cpp +++ b/libsensors/sensors.cpp @@ -35,6 +35,10 @@ #include "sensors.h" #include "MPLSensor.h" +#include "LightSensor.h" +#include "ProximitySensor.h" +#include "PressureSensor.h" + /*****************************************************************************/ @@ -49,6 +53,9 @@ #define SENSORS_ACCELERATION (1<<ID_A) #define SENSORS_MAGNETIC_FIELD (1<<ID_M) #define SENSORS_ORIENTATION (1<<ID_O) +#define SENSORS_LIGHT (1<<ID_L) +#define SENSORS_PROXIMITY (1<<ID_P) +#define SENSORS_PRESSURE (1<<ID_PR) #define SENSORS_ROTATION_VECTOR_HANDLE (ID_RV) #define SENSORS_LINEAR_ACCEL_HANDLE (ID_LA) @@ -57,7 +64,9 @@ #define SENSORS_ACCELERATION_HANDLE (ID_A) #define SENSORS_MAGNETIC_FIELD_HANDLE (ID_M) #define SENSORS_ORIENTATION_HANDLE (ID_O) - +#define SENSORS_LIGHT_HANDLE (ID_L) +#define SENSORS_PROXIMITY_HANDLE (ID_P) +#define SENSORS_PRESSURE_HANDLE (ID_PR) #define AKM_FTRACE 0 #define AKM_DEBUG 0 #define AKM_DATA 0 @@ -94,8 +103,18 @@ static const struct sensor_t sSensorList[] = { "Invensense", 1, SENSORS_ORIENTATION_HANDLE, SENSOR_TYPE_ORIENTATION, 360.0f, 1.0f, 9.7f, 20000,{ } }, - - + { "GP2A Light sensor", + "Sharp", + 1, SENSORS_LIGHT_HANDLE, + SENSOR_TYPE_LIGHT, 3000.0f, 1.0f, 0.75f, 0, { } }, + { "GP2A Proximity sensor", + "Sharp", + 1, SENSORS_PROXIMITY_HANDLE, + SENSOR_TYPE_PROXIMITY, 5.0f, 5.0f, 0.75f, 0, { } }, + { "BMP180 Pressure sensor", + "Bosch", + 1, SENSORS_PRESSURE_HANDLE, + SENSOR_TYPE_PRESSURE, 1100.0f, 0.01f, 0.67f, 20000, { } }, }; @@ -143,6 +162,9 @@ private: mpl = 0, //all mpl entries must be consecutive and in this order mpl_accel, mpl_timer, + light, + proximity, + pressure, numSensorDrivers, // wake pipe goes here mpl_power, //special handle for MPL pm interaction numFds, @@ -164,6 +186,12 @@ private: case ID_M: case ID_O: return mpl; + case ID_L: + return light; + case ID_P: + return proximity; + case ID_PR: + return pressure; } return -EINVAL; } @@ -192,6 +220,21 @@ sensors_poll_context_t::sensors_poll_context_t() mPollFds[mpl_timer].events = POLLIN; mPollFds[mpl_timer].revents = 0; + mSensors[light] = new LightSensor(); + mPollFds[light].fd = mSensors[light]->getFd(); + mPollFds[light].events = POLLIN; + mPollFds[light].revents = 0; + + mSensors[proximity] = new ProximitySensor(); + mPollFds[proximity].fd = mSensors[proximity]->getFd(); + mPollFds[proximity].events = POLLIN; + mPollFds[proximity].revents = 0; + + mSensors[pressure] = new PressureSensor(); + mPollFds[pressure].fd = mSensors[pressure]->getFd(); + mPollFds[pressure].events = POLLIN; + mPollFds[pressure].revents = 0; + int wakeFds[2]; int result = pipe(wakeFds); LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno)); diff --git a/libsensors/sensors.h b/libsensors/sensors.h index 4628865..49610ca 100644 --- a/libsensors/sensors.h +++ b/libsensors/sensors.h @@ -45,6 +45,9 @@ __BEGIN_DECLS #define ID_A (ID_GY + 1) #define ID_M (ID_A + 1) #define ID_O (ID_M + 1) +#define ID_L (ID_O + 1) +#define ID_P (ID_L + 1) +#define ID_PR (ID_P + 1) /*****************************************************************************/ |