| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055 |
- /*
- * Copyright (c) 2010-2012 Yamaha Corporation
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- */
- #include "yas.h"
- struct utimeval {
- int32_t tv_sec;
- int32_t tv_msec;
- };
- struct utimer {
- struct utimeval prev_time;
- struct utimeval total_time;
- struct utimeval delay_ms;
- };
- static int utimeval_init(struct utimeval *val);
- static int utimeval_is_initial(struct utimeval *val);
- static int utimeval_is_overflow(struct utimeval *val);
- static struct utimeval utimeval_plus(struct utimeval *first,
- struct utimeval *second);
- static struct utimeval utimeval_minus(struct utimeval *first,
- struct utimeval *second);
- static int utimeval_greater_than(struct utimeval *first,
- struct utimeval *second);
- static int utimeval_greater_or_equal(struct utimeval *first,
- struct utimeval *second);
- static int utimeval_greater_than_zero(struct utimeval *val);
- static int utimeval_less_than_zero(struct utimeval *val);
- static struct utimeval *msec_to_utimeval(struct utimeval *result,
- uint32_t msec);
- static uint32_t utimeval_to_msec(struct utimeval *val);
- static struct utimeval utimer_calc_next_time(struct utimer *ut,
- struct utimeval *cur);
- static struct utimeval utimer_current_time(void);
- static int utimer_is_timeout(struct utimer *ut);
- static int utimer_clear_timeout(struct utimer *ut);
- static uint32_t utimer_get_total_time(struct utimer *ut);
- static uint32_t utimer_get_delay(struct utimer *ut);
- static int utimer_set_delay(struct utimer *ut, uint32_t delay_ms);
- static int utimer_update(struct utimer *ut);
- static int utimer_update_with_curtime(struct utimer *ut, struct utimeval *cur);
- static uint32_t utimer_sleep_time(struct utimer *ut);
- static uint32_t utimer_sleep_time_with_curtime(struct utimer *ut,
- struct utimeval *cur);
- static int utimer_init(struct utimer *ut, uint32_t delay_ms);
- static int utimer_clear(struct utimer *ut);
- static void utimer_lib_init(void (*func)(int *sec, int *msec));
- #define YAS_REGADDR_DEVICE_ID (0x80)
- #define YAS_REGADDR_ACTUATE_INIT_COIL (0x81)
- #define YAS_REGADDR_MEASURE_COMMAND (0x82)
- #define YAS_REGADDR_CONFIG (0x83)
- #define YAS_REGADDR_MEASURE_INTERVAL (0x84)
- #define YAS_REGADDR_OFFSET_X (0x85)
- #define YAS_REGADDR_OFFSET_Y1 (0x86)
- #define YAS_REGADDR_OFFSET_Y2 (0x87)
- #define YAS_REGADDR_TEST1 (0x88)
- #define YAS_REGADDR_TEST2 (0x89)
- #define YAS_REGADDR_CAL (0x90)
- #define YAS_REGADDR_MEASURE_DATA (0xb0)
- #define YAS_YAS530_DEVICE_ID (0x01) /* YAS530 (MS-3E) */
- #define YAS_YAS530_VERSION_A (0) /* YAS530 (MS-3E Aver) */
- #define YAS_YAS530_VERSION_B (1) /* YAS530B (MS-3E Bver) */
- #define YAS_YAS530_VERSION_A_COEF (380)
- #define YAS_YAS530_VERSION_B_COEF (550)
- #define YAS_YAS530_DATA_CENTER (2048)
- #define YAS_YAS530_DATA_OVERFLOW (4095)
- #define YAS_YAS532_DEVICE_ID (0x02) /* YAS532 (MS-3R) */
- #define YAS_YAS532_VERSION_AB (0) /* YAS532AB (MS-3R ABver) */
- #define YAS_YAS532_VERSION_AC (1) /* YAS532AC (MS-3R ACver) */
- #define YAS_YAS532_VERSION_AB_COEF (1800)
- #define YAS_YAS532_VERSION_AC_COEF (900)
- #define YAS_YAS532_DATA_CENTER (4096)
- #define YAS_YAS532_DATA_OVERFLOW (8190)
- #define YAS_YAS530_CAL_SINGLE_READ
- struct yas_machdep_func {
- int (*device_open)(void);
- int (*device_close)(void);
- int (*device_write)(uint8_t slave, uint8_t addr, const uint8_t *buf, int len);
- int (*device_read)(uint8_t slave, uint8_t addr, uint8_t *buf, int len);
- void (*msleep)(int msec);
- };
- static int yas_cdrv_actuate_initcoil(void);
- static int yas_cdrv_set_offset(const int8_t *offset);
- static int yas_cdrv_recalc_calib_offset(int32_t *prev_calib_offset,
- int32_t *new_calib_offset, int8_t *prev_offset,
- int8_t *new_offset);
- static int yas_cdrv_set_transformatiom_matrix(const int8_t *transform);
- static int yas_cdrv_measure_and_set_offset(int8_t *offset);
- static int yas_cdrv_measure(int32_t *msens, int32_t *raw, int16_t *t);
- static int yas_cdrv_init(const int8_t *transform,
- struct yas_machdep_func *func);
- static int yas_cdrv_term(void);
- static void (*current_time)(int *sec, int *msec);
- static int
- utimeval_init(struct utimeval *val)
- {
- if (val == NULL)
- return -1;
- val->tv_sec = val->tv_msec = 0;
- return 0;
- }
- static int
- utimeval_is_initial(struct utimeval *val)
- {
- if (val == NULL)
- return 0;
- return val->tv_sec == 0 && val->tv_msec == 0;
- }
- static int
- utimeval_is_overflow(struct utimeval *val)
- {
- int32_t max;
- if (val == NULL)
- return 0;
- max = (int32_t) ((uint32_t) 0xffffffff / (uint32_t) 1000);
- if (val->tv_sec > max) {
- return 1; /* overflow */
- } else if (val->tv_sec == max) {
- if (val->tv_msec > (int32_t)((uint32_t)0xffffffff
- % (uint32_t)1000))
- return 1; /* overflow */
- }
- return 0;
- }
- static struct utimeval
- utimeval_plus(struct utimeval *first, struct utimeval *second)
- {
- struct utimeval result = {0, 0};
- int32_t tmp;
- if (first == NULL || second == NULL)
- return result;
- tmp = first->tv_sec + second->tv_sec;
- if (first->tv_sec >= 0 && second->tv_sec >= 0 && tmp < 0)
- goto overflow;
- if (first->tv_sec < 0 && second->tv_sec < 0 && tmp >= 0)
- goto underflow;
- result.tv_sec = tmp;
- result.tv_msec = first->tv_msec + second->tv_msec;
- if (1000 <= result.tv_msec) {
- tmp = result.tv_sec + result.tv_msec / 1000;
- if (result.tv_sec >= 0 && result.tv_msec >= 0 && tmp < 0)
- goto overflow;
- result.tv_sec = tmp;
- result.tv_msec = result.tv_msec % 1000;
- }
- if (result.tv_msec < 0) {
- tmp = result.tv_sec + result.tv_msec / 1000 - 1;
- if (result.tv_sec < 0 && result.tv_msec < 0 && tmp >= 0)
- goto underflow;
- result.tv_sec = tmp;
- result.tv_msec = result.tv_msec % 1000 + 1000;
- }
- return result;
- overflow:
- result.tv_sec = (int32_t)0x7fffffff;
- result.tv_msec = 999;
- return result;
- underflow:
- result.tv_sec = (int32_t)0x80000000;
- result.tv_msec = 0;
- return result;
- }
- static struct utimeval
- utimeval_minus(struct utimeval *first, struct utimeval *second)
- {
- struct utimeval result = {0, 0}, tmp;
- if (first == NULL || second == NULL
- || second->tv_sec == (int)0x80000000)
- return result;
- tmp.tv_sec = -second->tv_sec;
- tmp.tv_msec = -second->tv_msec;
- return utimeval_plus(first, &tmp);
- }
- static int
- utimeval_less_than(struct utimeval *first, struct utimeval *second)
- {
- if (first == NULL || second == NULL)
- return 0;
- if (first->tv_sec > second->tv_sec) {
- return 1;
- } else if (first->tv_sec < second->tv_sec) {
- return 0;
- } else {
- if (first->tv_msec > second->tv_msec)
- return 1;
- else
- return 0;
- }
- }
- static int
- utimeval_greater_than(struct utimeval *first, struct utimeval *second)
- {
- if (first == NULL || second == NULL)
- return 0;
- if (first->tv_sec < second->tv_sec) {
- return 1;
- } else if (first->tv_sec > second->tv_sec) {
- return 0;
- } else {
- if (first->tv_msec < second->tv_msec)
- return 1;
- else
- return 0;
- }
- }
- static int
- utimeval_greater_or_equal(struct utimeval *first,
- struct utimeval *second)
- {
- return !utimeval_less_than(first, second);
- }
- static int
- utimeval_greater_than_zero(struct utimeval *val)
- {
- struct utimeval zero = {0, 0};
- return utimeval_greater_than(&zero, val);
- }
- static int
- utimeval_less_than_zero(struct utimeval *val)
- {
- struct utimeval zero = {0, 0};
- return utimeval_less_than(&zero, val);
- }
- static struct utimeval *
- msec_to_utimeval(struct utimeval *result, uint32_t msec)
- {
- if (result == NULL)
- return result;
- result->tv_sec = (int32_t)(msec / 1000);
- result->tv_msec = (int32_t)(msec % 1000);
- return result;
- }
- static uint32_t
- utimeval_to_msec(struct utimeval *val)
- {
- if (val == NULL)
- return 0;
- if (utimeval_less_than_zero(val))
- return 0;
- if (utimeval_is_overflow(val))
- return 0xffffffff;
- return (uint32_t)(val->tv_sec * 1000 + val->tv_msec);
- }
- static struct utimeval
- utimer_calc_next_time(struct utimer *ut, struct utimeval *cur)
- {
- struct utimeval result = {0, 0}, delay;
- if (ut == NULL || cur == NULL)
- return result;
- utimer_update_with_curtime(ut, cur);
- if (utimer_is_timeout(ut)) {
- result = *cur;
- } else {
- delay = utimeval_minus(&ut->delay_ms, &ut->total_time);
- result = utimeval_plus(cur, &delay);
- }
- return result;
- }
- static struct utimeval
- utimer_current_time(void)
- {
- struct utimeval tv;
- int sec, msec;
- if (current_time != NULL)
- current_time(&sec, &msec);
- else
- sec = 0, msec = 0;
- tv.tv_sec = sec;
- tv.tv_msec = msec;
- return tv;
- }
- static int
- utimer_clear(struct utimer *ut)
- {
- if (ut == NULL)
- return -1;
- utimeval_init(&ut->prev_time);
- utimeval_init(&ut->total_time);
- return 0;
- }
- static int
- utimer_update_with_curtime(struct utimer *ut, struct utimeval *cur)
- {
- struct utimeval tmp;
- if (ut == NULL || cur == NULL)
- return -1;
- if (utimeval_is_initial(&ut->prev_time))
- ut->prev_time = *cur;
- if (utimeval_greater_than_zero(&ut->delay_ms)) {
- tmp = utimeval_minus(cur, &ut->prev_time);
- if (utimeval_less_than_zero(&tmp)) {
- utimeval_init(&ut->total_time);
- } else {
- ut->total_time = utimeval_plus(&tmp, &ut->total_time);
- if (utimeval_is_overflow(&ut->total_time))
- utimeval_init(&ut->total_time);
- }
- ut->prev_time = *cur;
- }
- return 0;
- }
- static int
- utimer_update(struct utimer *ut)
- {
- struct utimeval cur;
- if (ut == NULL)
- return -1;
- cur = utimer_current_time();
- utimer_update_with_curtime(ut, &cur);
- return 0;
- }
- static int
- utimer_is_timeout(struct utimer *ut)
- {
- if (ut == NULL)
- return 0;
- if (utimeval_greater_than_zero(&ut->delay_ms))
- return utimeval_greater_or_equal(&ut->delay_ms,
- &ut->total_time);
- else
- return 1;
- }
- static int
- utimer_clear_timeout(struct utimer *ut)
- {
- uint32_t delay, total;
- if (ut == NULL)
- return -1;
- delay = utimeval_to_msec(&ut->delay_ms);
- if (delay == 0 || utimeval_is_overflow(&ut->total_time)) {
- total = 0;
- } else {
- if (utimeval_is_overflow(&ut->total_time)) {
- total = 0;
- } else {
- total = utimeval_to_msec(&ut->total_time);
- total = total % delay;
- }
- }
- msec_to_utimeval(&ut->total_time, total);
- return 0;
- }
- static uint32_t
- utimer_sleep_time_with_curtime(struct utimer *ut, struct utimeval *cur)
- {
- struct utimeval tv;
- if (ut == NULL || cur == NULL)
- return 0;
- tv = utimer_calc_next_time(ut, cur);
- tv = utimeval_minus(&tv, cur);
- if (utimeval_less_than_zero(&tv))
- return 0;
- return utimeval_to_msec(&tv);
- }
- static uint32_t
- utimer_sleep_time(struct utimer *ut)
- {
- struct utimeval cur;
- if (ut == NULL)
- return 0;
- cur = utimer_current_time();
- return utimer_sleep_time_with_curtime(ut, &cur);
- }
- static int
- utimer_init(struct utimer *ut, uint32_t delay_ms)
- {
- if (ut == NULL)
- return -1;
- utimer_clear(ut);
- msec_to_utimeval(&ut->delay_ms, delay_ms);
- return 0;
- }
- static uint32_t
- utimer_get_total_time(struct utimer *ut)
- {
- return utimeval_to_msec(&ut->total_time);
- }
- static uint32_t
- utimer_get_delay(struct utimer *ut)
- {
- if (ut == NULL)
- return 0;
- return utimeval_to_msec(&ut->delay_ms);
- }
- static int
- utimer_set_delay(struct utimer *ut, uint32_t delay_ms)
- {
- return utimer_init(ut, delay_ms);
- }
- static void
- utimer_lib_init(void (*func)(int *sec, int *msec))
- {
- current_time = func;
- }
- struct yas_cal_data {
- uint8_t dx, dy1, dy2;
- uint8_t d2, d3, d4, d5, d6, d7, d8, d9, d0;
- uint8_t dck;
- uint8_t ver;
- };
- struct yas_correction_data {
- int32_t Cx, Cy1, Cy2;
- int32_t a2, a3, a4, a5, a6, a7, a8, a9, k;
- };
- struct yas_cdriver {
- struct yas_cal_data cal;
- struct yas_correction_data correct;
- struct yas_machdep_func func;
- int8_t transform[9];
- int16_t temperature;
- uint8_t dev_id;
- int32_t coef;
- int16_t center;
- int16_t overflow;
- };
- static struct yas_cdriver cdriver;
- static int
- device_open(void)
- {
- if (cdriver.func.device_open == NULL)
- return -1;
- return cdriver.func.device_open();
- }
- static int
- device_close(void)
- {
- if (cdriver.func.device_close == NULL)
- return -1;
- return cdriver.func.device_close();
- }
- static int
- device_write(uint8_t addr, const uint8_t *buf, int len)
- {
- if (cdriver.func.device_write == NULL)
- return -1;
- return cdriver.func.device_write(YAS_MAG_I2C_SLAVEADDR, addr, buf, len);
- }
- static int
- device_read(uint8_t addr, uint8_t *buf, int len)
- {
- if (cdriver.func.device_read == NULL)
- return -1;
- return cdriver.func.device_read(YAS_MAG_I2C_SLAVEADDR, addr, buf, len);
- }
- static void
- sleep(int millisec)
- {
- if (cdriver.func.msleep == NULL)
- return;
- cdriver.func.msleep(millisec);
- }
- static int
- init_test_register(void)
- {
- uint8_t data;
- data = 0x00;
- if (device_write(YAS_REGADDR_TEST1, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- data = 0x00;
- if (device_write(YAS_REGADDR_TEST2, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- return YAS_NO_ERROR;
- }
- static int
- get_device_id(uint8_t *id)
- {
- uint8_t data = 0;
- if (device_read(YAS_REGADDR_DEVICE_ID, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- *id = data;
- return YAS_NO_ERROR;
- }
- static int
- get_cal_data_yas530(struct yas_cal_data *cal)
- {
- uint8_t data[16];
- #ifdef YAS_YAS530_CAL_SINGLE_READ
- int i;
- for (i = 0; i < 16; i++) { /* dummy read */
- if (device_read(YAS_REGADDR_CAL + i, &data[i], 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- for (i = 0; i < 16; i++) {
- if (device_read(YAS_REGADDR_CAL + i, &data[i], 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- #else
- if (device_read(YAS_REGADDR_CAL, data, 16) < 0) /* dummy read */
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (device_read(YAS_REGADDR_CAL, data, 16) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- #endif
- cal->dx = data[0];
- cal->dy1 = data[1];
- cal->dy2 = data[2];
- cal->d2 = (data[3]>>2) & 0x03f;
- cal->d3 = (uint8_t)(((data[3]<<2) & 0x0c) | ((data[4]>>6) & 0x03));
- cal->d4 = (uint8_t)(data[4] & 0x3f);
- cal->d5 = (data[5]>>2) & 0x3f;
- cal->d6 = (uint8_t)(((data[5]<<4) & 0x30) | ((data[6]>>4) & 0x0f));
- cal->d7 = (uint8_t)(((data[6]<<3) & 0x78) | ((data[7]>>5) & 0x07));
- cal->d8 = (uint8_t)(((data[7]<<1) & 0x3e) | ((data[8]>>7) & 0x01));
- cal->d9 = (uint8_t)(((data[8]<<1) & 0xfe) | ((data[9]>>7) & 0x01));
- cal->d0 = (uint8_t)((data[9]>>2) & 0x1f);
- cal->dck = (uint8_t)(((data[9]<<1) & 0x06) | ((data[10]>>7) & 0x01));
- cal->ver = (uint8_t)((data[15]) & 0x03);
- return YAS_NO_ERROR;
- }
- static void
- get_correction_value_yas530(struct yas_cal_data *cal,
- struct yas_correction_data *correct)
- {
- correct->Cx = cal->dx * 6 - 768;
- correct->Cy1 = cal->dy1 * 6 - 768;
- correct->Cy2 = cal->dy2 * 6 - 768;
- correct->a2 = cal->d2 - 32;
- correct->a3 = cal->d3 - 8;
- correct->a4 = cal->d4 - 32;
- correct->a5 = cal->d5 + 38;
- correct->a6 = cal->d6 - 32;
- correct->a7 = cal->d7 - 64;
- correct->a8 = cal->d8 - 32;
- correct->a9 = cal->d9;
- correct->k = cal->d0 + 10;
- }
- static int
- get_cal_data_yas532(struct yas_cal_data *cal)
- {
- uint8_t data[14];
- #ifdef YAS_YAS530_CAL_SINGLE_READ
- int i;
- for (i = 0; i < 14; i++) { /* dummy read */
- if (device_read(YAS_REGADDR_CAL + i, &data[i], 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- for (i = 0; i < 14; i++) {
- if (device_read(YAS_REGADDR_CAL + i, &data[i], 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- #else
- if (device_read(YAS_REGADDR_CAL, data, 14) < 0) /* dummy read */
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (device_read(YAS_REGADDR_CAL, data, 14) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- #endif
- cal->dx = data[0];
- cal->dy1 = data[1];
- cal->dy2 = data[2];
- cal->d2 = (data[3]>>2) & 0x03f;
- cal->d3 = (uint8_t)(((data[3]<<2) & 0x0c) | ((data[4]>>6) & 0x03));
- cal->d4 = (uint8_t)(data[4] & 0x3f);
- cal->d5 = (data[5]>>2) & 0x3f;
- cal->d6 = (uint8_t)(((data[5]<<4) & 0x30) | ((data[6]>>4) & 0x0f));
- cal->d7 = (uint8_t)(((data[6]<<3) & 0x78) | ((data[7]>>5) & 0x07));
- cal->d8 = (uint8_t)(((data[7]<<1) & 0x3e) | ((data[8]>>7) & 0x01));
- cal->d9 = (uint8_t)(((data[8]<<1) & 0xfe) | ((data[9]>>7) & 0x01));
- cal->d0 = (uint8_t)((data[9]>>2) & 0x1f);
- cal->dck = (uint8_t)(((data[9]<<1) & 0x06) | ((data[10]>>7) & 0x01));
- cal->ver = (uint8_t)((data[13]) & 0x01);
- return YAS_NO_ERROR;
- }
- static void
- get_correction_value_yas532(struct yas_cal_data *cal,
- struct yas_correction_data *correct)
- {
- correct->Cx = cal->dx * 10 - 1280;
- correct->Cy1 = cal->dy1 * 10 - 1280;
- correct->Cy2 = cal->dy2 * 10 - 1280;
- correct->a2 = cal->d2 - 32;
- correct->a3 = cal->d3 - 8;
- correct->a4 = cal->d4 - 32;
- correct->a5 = cal->d5 + 38;
- correct->a6 = cal->d6 - 32;
- correct->a7 = cal->d7 - 64;
- correct->a8 = cal->d8 - 32;
- correct->a9 = cal->d9;
- correct->k = cal->d0;
- }
- static int
- set_configuration(int inton, int inthact, int cck)
- {
- uint8_t data = 0;
- data = (uint8_t)(data | ((!!inton) & 0x01));
- data = (uint8_t)(data | (((!!inthact)<<1) & 0x02));
- data = (uint8_t)(data | ((cck<<2) & 0x1c));
- if (device_write(YAS_REGADDR_CONFIG, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- return YAS_NO_ERROR;
- }
- static int
- get_measure_interval(int32_t *msec)
- {
- uint8_t data;
- int mult = 7;
- if (device_read(YAS_REGADDR_MEASURE_INTERVAL, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- switch (cdriver.dev_id) {
- case YAS_YAS532_DEVICE_ID:
- mult = 4;
- break;
- case YAS_YAS530_DEVICE_ID:
- default:
- mult = 7;
- break;
- }
- *msec = data * mult;
- return YAS_NO_ERROR;
- }
- static int
- set_measure_interval(int32_t msec)
- {
- uint8_t data = 0;
- int mult = 7;
- switch (cdriver.dev_id) {
- case YAS_YAS532_DEVICE_ID:
- mult = 4;
- break;
- case YAS_YAS530_DEVICE_ID:
- default:
- mult = 7;
- break;
- }
- if (msec > mult*0xff)
- data = 0xff;
- else
- if (msec % mult == 0)
- data = (uint8_t)(msec / mult);
- else
- data = (uint8_t)(msec / mult + 1);
- if (device_write(YAS_REGADDR_MEASURE_INTERVAL, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- return YAS_NO_ERROR;
- }
- static int
- set_measure_command(int ldtc, int fors, int dlymes)
- {
- uint8_t data = 0;
- data = (uint8_t)(data | 0x01);
- data = (uint8_t)(data | (((!!ldtc)<<1) & 0x02));
- data = (uint8_t)(data | (((!!fors)<<2) & 0x04));
- data = (uint8_t)(data | (((!!dlymes)<<4) & 0x10));
- if (device_write(YAS_REGADDR_MEASURE_COMMAND, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- return YAS_NO_ERROR;
- }
- static int
- measure_normal_yas530(int *busy, int16_t *t,
- int16_t *x, int16_t *y1, int16_t *y2)
- {
- uint8_t data[8];
- if (set_measure_command(0, 0, 0) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- sleep(2);
- if (device_read(YAS_REGADDR_MEASURE_DATA, data, 8) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- *busy = (data[0]>>7) & 0x01;
- *t = (int16_t)((((int32_t)data[0]<<2) & 0x1fc)
- | ((data[1]>>6) & 0x03));
- *x = (int16_t)((((int32_t)data[2]<<5) & 0xfe0)
- | ((data[3]>>3) & 0x1f));
- *y1 = (int16_t)((((int32_t)data[4]<<5) & 0xfe0)
- | ((data[5]>>3) & 0x1f));
- *y2 = (int16_t)((((int32_t)data[6]<<5) & 0xfe0)
- | ((data[7]>>3) & 0x1f));
- /*YLOGD(("f[%d] t[%d] x[%d] y1[%d] y2[%d]\n",
- *busy, *t, *x, *y1, *y2));*/
- return YAS_NO_ERROR;
- }
- static int
- measure_normal_yas532(int *busy, int16_t *t,
- int16_t *x, int16_t *y1, int16_t *y2)
- {
- uint8_t data[8];
- if (set_measure_command(0, 0, 0) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- sleep(2);
- if (device_read(YAS_REGADDR_MEASURE_DATA, data, 8) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- *busy = (data[0]>>7) & 0x01;
- *t = (int16_t)((((int32_t)data[0]<<3) & 0x3f8)
- | ((data[1]>>5) & 0x07));
- *x = (int16_t)((((int32_t)data[2]<<6) & 0x1fc0)
- | ((data[3]>>2) & 0x3f));
- *y1 = (int16_t)((((int32_t)data[4]<<6) & 0x1fc0)
- | ((data[5]>>2) & 0x3f));
- *y2 = (int16_t)((((int32_t)data[6]<<6) & 0x1fc0)
- | ((data[7]>>2) & 0x3f));
- /*YLOGD(("f[%d] t[%d] x[%d] y1[%d] y2[%d]\n",
- *busy, *t, *x, *y1, *y2));*/
- return YAS_NO_ERROR;
- }
- static int
- measure_normal(int *busy, int16_t *t, int16_t *x, int16_t *y1, int16_t *y2)
- {
- int result;
- switch (cdriver.dev_id) {
- case YAS_YAS532_DEVICE_ID:
- result = measure_normal_yas532(busy, t, x, y1, y2);
- break;
- case YAS_YAS530_DEVICE_ID:
- default:
- result = measure_normal_yas530(busy, t, x, y1, y2);
- break;
- }
- return result;
- }
- static int
- coordinate_conversion(int32_t x, int32_t y1, int32_t y2, int16_t t,
- int32_t *xo, int32_t *yo, int32_t *zo,
- struct yas_correction_data *c)
- {
- int32_t sx, sy1, sy2, sy, sz;
- int32_t hx, hy, hz;
- sx = x - (c->Cx * t) / 100;
- sy1 = y1 - (c->Cy1 * t) / 100;
- sy2 = y2 - (c->Cy2 * t) / 100;
- sy = sy1 - sy2;
- sz = -sy1 - sy2;
- hx = c->k * ((100 * sx + c->a2 * sy + c->a3 * sz) / 10);
- hy = c->k * ((c->a4 * sx + c->a5 * sy + c->a6 * sz) / 10);
- hz = c->k * ((c->a7 * sx + c->a8 * sy + c->a9 * sz) / 10);
- *xo = cdriver.transform[0] * hx
- + cdriver.transform[1] * hy
- + cdriver.transform[2] * hz;
- *yo = cdriver.transform[3] * hx
- + cdriver.transform[4] * hy
- + cdriver.transform[5] * hz;
- *zo = cdriver.transform[6] * hx
- + cdriver.transform[7] * hy
- + cdriver.transform[8] * hz;
- return YAS_NO_ERROR;
- }
- static int
- set_hardware_offset(int8_t offset_x, int8_t offset_y1, int8_t offset_y2)
- {
- uint8_t data;
- data = (uint8_t)(offset_x & 0x3f);
- if (device_write(YAS_REGADDR_OFFSET_X, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- data = (uint8_t)(offset_y1 & 0x3f);
- if (device_write(YAS_REGADDR_OFFSET_Y1, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- data = (uint8_t)(offset_y2 & 0x3f);
- if (device_write(YAS_REGADDR_OFFSET_Y2, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- return YAS_NO_ERROR;
- }
- static int
- yas_cdrv_actuate_initcoil(void)
- {
- uint8_t data = 0;
- if (device_write(YAS_REGADDR_ACTUATE_INIT_COIL, &data, 1) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- return YAS_NO_ERROR;
- }
- static int
- check_offset(int8_t offset_x, int8_t offset_y1, int8_t offset_y2,
- int *flag_x, int *flag_y1, int *flag_y2)
- {
- int busy;
- int16_t t, x, y1, y2;
- if (set_hardware_offset(offset_x, offset_y1, offset_y2) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (measure_normal(&busy, &t, &x, &y1, &y2) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- *flag_x = *flag_y1 = *flag_y2 = 0;
- if (x > cdriver.center)
- *flag_x = 1;
- if (y1 > cdriver.center)
- *flag_y1 = 1;
- if (y2 > cdriver.center)
- *flag_y2 = 1;
- if (x < cdriver.center)
- *flag_x = -1;
- if (y1 < cdriver.center)
- *flag_y1 = -1;
- if (y2 < cdriver.center)
- *flag_y2 = -1;
- return YAS_NO_ERROR;
- }
- static int
- yas_cdrv_measure_and_set_offset(int8_t *offset)
- {
- int i;
- int8_t offset_x = 0, offset_y1 = 0, offset_y2 = 0;
- int flag_x = 0, flag_y1 = 0, flag_y2 = 0;
- static const int correct[5] = {16, 8, 4, 2, 1};
- for (i = 0; i < 5; i++) {
- if (check_offset(offset_x, offset_y1, offset_y2,
- &flag_x, &flag_y1, &flag_y2) < 0) {
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- YLOGD(("offset[%d][%d][%d] flag[%d][%d][%d]\n",
- offset_x, offset_y1, offset_y2,
- flag_x, flag_y1, flag_y2));
- if (flag_x)
- offset_x = (int8_t)(offset_x + flag_x * correct[i]);
- if (flag_y1)
- offset_y1 = (int8_t)(offset_y1 + flag_y1 * correct[i]);
- if (flag_y2)
- offset_y2 = (int8_t)(offset_y2 + flag_y2 * correct[i]);
- }
- if (set_hardware_offset(offset_x, offset_y1, offset_y2) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- offset[0] = offset_x;
- offset[1] = offset_y1;
- offset[2] = offset_y2;
- return YAS_NO_ERROR;
- }
- static int
- yas_cdrv_set_offset(const int8_t *offset)
- {
- if (set_hardware_offset(offset[0], offset[1], offset[2]) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- return YAS_NO_ERROR;
- }
- static int
- yas_cdrv_measure(int32_t *data, int32_t *raw, int16_t *temperature)
- {
- int busy;
- int16_t x, y1, y2, t;
- int32_t xx, yy1, yy2;
- int result = 0;
- if (measure_normal(&busy, &t, &x, &y1, &y2) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (x == 0)
- result |= 0x01;
- if (x == cdriver.overflow)
- result |= 0x02;
- if (y1 == 0)
- result |= 0x04;
- if (y1 == cdriver.overflow)
- result |= 0x08;
- if (y2 == 0)
- result |= 0x10;
- if (y2 == cdriver.overflow)
- result |= 0x20;
- xx = x;
- yy1 = y1;
- yy2 = y2;
- if (coordinate_conversion(xx, yy1, yy2, t, &data[0], &data[1],
- &data[2], &cdriver.correct) < 0) {
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- cdriver.temperature = t;
- if (raw != NULL)
- raw[0] = xx, raw[1] = yy1, raw[2] = yy2;
- if (temperature != NULL)
- *temperature = t;
- return result;
- }
- static int
- yas_cdrv_recalc_calib_offset(int32_t *prev_calib_offset,
- int32_t *new_calib_offset, int8_t *prev_offset,
- int8_t *new_offset)
- {
- int32_t tmp[3], resolution[9], base[3];
- int32_t raw[3];
- int32_t diff, i;
- if (prev_calib_offset == NULL || new_calib_offset == NULL
- || prev_offset == NULL || new_offset == NULL) {
- return YAS_ERROR_ARG;
- }
- raw[0] = raw[1] = raw[2] = 0;
- if (coordinate_conversion(raw[0], raw[1], raw[2], cdriver.temperature,
- &base[0], &base[1], &base[2],
- &cdriver.correct) < 0) {
- return YAS_ERROR_ERROR;
- }
- for (i = 0; i < 3; i++) {
- raw[0] = raw[1] = raw[2] = 0;
- raw[i] = cdriver.coef;
- if (coordinate_conversion(raw[0], raw[1], raw[2],
- cdriver.temperature,
- &resolution[i*3 + 0],
- &resolution[i*3 + 1],
- &resolution[i*3 + 2],
- &cdriver.correct) < 0) {
- return YAS_ERROR_ERROR;
- }
- resolution[i*3 + 0] -= base[0];
- resolution[i*3 + 1] -= base[1];
- resolution[i*3 + 2] -= base[2];
- }
- for (i = 0; i < 3; i++)
- tmp[i] = prev_calib_offset[i];
- for (i = 0; i < 3; i++) {
- diff = (int32_t)new_offset[i] - (int32_t)prev_offset[i];
- while (diff > 0) {
- tmp[0] -= resolution[i*3 + 0];
- tmp[1] -= resolution[i*3 + 1];
- tmp[2] -= resolution[i*3 + 2];
- diff--;
- }
- while (diff < 0) {
- tmp[0] += resolution[i*3 + 0];
- tmp[1] += resolution[i*3 + 1];
- tmp[2] += resolution[i*3 + 2];
- diff++;
- }
- }
- for (i = 0; i < 3; i++)
- new_calib_offset[i] = tmp[i];
- return YAS_NO_ERROR;
- }
- static int
- yas_cdrv_set_transformatiom_matrix(const int8_t *transform)
- {
- int i;
- if (transform == NULL)
- return YAS_ERROR_ARG;
- for (i = 0; i < 9; i++)
- cdriver.transform[i] = transform[i];
- return YAS_NO_ERROR;
- }
- static int
- yas_cdrv_init(const int8_t *transform, struct yas_machdep_func *func)
- {
- int interval, i;
- uint8_t id;
- if (transform == NULL || func == NULL)
- return YAS_ERROR_ARG;
- for (i = 0; i < 9; i++)
- cdriver.transform[i] = transform[i];
- cdriver.func = *func;
- if (device_open() < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (init_test_register() < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (get_device_id(&id) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- YLOGD(("device id:%02x\n", id));
- switch (id) {
- case YAS_YAS530_DEVICE_ID:
- if (get_cal_data_yas530(&cdriver.cal) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- get_correction_value_yas530(&cdriver.cal, &cdriver.correct);
- cdriver.center = YAS_YAS530_DATA_CENTER;
- cdriver.overflow = YAS_YAS530_DATA_OVERFLOW;
- switch (cdriver.cal.ver) {
- case YAS_YAS530_VERSION_B:
- cdriver.coef = YAS_YAS530_VERSION_B_COEF;
- break;
- case YAS_YAS530_VERSION_A:
- default:
- cdriver.coef = YAS_YAS530_VERSION_A_COEF;
- break;
- }
- break;
- case YAS_YAS532_DEVICE_ID:
- if (get_cal_data_yas532(&cdriver.cal) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- get_correction_value_yas532(&cdriver.cal, &cdriver.correct);
- cdriver.center = YAS_YAS532_DATA_CENTER;
- cdriver.overflow = YAS_YAS532_DATA_OVERFLOW;
- switch (cdriver.cal.ver) {
- case YAS_YAS532_VERSION_AC:
- cdriver.coef = YAS_YAS532_VERSION_AC_COEF;
- break;
- case YAS_YAS532_VERSION_AB:
- default:
- cdriver.coef = YAS_YAS532_VERSION_AB_COEF;
- break;
- }
- break;
- default:
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- cdriver.dev_id = id;
- YLOGD(("%s %s\n",
- cdriver.dev_id == YAS_YAS532_DEVICE_ID
- ? "MS-3R" : "MS-3E",
- cdriver.cal.ver == YAS_YAS532_VERSION_AC
- ? "ACver" : "ABver"));
- YLOGD(("dx[%d] dy1[%d] dy2[%d] d2[%d] d3[%d] d4[%d] d5[%d] d6[%d] "
- "d7[%d] d8[%d] d9[%d] d0[%d] dck[%d] "
- "ver[%d]\n",
- cdriver.cal.dx, cdriver.cal.dy1, cdriver.cal.dy2,
- cdriver.cal.d2, cdriver.cal.d3, cdriver.cal.d4,
- cdriver.cal.d5, cdriver.cal.d6, cdriver.cal.d7,
- cdriver.cal.d8, cdriver.cal.d9, cdriver.cal.d0,
- cdriver.cal.dck, cdriver.cal.ver));
- YLOGD(("Cx[%4d] Cy1[%4d] Cy2[%4d] a2[%4d] a3[%4d] a4[%4d] a5[%4d] "
- "a6[%4d] a7[%4d] a8[%4d] a9[%4d] k[%4d]\n",
- cdriver.correct.Cx, cdriver.correct.Cy1,
- cdriver.correct.Cy2, cdriver.correct.a2,
- cdriver.correct.a3, cdriver.correct.a4,
- cdriver.correct.a5, cdriver.correct.a6,
- cdriver.correct.a7, cdriver.correct.a8,
- cdriver.correct.a9, cdriver.correct.k));
- if (set_configuration(0, 0, cdriver.cal.dck) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (set_measure_interval(0) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (get_measure_interval(&interval) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- YLOGD(("interval[%d]\n", interval));
- return YAS_NO_ERROR;
- }
- static int
- yas_cdrv_term(void)
- {
- device_close();
- return YAS_NO_ERROR;
- }
- #define YAS_DEFAULT_CALIB_INTERVAL (50) /* 50 msecs */
- #define YAS_DEFAULT_DATA_INTERVAL (200) /* 200 msecs */
- #define YAS_INITCOIL_INTERVAL (3000) /* 3 seconds */
- #define YAS_INITCOIL_GIVEUP_INTERVAL (180000) /* 180 seconds */
- #define YAS_DETECT_OVERFLOW_INTERVAL (0) /* 0 second */
- #define YAS_MAG_ERROR_DELAY (200)
- #define YAS_MAG_STATE_NORMAL (0)
- #define YAS_MAG_STATE_INIT_COIL (1)
- #define YAS_MAG_STATE_MEASURE_OFFSET (2)
- static const int8_t YAS_TRANSFORMATION[][9] = {
- { 0, 1, 0, -1, 0, 0, 0, 0, 1 },
- {-1, 0, 0, 0, -1, 0, 0, 0, 1 },
- { 0, -1, 0, 1, 0, 0, 0, 0, 1 },
- { 1, 0, 0, 0, 1, 0, 0, 0, 1 },
- { 0, -1, 0, -1, 0, 0, 0, 0, -1 },
- { 1, 0, 0, 0, -1, 0, 0, 0, -1 },
- { 0, 1, 0, 1, 0, 0, 0, 0, -1 },
- {-1, 0, 0, 0, 1, 0, 0, 0, -1 },
- };
- static const int supported_data_interval[] = {10, 20, 50, 60, 100, 200, 1000};
- static const int supported_calib_interval[] = {60, 60, 50, 60, 50, 50, 50};
- static const int32_t INVALID_CALIB_OFFSET[]
- = {0x7fffffff, 0x7fffffff, 0x7fffffff};
- static const int8_t INVALID_OFFSET[] = {0x7f, 0x7f, 0x7f};
- struct yas_adaptive_filter {
- int num;
- int index;
- int filter_len;
- int filter_noise;
- int32_t sequence[YAS_MAG_MAX_FILTER_LEN];
- };
- struct yas_thresh_filter {
- int32_t threshold;
- int32_t last;
- };
- struct yas_driver {
- int initialized;
- struct yas_mag_driver_callback callback;
- struct utimer data_timer;
- struct utimer initcoil_timer;
- struct utimer initcoil_giveup_timer;
- struct utimer detect_overflow_timer;
- int32_t prev_mag[3];
- int32_t prev_xy1y2[3];
- int32_t prev_mag_w_offset[3];
- int16_t prev_temperature;
- int measure_state;
- int active;
- int overflow;
- int initcoil_gaveup;
- int position;
- int delay_timer_use_data;
- int delay_timer_interval;
- int delay_timer_counter;
- int filter_enable;
- int filter_len;
- int filter_thresh;
- int filter_noise[3];
- struct yas_adaptive_filter adap_filter[3];
- struct yas_thresh_filter thresh_filter[3];
- struct yas_mag_offset offset;
- #ifdef YAS_MAG_MANUAL_OFFSET
- struct yas_vector manual_offset;
- #endif
- struct yas_matrix static_matrix;
- struct yas_matrix dynamic_matrix;
- };
- static struct yas_driver this_driver;
- static int
- lock(void)
- {
- if (this_driver.callback.lock != NULL) {
- if (this_driver.callback.lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- }
- return 0;
- }
- static int
- unlock(void)
- {
- if (this_driver.callback.unlock != NULL) {
- if (this_driver.callback.unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- }
- return 0;
- }
- static int32_t
- square(int32_t data)
- {
- return data * data;
- }
- static void
- adaptive_filter_init(struct yas_adaptive_filter *adap_filter, int len,
- int noise)
- {
- int i;
- adap_filter->num = 0;
- adap_filter->index = 0;
- adap_filter->filter_noise = noise;
- adap_filter->filter_len = len;
- for (i = 0; i < adap_filter->filter_len; ++i)
- adap_filter->sequence[i] = 0;
- }
- static int32_t
- adaptive_filter_filter(struct yas_adaptive_filter *adap_filter, int32_t in)
- {
- int32_t avg, sum;
- int i;
- if (adap_filter->filter_len == 0)
- return in;
- if (adap_filter->num < adap_filter->filter_len) {
- adap_filter->sequence[adap_filter->index++] = in / 100;
- adap_filter->num++;
- return in;
- }
- if (adap_filter->filter_len <= adap_filter->index)
- adap_filter->index = 0;
- adap_filter->sequence[adap_filter->index++] = in / 100;
- avg = 0;
- for (i = 0; i < adap_filter->filter_len; i++)
- avg += adap_filter->sequence[i];
- avg /= adap_filter->filter_len;
- sum = 0;
- for (i = 0; i < adap_filter->filter_len; i++)
- sum += square(avg - adap_filter->sequence[i]);
- sum /= adap_filter->filter_len;
- if (sum <= adap_filter->filter_noise)
- return avg * 100;
- return ((in/100 - avg) * (sum - adap_filter->filter_noise) / sum + avg)
- * 100;
- }
- static void
- thresh_filter_init(struct yas_thresh_filter *thresh_filter, int threshold)
- {
- thresh_filter->threshold = threshold;
- thresh_filter->last = 0;
- }
- static int32_t
- thresh_filter_filter(struct yas_thresh_filter *thresh_filter, int32_t in)
- {
- if (in < thresh_filter->last - thresh_filter->threshold
- || thresh_filter->last
- + thresh_filter->threshold < in) {
- thresh_filter->last = in;
- return in;
- } else {
- return thresh_filter->last;
- }
- }
- static void
- filter_init(struct yas_driver *d)
- {
- int i;
- for (i = 0; i < 3; i++) {
- adaptive_filter_init(&d->adap_filter[i], d->filter_len,
- d->filter_noise[i]);
- thresh_filter_init(&d->thresh_filter[i], d->filter_thresh);
- }
- }
- static void
- filter_filter(struct yas_driver *d, int32_t *orig, int32_t *filtered)
- {
- int i;
- for (i = 0; i < 3; i++) {
- filtered[i] = adaptive_filter_filter(&d->adap_filter[i],
- orig[i]);
- filtered[i] = thresh_filter_filter(&d->thresh_filter[i],
- filtered[i]);
- }
- }
- static int
- is_valid_offset(const int8_t *p)
- {
- return p != NULL && (p[0] <= 31) && (p[1] <= 31) && (p[2] <= 31)
- && (-31 <= p[0]) && (-31 <= p[1]) && (-31 <= p[2]);
- }
- int
- is_valid_calib_offset(const int32_t *p)
- {
- int i;
- for (i = 0; i < 3; i++) {
- if (p[i] != INVALID_CALIB_OFFSET[i])
- return 1;
- }
- return 0;
- }
- static int
- is_offset_differ(const int8_t *p0, const int8_t *p1)
- {
- return p0[0] != p1[0] || p0[1] != p1[1] || p0[2] != p1[2];
- }
- static int
- is_calib_offset_differ(const int32_t *p0, const int32_t *p1)
- {
- return p0[0] != p1[0] || p0[1] != p1[1] || p0[2] != p1[2];
- }
- static int
- get_overflow(struct yas_driver *d)
- {
- return d->overflow;
- }
- static void
- set_overflow(struct yas_driver *d, const int overflow)
- {
- if (d->overflow != overflow)
- d->overflow = overflow;
- }
- static int
- get_initcoil_gaveup(struct yas_driver *d)
- {
- return d->initcoil_gaveup;
- }
- static void
- set_initcoil_gaveup(struct yas_driver *d, const int initcoil_gaveup)
- {
- d->initcoil_gaveup = initcoil_gaveup;
- }
- static int32_t *
- get_calib_offset(struct yas_driver *d)
- {
- return d->offset.calib_offset.v;
- }
- static void
- set_calib_offset(struct yas_driver *d, const int32_t *offset)
- {
- int i;
- if (is_calib_offset_differ(d->offset.calib_offset.v, offset)) {
- for (i = 0; i < 3; i++)
- d->offset.calib_offset.v[i] = offset[i];
- }
- }
- #ifdef YAS_MAG_MANUAL_OFFSET
- static int32_t *
- get_manual_offset(struct yas_driver *d)
- {
- return d->manual_offset.v;
- }
- static void
- set_manual_offset(struct yas_driver *d, const int32_t *offset)
- {
- int i;
- for (i = 0; i < 3; i++)
- d->manual_offset.v[i] = offset[i];
- }
- #endif
- static int32_t *
- get_static_matrix(struct yas_driver *d)
- {
- return d->static_matrix.matrix;
- }
- static void
- set_static_matrix(struct yas_driver *d, const int32_t *matrix)
- {
- int i;
- for (i = 0; i < 9; i++)
- d->static_matrix.matrix[i] = matrix[i];
- }
- static int32_t *
- get_dynamic_matrix(struct yas_driver *d)
- {
- return d->dynamic_matrix.matrix;
- }
- static void
- set_dynamic_matrix(struct yas_driver *d, const int32_t *matrix)
- {
- int i;
- for (i = 0; i < 9; i++)
- d->dynamic_matrix.matrix[i] = matrix[i];
- }
- static int8_t *
- get_offset(struct yas_driver *d)
- {
- return d->offset.hard_offset;
- }
- static void
- set_offset(struct yas_driver *d, const int8_t *offset)
- {
- int i;
- if (is_offset_differ(d->offset.hard_offset, offset)) {
- for (i = 0; i < 3; i++)
- d->offset.hard_offset[i] = offset[i];
- }
- }
- static int
- get_active(struct yas_driver *d)
- {
- return d->active;
- }
- static void
- set_active(struct yas_driver *d, const int active)
- {
- d->active = active;
- }
- static int
- get_position(struct yas_driver *d)
- {
- return d->position;
- }
- static void
- set_position(struct yas_driver *d, const int position)
- {
- d->position = position;
- }
- static int
- get_measure_state(struct yas_driver *d)
- {
- return d->measure_state;
- }
- static void
- set_measure_state(struct yas_driver *d, const int state)
- {
- YLOGI(("state(%d)\n", state));
- d->measure_state = state;
- }
- static struct utimer *
- get_data_timer(struct yas_driver *d)
- {
- return &d->data_timer;
- }
- static struct utimer *
- get_initcoil_timer(struct yas_driver *d)
- {
- return &d->initcoil_timer;
- }
- static struct utimer *
- get_initcoil_giveup_timer(struct yas_driver *d)
- {
- return &d->initcoil_giveup_timer;
- }
- static struct utimer *
- get_detect_overflow_timer(struct yas_driver *d)
- {
- return &d->detect_overflow_timer;
- }
- static int
- get_delay_timer_use_data(struct yas_driver *d)
- {
- return d->delay_timer_use_data;
- }
- static void
- set_delay_timer_use_data(struct yas_driver *d, int flag)
- {
- d->delay_timer_use_data = !!flag;
- }
- static int
- get_delay_timer_interval(struct yas_driver *d)
- {
- return d->delay_timer_interval;
- }
- static void
- set_delay_timer_interval(struct yas_driver *d, int interval)
- {
- d->delay_timer_interval = interval;
- }
- static int
- get_delay_timer_counter(struct yas_driver *d)
- {
- return d->delay_timer_counter;
- }
- static void
- set_delay_timer_counter(struct yas_driver *d, int counter)
- {
- d->delay_timer_counter = counter;
- }
- static int
- get_filter_enable(struct yas_driver *d)
- {
- return d->filter_enable;
- }
- static void
- set_filter_enable(struct yas_driver *d, int enable)
- {
- if (enable)
- filter_init(d);
- d->filter_enable = !!enable;
- }
- static int
- get_filter_len(struct yas_driver *d)
- {
- return d->filter_len;
- }
- static void
- set_filter_len(struct yas_driver *d, int len)
- {
- if (len < 0)
- return;
- if (len > YAS_MAG_MAX_FILTER_LEN)
- return;
- d->filter_len = len;
- filter_init(d);
- }
- static int
- get_filter_noise(struct yas_driver *d, int *noise)
- {
- int i;
- for (i = 0; i < 3; i++)
- noise[i] = d->filter_noise[i];
- return 0;
- }
- static void
- set_filter_noise(struct yas_driver *d, int *noise)
- {
- int i;
- if (noise == NULL)
- return;
- for (i = 0; i < 3; i++) {
- if (noise[i] < 0)
- noise[i] = 0;
- d->filter_noise[i] = noise[i];
- }
- filter_init(d);
- }
- static int
- get_filter_thresh(struct yas_driver *d)
- {
- return d->filter_thresh;
- }
- static void
- set_filter_thresh(struct yas_driver *d, int threshold)
- {
- if (threshold < 0)
- return;
- d->filter_thresh = threshold;
- filter_init(d);
- }
- static int32_t*
- get_previous_mag(struct yas_driver *d)
- {
- return d->prev_mag;
- }
- static void
- set_previous_mag(struct yas_driver *d, int32_t *data)
- {
- int i;
- for (i = 0; i < 3; i++)
- d->prev_mag[i] = data[i];
- }
- static int32_t*
- get_previous_xy1y2(struct yas_driver *d)
- {
- return d->prev_xy1y2;
- }
- static void
- set_previous_xy1y2(struct yas_driver *d, int32_t *data)
- {
- int i;
- for (i = 0; i < 3; i++)
- d->prev_xy1y2[i] = data[i];
- }
- static int32_t*
- get_previous_mag_w_offset(struct yas_driver *d)
- {
- return d->prev_mag_w_offset;
- }
- static void
- set_previous_mag_w_offset(struct yas_driver *d, int32_t *data)
- {
- int i;
- for (i = 0; i < 3; i++)
- d->prev_mag_w_offset[i] = data[i];
- }
- static int16_t
- get_previous_temperature(struct yas_driver *d)
- {
- return d->prev_temperature;
- }
- static void
- set_previous_temperature(struct yas_driver *d, int16_t temperature)
- {
- d->prev_temperature = temperature;
- }
- static int
- init_coil(struct yas_driver *d)
- {
- int rt;
- YLOGD(("init_coil IN\n"));
- utimer_update(get_initcoil_timer(d));
- if (!get_initcoil_gaveup(d)) {
- utimer_update(get_initcoil_giveup_timer(d));
- if (utimer_is_timeout(get_initcoil_giveup_timer(d))) {
- utimer_clear_timeout(get_initcoil_giveup_timer(d));
- set_initcoil_gaveup(d, TRUE);
- }
- }
- if (utimer_is_timeout(get_initcoil_timer(d))
- && !get_initcoil_gaveup(d)) {
- utimer_clear_timeout(get_initcoil_timer(d));
- YLOGI(("init_coil!\n"));
- rt = yas_cdrv_actuate_initcoil();
- if (rt < 0) {
- YLOGE(("yas_cdrv_actuate_initcoil failed[%d]\n", rt));
- return rt;
- }
- if (get_overflow(d) || !is_valid_offset(get_offset(d)))
- set_measure_state(d, YAS_MAG_STATE_MEASURE_OFFSET);
- else
- set_measure_state(d, YAS_MAG_STATE_NORMAL);
- }
- YLOGD(("init_coil OUT\n"));
- return 0;
- }
- static int
- measure_offset(struct yas_driver *d)
- {
- int8_t offset[3];
- int32_t moffset[3];
- int rt, result = 0, i;
- YLOGI(("measure_offset IN\n"));
- rt = yas_cdrv_measure_and_set_offset(offset);
- if (rt < 0) {
- YLOGE(("yas_cdrv_measure_offset failed[%d]\n", rt));
- return rt;
- }
- YLOGI(("offset[%d][%d][%d]\n", offset[0], offset[1], offset[2]));
- for (i = 0; i < 3; i++)
- moffset[i] = get_calib_offset(d)[i];
- if (is_offset_differ(get_offset(d), offset)) {
- if (is_valid_offset(get_offset(d))
- && is_valid_calib_offset(get_calib_offset(d))) {
- yas_cdrv_recalc_calib_offset(get_calib_offset(d),
- moffset,
- get_offset(d),
- offset);
- result |= YAS_REPORT_CALIB_OFFSET_CHANGED;
- }
- }
- result |= YAS_REPORT_HARD_OFFSET_CHANGED;
- set_offset(d, offset);
- if (is_valid_calib_offset(moffset))
- set_calib_offset(d, moffset);
- set_measure_state(d, YAS_MAG_STATE_NORMAL);
- YLOGI(("measure_offset OUT\n"));
- return result;
- }
- static int
- measure_msensor_normal(struct yas_driver *d, int32_t *magnetic,
- int32_t *mag_w_offset, int32_t *xy1y2, int16_t *temperature)
- {
- int rt = 0, result, i;
- int32_t tmp[3];
- YLOGD(("measure_msensor_normal IN\n"));
- result = 0;
- rt = yas_cdrv_measure(mag_w_offset, tmp, temperature);
- if (rt < 0) {
- YLOGE(("yas_cdrv_measure failed[%d]\n", rt));
- return rt;
- }
- for (i = 0; i < 3; i++)
- xy1y2[i] = tmp[i];
- #ifdef YAS_MAG_MANUAL_OFFSET
- for (i = 0; i < 3; i++)
- mag_w_offset[i] -= get_manual_offset(d)[i];
- #endif
- if (rt > 0) {
- YLOGW(("yas_cdrv_measure under/overflow "
- "x[%c%c] y[%c%c] z[%c%c]\n",
- (rt&0x01) ? 'u' : ' ',
- (rt&0x02) ? 'o' : ' ',
- (rt&0x04) ? 'u' : ' ',
- (rt&0x08) ? 'o' : ' ',
- (rt&0x10) ? 'u' : ' ',
- (rt&0x20) ? 'o' : ' '));
- utimer_update(get_detect_overflow_timer(d));
- set_overflow(d, TRUE);
- if (utimer_is_timeout(get_detect_overflow_timer(d))) {
- utimer_clear_timeout(get_detect_overflow_timer(d));
- result |= YAS_REPORT_OVERFLOW_OCCURED;
- }
- if (get_measure_state(d) == YAS_MAG_STATE_NORMAL)
- set_measure_state(d, YAS_MAG_STATE_INIT_COIL);
- } else {
- utimer_clear(get_detect_overflow_timer(d));
- set_overflow(d, FALSE);
- if (get_measure_state(d) == YAS_MAG_STATE_NORMAL) {
- utimer_clear(get_initcoil_timer(d));
- utimer_clear(get_initcoil_giveup_timer(d));
- }
- }
- for (i = 0; i < 3; i++) {
- tmp[i]
- = (get_static_matrix(d)[i*3+0]/10
- * (mag_w_offset[0]/10)) / 100
- + (get_static_matrix(d)[i*3+1]/10
- * (mag_w_offset[1]/10)) / 100
- + (get_static_matrix(d)[i*3+2]/10
- * (mag_w_offset[2]/10)) / 100;
- }
- for (i = 0; i < 3; i++)
- magnetic[i] = mag_w_offset[i] = tmp[i];
- if (is_valid_calib_offset(get_calib_offset(d))) {
- for (i = 0; i < 3; i++)
- magnetic[i] -= get_calib_offset(d)[i];
- }
- for (i = 0; i < 3; i++) {
- tmp[i]
- = (get_dynamic_matrix(d)[i*3+0]/10
- * (magnetic[0]/10)) / 100
- + (get_dynamic_matrix(d)[i*3+1]/10
- * (magnetic[1]/10)) / 100
- + (get_dynamic_matrix(d)[i*3+2]/10
- * (magnetic[2]/10)) / 100;
- }
- for (i = 0; i < 3; i++)
- magnetic[i] = tmp[i];
- if (get_filter_enable(d))
- filter_filter(d, magnetic, magnetic);
- YLOGD(("measure_msensor_normal OUT\n"));
- return result;
- }
- static int
- measure_msensor(struct yas_driver *d, int32_t *magnetic, int32_t *mag_w_offset,
- int32_t *xy1y2, int16_t *temperature)
- {
- int result, i;
- YLOGD(("measure_msensor IN\n"));
- for (i = 0; i < 3; i++) {
- magnetic[i] = get_previous_mag(d)[i];
- mag_w_offset[i] = get_previous_mag_w_offset(d)[i];
- xy1y2[i] = get_previous_xy1y2(d)[i];
- *temperature = get_previous_temperature(d);
- }
- result = 0;
- switch (get_measure_state(d)) {
- case YAS_MAG_STATE_INIT_COIL:
- result = init_coil(d);
- break;
- case YAS_MAG_STATE_MEASURE_OFFSET:
- result = measure_offset(d);
- break;
- case YAS_MAG_STATE_NORMAL:
- result = 0;
- break;
- default:
- result = -1;
- break;
- }
- if (result < 0)
- return result;
- if (!(result & YAS_REPORT_OVERFLOW_OCCURED)) {
- result |= measure_msensor_normal(d, magnetic, mag_w_offset,
- xy1y2, temperature);
- }
- set_previous_mag(d, magnetic);
- set_previous_xy1y2(d, xy1y2);
- set_previous_mag_w_offset(d, mag_w_offset);
- set_previous_temperature(d, *temperature);
- YLOGD(("measure_msensor OUT\n"));
- return result;
- }
- static int
- measure(struct yas_driver *d, int32_t *magnetic, int32_t *mag_w_offset,
- int32_t *xy1y2, int16_t *temperature, uint32_t *time_delay)
- {
- int result;
- int counter;
- uint32_t total = 0;
- YLOGD(("measure IN\n"));
- utimer_update(get_data_timer(d));
- result = measure_msensor(d, magnetic, mag_w_offset, xy1y2, temperature);
- if (result < 0)
- return result;
- counter = get_delay_timer_counter(d);
- total = utimer_get_total_time(get_data_timer(d));
- if (utimer_get_delay(get_data_timer(d)) > 0)
- counter -= (int)(total / utimer_get_delay(get_data_timer(d)));
- else
- counter = 0;
- if (utimer_is_timeout(get_data_timer(d))) {
- utimer_clear_timeout(get_data_timer(d));
- if (get_delay_timer_use_data(d)) {
- result |= YAS_REPORT_DATA;
- if (counter <= 0)
- result |= YAS_REPORT_CALIB;
- } else {
- result |= YAS_REPORT_CALIB;
- if (counter <= 0)
- result |= YAS_REPORT_DATA;
- }
- }
- if (counter <= 0)
- set_delay_timer_counter(d, get_delay_timer_interval(d));
- else
- set_delay_timer_counter(d, counter);
- *time_delay = utimer_sleep_time(get_data_timer(d));
- YLOGD(("measure OUT [%d]\n", result));
- return result;
- }
- static int
- resume(struct yas_driver *d)
- {
- int32_t zero[] = {0, 0, 0};
- struct yas_machdep_func func;
- int rt;
- YLOGI(("resume IN\n"));
- func.device_open = d->callback.device_open;
- func.device_close = d->callback.device_close;
- func.device_write = d->callback.device_write;
- func.device_read = d->callback.device_read;
- func.msleep = d->callback.msleep;
- rt = yas_cdrv_init(YAS_TRANSFORMATION[get_position(d)], &func);
- if (rt < 0) {
- YLOGE(("yas_cdrv_init failed[%d]\n", rt));
- return rt;
- }
- utimer_clear(get_data_timer(d));
- utimer_clear(get_initcoil_giveup_timer(d));
- utimer_clear(get_initcoil_timer(d));
- utimer_clear(get_detect_overflow_timer(d));
- set_previous_mag(d, zero);
- set_previous_xy1y2(d, zero);
- set_previous_mag_w_offset(d, zero);
- set_previous_temperature(d, 0);
- set_overflow(d, FALSE);
- set_initcoil_gaveup(d, FALSE);
- filter_init(d);
- if (is_valid_offset(d->offset.hard_offset)) {
- yas_cdrv_set_offset(d->offset.hard_offset);
- rt = yas_cdrv_actuate_initcoil();
- if (rt < 0) {
- YLOGE(("yas_cdrv_actuate_initcoil failed[%d]\n", rt));
- set_measure_state(d, YAS_MAG_STATE_INIT_COIL);
- } else {
- set_measure_state(d, YAS_MAG_STATE_NORMAL);
- }
- } else {
- rt = yas_cdrv_actuate_initcoil();
- if (rt < 0) {
- YLOGE(("yas_cdrv_actuate_initcoil failed[%d]\n", rt));
- set_measure_state(d, YAS_MAG_STATE_INIT_COIL);
- } else {
- set_measure_state(d, YAS_MAG_STATE_MEASURE_OFFSET);
- }
- }
- YLOGI(("resume OUT\n"));
- return 0;
- }
- static int
- suspend(struct yas_driver *d)
- {
- YLOGI(("suspend IN\n"));
- (void) d;
- yas_cdrv_term();
- YLOGI(("suspend OUT\n"));
- return 0;
- }
- static int
- check_interval(int ms)
- {
- int index;
- if (ms <= supported_data_interval[0])
- ms = supported_data_interval[0];
- for (index = 0; index < NELEMS(supported_data_interval); index++) {
- if (ms == supported_data_interval[index])
- return index;
- }
- return -1;
- }
- static int
- yas_get_delay_nolock(struct yas_driver *d, int *ms)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- if (get_delay_timer_use_data(d))
- *ms = (int)utimer_get_delay(get_data_timer(d));
- else
- *ms = (int)utimer_get_delay(get_data_timer(d))
- * get_delay_timer_interval(d);
- return YAS_NO_ERROR;
- }
- static int
- yas_set_delay_nolock(struct yas_driver *d, int ms)
- {
- int index;
- uint32_t delay_data, delay_calib;
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- index = check_interval(ms);
- if (index < 0)
- return YAS_ERROR_ARG;
- delay_data = (uint32_t)supported_data_interval[index];
- delay_calib = (uint32_t)supported_calib_interval[index];
- set_delay_timer_use_data(d, delay_data < delay_calib);
- if (delay_data < delay_calib) {
- set_delay_timer_interval(d, (int)(delay_calib / delay_data));
- set_delay_timer_counter(d, (int)(delay_calib / delay_data));
- utimer_set_delay(get_data_timer(d),
- (uint32_t)supported_data_interval[index]);
- } else {
- set_delay_timer_interval(d, (int)(delay_data / delay_calib));
- set_delay_timer_counter(d, (int)(delay_data / delay_calib));
- utimer_set_delay(get_data_timer(d),
- (uint32_t)supported_calib_interval[index]);
- }
- return YAS_NO_ERROR;
- }
- static int
- yas_get_offset_nolock(struct yas_driver *d, struct yas_mag_offset *offset)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- *offset = d->offset;
- return YAS_NO_ERROR;
- }
- static int
- yas_set_offset_nolock(struct yas_driver *d, struct yas_mag_offset *offset)
- {
- int32_t zero[] = {0, 0, 0};
- int rt;
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- if (!get_active(d)) {
- d->offset = *offset;
- return YAS_NO_ERROR;
- }
- if (!is_valid_offset(offset->hard_offset)
- || is_offset_differ(offset->hard_offset,
- d->offset.hard_offset)) {
- filter_init(d);
- utimer_clear(get_data_timer(d));
- utimer_clear(get_initcoil_giveup_timer(d));
- utimer_clear(get_initcoil_timer(d));
- utimer_clear(get_detect_overflow_timer(d));
- set_previous_mag(d, zero);
- set_previous_xy1y2(d, zero);
- set_previous_mag_w_offset(d, zero);
- set_previous_temperature(d, 0);
- set_overflow(d, FALSE);
- set_initcoil_gaveup(d, FALSE);
- }
- d->offset = *offset;
- if (is_valid_offset(d->offset.hard_offset)) {
- yas_cdrv_set_offset(d->offset.hard_offset);
- } else {
- rt = yas_cdrv_actuate_initcoil();
- if (rt < 0) {
- YLOGE(("yas_cdrv_actuate_initcoil failed[%d]\n", rt));
- set_measure_state(d, YAS_MAG_STATE_INIT_COIL);
- } else {
- set_measure_state(d, YAS_MAG_STATE_MEASURE_OFFSET);
- }
- }
- return YAS_NO_ERROR;
- }
- #ifdef YAS_MAG_MANUAL_OFFSET
- static int
- yas_get_manual_offset_nolock(struct yas_driver *d, struct yas_vector *offset)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- *offset = d->manual_offset;
- return YAS_NO_ERROR;
- }
- static int
- yas_set_manual_offset_nolock(struct yas_driver *d, struct yas_vector *offset)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- set_manual_offset(d, offset->v);
- return YAS_NO_ERROR;
- }
- #endif
- static int
- yas_get_static_matrix_nolock(struct yas_driver *d, struct yas_matrix *matrix)
- {
- int i;
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- for (i = 0; i < 9; i++)
- matrix->matrix[i] = get_static_matrix(d)[i];
- return YAS_NO_ERROR;
- }
- static int
- yas_set_static_matrix_nolock(struct yas_driver *d, struct yas_matrix *matrix)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- set_static_matrix(d, matrix->matrix);
- return YAS_NO_ERROR;
- }
- static int
- yas_get_dynamic_matrix_nolock(struct yas_driver *d, struct yas_matrix *matrix)
- {
- int i;
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- for (i = 0; i < 9; i++)
- matrix->matrix[i] = get_dynamic_matrix(d)[i];
- return YAS_NO_ERROR;
- }
- static int
- yas_set_dynamic_matrix_nolock(struct yas_driver *d, struct yas_matrix *matrix)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- set_dynamic_matrix(d, matrix->matrix);
- return YAS_NO_ERROR;
- }
- static int
- yas_get_enable_nolock(struct yas_driver *d)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- return get_active(d);
- }
- static int
- yas_set_enable_nolock(struct yas_driver *d, int active)
- {
- int rt;
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- if (active) {
- if (get_active(d))
- return YAS_NO_ERROR;
- rt = resume(d);
- if (rt < 0)
- return rt;
- set_active(d, TRUE);
- } else {
- if (!get_active(d))
- return YAS_NO_ERROR;
- rt = suspend(d);
- if (rt < 0)
- return rt;
- set_active(d, FALSE);
- }
- return YAS_NO_ERROR;
- }
- static int
- yas_get_filter_nolock(struct yas_driver *d, struct yas_mag_filter *filter)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- filter->len = get_filter_len(d);
- get_filter_noise(d, filter->noise);
- filter->threshold = get_filter_thresh(d);
- return YAS_NO_ERROR;
- }
- static int
- yas_set_filter_nolock(struct yas_driver *d, struct yas_mag_filter *filter)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- set_filter_len(d, filter->len);
- set_filter_noise(d, filter->noise);
- set_filter_thresh(d, filter->threshold);
- return YAS_NO_ERROR;
- }
- static int
- yas_get_filter_enable_nolock(struct yas_driver *d)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- return get_filter_enable(d);
- }
- static int
- yas_set_filter_enable_nolock(struct yas_driver *d, int enable)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- set_filter_enable(d, enable);
- return YAS_NO_ERROR;
- }
- static int
- yas_get_position_nolock(struct yas_driver *d, int *position)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- *position = get_position(d);
- return YAS_NO_ERROR;
- }
- static int
- yas_set_position_nolock(struct yas_driver *d, int position)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- if (get_active(d))
- yas_cdrv_set_transformatiom_matrix(
- YAS_TRANSFORMATION[position]);
- set_position(d, position);
- filter_init(d);
- return YAS_NO_ERROR;
- }
- static int
- yas_read_reg_nolock(struct yas_driver *d, uint8_t addr, uint8_t *buf, int len)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- if (!get_active(d)) {
- if (d->callback.device_open() < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- if (d->callback.device_read(YAS_MAG_I2C_SLAVEADDR, addr, buf, len) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (!get_active(d)) {
- if (d->callback.device_close() < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- return YAS_NO_ERROR;
- }
- static int
- yas_write_reg_nolock(struct yas_driver *d, uint8_t addr, const uint8_t *buf,
- int len)
- {
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- if (!get_active(d)) {
- if (d->callback.device_open() < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- if (d->callback.device_write(YAS_MAG_I2C_SLAVEADDR, addr, buf, len) < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- if (!get_active(d)) {
- if (d->callback.device_close() < 0)
- return YAS_ERROR_DEVICE_COMMUNICATION;
- }
- return YAS_NO_ERROR;
- }
- static int
- yas_measure_nolock(struct yas_driver *d, struct yas_mag_data *data,
- int *time_delay_ms)
- {
- uint32_t time_delay = YAS_MAG_ERROR_DELAY;
- int rt, i;
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- *time_delay_ms = YAS_MAG_ERROR_DELAY;
- if (!get_active(d)) {
- for (i = 0; i < 3; i++) {
- data->xyz.v[i] = get_previous_mag(d)[i];
- data->raw.v[i] = get_previous_mag_w_offset(d)[i];
- data->xy1y2.v[i] = get_previous_xy1y2(d)[i];
- }
- data->temperature = get_previous_temperature(d);
- return YAS_NO_ERROR;
- }
- rt = measure(d, data->xyz.v, data->raw.v, data->xy1y2.v,
- &data->temperature, &time_delay);
- if (rt >= 0) {
- *time_delay_ms = (int)time_delay;
- if (*time_delay_ms > 0)
- *time_delay_ms += 1; /* for the system that the time is
- in usec unit */
- }
- return rt;
- }
- static int
- yas_init_nolock(struct yas_driver *d)
- {
- #ifdef YAS_MAG_MANUAL_OFFSET
- int32_t zero[] = {0, 0, 0};
- #endif
- int32_t notransform[] = {10000, 0, 0, 0, 10000, 0, 0, 0, 10000};
- int noise[] = {
- YAS_MAG_DEFAULT_FILTER_NOISE_X,
- YAS_MAG_DEFAULT_FILTER_NOISE_Y,
- YAS_MAG_DEFAULT_FILTER_NOISE_Z
- };
- YLOGI(("yas_init_nolock IN\n"));
- if (d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- utimer_lib_init(this_driver.callback.current_time);
- utimer_init(get_data_timer(d), 50);
- utimer_init(get_initcoil_timer(d), YAS_INITCOIL_INTERVAL);
- utimer_init(get_initcoil_giveup_timer(d), YAS_INITCOIL_GIVEUP_INTERVAL);
- utimer_init(get_detect_overflow_timer(d), YAS_DETECT_OVERFLOW_INTERVAL);
- set_delay_timer_use_data(d, 0);
- set_delay_timer_interval(d,
- YAS_DEFAULT_DATA_INTERVAL / YAS_DEFAULT_CALIB_INTERVAL);
- set_delay_timer_counter(d,
- YAS_DEFAULT_DATA_INTERVAL / YAS_DEFAULT_CALIB_INTERVAL);
- set_filter_enable(d, FALSE);
- set_filter_len(d, YAS_MAG_DEFAULT_FILTER_LEN);
- set_filter_thresh(d, YAS_MAG_DEFAULT_FILTER_THRESH);
- set_filter_noise(d, noise);
- filter_init(d);
- set_calib_offset(d, INVALID_CALIB_OFFSET);
- #ifdef YAS_MAG_MANUAL_OFFSET
- set_manual_offset(d, zero);
- #endif
- set_static_matrix(d, notransform);
- set_dynamic_matrix(d, notransform);
- set_offset(d, INVALID_OFFSET);
- set_active(d, FALSE);
- set_position(d, 0);
- d->initialized = 1;
- YLOGI(("yas_init_nolock OUT\n"));
- return YAS_NO_ERROR;
- }
- static int
- yas_term_nolock(struct yas_driver *d)
- {
- YLOGI(("yas_term_nolock\n"));
- if (!d->initialized)
- return YAS_ERROR_NOT_INITIALIZED;
- if (get_active(d))
- suspend(d);
- d->initialized = 0;
- YLOGI(("yas_term_nolock out\n"));
- return YAS_NO_ERROR;
- }
- static int
- yas_get_delay(void)
- {
- int ms = 0, rt;
- YLOGI(("yas_get_delay\n"));
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_get_delay_nolock(&this_driver, &ms);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_get_delay[%d] OUT\n", ms));
- return rt < 0 ? rt : ms;
- }
- static int
- yas_set_delay(int delay)
- {
- int rt;
- YLOGI(("yas_set_delay\n"));
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_set_delay_nolock(&this_driver, delay);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_set_delay OUT\n"));
- return rt;
- }
- static int
- yas_get_offset(struct yas_mag_offset *offset)
- {
- int rt;
- YLOGI(("yas_get_offset\n"));
- if (offset == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_get_offset_nolock(&this_driver, offset);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_get_offset[%d] OUT\n", rt));
- return rt;
- }
- static int
- yas_set_offset(struct yas_mag_offset *offset)
- {
- int rt;
- YLOGI(("yas_set_offset IN\n"));
- if (offset == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_set_offset_nolock(&this_driver, offset);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_set_offset OUT\n"));
- return rt;
- }
- #ifdef YAS_MAG_MANUAL_OFFSET
- static int
- yas_get_manual_offset(struct yas_vector *offset)
- {
- int rt;
- YLOGI(("yas_get_manual_offset\n"));
- if (offset == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_get_manual_offset_nolock(&this_driver, offset);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_get_manual_offset[%d] OUT\n", rt));
- return rt;
- }
- static int
- yas_set_manual_offset(struct yas_vector *offset)
- {
- int rt;
- YLOGI(("yas_set_manual_offset IN\n"));
- if (offset == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_set_manual_offset_nolock(&this_driver, offset);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_set_manual_offset OUT\n"));
- return rt;
- }
- #endif
- static int
- yas_get_static_matrix(struct yas_matrix *matrix)
- {
- int rt;
- YLOGI(("yas_get_static_matrix\n"));
- if (matrix == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_get_static_matrix_nolock(&this_driver, matrix);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_get_static_matrix[%d] OUT\n", rt));
- return rt;
- }
- static int
- yas_set_static_matrix(struct yas_matrix *matrix)
- {
- int rt;
- YLOGI(("yas_set_static_matrix IN\n"));
- if (matrix == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_set_static_matrix_nolock(&this_driver, matrix);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_set_static_matrix OUT\n"));
- return rt;
- }
- static int
- yas_get_dynamic_matrix(struct yas_matrix *matrix)
- {
- int rt;
- YLOGI(("yas_get_dynamic_matrix\n"));
- if (matrix == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_get_dynamic_matrix_nolock(&this_driver, matrix);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_get_dynamic_matrix[%d] OUT\n", rt));
- return rt;
- }
- static int
- yas_set_dynamic_matrix(struct yas_matrix *matrix)
- {
- int rt;
- YLOGI(("yas_set_dynamic_matrix IN\n"));
- if (matrix == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_set_dynamic_matrix_nolock(&this_driver, matrix);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_set_dynamic_matrix OUT\n"));
- return rt;
- }
- static int
- yas_get_enable(void)
- {
- int rt;
- YLOGI(("yas_get_enable\n"));
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_get_enable_nolock(&this_driver);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_get_enable OUT[%d]\n", rt));
- return rt;
- }
- static int
- yas_set_enable(int enable)
- {
- int rt;
- YLOGI(("yas_set_enable IN\n"));
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_set_enable_nolock(&this_driver, enable);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_set_enable OUT\n"));
- return rt;
- }
- static int
- yas_get_filter(struct yas_mag_filter *filter)
- {
- int rt;
- YLOGI(("yas_get_filter\n"));
- if (filter == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_get_filter_nolock(&this_driver, filter);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_get_filter[%d] OUT\n", rt));
- return rt;
- }
- static int
- yas_set_filter(struct yas_mag_filter *filter)
- {
- int rt, i;
- YLOGI(("yas_set_filter IN\n"));
- if (filter == NULL
- || filter->len < 0
- || YAS_MAG_MAX_FILTER_LEN < filter->len
- || filter->threshold < 0) {
- return YAS_ERROR_ARG;
- }
- for (i = 0; i < 3; i++) {
- if (filter->noise[i] < 0)
- return YAS_ERROR_ARG;
- }
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_set_filter_nolock(&this_driver, filter);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_set_filter OUT\n"));
- return rt;
- }
- static int
- yas_get_filter_enable(void)
- {
- int rt;
- YLOGI(("yas_get_filter_enable\n"));
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_get_filter_enable_nolock(&this_driver);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_get_filter_enable OUT[%d]\n", rt));
- return rt;
- }
- static int
- yas_set_filter_enable(int enable)
- {
- int rt;
- YLOGI(("yas_set_filter_enable IN\n"));
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_set_filter_enable_nolock(&this_driver, enable);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_set_filter_enable OUT\n"));
- return rt;
- }
- static int
- yas_get_position(void)
- {
- int position = 0;
- int rt;
- YLOGI(("yas_get_position\n"));
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_get_position_nolock(&this_driver, &position);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_get_position[%d] OUT\n", position));
- return rt < 0 ? rt : position;
- }
- static int
- yas_set_position(int position)
- {
- int rt;
- YLOGI(("yas_set_position\n"));
- if (position < 0 || 7 < position)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_set_position_nolock(&this_driver, position);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_set_position[%d] OUT\n", position));
- return rt;
- }
- static int
- yas_read_reg(uint8_t addr, uint8_t *buf, int len)
- {
- int rt;
- YLOGI(("yas_read_reg\n"));
- if (buf == NULL || len <= 0)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_read_reg_nolock(&this_driver, addr, buf, len);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_read_reg[%d] OUT\n", rt));
- return rt;
- }
- static int
- yas_write_reg(uint8_t addr, const uint8_t *buf, int len)
- {
- int rt;
- YLOGI(("yas_write_reg\n"));
- if (buf == NULL || len <= 0)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_write_reg_nolock(&this_driver, addr, buf, len);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGI(("yas_write_reg[%d] OUT\n", rt));
- return rt;
- }
- static int
- yas_measure(struct yas_mag_data *data, int *time_delay_ms)
- {
- int rt;
- YLOGD(("yas_measure IN\n"));
- if (data == NULL || time_delay_ms == NULL)
- return YAS_ERROR_ARG;
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_measure_nolock(&this_driver, data, time_delay_ms);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- YLOGD(("yas_measure OUT[%d]\n", rt));
- return rt;
- }
- static int
- yas_init(void)
- {
- int rt;
- YLOGI(("yas_init\n"));
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_init_nolock(&this_driver);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- return rt;
- }
- static int
- yas_term(void)
- {
- int rt;
- YLOGI(("yas_term\n"));
- if (lock() < 0)
- return YAS_ERROR_RESTARTSYS;
- rt = yas_term_nolock(&this_driver);
- if (unlock() < 0)
- return YAS_ERROR_RESTARTSYS;
- return rt;
- }
- int
- yas_mag_driver_init(struct yas_mag_driver *f)
- {
- if (f == NULL)
- return YAS_ERROR_ARG;
- if (f->callback.device_open == NULL
- || f->callback.device_close == NULL
- || f->callback.device_read == NULL
- || f->callback.device_write == NULL
- || f->callback.msleep == NULL
- || f->callback.current_time == NULL) {
- return YAS_ERROR_ARG;
- }
- f->init = yas_init;
- f->term = yas_term;
- f->get_delay = yas_get_delay;
- f->set_delay = yas_set_delay;
- f->get_offset = yas_get_offset;
- f->set_offset = yas_set_offset;
- #ifdef YAS_MAG_MANUAL_OFFSET
- f->get_manual_offset = yas_get_manual_offset;
- f->set_manual_offset = yas_set_manual_offset;
- #endif
- f->get_static_matrix = yas_get_static_matrix;
- f->set_static_matrix = yas_set_static_matrix;
- f->get_dynamic_matrix = yas_get_dynamic_matrix;
- f->set_dynamic_matrix = yas_set_dynamic_matrix;
- f->get_enable = yas_get_enable;
- f->set_enable = yas_set_enable;
- f->get_filter = yas_get_filter;
- f->set_filter = yas_set_filter;
- f->get_filter_enable = yas_get_filter_enable;
- f->set_filter_enable = yas_set_filter_enable;
- f->get_position = yas_get_position;
- f->set_position = yas_set_position;
- f->read_reg = yas_read_reg;
- f->write_reg = yas_write_reg;
- f->measure = yas_measure;
- if ((f->callback.lock == NULL && f->callback.unlock != NULL)
- || (f->callback.lock != NULL
- && f->callback.unlock == NULL)) {
- this_driver.callback.lock = NULL;
- this_driver.callback.unlock = NULL;
- } else {
- this_driver.callback.lock = f->callback.lock;
- this_driver.callback.unlock = f->callback.unlock;
- }
- this_driver.callback.device_open = f->callback.device_open;
- this_driver.callback.device_close = f->callback.device_close;
- this_driver.callback.device_write = f->callback.device_write;
- this_driver.callback.device_read = f->callback.device_read;
- this_driver.callback.msleep = f->callback.msleep;
- this_driver.callback.current_time = f->callback.current_time;
- yas_term();
- return YAS_NO_ERROR;
- }
|