vl53l1_core.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352
  1. /*
  2. * Copyright (c) 2017, STMicroelectronics - All Rights Reserved
  3. *
  4. * This file is part of VL53L1 Core and is dual licensed,
  5. * either 'STMicroelectronics
  6. * Proprietary license'
  7. * or 'BSD 3-clause "New" or "Revised" License' , at your option.
  8. *
  9. ********************************************************************************
  10. *
  11. * 'STMicroelectronics Proprietary license'
  12. *
  13. ********************************************************************************
  14. *
  15. * License terms: STMicroelectronics Proprietary in accordance with licensing
  16. * terms at www.st.com/sla0081
  17. *
  18. * STMicroelectronics confidential
  19. * Reproduction and Communication of this document is strictly prohibited unless
  20. * specifically authorized in writing by STMicroelectronics.
  21. *
  22. *
  23. ********************************************************************************
  24. *
  25. * Alternatively, VL53L1 Core may be distributed under the terms of
  26. * 'BSD 3-clause "New" or "Revised" License', in which case the following
  27. * provisions apply instead of the ones mentioned above :
  28. *
  29. ********************************************************************************
  30. *
  31. * License terms: BSD 3-clause "New" or "Revised" License.
  32. *
  33. * Redistribution and use in source and binary forms, with or without
  34. * modification, are permitted provided that the following conditions are met:
  35. *
  36. * 1. Redistributions of source code must retain the above copyright notice, this
  37. * list of conditions and the following disclaimer.
  38. *
  39. * 2. Redistributions in binary form must reproduce the above copyright notice,
  40. * this list of conditions and the following disclaimer in the documentation
  41. * and/or other materials provided with the distribution.
  42. *
  43. * 3. Neither the name of the copyright holder nor the names of its contributors
  44. * may be used to endorse or promote products derived from this software
  45. * without specific prior written permission.
  46. *
  47. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  48. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  49. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  51. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  52. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  53. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  54. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  55. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  56. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  57. *
  58. *
  59. ********************************************************************************
  60. *
  61. */
  62. /**
  63. * @file vl53l1_core.c
  64. *
  65. * @brief EwokPlus25 core function definition
  66. */
  67. #include "vl53l1_ll_def.h"
  68. #include "vl53l1_ll_device.h"
  69. #include "vl53l1_platform.h"
  70. #include "vl53l1_register_map.h"
  71. #include "vl53l1_register_funcs.h"
  72. #include "vl53l1_register_settings.h"
  73. #include "vl53l1_api_preset_modes.h"
  74. #include "vl53l1_core.h"
  75. #include "vl53l1_tuning_parm_defaults.h"
  76. #ifdef VL53L1_LOGGING
  77. #include "vl53l1_api_debug.h"
  78. #include "vl53l1_debug.h"
  79. #include "vl53l1_register_debug.h"
  80. #endif
  81. #define LOG_FUNCTION_START(fmt, ...) \
  82. _LOG_FUNCTION_START(VL53L1_TRACE_MODULE_CORE, fmt, ##__VA_ARGS__)
  83. #define LOG_FUNCTION_END(status, ...) \
  84. _LOG_FUNCTION_END(VL53L1_TRACE_MODULE_CORE, status, ##__VA_ARGS__)
  85. #define LOG_FUNCTION_END_FMT(status, fmt, ...) \
  86. _LOG_FUNCTION_END_FMT(VL53L1_TRACE_MODULE_CORE, \
  87. status, fmt, ##__VA_ARGS__)
  88. #define trace_print(level, ...) \
  89. _LOG_TRACE_PRINT(VL53L1_TRACE_MODULE_CORE, \
  90. level, VL53L1_TRACE_FUNCTION_NONE, ##__VA_ARGS__)
  91. void VL53L1_init_version(
  92. VL53L1_DEV Dev)
  93. {
  94. /**
  95. * Initialise version structure
  96. */
  97. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  98. pdev->version.ll_major = VL53L1_LL_API_IMPLEMENTATION_VER_MAJOR;
  99. pdev->version.ll_minor = VL53L1_LL_API_IMPLEMENTATION_VER_MINOR;
  100. pdev->version.ll_build = VL53L1_LL_API_IMPLEMENTATION_VER_SUB;
  101. pdev->version.ll_revision = VL53L1_LL_API_IMPLEMENTATION_VER_REVISION;
  102. }
  103. void VL53L1_init_ll_driver_state(
  104. VL53L1_DEV Dev,
  105. VL53L1_DeviceState device_state)
  106. {
  107. /**
  108. * Initialise LL Driver state variables
  109. */
  110. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  111. VL53L1_ll_driver_state_t *pstate = &(pdev->ll_state);
  112. pstate->cfg_device_state = device_state;
  113. pstate->cfg_stream_count = 0;
  114. pstate->cfg_gph_id = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
  115. pstate->cfg_timing_status = 0;
  116. pstate->rd_device_state = device_state;
  117. pstate->rd_stream_count = 0;
  118. pstate->rd_gph_id = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
  119. pstate->rd_timing_status = 0;
  120. }
  121. VL53L1_Error VL53L1_update_ll_driver_rd_state(
  122. VL53L1_DEV Dev)
  123. {
  124. /**
  125. * State machine for read device state
  126. *
  127. * VL53L1_DEVICESTATE_SW_STANDBY
  128. * VL53L1_DEVICESTATE_RANGING_WAIT_GPH_SYNC
  129. * VL53L1_DEVICESTATE_RANGING_GATHER_DATA
  130. * VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA
  131. */
  132. VL53L1_Error status = VL53L1_ERROR_NONE;
  133. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  134. VL53L1_ll_driver_state_t *pstate = &(pdev->ll_state);
  135. /* if top bits of mode start reset are zero then in standby state */
  136. LOG_FUNCTION_START("");
  137. #ifdef VL53L1_LOGGING
  138. VL53L1_print_ll_driver_state(pstate);
  139. #endif
  140. if ((pdev->sys_ctrl.system__mode_start &
  141. VL53L1_DEVICEMEASUREMENTMODE_MODE_MASK) == 0x00) {
  142. pstate->rd_device_state = VL53L1_DEVICESTATE_SW_STANDBY;
  143. pstate->rd_stream_count = 0;
  144. pstate->rd_gph_id = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
  145. pstate->rd_timing_status = 0;
  146. } else {
  147. /*
  148. * implement read stream count
  149. */
  150. if (pstate->rd_stream_count == 0xFF) {
  151. pstate->rd_stream_count = 0x80;
  152. } else {
  153. pstate->rd_stream_count++;
  154. }
  155. /*
  156. * Toggle grouped parameter hold ID
  157. */
  158. pstate->rd_gph_id ^= VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
  159. /* Ok now ranging */
  160. switch (pstate->rd_device_state) {
  161. case VL53L1_DEVICESTATE_SW_STANDBY:
  162. if ((pdev->dyn_cfg.system__grouped_parameter_hold &
  163. VL53L1_GROUPEDPARAMETERHOLD_ID_MASK) > 0) {
  164. pstate->rd_device_state =
  165. VL53L1_DEVICESTATE_RANGING_WAIT_GPH_SYNC;
  166. } else {
  167. pstate->rd_device_state =
  168. VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA;
  169. }
  170. pstate->rd_stream_count = 0;
  171. pstate->rd_timing_status = 0;
  172. break;
  173. case VL53L1_DEVICESTATE_RANGING_WAIT_GPH_SYNC:
  174. pstate->rd_stream_count = 0;
  175. pstate->rd_device_state =
  176. VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA;
  177. break;
  178. case VL53L1_DEVICESTATE_RANGING_GATHER_DATA:
  179. pstate->rd_device_state =
  180. VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA;
  181. break;
  182. case VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA:
  183. pstate->rd_timing_status ^= 0x01;
  184. pstate->rd_device_state =
  185. VL53L1_DEVICESTATE_RANGING_OUTPUT_DATA;
  186. break;
  187. default:
  188. pstate->rd_device_state =
  189. VL53L1_DEVICESTATE_SW_STANDBY;
  190. pstate->rd_stream_count = 0;
  191. pstate->rd_gph_id = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
  192. pstate->rd_timing_status = 0;
  193. break;
  194. }
  195. }
  196. #ifdef VL53L1_LOGGING
  197. VL53L1_print_ll_driver_state(pstate);
  198. #endif
  199. LOG_FUNCTION_END(status);
  200. return status;
  201. }
  202. VL53L1_Error VL53L1_check_ll_driver_rd_state(
  203. VL53L1_DEV Dev)
  204. {
  205. /*
  206. * Checks if the LL Driver Read state and expected stream count
  207. * matches the state and stream count received from the device
  208. *
  209. * Check is only use in back to back mode
  210. */
  211. VL53L1_Error status = VL53L1_ERROR_NONE;
  212. VL53L1_LLDriverData_t *pdev =
  213. VL53L1DevStructGetLLDriverHandle(Dev);
  214. VL53L1_ll_driver_state_t *pstate = &(pdev->ll_state);
  215. VL53L1_system_results_t *psys_results = &(pdev->sys_results);
  216. uint8_t device_range_status = 0;
  217. uint8_t device_stream_count = 0;
  218. uint8_t device_gph_id = 0;
  219. LOG_FUNCTION_START("");
  220. #ifdef VL53L1_LOGGING
  221. VL53L1_print_ll_driver_state(pstate);
  222. #endif
  223. device_range_status =
  224. psys_results->result__range_status &
  225. VL53L1_RANGE_STATUS__RANGE_STATUS_MASK;
  226. device_stream_count = psys_results->result__stream_count;
  227. /* load the correct GPH ID */
  228. device_gph_id = (psys_results->result__interrupt_status &
  229. VL53L1_INTERRUPT_STATUS__GPH_ID_INT_STATUS_MASK) >> 4;
  230. /* only apply checks in back to back mode */
  231. if ((pdev->sys_ctrl.system__mode_start &
  232. VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK) ==
  233. VL53L1_DEVICEMEASUREMENTMODE_BACKTOBACK) {
  234. /* if read state is wait for GPH sync interrupt then check the
  235. * device returns a GPH range status value otherwise check that
  236. * the stream count matches
  237. *
  238. * In theory the stream count should zero for the GPH interrupt
  239. * but that is not the case after at abort ....
  240. */
  241. if (pstate->rd_device_state ==
  242. VL53L1_DEVICESTATE_RANGING_WAIT_GPH_SYNC) {
  243. if (device_range_status !=
  244. VL53L1_DEVICEERROR_GPHSTREAMCOUNT0READY) {
  245. status = VL53L1_ERROR_GPH_SYNC_CHECK_FAIL;
  246. }
  247. } else {
  248. if (pstate->rd_stream_count != device_stream_count) {
  249. status = VL53L1_ERROR_STREAM_COUNT_CHECK_FAIL;
  250. }
  251. /*
  252. * Check Read state GPH ID
  253. */
  254. if (pstate->rd_gph_id != device_gph_id) {
  255. status = VL53L1_ERROR_GPH_ID_CHECK_FAIL;
  256. #ifdef VL53L1_LOGGING
  257. trace_print(VL53L1_TRACE_LEVEL_ALL,
  258. " RDSTATECHECK: Check failed: rd_gph_id: %d, device_gph_id: %d\n",
  259. pstate->rd_gph_id,
  260. device_gph_id);
  261. #endif
  262. } else {
  263. #ifdef VL53L1_LOGGING
  264. trace_print(VL53L1_TRACE_LEVEL_ALL,
  265. " RDSTATECHECK: Check passed: rd_gph_id: %d, device_gph_id: %d\n",
  266. pstate->rd_gph_id,
  267. device_gph_id);
  268. #endif
  269. }
  270. } /* else (not in WAIT_GPH_SYNC) */
  271. } /* if back to back */
  272. LOG_FUNCTION_END(status);
  273. return status;
  274. }
  275. VL53L1_Error VL53L1_update_ll_driver_cfg_state(
  276. VL53L1_DEV Dev)
  277. {
  278. /**
  279. * State machine for configuration device state
  280. */
  281. VL53L1_Error status = VL53L1_ERROR_NONE;
  282. VL53L1_LLDriverData_t *pdev =
  283. VL53L1DevStructGetLLDriverHandle(Dev);
  284. VL53L1_ll_driver_state_t *pstate = &(pdev->ll_state);
  285. LOG_FUNCTION_START("");
  286. #ifdef VL53L1_LOGGING
  287. VL53L1_print_ll_driver_state(pstate);
  288. #endif
  289. /* if top bits of mode start reset are zero then in standby state */
  290. if ((pdev->sys_ctrl.system__mode_start &
  291. VL53L1_DEVICEMEASUREMENTMODE_MODE_MASK) == 0x00) {
  292. pstate->cfg_device_state = VL53L1_DEVICESTATE_SW_STANDBY;
  293. pstate->cfg_stream_count = 0;
  294. pstate->cfg_gph_id = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
  295. pstate->cfg_timing_status = 0;
  296. } else {
  297. /*
  298. * implement configuration stream count
  299. */
  300. if (pstate->cfg_stream_count == 0xFF) {
  301. pstate->cfg_stream_count = 0x80;
  302. } else {
  303. pstate->cfg_stream_count++;
  304. }
  305. /*
  306. * Toggle grouped parameter hold ID
  307. */
  308. pstate->cfg_gph_id ^= VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
  309. /*
  310. * Implement configuration state machine
  311. */
  312. switch (pstate->cfg_device_state) {
  313. case VL53L1_DEVICESTATE_SW_STANDBY:
  314. pstate->cfg_timing_status ^= 0x01;
  315. pstate->cfg_stream_count = 1;
  316. pstate->cfg_device_state = VL53L1_DEVICESTATE_RANGING_DSS_AUTO;
  317. break;
  318. case VL53L1_DEVICESTATE_RANGING_DSS_AUTO:
  319. pstate->cfg_timing_status ^= 0x01;
  320. break;
  321. default:
  322. pstate->cfg_device_state = VL53L1_DEVICESTATE_SW_STANDBY;
  323. pstate->cfg_stream_count = 0;
  324. pstate->cfg_gph_id = VL53L1_GROUPEDPARAMETERHOLD_ID_MASK;
  325. pstate->cfg_timing_status = 0;
  326. break;
  327. }
  328. }
  329. #ifdef VL53L1_LOGGING
  330. VL53L1_print_ll_driver_state(pstate);
  331. #endif
  332. LOG_FUNCTION_END(status);
  333. return status;
  334. }
  335. void VL53L1_copy_rtn_good_spads_to_buffer(
  336. VL53L1_nvm_copy_data_t *pdata,
  337. uint8_t *pbuffer)
  338. {
  339. /*
  340. * Convenience function to copy return SPAD enables to buffer
  341. */
  342. *(pbuffer + 0) = pdata->global_config__spad_enables_rtn_0;
  343. *(pbuffer + 1) = pdata->global_config__spad_enables_rtn_1;
  344. *(pbuffer + 2) = pdata->global_config__spad_enables_rtn_2;
  345. *(pbuffer + 3) = pdata->global_config__spad_enables_rtn_3;
  346. *(pbuffer + 4) = pdata->global_config__spad_enables_rtn_4;
  347. *(pbuffer + 5) = pdata->global_config__spad_enables_rtn_5;
  348. *(pbuffer + 6) = pdata->global_config__spad_enables_rtn_6;
  349. *(pbuffer + 7) = pdata->global_config__spad_enables_rtn_7;
  350. *(pbuffer + 8) = pdata->global_config__spad_enables_rtn_8;
  351. *(pbuffer + 9) = pdata->global_config__spad_enables_rtn_9;
  352. *(pbuffer + 10) = pdata->global_config__spad_enables_rtn_10;
  353. *(pbuffer + 11) = pdata->global_config__spad_enables_rtn_11;
  354. *(pbuffer + 12) = pdata->global_config__spad_enables_rtn_12;
  355. *(pbuffer + 13) = pdata->global_config__spad_enables_rtn_13;
  356. *(pbuffer + 14) = pdata->global_config__spad_enables_rtn_14;
  357. *(pbuffer + 15) = pdata->global_config__spad_enables_rtn_15;
  358. *(pbuffer + 16) = pdata->global_config__spad_enables_rtn_16;
  359. *(pbuffer + 17) = pdata->global_config__spad_enables_rtn_17;
  360. *(pbuffer + 18) = pdata->global_config__spad_enables_rtn_18;
  361. *(pbuffer + 19) = pdata->global_config__spad_enables_rtn_19;
  362. *(pbuffer + 20) = pdata->global_config__spad_enables_rtn_20;
  363. *(pbuffer + 21) = pdata->global_config__spad_enables_rtn_21;
  364. *(pbuffer + 22) = pdata->global_config__spad_enables_rtn_22;
  365. *(pbuffer + 23) = pdata->global_config__spad_enables_rtn_23;
  366. *(pbuffer + 24) = pdata->global_config__spad_enables_rtn_24;
  367. *(pbuffer + 25) = pdata->global_config__spad_enables_rtn_25;
  368. *(pbuffer + 26) = pdata->global_config__spad_enables_rtn_26;
  369. *(pbuffer + 27) = pdata->global_config__spad_enables_rtn_27;
  370. *(pbuffer + 28) = pdata->global_config__spad_enables_rtn_28;
  371. *(pbuffer + 29) = pdata->global_config__spad_enables_rtn_29;
  372. *(pbuffer + 30) = pdata->global_config__spad_enables_rtn_30;
  373. *(pbuffer + 31) = pdata->global_config__spad_enables_rtn_31;
  374. }
  375. void VL53L1_init_system_results(
  376. VL53L1_system_results_t *pdata)
  377. {
  378. /*
  379. * Initialises the system results to all 0xFF just like the
  380. * device firmware does a the start of a range
  381. */
  382. pdata->result__interrupt_status = 0xFF;
  383. pdata->result__range_status = 0xFF;
  384. pdata->result__report_status = 0xFF;
  385. pdata->result__stream_count = 0xFF;
  386. pdata->result__dss_actual_effective_spads_sd0 = 0xFFFF;
  387. pdata->result__peak_signal_count_rate_mcps_sd0 = 0xFFFF;
  388. pdata->result__ambient_count_rate_mcps_sd0 = 0xFFFF;
  389. pdata->result__sigma_sd0 = 0xFFFF;
  390. pdata->result__phase_sd0 = 0xFFFF;
  391. pdata->result__final_crosstalk_corrected_range_mm_sd0 = 0xFFFF;
  392. pdata->result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 =
  393. 0xFFFF;
  394. pdata->result__mm_inner_actual_effective_spads_sd0 = 0xFFFF;
  395. pdata->result__mm_outer_actual_effective_spads_sd0 = 0xFFFF;
  396. pdata->result__avg_signal_count_rate_mcps_sd0 = 0xFFFF;
  397. pdata->result__dss_actual_effective_spads_sd1 = 0xFFFF;
  398. pdata->result__peak_signal_count_rate_mcps_sd1 = 0xFFFF;
  399. pdata->result__ambient_count_rate_mcps_sd1 = 0xFFFF;
  400. pdata->result__sigma_sd1 = 0xFFFF;
  401. pdata->result__phase_sd1 = 0xFFFF;
  402. pdata->result__final_crosstalk_corrected_range_mm_sd1 = 0xFFFF;
  403. pdata->result__spare_0_sd1 = 0xFFFF;
  404. pdata->result__spare_1_sd1 = 0xFFFF;
  405. pdata->result__spare_2_sd1 = 0xFFFF;
  406. pdata->result__spare_3_sd1 = 0xFF;
  407. }
  408. void VL53L1_i2c_encode_uint16_t(
  409. uint16_t ip_value,
  410. uint16_t count,
  411. uint8_t *pbuffer)
  412. {
  413. /*
  414. * Encodes a uint16_t register value into an I2C write buffer
  415. * MS byte first order (as per I2C register map.
  416. */
  417. uint16_t i = 0;
  418. uint16_t data = 0;
  419. data = ip_value;
  420. for (i = 0; i < count ; i++) {
  421. pbuffer[count-i-1] = (uint8_t)(data & 0x00FF);
  422. data = data >> 8;
  423. }
  424. }
  425. uint16_t VL53L1_i2c_decode_uint16_t(
  426. uint16_t count,
  427. uint8_t *pbuffer)
  428. {
  429. /*
  430. * Decodes a uint16_t from the input I2C read buffer
  431. * (MS byte first order)
  432. */
  433. uint16_t value = 0x00;
  434. while (count-- > 0) {
  435. value = (value << 8) | (uint16_t)*pbuffer++;
  436. }
  437. return value;
  438. }
  439. void VL53L1_i2c_encode_int16_t(
  440. int16_t ip_value,
  441. uint16_t count,
  442. uint8_t *pbuffer)
  443. {
  444. /*
  445. * Encodes a int16_t register value into an I2C write buffer
  446. * MS byte first order (as per I2C register map.
  447. */
  448. uint16_t i = 0;
  449. int16_t data = 0;
  450. data = ip_value;
  451. for (i = 0; i < count ; i++) {
  452. pbuffer[count-i-1] = (uint8_t)(data & 0x00FF);
  453. data = data >> 8;
  454. }
  455. }
  456. int16_t VL53L1_i2c_decode_int16_t(
  457. uint16_t count,
  458. uint8_t *pbuffer)
  459. {
  460. /*
  461. * Decodes a int16_t from the input I2C read buffer
  462. * (MS byte first order)
  463. */
  464. int16_t value = 0x00;
  465. /* implement sign extension */
  466. if (*pbuffer >= 0x80) {
  467. value = 0xFFFF;
  468. }
  469. while (count-- > 0) {
  470. value = (value << 8) | (int16_t)*pbuffer++;
  471. }
  472. return value;
  473. }
  474. void VL53L1_i2c_encode_uint32_t(
  475. uint32_t ip_value,
  476. uint16_t count,
  477. uint8_t *pbuffer)
  478. {
  479. /*
  480. * Encodes a uint32_t register value into an I2C write buffer
  481. * MS byte first order (as per I2C register map.
  482. */
  483. uint16_t i = 0;
  484. uint32_t data = 0;
  485. data = ip_value;
  486. for (i = 0; i < count ; i++) {
  487. pbuffer[count-i-1] = (uint8_t)(data & 0x00FF);
  488. data = data >> 8;
  489. }
  490. }
  491. uint32_t VL53L1_i2c_decode_uint32_t(
  492. uint16_t count,
  493. uint8_t *pbuffer)
  494. {
  495. /*
  496. * Decodes a uint32_t from the input I2C read buffer
  497. * (MS byte first order)
  498. */
  499. uint32_t value = 0x00;
  500. while (count-- > 0) {
  501. value = (value << 8) | (uint32_t)*pbuffer++;
  502. }
  503. return value;
  504. }
  505. uint32_t VL53L1_i2c_decode_with_mask(
  506. uint16_t count,
  507. uint8_t *pbuffer,
  508. uint32_t bit_mask,
  509. uint32_t down_shift,
  510. uint32_t offset)
  511. {
  512. /*
  513. * Decodes an integer from the input I2C read buffer
  514. * (MS byte first order)
  515. */
  516. uint32_t value = 0x00;
  517. /* extract from buffer */
  518. while (count-- > 0) {
  519. value = (value << 8) | (uint32_t)*pbuffer++;
  520. }
  521. /* Apply bit mask and down shift */
  522. value = value & bit_mask;
  523. if (down_shift > 0) {
  524. value = value >> down_shift;
  525. }
  526. /* add offset */
  527. value = value + offset;
  528. return value;
  529. }
  530. void VL53L1_i2c_encode_int32_t(
  531. int32_t ip_value,
  532. uint16_t count,
  533. uint8_t *pbuffer)
  534. {
  535. /*
  536. * Encodes a int32_t register value into an I2C write buffer
  537. * MS byte first order (as per I2C register map.
  538. */
  539. uint16_t i = 0;
  540. int32_t data = 0;
  541. data = ip_value;
  542. for (i = 0; i < count ; i++) {
  543. pbuffer[count-i-1] = (uint8_t)(data & 0x00FF);
  544. data = data >> 8;
  545. }
  546. }
  547. int32_t VL53L1_i2c_decode_int32_t(
  548. uint16_t count,
  549. uint8_t *pbuffer)
  550. {
  551. /*
  552. * Decodes a int32_t from the input I2C read buffer
  553. * (MS byte first order)
  554. */
  555. int32_t value = 0x00;
  556. /* implement sign extension */
  557. if (*pbuffer >= 0x80) {
  558. value = 0xFFFFFFFF;
  559. }
  560. while (count-- > 0) {
  561. value = (value << 8) | (int32_t)*pbuffer++;
  562. }
  563. return value;
  564. }
  565. #ifndef VL53L1_NOCALIB
  566. VL53L1_Error VL53L1_start_test(
  567. VL53L1_DEV Dev,
  568. uint8_t test_mode__ctrl)
  569. {
  570. /*
  571. * Triggers the start of a test mode
  572. */
  573. VL53L1_Error status = VL53L1_ERROR_NONE;
  574. LOG_FUNCTION_START("");
  575. if (status == VL53L1_ERROR_NONE) { /*lint !e774 always true*/
  576. status = VL53L1_WrByte(
  577. Dev,
  578. VL53L1_TEST_MODE__CTRL,
  579. test_mode__ctrl);
  580. }
  581. LOG_FUNCTION_END(status);
  582. return status;
  583. }
  584. #endif
  585. VL53L1_Error VL53L1_set_firmware_enable_register(
  586. VL53L1_DEV Dev,
  587. uint8_t value)
  588. {
  589. /*
  590. * Set FIRMWARE__ENABLE register
  591. */
  592. VL53L1_Error status = VL53L1_ERROR_NONE;
  593. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  594. pdev->sys_ctrl.firmware__enable = value;
  595. status = VL53L1_WrByte(
  596. Dev,
  597. VL53L1_FIRMWARE__ENABLE,
  598. pdev->sys_ctrl.firmware__enable);
  599. return status;
  600. }
  601. VL53L1_Error VL53L1_enable_firmware(
  602. VL53L1_DEV Dev)
  603. {
  604. /*
  605. * Enable firmware
  606. */
  607. VL53L1_Error status = VL53L1_ERROR_NONE;
  608. LOG_FUNCTION_START("");
  609. status = VL53L1_set_firmware_enable_register(Dev, 0x01);
  610. LOG_FUNCTION_END(status);
  611. return status;
  612. }
  613. VL53L1_Error VL53L1_disable_firmware(
  614. VL53L1_DEV Dev)
  615. {
  616. /*
  617. * Disable firmware
  618. */
  619. VL53L1_Error status = VL53L1_ERROR_NONE;
  620. LOG_FUNCTION_START("");
  621. status = VL53L1_set_firmware_enable_register(Dev, 0x00);
  622. LOG_FUNCTION_END(status);
  623. return status;
  624. }
  625. VL53L1_Error VL53L1_set_powerforce_register(
  626. VL53L1_DEV Dev,
  627. uint8_t value)
  628. {
  629. /*
  630. * Set power force register
  631. */
  632. VL53L1_Error status = VL53L1_ERROR_NONE;
  633. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  634. pdev->sys_ctrl.power_management__go1_power_force = value;
  635. status = VL53L1_WrByte(
  636. Dev,
  637. VL53L1_POWER_MANAGEMENT__GO1_POWER_FORCE,
  638. pdev->sys_ctrl.power_management__go1_power_force);
  639. return status;
  640. }
  641. VL53L1_Error VL53L1_enable_powerforce(
  642. VL53L1_DEV Dev)
  643. {
  644. /*
  645. * Enable power force
  646. */
  647. VL53L1_Error status = VL53L1_ERROR_NONE;
  648. LOG_FUNCTION_START("");
  649. status = VL53L1_set_powerforce_register(Dev, 0x01);
  650. LOG_FUNCTION_END(status);
  651. return status;
  652. }
  653. VL53L1_Error VL53L1_disable_powerforce(
  654. VL53L1_DEV Dev)
  655. {
  656. /*
  657. * Disable power force
  658. */
  659. VL53L1_Error status = VL53L1_ERROR_NONE;
  660. LOG_FUNCTION_START("");
  661. status = VL53L1_set_powerforce_register(Dev, 0x00);
  662. LOG_FUNCTION_END(status);
  663. return status;
  664. }
  665. VL53L1_Error VL53L1_clear_interrupt(
  666. VL53L1_DEV Dev)
  667. {
  668. /*
  669. * Clear Ranging interrupt by writing to
  670. */
  671. VL53L1_Error status = VL53L1_ERROR_NONE;
  672. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  673. LOG_FUNCTION_START("");
  674. pdev->sys_ctrl.system__interrupt_clear = VL53L1_CLEAR_RANGE_INT;
  675. status = VL53L1_WrByte(
  676. Dev,
  677. VL53L1_SYSTEM__INTERRUPT_CLEAR,
  678. pdev->sys_ctrl.system__interrupt_clear);
  679. LOG_FUNCTION_END(status);
  680. return status;
  681. }
  682. #ifdef VL53L1_DEBUG
  683. VL53L1_Error VL53L1_force_shadow_stream_count_to_zero(
  684. VL53L1_DEV Dev)
  685. {
  686. /*
  687. * Forces shadow stream count to zero
  688. */
  689. VL53L1_Error status = VL53L1_ERROR_NONE;
  690. if (status == VL53L1_ERROR_NONE) { /*lint !e774 always true*/
  691. status = VL53L1_disable_firmware(Dev);
  692. }
  693. if (status == VL53L1_ERROR_NONE) {
  694. status = VL53L1_WrByte(
  695. Dev,
  696. VL53L1_SHADOW_RESULT__STREAM_COUNT,
  697. 0x00);
  698. }
  699. if (status == VL53L1_ERROR_NONE) {
  700. status = VL53L1_enable_firmware(Dev);
  701. }
  702. return status;
  703. }
  704. #endif
  705. uint32_t VL53L1_calc_macro_period_us(
  706. uint16_t fast_osc_frequency,
  707. uint8_t vcsel_period)
  708. {
  709. /* Calculates macro period in [us] from the input fast oscillator
  710. * frequency and VCSEL period
  711. *
  712. * Macro period fixed point format = unsigned 12.12
  713. * Maximum supported macro period = 4095.9999 us
  714. */
  715. uint32_t pll_period_us = 0;
  716. uint8_t vcsel_period_pclks = 0;
  717. uint32_t macro_period_us = 0;
  718. LOG_FUNCTION_START("");
  719. /* Calculate PLL period in [us] from the fast_osc_frequency
  720. * Fast osc frequency fixed point format = unsigned 4.12
  721. */
  722. pll_period_us = VL53L1_calc_pll_period_us(fast_osc_frequency);
  723. /* VCSEL period
  724. * - the real VCSEL period in PLL clocks = 2*(VCSEL_PERIOD+1)
  725. */
  726. vcsel_period_pclks = VL53L1_decode_vcsel_period(vcsel_period);
  727. /* Macro period
  728. * - PLL period [us] = 0.24 format
  729. * - for 1.0 MHz fast oscillator freq
  730. * - max PLL period = 1/64 (6-bits)
  731. * - i.e only the lower 18-bits of PLL Period value are used
  732. * - Macro period [vclks] = 2304 (12-bits)
  733. *
  734. * Max bits (24 - 6) + 12 = 30-bits usage
  735. *
  736. * Downshift by 6 before multiplying by the VCSEL Period
  737. */
  738. macro_period_us =
  739. (uint32_t)VL53L1_MACRO_PERIOD_VCSEL_PERIODS *
  740. pll_period_us;
  741. macro_period_us = macro_period_us >> 6;
  742. macro_period_us = macro_period_us * (uint32_t)vcsel_period_pclks;
  743. macro_period_us = macro_period_us >> 6;
  744. #ifdef VL53L1_LOGGING
  745. trace_print(VL53L1_TRACE_LEVEL_DEBUG,
  746. " %-48s : %10u\n", "pll_period_us",
  747. pll_period_us);
  748. trace_print(VL53L1_TRACE_LEVEL_DEBUG,
  749. " %-48s : %10u\n", "vcsel_period_pclks",
  750. vcsel_period_pclks);
  751. trace_print(VL53L1_TRACE_LEVEL_DEBUG,
  752. " %-48s : %10u\n", "macro_period_us",
  753. macro_period_us);
  754. #endif
  755. LOG_FUNCTION_END(0);
  756. return macro_period_us;
  757. }
  758. uint16_t VL53L1_calc_range_ignore_threshold(
  759. uint32_t central_rate,
  760. int16_t x_gradient,
  761. int16_t y_gradient,
  762. uint8_t rate_mult)
  763. {
  764. /* Calculates Range Ignore Threshold rate per spad
  765. * in Mcps - 3.13 format
  766. *
  767. * Calculates worst case xtalk rate per spad in array corner
  768. * based on input central xtalk and x and y gradients
  769. *
  770. * Worst case rate = central rate + (8*(magnitude(xgrad)) +
  771. * (8*(magnitude(ygrad)))
  772. *
  773. * Range ignore threshold rate is then multiplied by user input
  774. * rate_mult (in 3.5 fractional format)
  775. *
  776. */
  777. int32_t range_ignore_thresh_int = 0;
  778. uint16_t range_ignore_thresh_kcps = 0;
  779. int32_t central_rate_int = 0;
  780. int16_t x_gradient_int = 0;
  781. int16_t y_gradient_int = 0;
  782. LOG_FUNCTION_START("");
  783. /* Shift central_rate to .13 fractional for simple addition */
  784. central_rate_int = ((int32_t)central_rate * (1 << 4)) / (1000);
  785. if (x_gradient < 0) {
  786. x_gradient_int = x_gradient * -1;
  787. }
  788. if (y_gradient < 0) {
  789. y_gradient_int = y_gradient * -1;
  790. }
  791. /* Calculate full rate per spad - worst case from measured xtalk */
  792. /* Generated here from .11 fractional kcps */
  793. /* Additional factor of 4 applied to bring fractional precision to .13 */
  794. range_ignore_thresh_int = (8 * x_gradient_int * 4) + (8 * y_gradient_int * 4);
  795. /* Convert Kcps to Mcps */
  796. range_ignore_thresh_int = range_ignore_thresh_int / 1000;
  797. /* Combine with Central Rate - Mcps .13 format*/
  798. range_ignore_thresh_int = range_ignore_thresh_int + central_rate_int;
  799. /* Mult by user input */
  800. range_ignore_thresh_int = (int32_t)rate_mult * range_ignore_thresh_int;
  801. range_ignore_thresh_int = (range_ignore_thresh_int + (1<<4)) / (1<<5);
  802. /* Finally clip and output in correct format */
  803. if (range_ignore_thresh_int > 0xFFFF) {
  804. range_ignore_thresh_kcps = 0xFFFF;
  805. } else {
  806. range_ignore_thresh_kcps = (uint16_t)range_ignore_thresh_int;
  807. }
  808. #ifdef VL53L1_LOGGING
  809. trace_print(VL53L1_TRACE_LEVEL_DEBUG,
  810. " %-48s : %10u\n", "range_ignore_thresh_kcps",
  811. range_ignore_thresh_kcps);
  812. #endif
  813. LOG_FUNCTION_END(0);
  814. return range_ignore_thresh_kcps;
  815. }
  816. uint32_t VL53L1_calc_timeout_mclks(
  817. uint32_t timeout_us,
  818. uint32_t macro_period_us)
  819. {
  820. /* Calculates the timeout value in macro periods based on the input
  821. * timeout period in milliseconds and the macro period in [us]
  822. *
  823. * Max timeout supported is 1000000 us (1 sec) -> 20-bits
  824. * Max timeout in 20.12 format = 32-bits
  825. *
  826. * Macro period [us] = 12.12 format
  827. */
  828. uint32_t timeout_mclks = 0;
  829. LOG_FUNCTION_START("");
  830. timeout_mclks =
  831. ((timeout_us << 12) + (macro_period_us>>1)) /
  832. macro_period_us;
  833. LOG_FUNCTION_END(0);
  834. return timeout_mclks;
  835. }
  836. uint16_t VL53L1_calc_encoded_timeout(
  837. uint32_t timeout_us,
  838. uint32_t macro_period_us)
  839. {
  840. /* Calculates the encoded timeout register value based on the input
  841. * timeout period in milliseconds and the macro period in [us]
  842. *
  843. * Max timeout supported is 1000000 us (1 sec) -> 20-bits
  844. * Max timeout in 20.12 format = 32-bits
  845. *
  846. * Macro period [us] = 12.12 format
  847. */
  848. uint32_t timeout_mclks = 0;
  849. uint16_t timeout_encoded = 0;
  850. LOG_FUNCTION_START("");
  851. timeout_mclks =
  852. VL53L1_calc_timeout_mclks(timeout_us, macro_period_us);
  853. timeout_encoded =
  854. VL53L1_encode_timeout(timeout_mclks);
  855. #ifdef VL53L1_LOGGING
  856. trace_print(VL53L1_TRACE_LEVEL_DEBUG,
  857. " %-48s : %10u (0x%04X)\n", "timeout_mclks",
  858. timeout_mclks, timeout_mclks);
  859. trace_print(VL53L1_TRACE_LEVEL_DEBUG,
  860. " %-48s : %10u (0x%04X)\n", "timeout_encoded",
  861. timeout_encoded, timeout_encoded);
  862. #endif
  863. LOG_FUNCTION_END(0);
  864. return timeout_encoded;
  865. }
  866. uint32_t VL53L1_calc_timeout_us(
  867. uint32_t timeout_mclks,
  868. uint32_t macro_period_us)
  869. {
  870. /* Calculates the timeout in [us] based on the input
  871. * encoded timeout and the macro period in [us]
  872. *
  873. * Max timeout supported is 1000000 us (1 sec) -> 20-bits
  874. * Max timeout in 20.12 format = 32-bits
  875. *
  876. * Macro period [us] = 12.12 format
  877. */
  878. uint32_t timeout_us = 0;
  879. uint64_t tmp = 0;
  880. LOG_FUNCTION_START("");
  881. tmp = (uint64_t)timeout_mclks * (uint64_t)macro_period_us;
  882. tmp += 0x00800;
  883. tmp = tmp >> 12;
  884. timeout_us = (uint32_t)tmp;
  885. #ifdef VL53L1_LOGGING
  886. trace_print(VL53L1_TRACE_LEVEL_DEBUG,
  887. " %-48s : %10u (0x%04X)\n", "timeout_mclks",
  888. timeout_mclks, timeout_mclks);
  889. trace_print(VL53L1_TRACE_LEVEL_DEBUG,
  890. " %-48s : %10u us\n", "timeout_us",
  891. timeout_us, timeout_us);
  892. #endif
  893. LOG_FUNCTION_END(0);
  894. return timeout_us;
  895. }
  896. uint32_t VL53L1_calc_crosstalk_plane_offset_with_margin(
  897. uint32_t plane_offset_kcps,
  898. int16_t margin_offset_kcps)
  899. {
  900. uint32_t plane_offset_with_margin = 0;
  901. int32_t plane_offset_kcps_temp = 0;
  902. LOG_FUNCTION_START("");
  903. plane_offset_kcps_temp =
  904. (int32_t)plane_offset_kcps +
  905. (int32_t)margin_offset_kcps;
  906. if (plane_offset_kcps_temp < 0) {
  907. plane_offset_kcps_temp = 0;
  908. } else {
  909. if (plane_offset_kcps_temp > 0x3FFFF) {
  910. plane_offset_kcps_temp = 0x3FFFF;
  911. }
  912. }
  913. plane_offset_with_margin = (uint32_t) plane_offset_kcps_temp;
  914. LOG_FUNCTION_END(0);
  915. return plane_offset_with_margin;
  916. }
  917. uint32_t VL53L1_calc_decoded_timeout_us(
  918. uint16_t timeout_encoded,
  919. uint32_t macro_period_us)
  920. {
  921. /* Calculates the timeout in [us] based on the input
  922. * encoded timeout and the macro period in [us]
  923. *
  924. * Max timeout supported is 1000000 us (1 sec) -> 20-bits
  925. * Max timeout in 20.12 format = 32-bits
  926. *
  927. * Macro period [us] = 12.12 format
  928. */
  929. uint32_t timeout_mclks = 0;
  930. uint32_t timeout_us = 0;
  931. LOG_FUNCTION_START("");
  932. timeout_mclks =
  933. VL53L1_decode_timeout(timeout_encoded);
  934. timeout_us =
  935. VL53L1_calc_timeout_us(timeout_mclks, macro_period_us);
  936. LOG_FUNCTION_END(0);
  937. return timeout_us;
  938. }
  939. uint16_t VL53L1_encode_timeout(uint32_t timeout_mclks)
  940. {
  941. /*
  942. * Encode timeout in macro periods in (LSByte * 2^MSByte) + 1 format
  943. */
  944. uint16_t encoded_timeout = 0;
  945. uint32_t ls_byte = 0;
  946. uint16_t ms_byte = 0;
  947. if (timeout_mclks > 0) {
  948. ls_byte = timeout_mclks - 1;
  949. while ((ls_byte & 0xFFFFFF00) > 0) {
  950. ls_byte = ls_byte >> 1;
  951. ms_byte++;
  952. }
  953. encoded_timeout = (ms_byte << 8)
  954. + (uint16_t) (ls_byte & 0x000000FF);
  955. }
  956. return encoded_timeout;
  957. }
  958. uint32_t VL53L1_decode_timeout(uint16_t encoded_timeout)
  959. {
  960. /*
  961. * Decode 16-bit timeout register value
  962. * format (LSByte * 2^MSByte) + 1
  963. */
  964. uint32_t timeout_macro_clks = 0;
  965. timeout_macro_clks = ((uint32_t) (encoded_timeout & 0x00FF)
  966. << (uint32_t) ((encoded_timeout & 0xFF00) >> 8)) + 1;
  967. return timeout_macro_clks;
  968. }
  969. VL53L1_Error VL53L1_calc_timeout_register_values(
  970. uint32_t phasecal_config_timeout_us,
  971. uint32_t mm_config_timeout_us,
  972. uint32_t range_config_timeout_us,
  973. uint16_t fast_osc_frequency,
  974. VL53L1_general_config_t *pgeneral,
  975. VL53L1_timing_config_t *ptiming)
  976. {
  977. /*
  978. * Converts the input MM and range timeouts in [us]
  979. * into the appropriate register values
  980. *
  981. * Must also be run after the VCSEL period settings are changed
  982. */
  983. VL53L1_Error status = VL53L1_ERROR_NONE;
  984. uint32_t macro_period_us = 0;
  985. uint32_t timeout_mclks = 0;
  986. uint16_t timeout_encoded = 0;
  987. LOG_FUNCTION_START("");
  988. if (fast_osc_frequency == 0) {
  989. status = VL53L1_ERROR_DIVISION_BY_ZERO;
  990. } else {
  991. /* Update Macro Period for Range A VCSEL Period */
  992. macro_period_us =
  993. VL53L1_calc_macro_period_us(
  994. fast_osc_frequency,
  995. ptiming->range_config__vcsel_period_a);
  996. /* Update Phase timeout - uses Timing A */
  997. timeout_mclks =
  998. VL53L1_calc_timeout_mclks(
  999. phasecal_config_timeout_us,
  1000. macro_period_us);
  1001. /* clip as the phase cal timeout register is only 8-bits */
  1002. if (timeout_mclks > 0xFF)
  1003. timeout_mclks = 0xFF;
  1004. pgeneral->phasecal_config__timeout_macrop =
  1005. (uint8_t)timeout_mclks;
  1006. /* Update MM Timing A timeout */
  1007. timeout_encoded =
  1008. VL53L1_calc_encoded_timeout(
  1009. mm_config_timeout_us,
  1010. macro_period_us);
  1011. ptiming->mm_config__timeout_macrop_a_hi =
  1012. (uint8_t)((timeout_encoded & 0xFF00) >> 8);
  1013. ptiming->mm_config__timeout_macrop_a_lo =
  1014. (uint8_t) (timeout_encoded & 0x00FF);
  1015. /* Update Range Timing A timeout */
  1016. timeout_encoded =
  1017. VL53L1_calc_encoded_timeout(
  1018. range_config_timeout_us,
  1019. macro_period_us);
  1020. ptiming->range_config__timeout_macrop_a_hi =
  1021. (uint8_t)((timeout_encoded & 0xFF00) >> 8);
  1022. ptiming->range_config__timeout_macrop_a_lo =
  1023. (uint8_t) (timeout_encoded & 0x00FF);
  1024. /* Update Macro Period for Range B VCSEL Period */
  1025. macro_period_us =
  1026. VL53L1_calc_macro_period_us(
  1027. fast_osc_frequency,
  1028. ptiming->range_config__vcsel_period_b);
  1029. /* Update MM Timing B timeout */
  1030. timeout_encoded =
  1031. VL53L1_calc_encoded_timeout(
  1032. mm_config_timeout_us,
  1033. macro_period_us);
  1034. ptiming->mm_config__timeout_macrop_b_hi =
  1035. (uint8_t)((timeout_encoded & 0xFF00) >> 8);
  1036. ptiming->mm_config__timeout_macrop_b_lo =
  1037. (uint8_t) (timeout_encoded & 0x00FF);
  1038. /* Update Range Timing B timeout */
  1039. timeout_encoded = VL53L1_calc_encoded_timeout(
  1040. range_config_timeout_us,
  1041. macro_period_us);
  1042. ptiming->range_config__timeout_macrop_b_hi =
  1043. (uint8_t)((timeout_encoded & 0xFF00) >> 8);
  1044. ptiming->range_config__timeout_macrop_b_lo =
  1045. (uint8_t) (timeout_encoded & 0x00FF);
  1046. }
  1047. LOG_FUNCTION_END(0);
  1048. return status;
  1049. }
  1050. uint8_t VL53L1_encode_vcsel_period(uint8_t vcsel_period_pclks)
  1051. {
  1052. /*
  1053. * Converts the encoded VCSEL period register value into
  1054. * the real period in PLL clocks
  1055. */
  1056. uint8_t vcsel_period_reg = 0;
  1057. vcsel_period_reg = (vcsel_period_pclks >> 1) - 1;
  1058. return vcsel_period_reg;
  1059. }
  1060. uint32_t VL53L1_decode_unsigned_integer(
  1061. uint8_t *pbuffer,
  1062. uint8_t no_of_bytes)
  1063. {
  1064. /*
  1065. * Decodes a integer number from the buffer
  1066. */
  1067. uint8_t i = 0;
  1068. uint32_t decoded_value = 0;
  1069. for (i = 0 ; i < no_of_bytes ; i++) {
  1070. decoded_value = (decoded_value << 8) + (uint32_t)pbuffer[i];
  1071. }
  1072. return decoded_value;
  1073. }
  1074. void VL53L1_encode_unsigned_integer(
  1075. uint32_t ip_value,
  1076. uint8_t no_of_bytes,
  1077. uint8_t *pbuffer)
  1078. {
  1079. /*
  1080. * Encodes an integer number into the buffer
  1081. */
  1082. uint8_t i = 0;
  1083. uint32_t data = 0;
  1084. data = ip_value;
  1085. for (i = 0; i < no_of_bytes ; i++) {
  1086. pbuffer[no_of_bytes-i-1] = data & 0x00FF;
  1087. data = data >> 8;
  1088. }
  1089. }
  1090. void VL53L1_spad_number_to_byte_bit_index(
  1091. uint8_t spad_number,
  1092. uint8_t *pbyte_index,
  1093. uint8_t *pbit_index,
  1094. uint8_t *pbit_mask)
  1095. {
  1096. /**
  1097. * Converts the input SPAD number into the SPAD Enable byte index, bit index and bit mask
  1098. *
  1099. * byte_index = (spad_no >> 3)
  1100. * bit_index = spad_no & 0x07
  1101. * bit_mask = 0x01 << bit_index
  1102. */
  1103. *pbyte_index = spad_number >> 3;
  1104. *pbit_index = spad_number & 0x07;
  1105. *pbit_mask = 0x01 << *pbit_index;
  1106. }
  1107. void VL53L1_encode_row_col(
  1108. uint8_t row,
  1109. uint8_t col,
  1110. uint8_t *pspad_number)
  1111. {
  1112. /**
  1113. * Encodes the input array(row,col) location as SPAD number.
  1114. */
  1115. if (row > 7) {
  1116. *pspad_number = 128 + (col << 3) + (15-row);
  1117. } else {
  1118. *pspad_number = ((15-col) << 3) + row;
  1119. }
  1120. }
  1121. void VL53L1_decode_zone_size(
  1122. uint8_t encoded_xy_size,
  1123. uint8_t *pwidth,
  1124. uint8_t *pheight)
  1125. {
  1126. /* extract x and y sizes
  1127. *
  1128. * Important: the sense of the device width and height is swapped
  1129. * versus the API sense
  1130. *
  1131. * MS Nibble = height
  1132. * LS Nibble = width
  1133. */
  1134. *pheight = encoded_xy_size >> 4;
  1135. *pwidth = encoded_xy_size & 0x0F;
  1136. }
  1137. void VL53L1_encode_zone_size(
  1138. uint8_t width,
  1139. uint8_t height,
  1140. uint8_t *pencoded_xy_size)
  1141. {
  1142. /* merge x and y sizes
  1143. *
  1144. * Important: the sense of the device width and height is swapped
  1145. * versus the API sense
  1146. *
  1147. * MS Nibble = height
  1148. * LS Nibble = width
  1149. */
  1150. *pencoded_xy_size = (height << 4) + width;
  1151. }
  1152. void VL53L1_decode_zone_limits(
  1153. uint8_t encoded_xy_centre,
  1154. uint8_t encoded_xy_size,
  1155. int16_t *px_ll,
  1156. int16_t *py_ll,
  1157. int16_t *px_ur,
  1158. int16_t *py_ur)
  1159. {
  1160. /*
  1161. * compute zone lower left and upper right limits
  1162. *
  1163. * centre (8,8) width = 16, height = 16 -> (0,0) -> (15,15)
  1164. * centre (8,8) width = 14, height = 16 -> (1,0) -> (14,15)
  1165. */
  1166. uint8_t x_centre = 0;
  1167. uint8_t y_centre = 0;
  1168. uint8_t width = 0;
  1169. uint8_t height = 0;
  1170. /* decode zone centre and size information */
  1171. VL53L1_decode_row_col(
  1172. encoded_xy_centre,
  1173. &y_centre,
  1174. &x_centre);
  1175. VL53L1_decode_zone_size(
  1176. encoded_xy_size,
  1177. &width,
  1178. &height);
  1179. /* compute bounds and clip */
  1180. *px_ll = (int16_t)x_centre - ((int16_t)width + 1) / 2;
  1181. if (*px_ll < 0)
  1182. *px_ll = 0;
  1183. *px_ur = *px_ll + (int16_t)width;
  1184. if (*px_ur > (VL53L1_SPAD_ARRAY_WIDTH-1))
  1185. *px_ur = VL53L1_SPAD_ARRAY_WIDTH-1;
  1186. *py_ll = (int16_t)y_centre - ((int16_t)height + 1) / 2;
  1187. if (*py_ll < 0)
  1188. *py_ll = 0;
  1189. *py_ur = *py_ll + (int16_t)height;
  1190. if (*py_ur > (VL53L1_SPAD_ARRAY_HEIGHT-1))
  1191. *py_ur = VL53L1_SPAD_ARRAY_HEIGHT-1;
  1192. }
  1193. uint8_t VL53L1_is_aperture_location(
  1194. uint8_t row,
  1195. uint8_t col)
  1196. {
  1197. /*
  1198. * Returns > 0 if input (row,col) location is an aperture
  1199. */
  1200. uint8_t is_aperture = 0;
  1201. uint8_t mod_row = row % 4;
  1202. uint8_t mod_col = col % 4;
  1203. if (mod_row == 0 && mod_col == 2)
  1204. is_aperture = 1;
  1205. if (mod_row == 2 && mod_col == 0)
  1206. is_aperture = 1;
  1207. return is_aperture;
  1208. }
  1209. void VL53L1_calc_mm_effective_spads(
  1210. uint8_t encoded_mm_roi_centre,
  1211. uint8_t encoded_mm_roi_size,
  1212. uint8_t encoded_zone_centre,
  1213. uint8_t encoded_zone_size,
  1214. uint8_t *pgood_spads,
  1215. uint16_t aperture_attenuation,
  1216. uint16_t *pmm_inner_effective_spads,
  1217. uint16_t *pmm_outer_effective_spads)
  1218. {
  1219. /* Calculates the effective SPAD counts for the MM inner and outer
  1220. * regions based on the input MM ROI, Zone info and return good
  1221. * SPAD map
  1222. */
  1223. int16_t x = 0;
  1224. int16_t y = 0;
  1225. int16_t mm_x_ll = 0;
  1226. int16_t mm_y_ll = 0;
  1227. int16_t mm_x_ur = 0;
  1228. int16_t mm_y_ur = 0;
  1229. int16_t zone_x_ll = 0;
  1230. int16_t zone_y_ll = 0;
  1231. int16_t zone_x_ur = 0;
  1232. int16_t zone_y_ur = 0;
  1233. uint8_t spad_number = 0;
  1234. uint8_t byte_index = 0;
  1235. uint8_t bit_index = 0;
  1236. uint8_t bit_mask = 0;
  1237. uint8_t is_aperture = 0;
  1238. uint16_t spad_attenuation = 0;
  1239. /* decode the MM ROI and Zone limits */
  1240. VL53L1_decode_zone_limits(
  1241. encoded_mm_roi_centre,
  1242. encoded_mm_roi_size,
  1243. &mm_x_ll,
  1244. &mm_y_ll,
  1245. &mm_x_ur,
  1246. &mm_y_ur);
  1247. VL53L1_decode_zone_limits(
  1248. encoded_zone_centre,
  1249. encoded_zone_size,
  1250. &zone_x_ll,
  1251. &zone_y_ll,
  1252. &zone_x_ur,
  1253. &zone_y_ur);
  1254. /*
  1255. * Loop though all SPAD within the zone. Check if it is
  1256. * a good SPAD then add the transmission value to either
  1257. * the inner or outer effective SPAD count dependent if
  1258. * the SPAD lies within the MM ROI.
  1259. */
  1260. *pmm_inner_effective_spads = 0;
  1261. *pmm_outer_effective_spads = 0;
  1262. for (y = zone_y_ll ; y <= zone_y_ur ; y++) {
  1263. for (x = zone_x_ll ; x <= zone_x_ur ; x++) {
  1264. /* Convert location into SPAD number */
  1265. VL53L1_encode_row_col(
  1266. (uint8_t)y,
  1267. (uint8_t)x,
  1268. &spad_number);
  1269. /* Convert spad number into byte and bit index
  1270. * this is required to look up the appropriate
  1271. * SPAD enable bit with the 32-byte good SPAD
  1272. * enable buffer
  1273. */
  1274. VL53L1_spad_number_to_byte_bit_index(
  1275. spad_number,
  1276. &byte_index,
  1277. &bit_index,
  1278. &bit_mask);
  1279. /* If spad is good then add it */
  1280. if ((pgood_spads[byte_index] & bit_mask) > 0) {
  1281. /* determine if apertured SPAD or not */
  1282. is_aperture = VL53L1_is_aperture_location(
  1283. (uint8_t)y,
  1284. (uint8_t)x);
  1285. if (is_aperture > 0)
  1286. spad_attenuation = aperture_attenuation;
  1287. else
  1288. spad_attenuation = 0x0100;
  1289. /*
  1290. * if inside MM roi add to inner effective SPAD count
  1291. * otherwise add to outer effective SPAD Count
  1292. */
  1293. if (x >= mm_x_ll && x <= mm_x_ur &&
  1294. y >= mm_y_ll && y <= mm_y_ur)
  1295. *pmm_inner_effective_spads +=
  1296. spad_attenuation;
  1297. else
  1298. *pmm_outer_effective_spads +=
  1299. spad_attenuation;
  1300. }
  1301. }
  1302. }
  1303. }
  1304. /*
  1305. * Encodes VL53L1_GPIO_interrupt_config_t structure to FW register format
  1306. */
  1307. uint8_t VL53L1_encode_GPIO_interrupt_config(
  1308. VL53L1_GPIO_interrupt_config_t *pintconf)
  1309. {
  1310. uint8_t system__interrupt_config;
  1311. system__interrupt_config = pintconf->intr_mode_distance;
  1312. system__interrupt_config |= ((pintconf->intr_mode_rate) << 2);
  1313. system__interrupt_config |= ((pintconf->intr_new_measure_ready) << 5);
  1314. system__interrupt_config |= ((pintconf->intr_no_target) << 6);
  1315. system__interrupt_config |= ((pintconf->intr_combined_mode) << 7);
  1316. return system__interrupt_config;
  1317. }
  1318. /*
  1319. * Decodes FW register to VL53L1_GPIO_interrupt_config_t structure
  1320. */
  1321. VL53L1_GPIO_interrupt_config_t VL53L1_decode_GPIO_interrupt_config(
  1322. uint8_t system__interrupt_config)
  1323. {
  1324. VL53L1_GPIO_interrupt_config_t intconf;
  1325. intconf.intr_mode_distance = system__interrupt_config & 0x03;
  1326. intconf.intr_mode_rate = (system__interrupt_config >> 2) & 0x03;
  1327. intconf.intr_new_measure_ready = (system__interrupt_config >> 5) & 0x01;
  1328. intconf.intr_no_target = (system__interrupt_config >> 6) & 0x01;
  1329. intconf.intr_combined_mode = (system__interrupt_config >> 7) & 0x01;
  1330. /* set some default values */
  1331. intconf.threshold_rate_low = 0;
  1332. intconf.threshold_rate_high = 0;
  1333. intconf.threshold_distance_low = 0;
  1334. intconf.threshold_distance_high = 0;
  1335. return intconf;
  1336. }
  1337. /*
  1338. * Set GPIO distance threshold
  1339. */
  1340. VL53L1_Error VL53L1_set_GPIO_distance_threshold(
  1341. VL53L1_DEV Dev,
  1342. uint16_t threshold_high,
  1343. uint16_t threshold_low)
  1344. {
  1345. VL53L1_Error status = VL53L1_ERROR_NONE;
  1346. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  1347. LOG_FUNCTION_START("");
  1348. pdev->dyn_cfg.system__thresh_high = threshold_high;
  1349. pdev->dyn_cfg.system__thresh_low = threshold_low;
  1350. LOG_FUNCTION_END(status);
  1351. return status;
  1352. }
  1353. /*
  1354. * Set GPIO rate threshold
  1355. */
  1356. VL53L1_Error VL53L1_set_GPIO_rate_threshold(
  1357. VL53L1_DEV Dev,
  1358. uint16_t threshold_high,
  1359. uint16_t threshold_low)
  1360. {
  1361. VL53L1_Error status = VL53L1_ERROR_NONE;
  1362. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  1363. LOG_FUNCTION_START("");
  1364. pdev->gen_cfg.system__thresh_rate_high = threshold_high;
  1365. pdev->gen_cfg.system__thresh_rate_low = threshold_low;
  1366. LOG_FUNCTION_END(status);
  1367. return status;
  1368. }
  1369. /*
  1370. * Set GPIO thresholds from structure
  1371. */
  1372. VL53L1_Error VL53L1_set_GPIO_thresholds_from_struct(
  1373. VL53L1_DEV Dev,
  1374. VL53L1_GPIO_interrupt_config_t *pintconf)
  1375. {
  1376. VL53L1_Error status = VL53L1_ERROR_NONE;
  1377. LOG_FUNCTION_START("");
  1378. status = VL53L1_set_GPIO_distance_threshold(
  1379. Dev,
  1380. pintconf->threshold_distance_high,
  1381. pintconf->threshold_distance_low);
  1382. if (status == VL53L1_ERROR_NONE) {
  1383. status =
  1384. VL53L1_set_GPIO_rate_threshold(
  1385. Dev,
  1386. pintconf->threshold_rate_high,
  1387. pintconf->threshold_rate_low);
  1388. }
  1389. LOG_FUNCTION_END(status);
  1390. return status;
  1391. }
  1392. #ifndef VL53L1_NOCALIB
  1393. VL53L1_Error VL53L1_set_ref_spad_char_config(
  1394. VL53L1_DEV Dev,
  1395. uint8_t vcsel_period_a,
  1396. uint32_t phasecal_timeout_us,
  1397. uint16_t total_rate_target_mcps,
  1398. uint16_t max_count_rate_rtn_limit_mcps,
  1399. uint16_t min_count_rate_rtn_limit_mcps,
  1400. uint16_t fast_osc_frequency)
  1401. {
  1402. /*
  1403. * Initialises the VCSEL period A and phasecal timeout registers
  1404. * for the Reference SPAD Characterisation test
  1405. */
  1406. VL53L1_Error status = VL53L1_ERROR_NONE;
  1407. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  1408. uint8_t buffer[2];
  1409. uint32_t macro_period_us = 0;
  1410. uint32_t timeout_mclks = 0;
  1411. LOG_FUNCTION_START("");
  1412. /*
  1413. * Update Macro Period for Range A VCSEL Period
  1414. */
  1415. macro_period_us =
  1416. VL53L1_calc_macro_period_us(
  1417. fast_osc_frequency,
  1418. vcsel_period_a);
  1419. /*
  1420. * Calculate PhaseCal timeout and clip to max of 255 macro periods
  1421. */
  1422. timeout_mclks = phasecal_timeout_us << 12;
  1423. timeout_mclks = timeout_mclks + (macro_period_us>>1);
  1424. timeout_mclks = timeout_mclks / macro_period_us;
  1425. if (timeout_mclks > 0xFF)
  1426. pdev->gen_cfg.phasecal_config__timeout_macrop = 0xFF;
  1427. else
  1428. pdev->gen_cfg.phasecal_config__timeout_macrop =
  1429. (uint8_t)timeout_mclks;
  1430. pdev->tim_cfg.range_config__vcsel_period_a = vcsel_period_a;
  1431. /*
  1432. * Update device settings
  1433. */
  1434. if (status == VL53L1_ERROR_NONE) /*lint !e774 always true*/
  1435. status =
  1436. VL53L1_WrByte(
  1437. Dev,
  1438. VL53L1_PHASECAL_CONFIG__TIMEOUT_MACROP,
  1439. pdev->gen_cfg.phasecal_config__timeout_macrop);
  1440. if (status == VL53L1_ERROR_NONE)
  1441. status =
  1442. VL53L1_WrByte(
  1443. Dev,
  1444. VL53L1_RANGE_CONFIG__VCSEL_PERIOD_A,
  1445. pdev->tim_cfg.range_config__vcsel_period_a);
  1446. /*
  1447. * Copy vcsel register value to the WOI registers to ensure that
  1448. * it is correctly set for the specified VCSEL period
  1449. */
  1450. buffer[0] = pdev->tim_cfg.range_config__vcsel_period_a;
  1451. buffer[1] = pdev->tim_cfg.range_config__vcsel_period_a;
  1452. if (status == VL53L1_ERROR_NONE)
  1453. status =
  1454. VL53L1_WriteMulti(
  1455. Dev,
  1456. VL53L1_SD_CONFIG__WOI_SD0,
  1457. buffer,
  1458. 2); /* It should be be replaced with a define */
  1459. /*
  1460. * Set min, target and max rate limits
  1461. */
  1462. pdev->customer.ref_spad_char__total_rate_target_mcps =
  1463. total_rate_target_mcps;
  1464. if (status == VL53L1_ERROR_NONE)
  1465. status =
  1466. VL53L1_WrWord(
  1467. Dev,
  1468. VL53L1_REF_SPAD_CHAR__TOTAL_RATE_TARGET_MCPS,
  1469. total_rate_target_mcps); /* 9.7 format */
  1470. if (status == VL53L1_ERROR_NONE)
  1471. status =
  1472. VL53L1_WrWord(
  1473. Dev,
  1474. VL53L1_RANGE_CONFIG__SIGMA_THRESH,
  1475. max_count_rate_rtn_limit_mcps);
  1476. if (status == VL53L1_ERROR_NONE)
  1477. status =
  1478. VL53L1_WrWord(
  1479. Dev,
  1480. VL53L1_RANGE_CONFIG__MIN_COUNT_RATE_RTN_LIMIT_MCPS,
  1481. min_count_rate_rtn_limit_mcps);
  1482. LOG_FUNCTION_END(status);
  1483. return status;
  1484. }
  1485. VL53L1_Error VL53L1_set_ssc_config(
  1486. VL53L1_DEV Dev,
  1487. VL53L1_ssc_config_t *pssc_cfg,
  1488. uint16_t fast_osc_frequency)
  1489. {
  1490. /**
  1491. * Builds and sends a single I2C multiple byte transaction to
  1492. * initialize the device for SSC.
  1493. *
  1494. * The function also sets the WOI registers based on the input
  1495. * vcsel period register value.
  1496. */
  1497. VL53L1_Error status = VL53L1_ERROR_NONE;
  1498. uint8_t buffer[5];
  1499. uint32_t macro_period_us = 0;
  1500. uint16_t timeout_encoded = 0;
  1501. LOG_FUNCTION_START("");
  1502. /*
  1503. * Update Macro Period for Range A VCSEL Period
  1504. */
  1505. macro_period_us =
  1506. VL53L1_calc_macro_period_us(
  1507. fast_osc_frequency,
  1508. pssc_cfg->vcsel_period);
  1509. /*
  1510. * Update MM Timing A timeout
  1511. */
  1512. timeout_encoded =
  1513. VL53L1_calc_encoded_timeout(
  1514. pssc_cfg->timeout_us,
  1515. macro_period_us);
  1516. /* update VCSEL timings */
  1517. if (status == VL53L1_ERROR_NONE)
  1518. status =
  1519. VL53L1_WrByte(
  1520. Dev,
  1521. VL53L1_CAL_CONFIG__VCSEL_START,
  1522. pssc_cfg->vcsel_start);
  1523. if (status == VL53L1_ERROR_NONE)
  1524. status =
  1525. VL53L1_WrByte(
  1526. Dev,
  1527. VL53L1_GLOBAL_CONFIG__VCSEL_WIDTH,
  1528. pssc_cfg->vcsel_width);
  1529. /* build buffer for timeouts, period and rate limit */
  1530. buffer[0] = (uint8_t)((timeout_encoded & 0x0000FF00) >> 8);
  1531. buffer[1] = (uint8_t) (timeout_encoded & 0x000000FF);
  1532. buffer[2] = pssc_cfg->vcsel_period;
  1533. buffer[3] = (uint8_t)((pssc_cfg->rate_limit_mcps & 0x0000FF00) >> 8);
  1534. buffer[4] = (uint8_t) (pssc_cfg->rate_limit_mcps & 0x000000FF);
  1535. if (status == VL53L1_ERROR_NONE)
  1536. status =
  1537. VL53L1_WriteMulti(
  1538. Dev,
  1539. VL53L1_RANGE_CONFIG__TIMEOUT_MACROP_B_HI,
  1540. buffer,
  1541. 5);
  1542. /*
  1543. * Copy vcsel register value to the WOI registers to ensure that
  1544. * it is correctly set for the specified VCSEL period
  1545. */
  1546. buffer[0] = pssc_cfg->vcsel_period;
  1547. buffer[1] = pssc_cfg->vcsel_period;
  1548. if (status == VL53L1_ERROR_NONE)
  1549. status =
  1550. VL53L1_WriteMulti(
  1551. Dev,
  1552. VL53L1_SD_CONFIG__WOI_SD0,
  1553. buffer,
  1554. 2);
  1555. /*
  1556. * Write zero to NVM_BIST_CTRL to send RTN CountRate to Patch RAM
  1557. * or 1 to write REF CountRate to Patch RAM
  1558. */
  1559. if (status == VL53L1_ERROR_NONE)
  1560. status =
  1561. VL53L1_WrByte(
  1562. Dev,
  1563. VL53L1_NVM_BIST__CTRL,
  1564. pssc_cfg->array_select);
  1565. LOG_FUNCTION_END(status);
  1566. return status;
  1567. }
  1568. #endif
  1569. #ifndef VL53L1_NOCALIB
  1570. VL53L1_Error VL53L1_get_spad_rate_data(
  1571. VL53L1_DEV Dev,
  1572. VL53L1_spad_rate_data_t *pspad_rates)
  1573. {
  1574. /**
  1575. * Gets the SSC rate map output
  1576. */
  1577. VL53L1_Error status = VL53L1_ERROR_NONE;
  1578. int i = 0;
  1579. uint8_t data[512];
  1580. uint8_t *pdata = &data[0];
  1581. LOG_FUNCTION_START("");
  1582. /* Disable Firmware to Read Patch Ram */
  1583. if (status == VL53L1_ERROR_NONE)
  1584. status = VL53L1_disable_firmware(Dev);
  1585. /*
  1586. * Read Return SPADs Rates from patch RAM.
  1587. * Note : platform layer splits the I2C comms into smaller chunks
  1588. */
  1589. if (status == VL53L1_ERROR_NONE)
  1590. status =
  1591. VL53L1_ReadMulti(
  1592. Dev,
  1593. VL53L1_PRIVATE__PATCH_BASE_ADDR_RSLV,
  1594. pdata,
  1595. 512);
  1596. /* now convert into 16-bit number */
  1597. pdata = &data[0];
  1598. for (i = 0 ; i < VL53L1_NO_OF_SPAD_ENABLES ; i++) {
  1599. pspad_rates->rate_data[i] =
  1600. (uint16_t)VL53L1_decode_unsigned_integer(pdata, 2);
  1601. pdata += 2;
  1602. }
  1603. /* Initialise structure info */
  1604. pspad_rates->buffer_size = VL53L1_NO_OF_SPAD_ENABLES;
  1605. pspad_rates->no_of_values = VL53L1_NO_OF_SPAD_ENABLES;
  1606. pspad_rates->fractional_bits = 15;
  1607. /* Re-enable Firmware */
  1608. if (status == VL53L1_ERROR_NONE)
  1609. status = VL53L1_enable_firmware(Dev);
  1610. LOG_FUNCTION_END(status);
  1611. return status;
  1612. }
  1613. #endif
  1614. /* Start Patch_LowPowerAutoMode */
  1615. VL53L1_Error VL53L1_low_power_auto_data_init(
  1616. VL53L1_DEV Dev
  1617. )
  1618. {
  1619. /*
  1620. * Initializes internal data structures for low power auto mode
  1621. */
  1622. /* don't really use this here */
  1623. VL53L1_Error status = VL53L1_ERROR_NONE;
  1624. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  1625. LOG_FUNCTION_START("");
  1626. pdev->low_power_auto_data.vhv_loop_bound =
  1627. VL53L1_TUNINGPARM_LOWPOWERAUTO_VHV_LOOP_BOUND_DEFAULT;
  1628. pdev->low_power_auto_data.is_low_power_auto_mode = 0;
  1629. pdev->low_power_auto_data.low_power_auto_range_count = 0;
  1630. pdev->low_power_auto_data.saved_interrupt_config = 0;
  1631. pdev->low_power_auto_data.saved_vhv_init = 0;
  1632. pdev->low_power_auto_data.saved_vhv_timeout = 0;
  1633. pdev->low_power_auto_data.first_run_phasecal_result = 0;
  1634. pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
  1635. pdev->low_power_auto_data.dss__required_spads = 0;
  1636. LOG_FUNCTION_END(status);
  1637. return status;
  1638. }
  1639. VL53L1_Error VL53L1_low_power_auto_data_stop_range(
  1640. VL53L1_DEV Dev
  1641. )
  1642. {
  1643. /*
  1644. * Range has been paused but may continue later
  1645. */
  1646. /* don't really use this here */
  1647. VL53L1_Error status = VL53L1_ERROR_NONE;
  1648. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  1649. LOG_FUNCTION_START("");
  1650. /* doing this ensures stop_range followed by a get_device_results does
  1651. * not mess up the counters */
  1652. pdev->low_power_auto_data.low_power_auto_range_count = 0xFF;
  1653. pdev->low_power_auto_data.first_run_phasecal_result = 0;
  1654. pdev->low_power_auto_data.dss__total_rate_per_spad_mcps = 0;
  1655. pdev->low_power_auto_data.dss__required_spads = 0;
  1656. /* restore vhv configs */
  1657. if (pdev->low_power_auto_data.saved_vhv_init != 0)
  1658. pdev->stat_nvm.vhv_config__init =
  1659. pdev->low_power_auto_data.saved_vhv_init;
  1660. if (pdev->low_power_auto_data.saved_vhv_timeout != 0)
  1661. pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
  1662. pdev->low_power_auto_data.saved_vhv_timeout;
  1663. /* remove phasecal override */
  1664. pdev->gen_cfg.phasecal_config__override = 0x00;
  1665. LOG_FUNCTION_END(status);
  1666. return status;
  1667. }
  1668. VL53L1_Error VL53L1_config_low_power_auto_mode(
  1669. VL53L1_general_config_t *pgeneral,
  1670. VL53L1_dynamic_config_t *pdynamic,
  1671. VL53L1_low_power_auto_data_t *plpadata
  1672. )
  1673. {
  1674. /*
  1675. * Initializes configs for when low power auto presets are selected
  1676. */
  1677. /* don't really use this here */
  1678. VL53L1_Error status = VL53L1_ERROR_NONE;
  1679. LOG_FUNCTION_START("");
  1680. /* set low power auto mode */
  1681. plpadata->is_low_power_auto_mode = 1;
  1682. /* set low power range count to 0 */
  1683. plpadata->low_power_auto_range_count = 0;
  1684. /* Turn off MM1/MM2 and DSS2 */
  1685. pdynamic->system__sequence_config = \
  1686. VL53L1_SEQUENCE_VHV_EN | \
  1687. VL53L1_SEQUENCE_PHASECAL_EN | \
  1688. VL53L1_SEQUENCE_DSS1_EN | \
  1689. /* VL53L1_SEQUENCE_DSS2_EN | \*/
  1690. /* VL53L1_SEQUENCE_MM1_EN | \*/
  1691. /* VL53L1_SEQUENCE_MM2_EN | \*/
  1692. VL53L1_SEQUENCE_RANGE_EN;
  1693. /* Set DSS to manual/expected SPADs */
  1694. pgeneral->dss_config__manual_effective_spads_select = 200 << 8;
  1695. pgeneral->dss_config__roi_mode_control =
  1696. VL53L1_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
  1697. LOG_FUNCTION_END(status);
  1698. return status;
  1699. }
  1700. VL53L1_Error VL53L1_low_power_auto_setup_manual_calibration(
  1701. VL53L1_DEV Dev)
  1702. {
  1703. /*
  1704. * Setup ranges after the first one in low power auto mode by turning
  1705. * off FW calibration steps and programming static values
  1706. */
  1707. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  1708. /* don't really use this here */
  1709. VL53L1_Error status = VL53L1_ERROR_NONE;
  1710. LOG_FUNCTION_START("");
  1711. /* save original vhv configs */
  1712. pdev->low_power_auto_data.saved_vhv_init =
  1713. pdev->stat_nvm.vhv_config__init;
  1714. pdev->low_power_auto_data.saved_vhv_timeout =
  1715. pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound;
  1716. /* disable VHV init */
  1717. pdev->stat_nvm.vhv_config__init &= 0x7F;
  1718. /* set loop bound to tuning param */
  1719. pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound =
  1720. (pdev->stat_nvm.vhv_config__timeout_macrop_loop_bound & 0x03) +
  1721. (pdev->low_power_auto_data.vhv_loop_bound << 2);
  1722. /* override phasecal */
  1723. pdev->gen_cfg.phasecal_config__override = 0x01;
  1724. pdev->low_power_auto_data.first_run_phasecal_result =
  1725. pdev->dbg_results.phasecal_result__vcsel_start;
  1726. pdev->gen_cfg.cal_config__vcsel_start =
  1727. pdev->low_power_auto_data.first_run_phasecal_result;
  1728. LOG_FUNCTION_END(status);
  1729. return status;
  1730. }
  1731. VL53L1_Error VL53L1_low_power_auto_update_DSS(
  1732. VL53L1_DEV Dev)
  1733. {
  1734. /*
  1735. * Do a DSS calculation and update manual config
  1736. */
  1737. VL53L1_LLDriverData_t *pdev = VL53L1DevStructGetLLDriverHandle(Dev);
  1738. /* don't really use this here */
  1739. VL53L1_Error status = VL53L1_ERROR_NONE;
  1740. uint32_t utemp32a;
  1741. LOG_FUNCTION_START("");
  1742. /* Calc total rate per spad */
  1743. /* 9.7 format */
  1744. utemp32a = pdev->sys_results.result__peak_signal_count_rate_crosstalk_corrected_mcps_sd0 +
  1745. pdev->sys_results.result__ambient_count_rate_mcps_sd0;
  1746. /* clip to 16 bits */
  1747. if (utemp32a > 0xFFFF)
  1748. utemp32a = 0xFFFF;
  1749. /* shift up to take advantage of 32 bits */
  1750. /* 9.23 format */
  1751. utemp32a = utemp32a << 16;
  1752. /* check SPAD count */
  1753. if (pdev->sys_results.result__dss_actual_effective_spads_sd0 == 0)
  1754. status = VL53L1_ERROR_DIVISION_BY_ZERO;
  1755. else {
  1756. /* format 17.15 */
  1757. utemp32a = utemp32a /
  1758. pdev->sys_results.result__dss_actual_effective_spads_sd0;
  1759. /* save intermediate result */
  1760. pdev->low_power_auto_data.dss__total_rate_per_spad_mcps =
  1761. utemp32a;
  1762. /* get the target rate and shift up by 16
  1763. * format 9.23 */
  1764. utemp32a = pdev->stat_cfg.dss_config__target_total_rate_mcps <<
  1765. 16;
  1766. /* check for divide by zero */
  1767. if (pdev->low_power_auto_data.dss__total_rate_per_spad_mcps == 0)
  1768. status = VL53L1_ERROR_DIVISION_BY_ZERO;
  1769. else {
  1770. /* divide by rate per spad
  1771. * format 24.8 */
  1772. utemp32a = utemp32a /
  1773. pdev->low_power_auto_data.dss__total_rate_per_spad_mcps;
  1774. /* clip to 16 bit */
  1775. if (utemp32a > 0xFFFF)
  1776. utemp32a = 0xFFFF;
  1777. /* save result in low power auto data */
  1778. pdev->low_power_auto_data.dss__required_spads =
  1779. (uint16_t)utemp32a;
  1780. /* override DSS config */
  1781. pdev->gen_cfg.dss_config__manual_effective_spads_select =
  1782. pdev->low_power_auto_data.dss__required_spads;
  1783. pdev->gen_cfg.dss_config__roi_mode_control =
  1784. VL53L1_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
  1785. }
  1786. }
  1787. if (status == VL53L1_ERROR_DIVISION_BY_ZERO) {
  1788. /* We want to gracefully set a spad target, not just exit with
  1789. * an error */
  1790. /* set target to mid point */
  1791. pdev->low_power_auto_data.dss__required_spads = 0x8000;
  1792. /* override DSS config */
  1793. pdev->gen_cfg.dss_config__manual_effective_spads_select =
  1794. pdev->low_power_auto_data.dss__required_spads;
  1795. pdev->gen_cfg.dss_config__roi_mode_control =
  1796. VL53L1_DEVICEDSSMODE__REQUESTED_EFFFECTIVE_SPADS;
  1797. /* reset error */
  1798. status = VL53L1_ERROR_NONE;
  1799. }
  1800. LOG_FUNCTION_END(status);
  1801. return status;
  1802. }
  1803. /* End Patch_LowPowerAutoMode */