android13/hardware/rockchip/sensor/st/akm09911/FST_AK09911.c

362 lines
10 KiB
C
Executable File

/******************************************************************************
*
* $Id: FST_AK09911.c 982 2013-02-08 04:20:37Z miyazaki.hr $
*
* -- Copyright Notice --
*
* Copyright (c) 2004 Asahi Kasei Microdevices Corporation, Japan
* All Rights Reserved.
*
* This software program is the proprietary program of Asahi Kasei Microdevices
* Corporation("AKM") licensed to authorized Licensee under the respective
* agreement between the Licensee and AKM only for use with AKM's electronic
* compass IC.
*
* THIS SOFTWARE IS PROVIDED TO YOU "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABLITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT OF
* THIRD PARTY RIGHTS, AND WE SHALL NOT BE LIABLE FOR ANY LOSSES AND DAMAGES
* WHICH MAY OCCUR THROUGH USE OF THIS SOFTWARE.
*
* -- End Asahi Kasei Microdevices Copyright Notice --
*
******************************************************************************/
#include "AKCommon.h"
#include "AKMD_Driver.h"
#include "FST.h"
#include "misc.h"
#ifndef AKMD_FOR_AK09911
#error "AKMD parameter is not set"
#endif
#define TLIMIT_TN_REVISION ""
#define TLIMIT_NO_RST_WIA1 "1-3"
#define TLIMIT_TN_RST_WIA1 "RST_WIA1"
#define TLIMIT_LO_RST_WIA1 0x48
#define TLIMIT_HI_RST_WIA1 0x48
#define TLIMIT_NO_RST_WIA2 "1-4"
#define TLIMIT_TN_RST_WIA2 "RST_WIA2"
#define TLIMIT_LO_RST_WIA2 0x05
#define TLIMIT_HI_RST_WIA2 0x05
#define TLIMIT_NO_ASAX "1-7"
#define TLIMIT_TN_ASAX "ASAX"
#define TLIMIT_LO_ASAX 1
#define TLIMIT_HI_ASAX 254
#define TLIMIT_NO_ASAY "1-8"
#define TLIMIT_TN_ASAY "ASAY"
#define TLIMIT_LO_ASAY 1
#define TLIMIT_HI_ASAY 254
#define TLIMIT_NO_ASAZ "1-9"
#define TLIMIT_TN_ASAZ "ASAZ"
#define TLIMIT_LO_ASAZ 1
#define TLIMIT_HI_ASAZ 254
#define TLIMIT_NO_SNG_ST1 "2-3"
#define TLIMIT_TN_SNG_ST1 "SNG_ST1"
#define TLIMIT_LO_SNG_ST1 1
#define TLIMIT_HI_SNG_ST1 1
#define TLIMIT_NO_SNG_HX "2-4"
#define TLIMIT_TN_SNG_HX "SNG_HX"
#define TLIMIT_LO_SNG_HX -8189
#define TLIMIT_HI_SNG_HX 8189
#define TLIMIT_NO_SNG_HY "2-6"
#define TLIMIT_TN_SNG_HY "SNG_HY"
#define TLIMIT_LO_SNG_HY -8189
#define TLIMIT_HI_SNG_HY 8189
#define TLIMIT_NO_SNG_HZ "2-8"
#define TLIMIT_TN_SNG_HZ "SNG_HZ"
#define TLIMIT_LO_SNG_HZ -8189
#define TLIMIT_HI_SNG_HZ 8189
#define TLIMIT_NO_SNG_ST2 "2-10"
#define TLIMIT_TN_SNG_ST2 "SNG_ST2"
#define TLIMIT_LO_SNG_ST2 0
#define TLIMIT_HI_SNG_ST2 0
#define TLIMIT_NO_SLF_ST1 "2-13"
#define TLIMIT_TN_SLF_ST1 "SLF_ST1"
#define TLIMIT_LO_SLF_ST1 1
#define TLIMIT_HI_SLF_ST1 1
#define TLIMIT_NO_SLF_RVHX "2-14"
#define TLIMIT_TN_SLF_RVHX "SLF_REVSHX"
#define TLIMIT_LO_SLF_RVHX -50
#define TLIMIT_HI_SLF_RVHX 50
#define TLIMIT_NO_SLF_RVHY "2-16"
#define TLIMIT_TN_SLF_RVHY "SLF_REVSHY"
#define TLIMIT_LO_SLF_RVHY -50
#define TLIMIT_HI_SLF_RVHY 50
#define TLIMIT_NO_SLF_RVHZ "2-18"
#define TLIMIT_TN_SLF_RVHZ "SLF_REVSHZ"
#define TLIMIT_LO_SLF_RVHZ -400
#define TLIMIT_HI_SLF_RVHZ -100
#define TLIMIT_NO_SLF_ST2 "2-20"
#define TLIMIT_TN_SLF_ST2 "SLF_ST2"
#define TLIMIT_LO_SLF_ST2 0
#define TLIMIT_HI_SLF_ST2 0
/*!
@return If @a testdata is in the range of between @a lolimit and @a hilimit,
the return value is 1, otherwise -1.
@param[in] testno A pointer to a text string.
@param[in] testname A pointer to a text string.
@param[in] testdata A data to be tested.
@param[in] lolimit The maximum allowable value of @a testdata.
@param[in] hilimit The minimum allowable value of @a testdata.
@param[in,out] pf_total
*/
int16
TEST_DATA(const char testno[],
const char testname[],
const int16 testdata,
const int16 lolimit,
const int16 hilimit,
int16 * pf_total)
{
int16 pf; //Pass;1, Fail;-1
if ((testno == NULL) && (strncmp(testname, "START", 5) == 0)) {
// Display header
AKMDEBUG(AKMDBG_DISP1, "--------------------------------------------------------------------\n");
AKMDEBUG(AKMDBG_DISP1, " Test No. Test Name Fail Test Data [ Low High]\n");
AKMDEBUG(AKMDBG_DISP1, "--------------------------------------------------------------------\n");
pf = 1;
} else if ((testno == NULL) && (strncmp(testname, "END", 3) == 0)) {
// Display result
AKMDEBUG(AKMDBG_DISP1, "--------------------------------------------------------------------\n");
if (*pf_total == 1) {
AKMDEBUG(AKMDBG_DISP1, "Factory shipment test was passed.\n\n");
} else {
AKMDEBUG(AKMDBG_DISP1, "Factory shipment test was failed.\n\n");
}
pf = 1;
} else {
if ((lolimit <= testdata) && (testdata <= hilimit)) {
//Pass
pf = 1;
} else {
//Fail
pf = -1;
}
//display result
AKMDEBUG(AKMDBG_DISP1, " %7s %-10s %c %9d [%9d %9d]\n",
testno, testname, ((pf == 1) ? ('.') : ('F')), testdata,
lolimit, hilimit);
}
//Pass/Fail check
if (*pf_total != 0) {
if ((*pf_total == 1) && (pf == 1)) {
*pf_total = 1; //Pass
} else {
*pf_total = -1; //Fail
}
}
return pf;
}
/*!
Execute "Onboard Function Test" (NOT includes "START" and "END" command).
@retval 1 The test is passed successfully.
@retval -1 The test is failed.
@retval 0 The test is aborted by kind of system error.
*/
int16 FST_AK09911(void)
{
int16 pf_total; //p/f flag for this subtest
BYTE i2cData[16];
int16 hdata[3];
int16 asax;
int16 asay;
int16 asaz;
int i;
//***********************************************
// Reset Test Result
//***********************************************
pf_total = 1;
//***********************************************
// Step1
//***********************************************
// Reset device.
if (AKD_Reset() != AKD_SUCCESS) {
AKMERROR;
return 0;
}
// Read values from WIA.
if (AKD_RxData(AK09911_REG_WIA1, i2cData, 2) != AKD_SUCCESS) {
AKMERROR;
return 0;
}
// TEST
TEST_DATA(TLIMIT_NO_RST_WIA1, TLIMIT_TN_RST_WIA1, (int16)i2cData[0], TLIMIT_LO_RST_WIA1, TLIMIT_HI_RST_WIA1, &pf_total);
TEST_DATA(TLIMIT_NO_RST_WIA2, TLIMIT_TN_RST_WIA2, (int16)i2cData[1], TLIMIT_LO_RST_WIA2, TLIMIT_HI_RST_WIA2, &pf_total);
// Set to FUSE ROM access mode
if (AKD_SetMode(AK09911_MODE_FUSE_ACCESS) != AKD_SUCCESS) {
AKMERROR;
return 0;
}
// Read values from ASAX to ASAZ
if (AKD_RxData(AK09911_FUSE_ASAX, i2cData, 3) != AKD_SUCCESS) {
AKMERROR;
return 0;
}
asax = (int16)i2cData[0];
asay = (int16)i2cData[1];
asaz = (int16)i2cData[2];
// TEST
TEST_DATA(TLIMIT_NO_ASAX, TLIMIT_TN_ASAX, asax, TLIMIT_LO_ASAX, TLIMIT_HI_ASAX, &pf_total);
TEST_DATA(TLIMIT_NO_ASAY, TLIMIT_TN_ASAY, asay, TLIMIT_LO_ASAY, TLIMIT_HI_ASAY, &pf_total);
TEST_DATA(TLIMIT_NO_ASAZ, TLIMIT_TN_ASAZ, asaz, TLIMIT_LO_ASAZ, TLIMIT_HI_ASAZ, &pf_total);
// Set to PowerDown mode
if (AKD_SetMode(AK09911_MODE_POWERDOWN) != AKD_SUCCESS) {
AKMERROR;
return 0;
}
//***********************************************
// Step2
//***********************************************
// Set to SNG measurement pattern (Set CNTL register)
if (AKD_SetMode(AK09911_MODE_SNG_MEASURE) != AKD_SUCCESS) {
AKMERROR;
return 0;
}
// Wait for DRDY pin changes to HIGH.
//usleep(AKM_MEASURE_TIME_US);
// Get measurement data from AK09911
// ST1 + (HXL + HXH) + (HYL + HYH) + (HZL + HZH) + TEMP + ST2
// = 1 + (1 + 1) + (1 + 1) + (1 + 1) + 1 + 1 = 9yte
if (AKD_GetMagneticData(i2cData) != AKD_SUCCESS) {
AKMERROR;
return 0;
}
hdata[0] = (int16)((((uint16)(i2cData[2]))<<8)+(uint16)(i2cData[1]));
hdata[1] = (int16)((((uint16)(i2cData[4]))<<8)+(uint16)(i2cData[3]));
hdata[2] = (int16)((((uint16)(i2cData[6]))<<8)+(uint16)(i2cData[5]));
// TEST
i2cData[0] &= 0x7F;
TEST_DATA(TLIMIT_NO_SNG_ST1, TLIMIT_TN_SNG_ST1, (int16)i2cData[0], TLIMIT_LO_SNG_ST1, TLIMIT_HI_SNG_ST1, &pf_total);
// TEST
TEST_DATA(TLIMIT_NO_SNG_HX, TLIMIT_TN_SNG_HX, hdata[0], TLIMIT_LO_SNG_HX, TLIMIT_HI_SNG_HX, &pf_total);
TEST_DATA(TLIMIT_NO_SNG_HY, TLIMIT_TN_SNG_HY, hdata[1], TLIMIT_LO_SNG_HY, TLIMIT_HI_SNG_HY, &pf_total);
TEST_DATA(TLIMIT_NO_SNG_HZ, TLIMIT_TN_SNG_HZ, hdata[2], TLIMIT_LO_SNG_HZ, TLIMIT_HI_SNG_HZ, &pf_total);
TEST_DATA(TLIMIT_NO_SNG_ST2, TLIMIT_TN_SNG_ST2, (int16)i2cData[8], TLIMIT_LO_SNG_ST2, TLIMIT_HI_SNG_ST2, &pf_total);
// Set to Self-test mode (Set CNTL register)
if (AKD_SetMode(AK09911_MODE_SELF_TEST) != AKD_SUCCESS) {
AKMERROR;
return 0;
}
// Wait for DRDY pin changes to HIGH.
//usleep(AKM_MEASURE_TIME_US);
// Get measurement data from AK09911
// ST1 + (HXL + HXH) + (HYL + HYH) + (HZL + HZH) + TEMP + ST2
// = 1 + (1 + 1) + (1 + 1) + (1 + 1) + 1 + 1 = 9byte
if (AKD_GetMagneticData(i2cData) != AKD_SUCCESS) {
AKMERROR;
return 0;
}
// TEST
i2cData[0] &= 0x7F;
TEST_DATA(TLIMIT_NO_SLF_ST1, TLIMIT_TN_SLF_ST1, (int16)i2cData[0], TLIMIT_LO_SLF_ST1, TLIMIT_HI_SLF_ST1, &pf_total);
hdata[0] = (int16)((((uint16)(i2cData[2]))<<8)+(uint16)(i2cData[1]));
hdata[1] = (int16)((((uint16)(i2cData[4]))<<8)+(uint16)(i2cData[3]));
hdata[2] = (int16)((((uint16)(i2cData[6]))<<8)+(uint16)(i2cData[5]));
// TEST
TEST_DATA(
TLIMIT_NO_SLF_RVHX,
TLIMIT_TN_SLF_RVHX,
(hdata[0])*(asax/128.0f + 1),
TLIMIT_LO_SLF_RVHX,
TLIMIT_HI_SLF_RVHX,
&pf_total
);
TEST_DATA(
TLIMIT_NO_SLF_RVHY,
TLIMIT_TN_SLF_RVHY,
(hdata[1])*(asay/128.0f + 1),
TLIMIT_LO_SLF_RVHY,
TLIMIT_HI_SLF_RVHY,
&pf_total
);
TEST_DATA(
TLIMIT_NO_SLF_RVHZ,
TLIMIT_TN_SLF_RVHZ,
(hdata[2])*(asaz/128.0f + 1),
TLIMIT_LO_SLF_RVHZ,
TLIMIT_HI_SLF_RVHZ,
&pf_total
);
TEST_DATA(
TLIMIT_NO_SLF_ST2,
TLIMIT_TN_SLF_ST2,
(int16)i2cData[8],
TLIMIT_LO_SLF_ST2,
TLIMIT_HI_SLF_ST2,
&pf_total
);
return pf_total;
}
/*!
Execute "Onboard Function Test" (includes "START" and "END" command).
@retval 1 The test is passed successfully.
@retval -1 The test is failed.
@retval 0 The test is aborted by kind of system error.
*/
int16 FST_Body(void)
{
int16 pf_total = 1;
//***********************************************
// Reset Test Result
//***********************************************
TEST_DATA(NULL, "START", 0, 0, 0, &pf_total);
//***********************************************
// Step 1 to 2
//***********************************************
pf_total = FST_AK09911();
//***********************************************
// Judge Test Result
//***********************************************
TEST_DATA(NULL, "END", 0, 0, 0, &pf_total);
return pf_total;
}