You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
6.5 KiB
294 lines
6.5 KiB
/****************************************************************************** |
|
* $Id: main.c 580 2012-03-29 09:56:21Z yamada.rj $ |
|
****************************************************************************** |
|
* |
|
* 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_Common.h" |
|
#include "AKFS_Compass.h" |
|
#include "AKFS_Disp.h" |
|
#include "AKFS_FileIO.h" |
|
#include "AKFS_Measure.h" |
|
#include "AKFS_APIs.h" |
|
|
|
#ifndef WIN32 |
|
#include <sched.h> |
|
#include <pthread.h> |
|
#include <linux/input.h> |
|
#endif |
|
|
|
#define ERROR_INITDEVICE (-1) |
|
#define ERROR_OPTPARSE (-2) |
|
#define ERROR_SELF_TEST (-3) |
|
#define ERROR_READ_FUSE (-4) |
|
#define ERROR_INIT (-5) |
|
#define ERROR_GETOPEN_STAT (-6) |
|
#define ERROR_STARTCLONE (-7) |
|
#define ERROR_GETCLOSE_STAT (-8) |
|
|
|
/* Global variable. See AKFS_Common.h file. */ |
|
int g_stopRequest = 0; |
|
int g_opmode = 0; |
|
int g_dbgzone = 0; |
|
int g_mainQuit = AKD_FALSE; |
|
|
|
/* Static variable. */ |
|
static pthread_t s_thread; /*!< Thread handle */ |
|
|
|
/*! |
|
A thread function which is raised when measurement is started. |
|
@param[in] args This parameter is not used currently. |
|
*/ |
|
static void* thread_main(void* args) |
|
{ |
|
AKFS_MeasureLoop(); |
|
return ((void*)0); |
|
} |
|
|
|
/*! |
|
Signal handler. This should be used only in DEBUG mode. |
|
@param[in] sig Event |
|
*/ |
|
static void signal_handler(int sig) |
|
{ |
|
if (sig == SIGINT) { |
|
ALOGE("SIGINT signal"); |
|
g_stopRequest = 1; |
|
g_mainQuit = AKD_TRUE; |
|
} |
|
} |
|
|
|
/*! |
|
Starts new thread. |
|
@return If this function succeeds, the return value is 1. Otherwise, |
|
the return value is 0. |
|
*/ |
|
static int startClone(void) |
|
{ |
|
pthread_attr_t attr; |
|
|
|
pthread_attr_init(&attr); |
|
g_stopRequest = 0; |
|
if (pthread_create(&s_thread, &attr, thread_main, NULL) == 0) { |
|
return 1; |
|
} else { |
|
return 0; |
|
} |
|
} |
|
|
|
/*! |
|
This function parse the option. |
|
@retval 1 Parse succeeds. |
|
@retval 0 Parse failed. |
|
@param[in] argc Argument count |
|
@param[in] argv Argument vector |
|
@param[out] layout_patno |
|
*/ |
|
int OptParse( |
|
int argc, |
|
char* argv[], |
|
AKFS_PATNO* layout_patno) |
|
{ |
|
#ifdef WIN32 |
|
/* Static */ |
|
#if defined(AKFS_WIN32_PAT1) |
|
*layout_patno = PAT1; |
|
#elif defined(AKFS_WIN32_PAT2) |
|
*layout_patno = PAT2; |
|
#elif defined(AKFS_WIN32_PAT3) |
|
*layout_patno = PAT3; |
|
#elif defined(AKFS_WIN32_PAT4) |
|
*layout_patno = PAT4; |
|
#elif defined(AKFS_WIN32_PAT5) |
|
*layout_patno = PAT5; |
|
#else |
|
*layout_patno = PAT1; |
|
#endif |
|
g_opmode = OPMODE_CONSOLE; |
|
/*g_opmode = 0;*/ |
|
g_dbgzone = AKMDATA_LOOP | AKMDATA_TEST; |
|
#else |
|
int opt; |
|
char optVal; |
|
|
|
*layout_patno = PAT_INVALID; |
|
|
|
while ((opt = getopt(argc, argv, "sm:z:")) != -1) { |
|
switch(opt){ |
|
case 'm': |
|
optVal = (char)(optarg[0] - '0'); |
|
if ((PAT1 <= optVal) && (optVal <= PAT8)) { |
|
*layout_patno = (AKFS_PATNO)optVal; |
|
AKMDEBUG(DBG_LEVEL2, "%s: Layout=%d\n", __FUNCTION__, optVal); |
|
} |
|
break; |
|
case 's': |
|
g_opmode |= OPMODE_CONSOLE; |
|
break; |
|
case 'z': |
|
/* If error detected, hopefully 0 is returned. */ |
|
errno = 0; |
|
g_dbgzone = (int)strtol(optarg, (char**)NULL, 0); |
|
AKMDEBUG(DBG_LEVEL2, "%s: Dbg Zone=%d\n", __FUNCTION__, g_dbgzone); |
|
break; |
|
default: |
|
ALOGE("%s: Invalid argument", argv[0]); |
|
return 0; |
|
} |
|
} |
|
|
|
/* If layout is not specified with argument, get parameter from driver */ |
|
if (*layout_patno == PAT_INVALID) { |
|
int16_t n; |
|
if (AKD_GetLayout(&n) == AKM_SUCCESS) { |
|
if ((PAT1 <= n) && (n <= PAT8)) { |
|
*layout_patno = (AKFS_PATNO)n; |
|
} |
|
} |
|
} |
|
/* Error */ |
|
if (*layout_patno == PAT_INVALID) { |
|
ALOGE("No layout is specified."); |
|
return 0; |
|
} |
|
#endif |
|
|
|
return 1; |
|
} |
|
|
|
void ConsoleMode(void) |
|
{ |
|
/*** Console Mode *********************************************/ |
|
while (AKD_TRUE) { |
|
/* Select operation */ |
|
switch (Menu_Main()) { |
|
case MODE_SelfTest: |
|
AKFS_SelfTest(); |
|
break; |
|
case MODE_Measure: |
|
/* Reset flag */ |
|
g_stopRequest = 0; |
|
/* Measurement routine */ |
|
AKFS_MeasureLoop(); |
|
break; |
|
|
|
case MODE_Quit: |
|
return; |
|
|
|
default: |
|
AKMDEBUG(DBG_LEVEL0, "Unknown operation mode.\n"); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
int main(int argc, char **argv) |
|
{ |
|
int retValue = 0; |
|
AKFS_PATNO pat; |
|
uint8 regs[3]; |
|
|
|
/* Show the version info of this software. */ |
|
Disp_StartMessage(); |
|
|
|
#if ENABLE_AKMDEBUG |
|
/* Register signal handler */ |
|
signal(SIGINT, signal_handler); |
|
#endif |
|
|
|
/* Open device driver */ |
|
if(AKD_InitDevice() != AKD_SUCCESS) { |
|
retValue = ERROR_INITDEVICE; |
|
goto MAIN_QUIT; |
|
} |
|
|
|
/* Parse command-line options */ |
|
/* This function calls device driver function to get layout */ |
|
if (OptParse(argc, argv, &pat) == 0) { |
|
retValue = ERROR_OPTPARSE; |
|
goto MAIN_QUIT; |
|
} |
|
|
|
/* Self Test */ |
|
if (g_opmode & OPMODE_FST){ |
|
if (AKFS_SelfTest() != AKD_SUCCESS) { |
|
retValue = ERROR_SELF_TEST; |
|
goto MAIN_QUIT; |
|
} |
|
} |
|
|
|
/* OK, then start */ |
|
if (AKFS_ReadAK8975FUSEROM(regs) != AKM_SUCCESS) { |
|
retValue = ERROR_READ_FUSE; |
|
goto MAIN_QUIT; |
|
} |
|
|
|
/* Initialize library. */ |
|
if (AKFS_Init(pat, regs) != AKM_SUCCESS) { |
|
retValue = ERROR_INIT; |
|
goto MAIN_QUIT; |
|
} |
|
|
|
/* Start console mode */ |
|
if (g_opmode & OPMODE_CONSOLE) { |
|
ConsoleMode(); |
|
goto MAIN_QUIT; |
|
} |
|
|
|
/*** Start Daemon ********************************************/ |
|
while (g_mainQuit == AKD_FALSE) { |
|
int st = 0; |
|
/* Wait until device driver is opened. */ |
|
if (AKD_GetOpenStatus(&st) != AKD_SUCCESS) { |
|
retValue = ERROR_GETOPEN_STAT; |
|
goto MAIN_QUIT; |
|
} |
|
if (st == 0) { |
|
ALOGI("Suspended."); |
|
} else { |
|
ALOGI("Compass Opened."); |
|
/* Reset flag */ |
|
g_stopRequest = 0; |
|
/* Start measurement thread. */ |
|
if (startClone() == 0) { |
|
retValue = ERROR_STARTCLONE; |
|
goto MAIN_QUIT; |
|
} |
|
|
|
/* Wait until device driver is closed. */ |
|
if (AKD_GetCloseStatus(&st) != AKD_SUCCESS) { |
|
retValue = ERROR_GETCLOSE_STAT; |
|
g_mainQuit = AKD_TRUE; |
|
} |
|
/* Wait thread completion. */ |
|
g_stopRequest = 1; |
|
pthread_join(s_thread, NULL); |
|
ALOGI("Compass Closed."); |
|
} |
|
} |
|
|
|
MAIN_QUIT: |
|
|
|
/* Release library */ |
|
AKFS_Release(); |
|
/* Close device driver. */ |
|
AKD_DeinitDevice(); |
|
/* Show the last message. */ |
|
Disp_EndMessage(retValue); |
|
|
|
return retValue; |
|
} |
|
|
|
|
|
|