1 /******************************************************************************
2 * $Id: main.c 580 2012-03-29 09:56:21Z yamada.rj $
3 ******************************************************************************
4 *
5 * Copyright (C) 2012 Asahi Kasei Microdevices Corporation, Japan
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19 #include "AKFS_Common.h"
20 #include "AKFS_Compass.h"
21 #include "AKFS_Disp.h"
22 #include "AKFS_FileIO.h"
23 #include "AKFS_Measure.h"
24 #include "AKFS_APIs.h"
25
26 #ifndef WIN32
27 #include <sched.h>
28 #include <pthread.h>
29 #include <linux/input.h>
30 #endif
31
32 #define ERROR_INITDEVICE (-1)
33 #define ERROR_OPTPARSE (-2)
34 #define ERROR_SELF_TEST (-3)
35 #define ERROR_READ_FUSE (-4)
36 #define ERROR_INIT (-5)
37 #define ERROR_GETOPEN_STAT (-6)
38 #define ERROR_STARTCLONE (-7)
39 #define ERROR_GETCLOSE_STAT (-8)
40
41 /* Global variable. See AKFS_Common.h file. */
42 int g_stopRequest = 0;
43 int g_opmode = 0;
44 int g_dbgzone = 0;
45 int g_mainQuit = AKD_FALSE;
46
47 /* Static variable. */
48 static pthread_t s_thread; /*!< Thread handle */
49
50 /*!
51 A thread function which is raised when measurement is started.
52 @param[in] args This parameter is not used currently.
53 */
thread_main(void * args)54 static void* thread_main(void* args)
55 {
56 AKFS_MeasureLoop();
57 return ((void*)0);
58 }
59
60 /*!
61 Signal handler. This should be used only in DEBUG mode.
62 @param[in] sig Event
63 */
signal_handler(int sig)64 static void signal_handler(int sig)
65 {
66 if (sig == SIGINT) {
67 ALOGE("SIGINT signal");
68 g_stopRequest = 1;
69 g_mainQuit = AKD_TRUE;
70 }
71 }
72
73 /*!
74 Starts new thread.
75 @return If this function succeeds, the return value is 1. Otherwise,
76 the return value is 0.
77 */
startClone(void)78 static int startClone(void)
79 {
80 pthread_attr_t attr;
81
82 pthread_attr_init(&attr);
83 g_stopRequest = 0;
84 if (pthread_create(&s_thread, &attr, thread_main, NULL) == 0) {
85 return 1;
86 } else {
87 return 0;
88 }
89 }
90
91 /*!
92 This function parse the option.
93 @retval 1 Parse succeeds.
94 @retval 0 Parse failed.
95 @param[in] argc Argument count
96 @param[in] argv Argument vector
97 @param[out] layout_patno
98 */
OptParse(int argc,char * argv[],AKFS_PATNO * layout_patno)99 int OptParse(
100 int argc,
101 char* argv[],
102 AKFS_PATNO* layout_patno)
103 {
104 #ifdef WIN32
105 /* Static */
106 #if defined(AKFS_WIN32_PAT1)
107 *layout_patno = PAT1;
108 #elif defined(AKFS_WIN32_PAT2)
109 *layout_patno = PAT2;
110 #elif defined(AKFS_WIN32_PAT3)
111 *layout_patno = PAT3;
112 #elif defined(AKFS_WIN32_PAT4)
113 *layout_patno = PAT4;
114 #elif defined(AKFS_WIN32_PAT5)
115 *layout_patno = PAT5;
116 #else
117 *layout_patno = PAT1;
118 #endif
119 g_opmode = OPMODE_CONSOLE;
120 /*g_opmode = 0;*/
121 g_dbgzone = AKMDATA_LOOP | AKMDATA_TEST;
122 #else
123 int opt;
124 char optVal;
125
126 *layout_patno = PAT_INVALID;
127
128 while ((opt = getopt(argc, argv, "sm:z:")) != -1) {
129 switch(opt){
130 case 'm':
131 optVal = (char)(optarg[0] - '0');
132 if ((PAT1 <= optVal) && (optVal <= PAT8)) {
133 *layout_patno = (AKFS_PATNO)optVal;
134 AKMDEBUG(DBG_LEVEL2, "%s: Layout=%d\n", __FUNCTION__, optVal);
135 }
136 break;
137 case 's':
138 g_opmode |= OPMODE_CONSOLE;
139 break;
140 case 'z':
141 /* If error detected, hopefully 0 is returned. */
142 errno = 0;
143 g_dbgzone = (int)strtol(optarg, (char**)NULL, 0);
144 AKMDEBUG(DBG_LEVEL2, "%s: Dbg Zone=%d\n", __FUNCTION__, g_dbgzone);
145 break;
146 default:
147 ALOGE("%s: Invalid argument", argv[0]);
148 return 0;
149 }
150 }
151
152 /* If layout is not specified with argument, get parameter from driver */
153 if (*layout_patno == PAT_INVALID) {
154 int16_t n;
155 if (AKD_GetLayout(&n) == AKM_SUCCESS) {
156 if ((PAT1 <= n) && (n <= PAT8)) {
157 *layout_patno = (AKFS_PATNO)n;
158 }
159 }
160 }
161 /* Error */
162 if (*layout_patno == PAT_INVALID) {
163 ALOGE("No layout is specified.");
164 return 0;
165 }
166 #endif
167
168 return 1;
169 }
170
ConsoleMode(void)171 void ConsoleMode(void)
172 {
173 /*** Console Mode *********************************************/
174 while (AKD_TRUE) {
175 /* Select operation */
176 switch (Menu_Main()) {
177 case MODE_SelfTest:
178 AKFS_SelfTest();
179 break;
180 case MODE_Measure:
181 /* Reset flag */
182 g_stopRequest = 0;
183 /* Measurement routine */
184 AKFS_MeasureLoop();
185 break;
186
187 case MODE_Quit:
188 return;
189
190 default:
191 AKMDEBUG(DBG_LEVEL0, "Unknown operation mode.\n");
192 break;
193 }
194 }
195 }
196
main(int argc,char ** argv)197 int main(int argc, char **argv)
198 {
199 int retValue = 0;
200 AKFS_PATNO pat;
201 uint8 regs[3];
202
203 /* Show the version info of this software. */
204 Disp_StartMessage();
205
206 #if ENABLE_AKMDEBUG
207 /* Register signal handler */
208 signal(SIGINT, signal_handler);
209 #endif
210
211 /* Open device driver */
212 if(AKD_InitDevice() != AKD_SUCCESS) {
213 retValue = ERROR_INITDEVICE;
214 goto MAIN_QUIT;
215 }
216
217 /* Parse command-line options */
218 /* This function calls device driver function to get layout */
219 if (OptParse(argc, argv, &pat) == 0) {
220 retValue = ERROR_OPTPARSE;
221 goto MAIN_QUIT;
222 }
223
224 /* Self Test */
225 if (g_opmode & OPMODE_FST){
226 if (AKFS_SelfTest() != AKD_SUCCESS) {
227 retValue = ERROR_SELF_TEST;
228 goto MAIN_QUIT;
229 }
230 }
231
232 /* OK, then start */
233 if (AKFS_ReadAK8975FUSEROM(regs) != AKM_SUCCESS) {
234 retValue = ERROR_READ_FUSE;
235 goto MAIN_QUIT;
236 }
237
238 /* Initialize library. */
239 if (AKFS_Init(pat, regs) != AKM_SUCCESS) {
240 retValue = ERROR_INIT;
241 goto MAIN_QUIT;
242 }
243
244 /* Start console mode */
245 if (g_opmode & OPMODE_CONSOLE) {
246 ConsoleMode();
247 goto MAIN_QUIT;
248 }
249
250 /*** Start Daemon ********************************************/
251 while (g_mainQuit == AKD_FALSE) {
252 int st = 0;
253 /* Wait until device driver is opened. */
254 if (AKD_GetOpenStatus(&st) != AKD_SUCCESS) {
255 retValue = ERROR_GETOPEN_STAT;
256 goto MAIN_QUIT;
257 }
258 if (st == 0) {
259 ALOGI("Suspended.");
260 } else {
261 ALOGI("Compass Opened.");
262 /* Reset flag */
263 g_stopRequest = 0;
264 /* Start measurement thread. */
265 if (startClone() == 0) {
266 retValue = ERROR_STARTCLONE;
267 goto MAIN_QUIT;
268 }
269
270 /* Wait until device driver is closed. */
271 if (AKD_GetCloseStatus(&st) != AKD_SUCCESS) {
272 retValue = ERROR_GETCLOSE_STAT;
273 g_mainQuit = AKD_TRUE;
274 }
275 /* Wait thread completion. */
276 g_stopRequest = 1;
277 pthread_join(s_thread, NULL);
278 ALOGI("Compass Closed.");
279 }
280 }
281
282 MAIN_QUIT:
283
284 /* Release library */
285 AKFS_Release();
286 /* Close device driver. */
287 AKD_DeinitDevice();
288 /* Show the last message. */
289 Disp_EndMessage(retValue);
290
291 return retValue;
292 }
293
294
295