diff options
author | Paul Kocialkowski <contact@paulk.fr> | 2013-07-12 19:43:35 +0200 |
---|---|---|
committer | Paul Kocialkowski <contact@paulk.fr> | 2013-07-12 19:43:35 +0200 |
commit | e49c15824e1a18c6b2bf4b0a89d558749cbb7dac (patch) | |
tree | a3b797e837535b311ea42a5a90f0a5a2839b03f9 /sensors/akmdfs/AKFS_APIs_8975 | |
parent | 279b327bda1151b0b6040e70e9b62fa4c649121a (diff) | |
download | device_samsung_i9300-e49c15824e1a18c6b2bf4b0a89d558749cbb7dac.zip device_samsung_i9300-e49c15824e1a18c6b2bf4b0a89d558749cbb7dac.tar.gz device_samsung_i9300-e49c15824e1a18c6b2bf4b0a89d558749cbb7dac.tar.bz2 |
Galaxy S3 Exynos Sensors module
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
Diffstat (limited to 'sensors/akmdfs/AKFS_APIs_8975')
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_AK8975.c | 44 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_AK8975.h | 50 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_AOC.c | 333 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_AOC.h | 53 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_Configure.h | 37 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_Device.c | 110 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_Device.h | 107 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_Direction.c | 133 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_Direction.h | 39 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_Math.h | 47 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_VNorm.c | 107 | ||||
-rw-r--r-- | sensors/akmdfs/AKFS_APIs_8975/AKFS_VNorm.h | 46 |
12 files changed, 1106 insertions, 0 deletions
diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_AK8975.c b/sensors/akmdfs/AKFS_APIs_8975/AKFS_AK8975.c new file mode 100644 index 0000000..7bac9a1 --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_AK8975.c @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 "AKFS_AK8975.h" +#include "AKFS_Device.h" + +/*! + */ +int16 AKFS_DecompAK8975( + const int16 mag[3], + const int16 status, + const uint8vec* asa, + const int16 nhdata, + AKFVEC hdata[] +) +{ + /* put st1 and st2 value */ + if (AK8975_ST_ERROR(status)) { + return AKFS_ERROR; + } + + /* magnetic */ + AKFS_BufShift(nhdata, 1, hdata); + hdata[0].u.x = mag[0] * (((asa->u.x)/256.0f) + 0.5f); + hdata[0].u.y = mag[1] * (((asa->u.y)/256.0f) + 0.5f); + hdata[0].u.z = mag[2] * (((asa->u.z)/256.0f) + 0.5f); + + return AKFS_SUCCESS; +} + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_AK8975.h b/sensors/akmdfs/AKFS_APIs_8975/AKFS_AK8975.h new file mode 100644 index 0000000..25459e3 --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_AK8975.h @@ -0,0 +1,50 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 AKFS_INC_AK8975_H +#define AKFS_INC_AK8975_H + +#include "AKFS_Device.h" + +/***** Constant definition ****************************************************/ +#define AK8975_BDATA_SIZE 8 + +#define AK8975_HSENSE_DEFAULT 1 +#define AK8975_HSENSE_TARGET 0.3f +#define AK8975_ASENSE_DEFAULT 720 +#define AK8975_ASENSE_TARGET 9.80665f + +#define AK8975_HDATA_CONVERTER(hi, low, asa) \ + (AKFLOAT)((int16)((((uint16)(hi))<<8)+(uint16)(low))*(((asa)/256.0f) + 0.5f)) + +#define AK8975_ST_ERROR(st) (((st)&0x09) != 0x01) + +/***** Type declaration *******************************************************/ + +/***** Prototype of function **************************************************/ +AKLIB_C_API_START +int16 AKFS_DecompAK8975( + const int16 mag[3], + const int16 status, + const uint8vec* asa, + const int16 nhdata, + AKFVEC hdata[] +); +AKLIB_C_API_END + +#endif + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_AOC.c b/sensors/akmdfs/AKFS_APIs_8975/AKFS_AOC.c new file mode 100644 index 0000000..62b2361 --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_AOC.c @@ -0,0 +1,333 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 "AKFS_AOC.h" +#include "AKFS_Math.h" + +/* + * CalcR + */ +static AKFLOAT CalcR( + const AKFVEC* x, + const AKFVEC* y +){ + int16 i; + AKFLOAT r; + + r = 0.0; + for(i = 0; i < 3; i++){ + r += (x->v[i]-y->v[i]) * (x->v[i]-y->v[i]); + } + r = sqrt(r); + + return r; +} + +/* + * From4Points2Sphere() + */ +static int16 From4Points2Sphere( + const AKFVEC points[], /*! (i/o) : input vectors */ + AKFVEC* center, /*! (o) : center of sphere */ + AKFLOAT* r /*! (i) : add/subtract value */ +){ + AKFLOAT dif[3][3]; + AKFLOAT r2[3]; + + AKFLOAT A; + AKFLOAT B; + AKFLOAT C; + AKFLOAT D; + AKFLOAT E; + AKFLOAT F; + AKFLOAT G; + + AKFLOAT OU; + AKFLOAT OD; + + int16 i, j; + + for(i = 0; i < 3; i++){ + r2[i] = 0.0; + for(j = 0; j < 3; j++){ + dif[i][j] = points[i].v[j] - points[3].v[j]; + r2[i] += (points[i].v[j]*points[i].v[j] + - points[3].v[j]*points[3].v[j]); + } + r2[i] *= 0.5; + } + + A = dif[0][0]*dif[2][2] - dif[0][2]*dif[2][0]; + B = dif[0][1]*dif[2][0] - dif[0][0]*dif[2][1]; + C = dif[0][0]*dif[2][1] - dif[0][1]*dif[2][0]; + D = dif[0][0]*r2[2] - dif[2][0]*r2[0]; + E = dif[0][0]*dif[1][1] - dif[0][1]*dif[1][0]; + F = dif[1][0]*dif[0][2] - dif[0][0]*dif[1][2]; + G = dif[0][0]*r2[1] - dif[1][0]*r2[0]; + + OU = D*E + B*G; + OD = C*F + A*E; + + if(fabs(OD) < AKFS_EPSILON){ + return -1; + } + + center->v[2] = OU / OD; + + OU = F*center->v[2] + G; + OD = E; + + if(fabs(OD) < AKFS_EPSILON){ + return -1; + } + + center->v[1] = OU / OD; + + OU = r2[0] - dif[0][1]*center->v[1] - dif[0][2]*center->v[2]; + OD = dif[0][0]; + + if(fabs(OD) < AKFS_EPSILON){ + return -1; + } + + center->v[0] = OU / OD; + + *r = CalcR(&points[0], center); + + return 0; + +} + +/* + * MeanVar + */ +static void MeanVar( + const AKFVEC v[], /*!< (i) : input vectors */ + const int16 n, /*!< (i) : number of vectors */ + AKFVEC* mean, /*!< (o) : (max+min)/2 */ + AKFVEC* var /*!< (o) : variation in vectors */ +){ + int16 i; + int16 j; + AKFVEC max; + AKFVEC min; + + for(j = 0; j < 3; j++){ + min.v[j] = v[0].v[j]; + max.v[j] = v[0].v[j]; + for(i = 1; i < n; i++){ + if(v[i].v[j] < min.v[j]){ + min.v[j] = v[i].v[j]; + } + if(v[i].v[j] > max.v[j]){ + max.v[j] = v[i].v[j]; + } + } + mean->v[j] = (max.v[j] + min.v[j]) / 2.0; /*mean */ + var->v[j] = max.v[j] - min.v[j]; /*var */ + } +} + +/* + * Get4points + */ +static void Get4points( + const AKFVEC v[], /*!< (i) : input vectors */ + const int16 n, /*!< (i) : number of vectors */ + AKFVEC out[] /*!< (o) : */ +){ + int16 i, j; + AKFLOAT temp; + AKFLOAT d; + + AKFVEC dv[AKFS_HBUF_SIZE]; + AKFVEC cross; + AKFVEC tempv; + + /* out 0 */ + out[0] = v[0]; + + /* out 1 */ + d = 0.0; + for(i = 1; i < n; i++){ + temp = CalcR(&v[i], &out[0]); + if(d < temp){ + d = temp; + out[1] = v[i]; + } + } + + /* out 2 */ + d = 0.0; + for(j = 0; j < 3; j++){ + dv[0].v[j] = out[1].v[j] - out[0].v[j]; + } + for(i = 1; i < n; i++){ + for(j = 0; j < 3; j++){ + dv[i].v[j] = v[i].v[j] - out[0].v[j]; + } + tempv.v[0] = dv[0].v[1]*dv[i].v[2] - dv[0].v[2]*dv[i].v[1]; + tempv.v[1] = dv[0].v[2]*dv[i].v[0] - dv[0].v[0]*dv[i].v[2]; + tempv.v[2] = dv[0].v[0]*dv[i].v[1] - dv[0].v[1]*dv[i].v[0]; + temp = tempv.u.x * tempv.u.x + + tempv.u.y * tempv.u.y + + tempv.u.z * tempv.u.z; + if(d < temp){ + d = temp; + out[2] = v[i]; + cross = tempv; + } + } + + /* out 3 */ + d = 0.0; + for(i = 1; i < n; i++){ + temp = dv[i].u.x * cross.u.x + + dv[i].u.y * cross.u.y + + dv[i].u.z * cross.u.z; + temp = fabs(temp); + if(d < temp){ + d = temp; + out[3] = v[i]; + } + } +} + +/* + * CheckInitFvec + */ +static int16 CheckInitFvec( + const AKFVEC *v /*!< [in] vector */ +){ + int16 i; + + for(i = 0; i < 3; i++){ + if(AKFS_FMAX <= v->v[i]){ + return 1; /* initvalue */ + } + } + + return 0; /* not initvalue */ +} + +/* + * AKFS_AOC + */ +int16 AKFS_AOC( /*!< (o) : calibration success(1), failure(0) */ + AKFS_AOC_VAR* haocv, /*!< (i/o) : a set of variables */ + const AKFVEC* hdata, /*!< (i) : vectors of data */ + AKFVEC* ho /*!< (i/o) : offset */ +){ + int16 i, j; + int16 num; + AKFLOAT tempf; + AKFVEC tempho; + + AKFVEC fourpoints[4]; + + AKFVEC var; + AKFVEC mean; + + /* buffer new data */ + for(i = 1; i < AKFS_HBUF_SIZE; i++){ + haocv->hbuf[AKFS_HBUF_SIZE-i] = haocv->hbuf[AKFS_HBUF_SIZE-i-1]; + } + haocv->hbuf[0] = *hdata; + + /* Check Init */ + num = 0; + for(i = AKFS_HBUF_SIZE; 3 < i; i--){ + if(CheckInitFvec(&haocv->hbuf[i-1]) == 0){ + num = i; + break; + } + } + if(num < 4){ + return AKFS_ERROR; + } + + /* get 4 points */ + Get4points(haocv->hbuf, num, fourpoints); + + /* estimate offset */ + if(0 != From4Points2Sphere(fourpoints, &tempho, &haocv->hraoc)){ + return AKFS_ERROR; + } + + /* check distance */ + for(i = 0; i < 4; i++){ + for(j = (i+1); j < 4; j++){ + tempf = CalcR(&fourpoints[i], &fourpoints[j]); + if((tempf < haocv->hraoc)||(tempf < AKFS_HR_TH)){ + return AKFS_ERROR; + } + } + } + + /* update offset buffer */ + for(i = 1; i < AKFS_HOBUF_SIZE; i++){ + haocv->hobuf[AKFS_HOBUF_SIZE-i] = haocv->hobuf[AKFS_HOBUF_SIZE-i-1]; + } + haocv->hobuf[0] = tempho; + + /* clear hbuf */ + for(i = (AKFS_HBUF_SIZE>>1); i < AKFS_HBUF_SIZE; i++) { + for(j = 0; j < 3; j++) { + haocv->hbuf[i].v[j]= AKFS_FMAX; + } + } + + /* Check Init */ + if(CheckInitFvec(&haocv->hobuf[AKFS_HOBUF_SIZE-1]) == 1){ + return AKFS_ERROR; + } + + /* Check ovar */ + tempf = haocv->hraoc * AKFS_HO_TH; + MeanVar(haocv->hobuf, AKFS_HOBUF_SIZE, &mean, &var); + if ((var.u.x >= tempf) || (var.u.y >= tempf) || (var.u.z >= tempf)){ + return AKFS_ERROR; + } + + *ho = mean; + + return AKFS_SUCCESS; +} + +/* + * AKFS_InitAOC + */ +void AKFS_InitAOC( + AKFS_AOC_VAR* haocv +){ + int16 i, j; + + /* Initialize buffer */ + for(i = 0; i < AKFS_HBUF_SIZE; i++) { + for(j = 0; j < 3; j++) { + haocv->hbuf[i].v[j]= AKFS_FMAX; + } + } + for(i = 0; i < AKFS_HOBUF_SIZE; i++) { + for(j = 0; j < 3; j++) { + haocv->hobuf[i].v[j]= AKFS_FMAX; + } + } + + haocv->hraoc = 0.0; +} + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_AOC.h b/sensors/akmdfs/AKFS_APIs_8975/AKFS_AOC.h new file mode 100644 index 0000000..ffaaa88 --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_AOC.h @@ -0,0 +1,53 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 AKFS_INC_AOC_H +#define AKFS_INC_AOC_H + +#include "AKFS_Device.h" + +/***** Constant definition ****************************************************/ +#define AKFS_HBUF_SIZE 20 +#define AKFS_HOBUF_SIZE 4 +#define AKFS_HR_TH 10 +#define AKFS_HO_TH 0.15 + +/***** Macro definition *******************************************************/ + +/***** Type declaration *******************************************************/ +typedef struct _AKFS_AOC_VAR{ + AKFVEC hbuf[AKFS_HBUF_SIZE]; + AKFVEC hobuf[AKFS_HOBUF_SIZE]; + AKFLOAT hraoc; +} AKFS_AOC_VAR; + +/***** Prototype of function **************************************************/ +AKLIB_C_API_START +int16 AKFS_AOC( + AKFS_AOC_VAR* haocv, + const AKFVEC* hdata, + AKFVEC* ho +); + +void AKFS_InitAOC( + AKFS_AOC_VAR* haocv +); + +AKLIB_C_API_END + +#endif + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_Configure.h b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Configure.h new file mode 100644 index 0000000..1f80f48 --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Configure.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 AKFS_INC_CONFIG_H +#define AKFS_INC_CONFIG_H + +/***** Language configuration *************************************************/ +#if defined(__cplusplus) +#define AKLIB_C_API_START extern "C" { +#define AKLIB_C_API_END } +#else +#define AKLIB_C_API_START +#define AKLIB_C_API_END +#endif + +/*! If following line is commented in, double type is used for floating point + calculation */ +/* +#define AKFS_PRECISION_DOUBLE +*/ + +#endif + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_Device.c b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Device.c new file mode 100644 index 0000000..3d99ab1 --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Device.c @@ -0,0 +1,110 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 "AKFS_Device.h" + +int16 AKFS_InitBuffer( + const int16 ndata, /*!< Size of vector buffer */ + AKFVEC vdata[] /*!< Vector buffer */ +) +{ + int i; + + /* size check */ + if (ndata <= 0) { + return AKFS_ERROR; + } + + for (i=0; i<ndata; i++) { + vdata[i].u.x = AKFS_INIT_VALUE_F; + vdata[i].u.y = AKFS_INIT_VALUE_F; + vdata[i].u.z = AKFS_INIT_VALUE_F; + } + + return AKFS_SUCCESS; +} + +int16 AKFS_BufShift( + const int16 len, /*!< size of buffer */ + const int16 shift, /*!< shift size */ + AKFVEC v[] /*!< buffer */ +) +{ + int16 i; + + if((shift < 1) || (len < shift)) { + return AKFS_ERROR; + } + for (i = len-1; i >= shift; i--) { + v[i] = v[i-shift]; + } + return AKFS_SUCCESS; +} + +int16 AKFS_Rotate( + const AKFS_PATNO pat, + AKFVEC* vec +) +{ + AKFLOAT tmp; + switch(pat){ + /* Obverse */ + case PAT1: + /* This is Android default */ + break; + case PAT2: + tmp = vec->u.x; + vec->u.x = vec->u.y; + vec->u.y = -tmp; + break; + case PAT3: + vec->u.x = -(vec->u.x); + vec->u.y = -(vec->u.y); + break; + case PAT4: + tmp = vec->u.x; + vec->u.x = -(vec->u.y); + vec->u.y = tmp; + break; + /* Reverse */ + case PAT5: + vec->u.x = -(vec->u.x); + vec->u.z = -(vec->u.z); + break; + case PAT6: + tmp = vec->u.x; + vec->u.x = vec->u.y; + vec->u.y = tmp; + vec->u.z = -(vec->u.z); + break; + case PAT7: + vec->u.y = -(vec->u.y); + vec->u.z = -(vec->u.z); + break; + case PAT8: + tmp = vec->u.x; + vec->u.x = -(vec->u.y); + vec->u.y = -tmp; + vec->u.z = -(vec->u.z); + break; + default: + return AKFS_ERROR; + } + + return AKFS_SUCCESS; +} + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_Device.h b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Device.h new file mode 100644 index 0000000..0292d54 --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Device.h @@ -0,0 +1,107 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 AKFS_INC_DEVICE_H +#define AKFS_INC_DEVICE_H + +#include <float.h> +#include "AKFS_Configure.h" + +/***** Constant definition ****************************************************/ +#define AKFS_ERROR 0 +#define AKFS_SUCCESS 1 + +#define AKFS_HDATA_SIZE 32 +#define AKFS_ADATA_SIZE 32 + +/***** Type declaration *******************************************************/ +typedef signed char int8; +typedef signed short int16; +typedef unsigned char uint8; +typedef unsigned short uint16; + + +#ifdef AKFS_PRECISION_DOUBLE +typedef double AKFLOAT; +#define AKFS_EPSILON DBL_EPSILON +#define AKFS_FMAX DBL_MAX +#define AKFS_FMIN DBL_MIN + +#else +typedef float AKFLOAT; +#define AKFS_EPSILON FLT_EPSILON +#define AKFS_FMAX FLT_MAX +#define AKFS_FMIN FLT_MIN + +#endif + +/* Treat maximum value as initial value */ +#define AKFS_INIT_VALUE_F AKFS_FMAX + +/***** Vector *****/ +typedef union _uint8vec{ + struct { + uint8 x; + uint8 y; + uint8 z; + }u; + uint8 v[3]; +} uint8vec; + +typedef union _AKFVEC{ + struct { + AKFLOAT x; + AKFLOAT y; + AKFLOAT z; + }u; + AKFLOAT v[3]; +} AKFVEC; + +/***** Layout pattern *****/ +typedef enum _AKFS_PATNO { + PAT_INVALID = 0, + PAT1, /* obverse: 1st pin is right down */ + PAT2, /* obverse: 1st pin is left down */ + PAT3, /* obverse: 1st pin is left top */ + PAT4, /* obverse: 1st pin is right top */ + PAT5, /* reverse: 1st pin is left down (from top view) */ + PAT6, /* reverse: 1st pin is left top (from top view) */ + PAT7, /* reverse: 1st pin is right top (from top view) */ + PAT8 /* reverse: 1st pin is right down (from top view) */ +} AKFS_PATNO; + +/***** Prototype of function **************************************************/ +AKLIB_C_API_START +int16 AKFS_InitBuffer( + const int16 ndata, /*!< Size of raw vector buffer */ + AKFVEC vdata[] /*!< Raw vector buffer */ +); + +int16 AKFS_BufShift( + const int16 len, + const int16 shift, + AKFVEC v[] +); + +int16 AKFS_Rotate( + const AKFS_PATNO pat, + AKFVEC* vec +); +AKLIB_C_API_END + +#endif + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_Direction.c b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Direction.c new file mode 100644 index 0000000..f47e930 --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Direction.c @@ -0,0 +1,133 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 "AKFS_Direction.h" +#include "AKFS_VNorm.h" +#include "AKFS_Math.h" + +/* + Coordinate system is right-handed. + X-Axis: from left to right. + Y-Axis: from bottom to top. + Z-Axis: from reverse to obverse. + + azimuth: Rotaion around Z axis, with positive values + when y-axis moves toward the x-axis. + pitch: Rotation around X axis, with positive values + when z-axis moves toward the y-axis. + roll: Rotation around Y axis, with positive values + when x-axis moves toward the z-axis. +*/ + +/* + This function is used internaly, so output is RADIAN! + */ +static void AKFS_Angle( + const AKFVEC* avec, + AKFLOAT* pitch, /* radian */ + AKFLOAT* roll /* radian */ +) +{ + AKFLOAT av; /* Size of vector */ + + av = AKFS_SQRT((avec->u.x)*(avec->u.x) + (avec->u.y)*(avec->u.y) + (avec->u.z)*(avec->u.z)); + + *pitch = AKFS_ASIN(-(avec->u.y) / av); + *roll = AKFS_ASIN((avec->u.x) / av); +} + +/* + This function is used internaly, so output is RADIAN! + */ +static void AKFS_Azimuth( + const AKFVEC* hvec, + const AKFLOAT pitch, /* radian */ + const AKFLOAT roll, /* radian */ + AKFLOAT* azimuth /* radian */ +) +{ + AKFLOAT sinP; /* sin value of pitch angle */ + AKFLOAT cosP; /* cos value of pitch angle */ + AKFLOAT sinR; /* sin value of roll angle */ + AKFLOAT cosR; /* cos value of roll angle */ + AKFLOAT Xh; /* X axis element of vector which is projected to horizontal plane */ + AKFLOAT Yh; /* Y axis element of vector which is projected to horizontal plane */ + + sinP = AKFS_SIN(pitch); + cosP = AKFS_COS(pitch); + sinR = AKFS_SIN(roll); + cosR = AKFS_COS(roll); + + Yh = -(hvec->u.x)*cosR + (hvec->u.z)*sinR; + Xh = (hvec->u.x)*sinP*sinR + (hvec->u.y)*cosP + (hvec->u.z)*sinP*cosR; + + /* atan2(y, x) -> divisor and dividend is opposite from mathematical equation. */ + *azimuth = AKFS_ATAN2(Yh, Xh); +} + +int16 AKFS_Direction( + const int16 nhvec, + const AKFVEC hvec[], + const int16 hnave, + const int16 navec, + const AKFVEC avec[], + const int16 anave, + AKFLOAT* azimuth, + AKFLOAT* pitch, + AKFLOAT* roll +) +{ + AKFVEC have, aave; + AKFLOAT azimuthRad; + AKFLOAT pitchRad; + AKFLOAT rollRad; + + /* arguments check */ + if ((nhvec <= 0) || (navec <= 0) || (hnave <= 0) || (anave <= 0)) { + return AKFS_ERROR; + } + if ((nhvec < hnave) || (navec < anave)) { + return AKFS_ERROR; + } + + /* average */ + if (AKFS_VbAve(nhvec, hvec, hnave, &have) != AKFS_SUCCESS) { + return AKFS_ERROR; + } + if (AKFS_VbAve(navec, avec, anave, &aave) != AKFS_SUCCESS) { + return AKFS_ERROR; + } + + /* calculate pitch and roll */ + AKFS_Angle(&aave, &pitchRad, &rollRad); + + /* calculate azimuth */ + AKFS_Azimuth(&have, pitchRad, rollRad, &azimuthRad); + + *azimuth = RAD2DEG(azimuthRad); + *pitch = RAD2DEG(pitchRad); + *roll = RAD2DEG(rollRad); + + /* Adjust range of azimuth */ + if (*azimuth < 0) { + *azimuth += 360.0f; + } + + return AKFS_SUCCESS; +} + + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_Direction.h b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Direction.h new file mode 100644 index 0000000..c08338d --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Direction.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 AKFS_INC_DIRECTION_H +#define AKFS_INC_DIRECTION_H + +#include "AKFS_Device.h" + +/***** Prototype of function **************************************************/ +AKLIB_C_API_START +int16 AKFS_Direction( + const int16 nhvec, + const AKFVEC hvec[], + const int16 hnave, + const int16 navec, + const AKFVEC avec[], + const int16 anave, + AKFLOAT* azimuth, + AKFLOAT* pitch, + AKFLOAT* roll +); +AKLIB_C_API_END + +#endif + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_Math.h b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Math.h new file mode 100644 index 0000000..dfe48b3 --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_Math.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 AKFS_INC_MATH_H +#define AKFS_INC_MATH_H + +#include <math.h> +#include "AKFS_Configure.h" + +/***** Constant definition ****************************************************/ +#define AKFS_PI 3.141592654f +#define RAD2DEG(rad) ((rad)*180.0f/AKFS_PI) + +/***** Macro definition *******************************************************/ + +#ifdef AKFS_PRECISION_DOUBLE +#define AKFS_SIN(x) sin(x) +#define AKFS_COS(x) cos(x) +#define AKFS_ASIN(x) asin(x) +#define AKFS_ACOS(x) acos(x) +#define AKFS_ATAN2(y, x) atan2((y), (x)) +#define AKFS_SQRT(x) sqrt(x) +#else +#define AKFS_SIN(x) sinf(x) +#define AKFS_COS(x) cosf(x) +#define AKFS_ASIN(x) asinf(x) +#define AKFS_ACOS(x) acosf(x) +#define AKFS_ATAN2(y, x) atan2f((y), (x)) +#define AKFS_SQRT(x) sqrtf(x) +#endif + +#endif + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_VNorm.c b/sensors/akmdfs/AKFS_APIs_8975/AKFS_VNorm.c new file mode 100644 index 0000000..ffa934a --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_VNorm.c @@ -0,0 +1,107 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 "AKFS_VNorm.h" +#include "AKFS_Device.h" + +/*! + */ +int16 AKFS_VbNorm( + const int16 ndata, /*!< Size of raw vector buffer */ + const AKFVEC vdata[], /*!< Raw vector buffer */ + const int16 nbuf, /*!< Size of data to be buffered */ + const AKFVEC* o, /*!< Offset */ + const AKFVEC* s, /*!< Sensitivity */ + const AKFLOAT tgt, /*!< Target sensitivity */ + const int16 nvec, /*!< Size of normalized vector buffer */ + AKFVEC vvec[] /*!< Normalized vector buffer */ +) +{ + int i; + + /* size check */ + if ((ndata <= 0) || (nvec <= 0) || (nbuf <= 0)) { + return AKFS_ERROR; + } + /* dependency check */ + if ((nbuf < 1) || (ndata < nbuf) || (nvec < nbuf)) { + return AKFS_ERROR; + } + /* sensitivity check */ + if ((s->u.x <= AKFS_EPSILON) || + (s->u.y <= AKFS_EPSILON) || + (s->u.z <= AKFS_EPSILON) || + (tgt <= 0)) { + return AKFS_ERROR; + } + + /* calculate and store data to buffer */ + if (AKFS_BufShift(nvec, nbuf, vvec) != AKFS_SUCCESS) { + return AKFS_ERROR; + } + for (i=0; i<nbuf; i++) { + vvec[i].u.x = ((vdata[i].u.x - o->u.x) / (s->u.x) * (AKFLOAT)tgt); + vvec[i].u.y = ((vdata[i].u.y - o->u.y) / (s->u.y) * (AKFLOAT)tgt); + vvec[i].u.z = ((vdata[i].u.z - o->u.z) / (s->u.z) * (AKFLOAT)tgt); + } + + return AKFS_SUCCESS; +} + +/*! + */ +int16 AKFS_VbAve( + const int16 nvec, /*!< Size of normalized vector buffer */ + const AKFVEC vvec[], /*!< Normalized vector buffer */ + const int16 nave, /*!< Number of averaeg */ + AKFVEC* vave /*!< Averaged vector */ +) +{ + int i; + + /* arguments check */ + if ((nave <= 0) || (nvec <= 0) || (nvec < nave)) { + return AKFS_ERROR; + } + + /* calculate average */ + vave->u.x = 0; + vave->u.y = 0; + vave->u.z = 0; + for (i=0; i<nave; i++) { + if ((vvec[i].u.x == AKFS_INIT_VALUE_F) || + (vvec[i].u.y == AKFS_INIT_VALUE_F) || + (vvec[i].u.z == AKFS_INIT_VALUE_F)) { + break; + } + vave->u.x += vvec[i].u.x; + vave->u.y += vvec[i].u.y; + vave->u.z += vvec[i].u.z; + } + if (i == 0) { + vave->u.x = 0; + vave->u.y = 0; + vave->u.z = 0; + } else { + vave->u.x /= i; + vave->u.y /= i; + vave->u.z /= i; + } + return AKFS_SUCCESS; +} + + diff --git a/sensors/akmdfs/AKFS_APIs_8975/AKFS_VNorm.h b/sensors/akmdfs/AKFS_APIs_8975/AKFS_VNorm.h new file mode 100644 index 0000000..c3c9bed --- /dev/null +++ b/sensors/akmdfs/AKFS_APIs_8975/AKFS_VNorm.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * + * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan + * + * 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 AKFS_INC_VNORM_H +#define AKFS_INC_VNORM_H + +#include "AKFS_Device.h" + +/***** Prototype of function **************************************************/ +AKLIB_C_API_START +int16 AKFS_VbNorm( + const int16 ndata, /*!< Size of raw vector buffer */ + const AKFVEC vdata[], /*!< Raw vector buffer */ + const int16 nbuf, /*!< Size of data to be buffered */ + const AKFVEC* o, /*!< Offset */ + const AKFVEC* s, /*!< Sensitivity */ + const AKFLOAT tgt, /*!< Target sensitivity */ + const int16 nvec, /*!< Size of normalized vector buffer */ + AKFVEC vvec[] /*!< Normalized vector buffer */ +); + +int16 AKFS_VbAve( + const int16 nvec, /*!< Size of normalized vector buffer */ + const AKFVEC vvec[], /*!< Normalized vector buffer */ + const int16 nave, /*!< Number of averaeg */ + AKFVEC* vave /*!< Averaged vector */ +); + +AKLIB_C_API_END + +#endif + |