yas53x_drv.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. /*
  2. * Copyright (c) 2012-2013 Yamaha Corporation
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. */
  20. #include "yas53x.h"
  21. #define YAS_REG_DEVICE_ID (0x80)
  22. #define YAS_REG_ACTUATE_INIT_COIL (0x81)
  23. #define YAS_REG_MEASURE_COMMAND (0x82)
  24. #define YAS_REG_CONFIG (0x83)
  25. #define YAS_REG_MEASURE_INTERVAL (0x84)
  26. #define YAS_REG_OFFSET_X (0x85)
  27. #define YAS_REG_OFFSET_Y1 (0x86)
  28. #define YAS_REG_OFFSET_Y2 (0x87)
  29. #define YAS_REG_TEST1 (0x88)
  30. #define YAS_REG_TEST2 (0x89)
  31. #define YAS_REG_CAL (0x90)
  32. #define YAS_REG_MEASURE_DATA (0xb0)
  33. #define YAS_YAS530_DEVICE_ID (0x01) /* YAS530 (MS-3E) */
  34. #define YAS_YAS530_VERSION_A (0) /* YAS530 (MS-3E Aver) */
  35. #define YAS_YAS530_VERSION_B (1) /* YAS530B (MS-3E Bver) */
  36. #define YAS_YAS530_VERSION_A_COEF (380)
  37. #define YAS_YAS530_VERSION_B_COEF (550)
  38. #define YAS_YAS530_DATA_CENTER (2048)
  39. #define YAS_YAS530_DATA_UNDERFLOW (0)
  40. #define YAS_YAS530_DATA_OVERFLOW (4095)
  41. #define YAS_YAS532_DEVICE_ID (0x02) /* YAS532_533 (MS-3R/3F) */
  42. #define YAS_YAS532_VERSION_AB (0) /* YAS532_533AB (MS-3R/3F ABver) */
  43. #define YAS_YAS532_VERSION_AC (1) /* YAS532_533AC (MS-3R/3F ACver) */
  44. #define YAS_YAS532_VERSION_AB_COEF (1800)
  45. #define YAS_YAS532_VERSION_AC_COEF_X (850)
  46. #define YAS_YAS532_VERSION_AC_COEF_Y1 (750)
  47. #define YAS_YAS532_VERSION_AC_COEF_Y2 (750)
  48. #define YAS_YAS532_DATA_CENTER (4096)
  49. #define YAS_YAS532_DATA_UNDERFLOW (0)
  50. #define YAS_YAS532_DATA_OVERFLOW (8190)
  51. #define YAS_MAG_STATE_NORMAL (0)
  52. #define YAS_MAG_STATE_INIT_COIL (1)
  53. #define YAS_MAG_STATE_MEASURE_OFFSET (2)
  54. #define YAS_MAG_NOTRANS_POSITION (3)
  55. #define YAS_MAG_INITCOIL_TIMEOUT (500) /* msec */
  56. #define YAS_MAG_TEMPERATURE_LOG (10)
  57. #define set_vector(to, from) \
  58. {int _l; for (_l = 0; _l < 3; _l++) to[_l] = from[_l]; }
  59. #define set_matrix(to, from) \
  60. {int _l; for (_l = 0; _l < 9; _l++) to[_l] = from[_l]; }
  61. #define is_vector_differ(a, b) \
  62. ((a)[0] != (b)[0] || (a)[1] != (b)[1] || (a)[2] != (b)[2])
  63. #define is_valid_offset(a) \
  64. ((a) != NULL && ((a)[0] <= 31) && ((a)[1] <= 31) && ((a)[2] <= 31) \
  65. && (-31 <= (a)[0]) && (-31 <= (a)[1]) && (-31 <= (a)[2]))
  66. struct yas_correction_data {
  67. int8_t rxy1y2[3];
  68. uint8_t fxy1y2[3];
  69. uint8_t ver;
  70. int32_t Cx, Cy1, Cy2;
  71. int32_t a2, a3, a4, a5, a6, a7, a8, a9, k;
  72. };
  73. #if 1 < YAS_MAG_TEMPERATURE_LOG
  74. struct yas_temperature_filter {
  75. int16_t log[YAS_MAG_TEMPERATURE_LOG];
  76. int num;
  77. int idx;
  78. };
  79. #endif
  80. struct yas_cdriver {
  81. int initialized;
  82. struct yas_correction_data correct;
  83. struct yas_mag_driver_callback cbk;
  84. int measure_state;
  85. int8_t hard_offset[3];
  86. int overflow;
  87. uint32_t overflow_time;
  88. int16_t center_thresh;
  89. int16_t underflow_thresh;
  90. int16_t overflow_thresh;
  91. int32_t coef[3];
  92. int position;
  93. int8_t *transform;
  94. uint8_t dev_id;
  95. #if 1 < YAS_MAG_TEMPERATURE_LOG
  96. struct yas_temperature_filter t;
  97. #endif
  98. };
  99. static const int yas532_version_ac_coef[] = {YAS_YAS532_VERSION_AC_COEF_X,
  100. YAS_YAS532_VERSION_AC_COEF_Y1, YAS_YAS532_VERSION_AC_COEF_Y2};
  101. static const int8_t INVALID_OFFSET[] = {0x7f, 0x7f, 0x7f};
  102. static const int8_t YAS_TRANSFORMATION[][9] = {
  103. { 0, 1, 0, -1, 0, 0, 0, 0, 1 },
  104. {-1, 0, 0, 0, -1, 0, 0, 0, 1 },
  105. { 0, -1, 0, 1, 0, 0, 0, 0, 1 },
  106. { 1, 0, 0, 0, 1, 0, 0, 0, 1 },
  107. { 0, -1, 0, -1, 0, 0, 0, 0, -1 },
  108. { 1, 0, 0, 0, -1, 0, 0, 0, -1 },
  109. { 0, 1, 0, 1, 0, 0, 0, 0, -1 },
  110. {-1, 0, 0, 0, 1, 0, 0, 0, -1 },
  111. };
  112. static struct yas_cdriver driver;
  113. static int
  114. get_cal_data_yas530(struct yas_correction_data *c)
  115. {
  116. uint8_t data[16]; int i;
  117. if (driver.cbk.device_read(YAS_REG_CAL, data, 16) < 0)
  118. return YAS_ERROR_DEVICE_COMMUNICATION;
  119. if (driver.cbk.device_read(YAS_REG_CAL, data, 16) < 0)
  120. return YAS_ERROR_DEVICE_COMMUNICATION;
  121. c->fxy1y2[0] = (uint8_t)((data[12]>>5) & 0x03);
  122. c->rxy1y2[0] = ((int8_t)((((data[11]<<1) & 0x3e)
  123. | ((data[12]>>7) & 0x01))<<2))>>2;
  124. c->fxy1y2[1] = (uint8_t)((data[13]>>5) & 0x03);
  125. c->rxy1y2[1] = ((int8_t)((((data[12]<<1) & 0x3e)
  126. | ((data[13]>>7) & 0x01))<<2))>>2;
  127. c->fxy1y2[2] = (uint8_t)((data[14]>>5) & 0x03);
  128. c->rxy1y2[2] = ((int8_t)((((data[13]<<1) & 0x3e)
  129. | ((data[14]>>7) & 0x01))<<2))>>2;
  130. c->ver = (uint8_t)((data[15]) & 0x03);
  131. c->Cx = data[0] * 6 - 768;
  132. c->Cy1 = data[1] * 6 - 768;
  133. c->Cy2 = data[2] * 6 - 768;
  134. c->a2 = ((data[3]>>2) & 0x03f) - 32;
  135. c->a3 = (uint8_t)(((data[3]<<2) & 0x0c) | ((data[4]>>6) & 0x03)) - 8;
  136. c->a4 = (uint8_t)(data[4] & 0x3f) - 32;
  137. c->a5 = ((data[5]>>2) & 0x3f) + 38;
  138. c->a6 = (uint8_t)(((data[5]<<4) & 0x30) | ((data[6]>>4) & 0x0f)) - 32;
  139. c->a7 = (uint8_t)(((data[6]<<3) & 0x78) | ((data[7]>>5) & 0x07)) - 64;
  140. c->a8 = (uint8_t)(((data[7]<<1) & 0x3e) | ((data[8]>>7) & 0x01)) - 32;
  141. c->a9 = (uint8_t)(((data[8]<<1) & 0xfe) | ((data[9]>>7) & 0x01));
  142. c->k = (uint8_t)((data[9]>>2) & 0x1f) + 10;
  143. for (i = 0; i < 16; i++)
  144. if (data[i] != 0)
  145. return YAS_NO_ERROR;
  146. return YAS_ERROR_CALREG;
  147. }
  148. static int
  149. get_cal_data_yas532(struct yas_correction_data *c)
  150. {
  151. uint8_t data[14]; int i;
  152. if (driver.cbk.device_read(YAS_REG_CAL, data, 14) < 0)
  153. return YAS_ERROR_DEVICE_COMMUNICATION;
  154. if (driver.cbk.device_read(YAS_REG_CAL, data, 14) < 0)
  155. return YAS_ERROR_DEVICE_COMMUNICATION;
  156. c->fxy1y2[0] = (uint8_t)(((data[10]&0x01)<<1) | ((data[11]>>7)&0x01));
  157. c->rxy1y2[0] = ((int8_t)(((data[10]>>1) & 0x3f)<<2))>>2;
  158. c->fxy1y2[1] = (uint8_t)(((data[11]&0x01)<<1) | ((data[12]>>7)&0x01));
  159. c->rxy1y2[1] = ((int8_t)(((data[11]>>1) & 0x3f)<<2))>>2;
  160. c->fxy1y2[2] = (uint8_t)(((data[12]&0x01)<<1) | ((data[13]>>7)&0x01));
  161. c->rxy1y2[2] = ((int8_t)(((data[12]>>1) & 0x3f)<<2))>>2;
  162. c->Cx = data[0] * 10 - 1280;
  163. c->Cy1 = data[1] * 10 - 1280;
  164. c->Cy2 = data[2] * 10 - 1280;
  165. c->a2 = ((data[3]>>2)&0x03f) - 32;
  166. c->a3 = (uint8_t)(((data[3]<<2) & 0x0c) | ((data[4]>>6) & 0x03)) - 8;
  167. c->a4 = (uint8_t)(data[4] & 0x3f) - 32;
  168. c->a5 = ((data[5]>>2) & 0x3f) + 38;
  169. c->a6 = (uint8_t)(((data[5]<<4) & 0x30) | ((data[6]>>4) & 0x0f)) - 32;
  170. c->a7 = (uint8_t)(((data[6]<<3) & 0x78) | ((data[7]>>5) & 0x07)) - 64;
  171. c->a8 = (uint8_t)(((data[7]<<1) & 0x3e) | ((data[8]>>7) & 0x01)) - 32;
  172. c->a9 = (uint8_t)(((data[8]<<1) & 0xfe) | ((data[9]>>7) & 0x01));
  173. c->k = (uint8_t)((data[9]>>2) & 0x1f);
  174. c->ver=data[13]&0x01;
  175. for (i = 0; i < 13; i++)
  176. if (data[i] != 0)
  177. return YAS_NO_ERROR;
  178. if (data[13] & 0x80)
  179. return YAS_NO_ERROR;
  180. return YAS_ERROR_CALREG;
  181. }
  182. static int
  183. set_measure_command(int ldtc, int fors, int dlymes)
  184. {
  185. uint8_t data = 0x01;
  186. data = (uint8_t)(data | (((!!ldtc)<<1) & 0x02));
  187. data = (uint8_t)(data | (((!!fors)<<2) & 0x04));
  188. data = (uint8_t)(data | (((!!dlymes)<<4) & 0x10));
  189. if (driver.cbk.device_write(YAS_REG_MEASURE_COMMAND, &data, 1) < 0)
  190. return YAS_ERROR_DEVICE_COMMUNICATION;
  191. return YAS_NO_ERROR;
  192. }
  193. static int
  194. measure_normal_yas530(int ldtc, int fors, int *busy, int16_t *t,
  195. int16_t *xy1y2)
  196. {
  197. uint8_t data[8];
  198. if (set_measure_command(ldtc, fors, 0) < 0)
  199. return YAS_ERROR_DEVICE_COMMUNICATION;
  200. driver.cbk.msleep(2);
  201. if (driver.cbk.device_read(YAS_REG_MEASURE_DATA, data, 8) < 0)
  202. return YAS_ERROR_DEVICE_COMMUNICATION;
  203. *busy = (data[0]>>7) & 0x01;
  204. *t = (int16_t)((((int32_t)data[0]<<2) & 0x1fc)|((data[1]>>6) & 0x03));
  205. xy1y2[0] = (int16_t)((((int32_t)data[2]<<5) & 0xfe0)
  206. | ((data[3]>>3) & 0x1f));
  207. xy1y2[1] = (int16_t)((((int32_t)data[4]<<5) & 0xfe0)
  208. | ((data[5]>>3) & 0x1f));
  209. xy1y2[2] = (int16_t)((((int32_t)data[6]<<5) & 0xfe0)
  210. | ((data[7]>>3) & 0x1f));
  211. return YAS_NO_ERROR;
  212. }
  213. static int
  214. measure_normal_yas532(int ldtc, int fors, int *busy, int16_t *t,
  215. int16_t *xy1y2)
  216. {
  217. uint8_t data[8];
  218. if (set_measure_command(ldtc, fors, 0) < 0)
  219. return YAS_ERROR_DEVICE_COMMUNICATION;
  220. driver.cbk.msleep(2);
  221. if (driver.cbk.device_read(YAS_REG_MEASURE_DATA, data, 8) < 0)
  222. return YAS_ERROR_DEVICE_COMMUNICATION;
  223. *busy = (data[0]>>7) & 0x01;
  224. *t = (int16_t)((((int32_t)data[0]<<3) & 0x3f8)|((data[1]>>5) & 0x07));
  225. xy1y2[0] = (int16_t)((((int32_t)data[2]<<6) & 0x1fc0)
  226. | ((data[3]>>2) & 0x3f));
  227. xy1y2[1] = (int16_t)((((int32_t)data[4]<<6) & 0x1fc0)
  228. | ((data[5]>>2) & 0x3f));
  229. xy1y2[2] = (int16_t)((((int32_t)data[6]<<6) & 0x1fc0)
  230. | ((data[7]>>2) & 0x3f));
  231. return YAS_NO_ERROR;
  232. }
  233. static int
  234. measure_normal(int ldtc, int fors, int *busy, int16_t *t, int16_t *xy1y2,
  235. int *ouflow)
  236. {
  237. int result, i;
  238. switch (driver.dev_id) {
  239. case YAS_YAS532_DEVICE_ID:
  240. result = measure_normal_yas532(ldtc, fors, busy, t, xy1y2);
  241. break;
  242. case YAS_YAS530_DEVICE_ID:
  243. default:
  244. result = measure_normal_yas530(ldtc, fors, busy, t, xy1y2);
  245. break;
  246. }
  247. *ouflow = 0;
  248. for (i = 0; i < 3; i++) {
  249. if (xy1y2[i] == driver.overflow_thresh)
  250. *ouflow |= (1<<(i*2));
  251. if (xy1y2[i] == driver.underflow_thresh)
  252. *ouflow |= (1<<(i*2+1));
  253. }
  254. return result;
  255. }
  256. static int
  257. yas_cdrv_set_offset(const int8_t *offset)
  258. {
  259. if (driver.cbk.device_write(YAS_REG_OFFSET_X,
  260. (const uint8_t *)&offset[0], 1) < 0)
  261. return YAS_ERROR_DEVICE_COMMUNICATION;
  262. if (driver.cbk.device_write(YAS_REG_OFFSET_Y1,
  263. (const uint8_t *)&offset[1], 1) < 0)
  264. return YAS_ERROR_DEVICE_COMMUNICATION;
  265. if (driver.cbk.device_write(YAS_REG_OFFSET_Y2,
  266. (const uint8_t *)&offset[2], 1) < 0)
  267. return YAS_ERROR_DEVICE_COMMUNICATION;
  268. set_vector(driver.hard_offset, offset);
  269. return YAS_NO_ERROR;
  270. }
  271. static int
  272. yas_cdrv_actuate_initcoil(void)
  273. {
  274. uint8_t data = 0;
  275. return driver.cbk.device_write(YAS_REG_ACTUATE_INIT_COIL, &data, 1);
  276. }
  277. static int
  278. yas_cdrv_measure_and_set_offset(void)
  279. {
  280. static const int correct[5] = {16, 8, 4, 2, 1};
  281. int8_t hard_offset[3] = {0, 0, 0};
  282. int16_t t, xy1y2[3];
  283. int32_t flag[3];
  284. int i, j, busy, ouflow;
  285. for (i = 0; i < 5; i++) {
  286. if (yas_cdrv_set_offset(hard_offset) < 0)
  287. return YAS_ERROR_DEVICE_COMMUNICATION;
  288. if (measure_normal(0, 0, &busy, &t, xy1y2, &ouflow) < 0)
  289. return YAS_ERROR_DEVICE_COMMUNICATION;
  290. if (busy)
  291. return YAS_ERROR_BUSY;
  292. for (j = 0; j < 3; j++) {
  293. if (driver.center_thresh == xy1y2[j])
  294. flag[j] = 0;
  295. if (driver.center_thresh < xy1y2[j])
  296. flag[j] = 1;
  297. if (xy1y2[j] < driver.center_thresh)
  298. flag[j] = -1;
  299. }
  300. for (j = 0; j < 3; j++)
  301. if (flag[j])
  302. hard_offset[j] = (int8_t)(hard_offset[j]
  303. + flag[j] * correct[i]);
  304. }
  305. return yas_cdrv_set_offset(hard_offset);
  306. }
  307. static int
  308. yas_cdrv_sensitivity_measuremnet(int32_t *sx, int32_t *sy)
  309. {
  310. struct yas_correction_data *c = &driver.correct;
  311. int16_t xy1y2_on[3], xy1y2_off[3], t;
  312. int busy, flowon = 0, flowoff = 0;
  313. if (measure_normal(1, 0, &busy, &t, xy1y2_on, &flowon) , 0)
  314. return YAS_ERROR_DEVICE_COMMUNICATION;
  315. if (busy)
  316. return YAS_ERROR_BUSY;
  317. if (measure_normal(1, 1, &busy, &t, xy1y2_off, &flowoff) , 0)
  318. return YAS_ERROR_DEVICE_COMMUNICATION;
  319. if (busy)
  320. return YAS_ERROR_BUSY;
  321. switch (driver.dev_id) {
  322. case YAS_YAS532_DEVICE_ID:
  323. *sx = c->k * (xy1y2_on[0] - xy1y2_off[0]) / 10 / YAS_VCORE;
  324. *sy = c->k * c->a5 * ((xy1y2_on[1] - xy1y2_off[1])
  325. - (xy1y2_on[2] - xy1y2_off[2])) / 1000
  326. / YAS_VCORE;
  327. break;
  328. case YAS_YAS530_DEVICE_ID:
  329. default:
  330. *sx = xy1y2_off[0] - xy1y2_on[0];
  331. *sy = (xy1y2_off[1] - xy1y2_on[1])
  332. - (xy1y2_off[2] - xy1y2_on[2]);
  333. break;
  334. }
  335. return flowon | flowoff;
  336. }
  337. static int
  338. yas_cdrv_measure(int32_t *xyz, int16_t *xy1y2, int32_t *xy1y2_linear,
  339. int16_t *temperature, int temp_correction)
  340. {
  341. static const int16_t cval[] = {3721, 3971, 4221, 4471};
  342. struct yas_correction_data *c = &driver.correct;
  343. int16_t t;
  344. int32_t xyz_tmp[3], tmp;
  345. int32_t sx, sy1, sy2, sy, sz;
  346. int i, ouflow = 0, busy;
  347. #if 1 < YAS_MAG_TEMPERATURE_LOG
  348. int32_t sum = 0;
  349. #endif
  350. if (measure_normal(0, 0, &busy, &t, xy1y2, &ouflow) < 0)
  351. return YAS_ERROR_DEVICE_COMMUNICATION;
  352. for (i = 0; i < 3; i++)
  353. xy1y2_linear[i] = xy1y2[i] - cval[driver.correct.fxy1y2[i]]
  354. + (driver.hard_offset[i] - driver.correct.rxy1y2[i])
  355. * driver.coef[i];
  356. #if 1 < YAS_MAG_TEMPERATURE_LOG
  357. driver.t.log[driver.t.idx++] = t;
  358. if (YAS_MAG_TEMPERATURE_LOG <= driver.t.idx)
  359. driver.t.idx = 0;
  360. driver.t.num++;
  361. if (YAS_MAG_TEMPERATURE_LOG <= driver.t.num)
  362. driver.t.num = YAS_MAG_TEMPERATURE_LOG;
  363. for (i = 0; i < driver.t.num; i++)
  364. sum += driver.t.log[i];
  365. tmp = sum * 10 / driver.t.num;
  366. #else
  367. tmp = t * 10;
  368. #endif
  369. sx = xy1y2_linear[0];
  370. sy1 = xy1y2_linear[1];
  371. sy2 = xy1y2_linear[2];
  372. if (temp_correction) {
  373. sx -= (c->Cx * tmp) / 1000;
  374. sy1 -= (c->Cy1 * tmp) / 1000;
  375. sy2 -= (c->Cy2 * tmp) / 1000;
  376. }
  377. sy = sy1 - sy2;
  378. sz = -sy1 - sy2;
  379. xyz[0] = c->k * ((100 * sx + c->a2 * sy + c->a3 * sz) / 10);
  380. xyz[1] = c->k * ((c->a4 * sx + c->a5 * sy + c->a6 * sz) / 10);
  381. xyz[2] = c->k * ((c->a7 * sx + c->a8 * sy + c->a9 * sz) / 10);
  382. if (temperature != NULL)
  383. *temperature = t;
  384. if (driver.transform != NULL) {
  385. for (i = 0; i < 3; i++) {
  386. xyz_tmp[i] = driver.transform[i*3] * xyz[0]
  387. + driver.transform[i*3+1] * xyz[1]
  388. + driver.transform[i*3+2] * xyz[2];
  389. }
  390. } else
  391. for (i = 0; i < 3; i++)
  392. xyz_tmp[i] = xyz[i];
  393. for (i = 0; i < 3; i++) {
  394. xyz_tmp[i] -= xyz_tmp[i] % 10;
  395. if (ouflow & (1<<(i*2)))
  396. xyz_tmp[i] += 1; /* set overflow */
  397. if (ouflow & (1<<(i*2+1)))
  398. xyz_tmp[i] += 2; /* set underflow */
  399. }
  400. set_vector(xyz, xyz_tmp);
  401. if (busy)
  402. return YAS_ERROR_BUSY;
  403. return ouflow;
  404. }
  405. static int
  406. yas_cdrv_set_transformatiom_matrix(const int8_t *transform)
  407. {
  408. static int8_t t[9];
  409. if (transform == NULL)
  410. driver.transform = NULL;
  411. else {
  412. set_matrix(t, transform);
  413. driver.transform = t;
  414. }
  415. return YAS_NO_ERROR;
  416. }
  417. static int
  418. yas_get_position(void)
  419. {
  420. if (!driver.initialized)
  421. return 0;
  422. return driver.position;
  423. }
  424. static int
  425. yas_set_position(int position)
  426. {
  427. if (!driver.initialized)
  428. return YAS_ERROR_NOT_INITIALIZED;
  429. if (position < 0 || 7 < position)
  430. return YAS_ERROR_ARG;
  431. if (position == YAS_MAG_NOTRANS_POSITION)
  432. yas_cdrv_set_transformatiom_matrix(NULL);
  433. else
  434. yas_cdrv_set_transformatiom_matrix(
  435. YAS_TRANSFORMATION[position]);
  436. driver.position = position;
  437. return YAS_NO_ERROR;
  438. }
  439. static int
  440. yas_get_offset(int8_t *hard_offset)
  441. {
  442. if (!driver.initialized)
  443. return YAS_ERROR_NOT_INITIALIZED;
  444. if (hard_offset == NULL)
  445. return YAS_ERROR_ARG;
  446. set_vector(hard_offset, driver.hard_offset);
  447. return YAS_NO_ERROR;
  448. }
  449. static int
  450. yas_set_offset(const int8_t *hard_offset)
  451. {
  452. if (!driver.initialized)
  453. return YAS_ERROR_NOT_INITIALIZED;
  454. if (hard_offset == NULL)
  455. return YAS_ERROR_ARG;
  456. if (yas_cdrv_actuate_initcoil() < 0)
  457. return YAS_ERROR_DEVICE_COMMUNICATION;
  458. if (is_valid_offset(hard_offset)) {
  459. if (yas_cdrv_set_offset(hard_offset) < 0)
  460. return YAS_ERROR_DEVICE_COMMUNICATION;
  461. driver.measure_state = YAS_MAG_STATE_NORMAL;
  462. } else {
  463. set_vector(driver.hard_offset, INVALID_OFFSET);
  464. driver.measure_state = YAS_MAG_STATE_MEASURE_OFFSET;
  465. }
  466. return YAS_NO_ERROR;
  467. }
  468. static int
  469. yas_measure(struct yas_mag_data *data, int temp_correction)
  470. {
  471. int result = 0, rt;
  472. int8_t hard_offset[3];
  473. uint32_t t;
  474. if (!driver.initialized)
  475. return YAS_ERROR_NOT_INITIALIZED;
  476. if (data == NULL)
  477. return YAS_ERROR_ARG;
  478. switch (driver.measure_state) {
  479. case YAS_MAG_STATE_INIT_COIL:
  480. driver.cbk.current_time(&t);
  481. if (t - driver.overflow_time < YAS_MAG_INITCOIL_TIMEOUT)
  482. break;
  483. driver.overflow_time = t;
  484. if (yas_cdrv_actuate_initcoil() < 0)
  485. return YAS_ERROR_DEVICE_COMMUNICATION;
  486. if (!driver.overflow && is_valid_offset(driver.hard_offset)) {
  487. driver.measure_state = YAS_MAG_STATE_NORMAL;
  488. break;
  489. }
  490. /* FALLTHRU */
  491. case YAS_MAG_STATE_MEASURE_OFFSET:
  492. set_vector(hard_offset, driver.hard_offset);
  493. rt = yas_cdrv_measure_and_set_offset();
  494. if (rt < 0)
  495. return rt;
  496. if (is_vector_differ(driver.hard_offset, hard_offset))
  497. result = YAS_REPORT_HARD_OFFSET_CHANGED;
  498. driver.measure_state = YAS_MAG_STATE_NORMAL;
  499. break;
  500. }
  501. rt = yas_cdrv_measure(data->xyz.v, data->xy1y2, data->xy1y2_linear,
  502. &data->temperature, temp_correction);
  503. if (rt < 0)
  504. return rt;
  505. if (0 < rt) {
  506. if (!driver.overflow)
  507. driver.cbk.current_time(&driver.overflow_time);
  508. driver.overflow = 1;
  509. driver.measure_state = YAS_MAG_STATE_INIT_COIL;
  510. result |= rt;
  511. } else
  512. driver.overflow = 0;
  513. return result;
  514. }
  515. static int
  516. yas_measure_wrap(struct yas_mag_data *data)
  517. {
  518. return yas_measure(data, 1);
  519. }
  520. static int
  521. yas_init(void)
  522. {
  523. int i, rt;
  524. uint8_t data;
  525. if (driver.initialized)
  526. return YAS_ERROR_NOT_INITIALIZED;
  527. driver.measure_state = YAS_MAG_STATE_INIT_COIL;
  528. driver.overflow = 0;
  529. driver.cbk.current_time(&driver.overflow_time);
  530. driver.position = YAS_MAG_NOTRANS_POSITION;
  531. driver.transform = NULL;
  532. #if 1 < YAS_MAG_TEMPERATURE_LOG
  533. driver.t.num = driver.t.idx = 0;
  534. #endif
  535. set_vector(driver.hard_offset, INVALID_OFFSET);
  536. if (driver.cbk.device_open() < 0)
  537. return YAS_ERROR_DEVICE_COMMUNICATION;
  538. data = 0;
  539. if (driver.cbk.device_write(YAS_REG_TEST1, &data, 1) < 0) {
  540. driver.cbk.device_close();
  541. return YAS_ERROR_DEVICE_COMMUNICATION;
  542. }
  543. if (driver.cbk.device_write(YAS_REG_TEST2, &data, 1) < 0) {
  544. driver.cbk.device_close();
  545. return YAS_ERROR_DEVICE_COMMUNICATION;
  546. }
  547. if (driver.cbk.device_read(YAS_REG_DEVICE_ID, &data, 1) < 0) {
  548. driver.cbk.device_close();
  549. return YAS_ERROR_DEVICE_COMMUNICATION;
  550. }
  551. driver.dev_id = data;
  552. switch (driver.dev_id) {
  553. case YAS_YAS530_DEVICE_ID:
  554. rt = get_cal_data_yas530(&driver.correct);
  555. if (rt < 0) {
  556. driver.cbk.device_close();
  557. return rt;
  558. }
  559. driver.center_thresh = YAS_YAS530_DATA_CENTER;
  560. driver.underflow_thresh = YAS_YAS530_DATA_UNDERFLOW;
  561. driver.overflow_thresh = YAS_YAS530_DATA_OVERFLOW;
  562. switch (driver.correct.ver) {
  563. case YAS_YAS530_VERSION_B:
  564. for (i = 0; i < 3; i++)
  565. driver.coef[i]
  566. = YAS_YAS530_VERSION_B_COEF;
  567. break;
  568. case YAS_YAS530_VERSION_A:
  569. default:
  570. for (i = 0; i < 3; i++)
  571. driver.coef[i]
  572. = YAS_YAS530_VERSION_A_COEF;
  573. break;
  574. }
  575. break;
  576. case YAS_YAS532_DEVICE_ID:
  577. rt = get_cal_data_yas532(&driver.correct);
  578. if (rt < 0) {
  579. driver.cbk.device_close();
  580. return rt;
  581. }
  582. driver.center_thresh = YAS_YAS532_DATA_CENTER;
  583. driver.underflow_thresh = YAS_YAS532_DATA_UNDERFLOW;
  584. driver.overflow_thresh = YAS_YAS532_DATA_OVERFLOW;
  585. switch (driver.correct.ver) {
  586. case YAS_YAS532_VERSION_AC:
  587. for (i = 0; i < 3; i++)
  588. driver.coef[i]
  589. = yas532_version_ac_coef[i];
  590. break;
  591. case YAS_YAS532_VERSION_AB:
  592. default:
  593. for (i = 0; i < 3; i++)
  594. driver.coef[i]
  595. = YAS_YAS532_VERSION_AB_COEF;
  596. break;
  597. }
  598. break;
  599. default:
  600. driver.cbk.device_close();
  601. return YAS_ERROR_DEVICE_COMMUNICATION;
  602. }
  603. rt = yas_cdrv_actuate_initcoil();
  604. if (rt < 0) {
  605. driver.cbk.device_close();
  606. return rt;
  607. }
  608. driver.measure_state = YAS_MAG_STATE_MEASURE_OFFSET;
  609. driver.initialized = 1;
  610. return YAS_NO_ERROR;
  611. }
  612. static int
  613. yas_term(void)
  614. {
  615. if (!driver.initialized)
  616. return YAS_ERROR_NOT_INITIALIZED;
  617. driver.initialized = 0;
  618. return driver.cbk.device_close();
  619. }
  620. static int
  621. yas_self_test(struct yas_self_test_result *r)
  622. {
  623. struct yas_mag_data data;
  624. int rt, i;
  625. if (!driver.initialized)
  626. return YAS_ERROR_TEST_ORDER;
  627. if (r == NULL)
  628. return YAS_ERROR_ARG;
  629. r->id = driver.dev_id;
  630. rt = yas_set_offset(INVALID_OFFSET);
  631. if (rt < 0)
  632. return rt;
  633. rt = yas_measure(&data, 0);
  634. set_vector(r->xy1y2, driver.hard_offset);
  635. if (rt < 0)
  636. return rt;
  637. if (rt & YAS_OVERFLOW)
  638. return YAS_ERROR_OVERFLOW;
  639. if (rt & YAS_UNDERFLOW)
  640. return YAS_ERROR_UNDERFLOW;
  641. if (data.xyz.v[0] == 0 && data.xyz.v[1] == 0 && data.xyz.v[2] == 0)
  642. return YAS_ERROR_DIRCALC;
  643. r->dir = 99;
  644. for (i = 0; i < 3; i++)
  645. r->xyz[i] = data.xyz.v[i] / 1000;
  646. rt = yas_cdrv_sensitivity_measuremnet(&r->sx, &r->sy);
  647. if (rt < 0)
  648. return rt;
  649. if (rt & YAS_OVERFLOW)
  650. return YAS_ERROR_OVERFLOW;
  651. if (rt & YAS_UNDERFLOW)
  652. return YAS_ERROR_UNDERFLOW;
  653. return YAS_NO_ERROR;
  654. }
  655. static int
  656. yas_self_test_noise(struct yas_vector *raw_xyz)
  657. {
  658. struct yas_mag_data data;
  659. int rt;
  660. if (!driver.initialized)
  661. return YAS_ERROR_TEST_ORDER;
  662. if (raw_xyz == NULL)
  663. return YAS_ERROR_ARG;
  664. rt = yas_measure(&data, 0);
  665. raw_xyz->v[0] = data.xy1y2_linear[0];
  666. raw_xyz->v[1] = data.xy1y2_linear[1] - data.xy1y2_linear[2];
  667. raw_xyz->v[2] = -data.xy1y2_linear[1] - data.xy1y2_linear[2];
  668. if (rt < 0)
  669. return rt;
  670. if (rt & YAS_OVERFLOW)
  671. return YAS_ERROR_OVERFLOW;
  672. if (rt & YAS_UNDERFLOW)
  673. return YAS_ERROR_UNDERFLOW;
  674. return YAS_NO_ERROR;
  675. }
  676. int
  677. yas_mag_driver_init(struct yas_mag_driver *f)
  678. {
  679. if (f == NULL || f->callback.device_open == NULL
  680. || f->callback.device_close == NULL
  681. || f->callback.device_read == NULL
  682. || f->callback.device_write == NULL
  683. || f->callback.msleep == NULL
  684. || f->callback.current_time == NULL)
  685. return YAS_ERROR_ARG;
  686. f->init = yas_init;
  687. f->term = yas_term;
  688. f->self_test = yas_self_test;
  689. f->self_test_noise = yas_self_test_noise;
  690. f->get_offset = yas_get_offset;
  691. f->set_offset = yas_set_offset;
  692. f->get_position = yas_get_position;
  693. f->set_position = yas_set_position;
  694. f->measure = yas_measure_wrap;
  695. driver.cbk = f->callback;
  696. yas_term();
  697. return YAS_NO_ERROR;
  698. }