248 lines
6.3 KiB
C++
248 lines
6.3 KiB
C++
/*
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
*
|
|
* 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 HUB_CONNECTION_H_
|
|
|
|
#define HUB_CONNECTION_H_
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <poll.h>
|
|
|
|
#include <utils/Errors.h>
|
|
#include <utils/Mutex.h>
|
|
#include <utils/Thread.h>
|
|
|
|
#include "activityeventhandler.h"
|
|
#include "eventnums.h"
|
|
#include "hubdefs.h"
|
|
#include "ring.h"
|
|
|
|
namespace android {
|
|
|
|
struct HubConnection : public Thread {
|
|
static HubConnection *getInstance();
|
|
|
|
status_t initCheck() const;
|
|
|
|
enum ProximitySensorType {
|
|
PROXIMITY_UNKNOWN,
|
|
PROXIMITY_ROHM,
|
|
PROXIMITY_AMS,
|
|
};
|
|
|
|
// Blocks until it can return a status
|
|
status_t getAliveCheck();
|
|
|
|
virtual bool threadLoop();
|
|
|
|
void queueActivate(int handle, bool enable);
|
|
void queueSetDelay(int handle, nsecs_t delayNs);
|
|
void queueBatch(int handle, nsecs_t sampling_period_ns,
|
|
nsecs_t max_report_latency_ns);
|
|
void queueFlush(int handle);
|
|
void queueData(int handle, void *data, size_t length);
|
|
|
|
ssize_t read(sensors_event_t *ev, size_t size);
|
|
|
|
void setActivityCallback(ActivityEventHandler *eventHandler);
|
|
|
|
void saveSensorSettings() const;
|
|
|
|
protected:
|
|
HubConnection();
|
|
virtual ~HubConnection();
|
|
|
|
virtual void onFirstRef();
|
|
|
|
private:
|
|
typedef uint32_t rate_q10_t; // q10 means lower 10 bits are for fractions
|
|
|
|
static inline uint64_t period_ns_to_frequency_q10(nsecs_t period_ns) {
|
|
return 1024000000000ULL / period_ns;
|
|
}
|
|
|
|
static inline nsecs_t frequency_q10_to_period_ns(uint64_t frequency_q10) {
|
|
if (frequency_q10)
|
|
return 1024000000000LL / frequency_q10;
|
|
else
|
|
return (nsecs_t)0;
|
|
}
|
|
|
|
enum
|
|
{
|
|
CONFIG_CMD_DISABLE = 0,
|
|
CONFIG_CMD_ENABLE = 1,
|
|
CONFIG_CMD_FLUSH = 2,
|
|
CONFIG_CMD_CFG_DATA = 3,
|
|
CONFIG_CMD_CALIBRATE = 4,
|
|
};
|
|
|
|
struct ConfigCmd
|
|
{
|
|
uint32_t evtType;
|
|
uint64_t latency;
|
|
rate_q10_t rate;
|
|
uint8_t sensorType;
|
|
uint8_t cmd;
|
|
uint16_t flags;
|
|
uint8_t data[];
|
|
} __attribute__((packed));
|
|
|
|
struct MsgCmd
|
|
{
|
|
uint32_t evtType;
|
|
struct HostHubRawPacket msg;
|
|
} __attribute__((packed));
|
|
|
|
struct SensorState {
|
|
uint64_t latency;
|
|
rate_q10_t rate;
|
|
uint8_t sensorType;
|
|
uint8_t alt;
|
|
uint8_t flushCnt;
|
|
bool enable;
|
|
};
|
|
|
|
struct FirstSample
|
|
{
|
|
uint8_t numSamples;
|
|
uint8_t numFlushes;
|
|
uint8_t highAccuracy : 1;
|
|
uint8_t biasPresent : 1;
|
|
uint8_t biasSample : 6;
|
|
uint8_t pad;
|
|
};
|
|
|
|
struct RawThreeAxisSample
|
|
{
|
|
uint32_t deltaTime;
|
|
int16_t ix, iy, iz;
|
|
} __attribute__((packed));
|
|
|
|
struct ThreeAxisSample
|
|
{
|
|
uint32_t deltaTime;
|
|
float x, y, z;
|
|
} __attribute__((packed));
|
|
|
|
struct OneAxisSample
|
|
{
|
|
uint32_t deltaTime;
|
|
union
|
|
{
|
|
float fdata;
|
|
uint32_t idata;
|
|
};
|
|
} __attribute__((packed));
|
|
|
|
// The following structure should match struct HostIntfDataBuffer found in
|
|
// firmware/inc/hostIntf.h
|
|
struct nAxisEvent
|
|
{
|
|
uint32_t evtType;
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint64_t referenceTime;
|
|
union
|
|
{
|
|
struct FirstSample firstSample;
|
|
struct OneAxisSample oneSamples[];
|
|
struct RawThreeAxisSample rawThreeSamples[];
|
|
struct ThreeAxisSample threeSamples[];
|
|
};
|
|
};
|
|
uint8_t buffer[];
|
|
};
|
|
} __attribute__((packed));
|
|
|
|
static Mutex sInstanceLock;
|
|
static HubConnection *sInstance;
|
|
|
|
// This lock is used for synchronization between the write thread (from
|
|
// sensorservice) and the read thread polling from the nanohub driver.
|
|
Mutex mLock;
|
|
|
|
RingBuffer mRing;
|
|
|
|
ActivityEventHandler *mActivityEventHandler;
|
|
|
|
float mMagBias[3];
|
|
uint8_t mMagAccuracy;
|
|
uint8_t mMagAccuracyRestore;
|
|
|
|
float mGyroBias[3], mAccelBias[3];
|
|
|
|
SensorState mSensorState[NUM_COMMS_SENSORS_PLUS_1];
|
|
|
|
uint64_t mStepCounterOffset;
|
|
uint64_t mLastStepCount;
|
|
|
|
int mFd;
|
|
int mInotifyPollIndex;
|
|
struct pollfd mPollFds[4];
|
|
int mNumPollFds;
|
|
|
|
sensors_event_t *initEv(sensors_event_t *ev, uint64_t timestamp, uint32_t type, uint32_t sensor);
|
|
void magAccuracyUpdate(float x, float y, float z);
|
|
void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct OneAxisSample *sample, bool highAccuracy);
|
|
void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct RawThreeAxisSample *sample, bool highAccuracy);
|
|
void processSample(uint64_t timestamp, uint32_t type, uint32_t sensor, struct ThreeAxisSample *sample, bool highAccuracy);
|
|
void postOsLog(uint8_t *buf, ssize_t len);
|
|
ssize_t processBuf(uint8_t *buf, size_t len);
|
|
|
|
void initConfigCmd(struct ConfigCmd *cmd, int handle);
|
|
|
|
void queueDataInternal(int handle, void *data, size_t length);
|
|
|
|
void discardInotifyEvent();
|
|
void waitOnNanohubLock();
|
|
|
|
void initNanohubLock();
|
|
|
|
void restoreSensorState();
|
|
void sendCalibrationOffsets();
|
|
|
|
// Enable SCHED_FIFO priority for main thread
|
|
void enableSchedFifoMode();
|
|
|
|
#ifdef LID_STATE_REPORTING_ENABLED
|
|
int mUinputFd;
|
|
|
|
status_t initializeUinputNode();
|
|
void sendFolioEvent(int32_t data);
|
|
#endif // LID_STATE_REPORTING_ENABLED
|
|
|
|
#ifdef USB_MAG_BIAS_REPORTING_ENABLED
|
|
int mMagBiasPollIndex;
|
|
float mUsbMagBias;
|
|
|
|
void queueUsbMagBias();
|
|
#endif // USB_MAG_BIAS_REPORTING_ENABLED
|
|
|
|
#ifdef DOUBLE_TOUCH_ENABLED
|
|
int mDoubleTouchPollIndex;
|
|
#endif // DOUBLE_TOUCH_ENABLED
|
|
|
|
DISALLOW_EVIL_CONSTRUCTORS(HubConnection);
|
|
};
|
|
|
|
} // namespace android
|
|
|
|
#endif // HUB_CONNECTION_H_
|