Joel von Rotz / VL53L0X

Dependents:   BigBot_v1 PololuDistanceSensorTest Lidar Ares test ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers vl53l0x_platform.cpp Source File

vl53l0x_platform.cpp

00001 /*******************************************************************************
00002 Copyright � 2015, STMicroelectronics International N.V.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007     * Redistributions of source code must retain the above copyright
00008       notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright
00010       notice, this list of conditions and the following disclaimer in the
00011       documentation and/or other materials provided with the distribution.
00012     * Neither the name of STMicroelectronics nor the
00013       names of its contributors may be used to endorse or promote products
00014       derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
00019 NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS ARE DISCLAIMED.
00020 IN NO EVENT SHALL STMICROELECTRONICS INTERNATIONAL N.V. BE LIABLE FOR ANY
00021 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 ********************************************************************************/
00028 
00029 /**
00030  * @file VL53L0X_i2c.c
00031  *
00032  * Copyright (C) 2014 ST MicroElectronics
00033  *
00034  * provide variable word size byte/Word/dword VL6180x register access via i2c
00035  *
00036  */
00037 #include "mbed.h"
00038 #include "vl53l0x_platform.h"
00039 #include "vl53l0x_api.h"
00040 #include "stdint.h"
00041 
00042 /**
00043  * @def I2C_BUFFER_CONFIG
00044  *
00045  * @brief Configure Device register I2C access
00046  *
00047  * @li 0 : one GLOBAL buffer \n
00048  *   Use one global buffer of MAX_I2C_XFER_SIZE byte in data space \n
00049  *   This solution is not multi-Device compliant nor multi-thread cpu safe \n
00050  *   It can be the best option for small 8/16 bit MCU without stack and limited ram  (STM8s, 80C51 ...)
00051  *
00052  * @li 1 : ON_STACK/local \n
00053  *   Use local variable (on stack) buffer \n
00054  *   This solution is multi-thread with use of i2c resource lock or mutex see VL6180x_GetI2CAccess() \n
00055  *
00056  * @li 2 : User defined \n
00057  *    Per Device potentially dynamic allocated. Requires VL6180x_GetI2cBuffer() to be implemented.
00058  * @ingroup Configuration
00059  */
00060 #define I2C_BUFFER_CONFIG 1
00061 /** Maximum buffer size to be used in i2c */
00062 #define VL53L0X_MAX_I2C_XFER_SIZE 64 /* Maximum buffer size to be used in i2c */
00063 
00064 #if I2C_BUFFER_CONFIG == 0
00065 /* GLOBAL config buffer */
00066   uint8_t i2c_global_buffer[VL53L0X_MAX_I2C_XFER_SIZE];
00067 
00068   #define DECL_I2C_BUFFER
00069   #define VL53L0X_GetLocalBuffer(Dev, n_byte) i2c_global_buffer
00070 
00071 #elif I2C_BUFFER_CONFIG == 1
00072 /* ON STACK */
00073   #define DECL_I2C_BUFFER uint8_t LocBuffer[VL53L0X_MAX_I2C_XFER_SIZE];
00074   #define VL53L0X_GetLocalBuffer(Dev, n_byte) LocBuffer
00075 #elif I2C_BUFFER_CONFIG == 2
00076 /* user define buffer type declare DECL_I2C_BUFFER  as access  via VL53L0X_GetLocalBuffer */
00077   #define DECL_I2C_BUFFER
00078 #else
00079   #error "invalid I2C_BUFFER_CONFIG "
00080 #endif
00081 
00082 VL53L0X_Error VL53L0X_LockSequenceAccess(VL53L0X_DEV Dev)
00083 {
00084   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00085 
00086   return Status;
00087 }
00088 
00089 VL53L0X_Error VL53L0X_UnlockSequenceAccess(VL53L0X_DEV Dev)
00090 {
00091   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00092 
00093   return Status;
00094 }
00095 
00096 VL53L0X_Error VL53L0X_WriteMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata, uint32_t count)
00097 {
00098   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00099   int32_t status_int = 0;
00100 
00101   char data[count+1];
00102   data[0]=index;
00103   for (int i = 1; i< count+1; i++)
00104   {
00105       data[i]=pdata[i-1];
00106   }
00107   status_int = Dev->i2c_device->write((Dev->i2c_address << 1), data, static_cast<int>(count));
00108 
00109   if (status_int != 0)
00110   {
00111     Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00112   }
00113 
00114   return Status;
00115 }
00116 
00117 // the ranging_sensor_comms.dll will take care of the page selection
00118 VL53L0X_Error VL53L0X_ReadMulti(VL53L0X_DEV Dev, uint8_t index, uint8_t *pdata, uint32_t count)
00119 {
00120   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00121   int32_t status_int;
00122   char i2c_package_cmd[1];
00123   char i2c_package_data[count];
00124   
00125 
00126   if (count >= VL53L0X_MAX_I2C_XFER_SIZE)
00127   {
00128     
00129     Status = VL53L0X_ERROR_INVALID_PARAMS;
00130   }
00131   else  
00132   {
00133     i2c_package_cmd[0]=index;
00134     status_int = Dev->i2c_device->write((Dev->i2c_address << 1), i2c_package_cmd, 1, true);
00135     status_int = Dev->i2c_device->read( (Dev->i2c_address << 1), i2c_package_data, count);
00136   }
00137 
00138   for(int x = 0 ; x < count ; x++)
00139   {
00140     pdata[x] = i2c_package_data[x];
00141   }
00142 
00143   if (status_int != 0)
00144   {
00145     Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00146   }
00147 
00148   return Status;
00149 }
00150 
00151 VL53L0X_Error VL53L0X_WrByte(VL53L0X_DEV Dev, uint8_t index, uint8_t data)
00152 {
00153   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00154   int32_t status_int;
00155   char i2c_package[2];
00156   i2c_package[0] = index;
00157   i2c_package[1] = data;  
00158 
00159   status_int = Dev->i2c_device->write((Dev->i2c_address << 1), i2c_package, 2);
00160 
00161   if (status_int != 0)
00162   {
00163     Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00164   }
00165 
00166   return Status;
00167 }
00168 
00169 VL53L0X_Error VL53L0X_WrWord(VL53L0X_DEV Dev, uint8_t index, uint16_t data)
00170 {
00171   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00172   int32_t status_int;
00173   char i2c_package[3];
00174   i2c_package[0] = index;
00175   i2c_package[1] = (data >> 8) & 0xFF;  
00176   i2c_package[2] = (data >> 0) & 0xFF;  
00177 
00178   status_int = Dev->i2c_device->write((Dev->i2c_address << 1), i2c_package, 3);
00179 
00180   if (status_int != 0)
00181   {
00182     Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00183   }
00184 
00185   return Status;
00186 }
00187 
00188 VL53L0X_Error VL53L0X_WrDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t data)
00189 {
00190   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00191   int32_t status_int;
00192 
00193   char i2c_package[5];
00194   i2c_package[0] = index;
00195   i2c_package[1] = (data >> 24) & 0xFF;  
00196   i2c_package[2] = (data >> 16) & 0xFF;  
00197   i2c_package[3] = (data >>  8) & 0xFF;  
00198   i2c_package[4] = (data >>  0) & 0xFF;  
00199 
00200   status_int = Dev->i2c_device->write((Dev->i2c_address << 1), i2c_package, 5);
00201 
00202   if (status_int != 0)
00203   {
00204     Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00205   }
00206   return Status;
00207 }
00208 
00209 VL53L0X_Error VL53L0X_UpdateByte(VL53L0X_DEV Dev, uint8_t index, uint8_t AndData, uint8_t OrData)
00210 {
00211   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00212   int32_t status_int;
00213   char data;
00214   char ind = index;
00215   status_int = Dev->i2c_device->write((Dev->i2c_address << 1), &ind, 1, true);
00216   status_int = Dev->i2c_device->read((Dev->i2c_address << 1), &data, 1);
00217 
00218   if (status_int != 0)
00219   {
00220     Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00221   }
00222 
00223   if (Status == VL53L0X_ERROR_NONE)
00224   {
00225     data = (data & AndData) | OrData;
00226 
00227     status_int = Dev->i2c_device->write((Dev->i2c_address << 1), &data, 1);
00228 
00229     if (status_int != 0)
00230     {
00231       Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00232     }
00233   }
00234 
00235   return Status;
00236 }
00237 
00238 VL53L0X_Error VL53L0X_RdByte(VL53L0X_DEV Dev, uint8_t index, uint8_t *data)
00239 {
00240   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00241   int32_t status_int;
00242   char  pdata;
00243   char  ind = index;
00244 
00245   status_int = Dev->i2c_device->write((Dev->i2c_address << 1), &ind, 1, true);
00246   status_int = Dev->i2c_device->read((Dev->i2c_address << 1), &pdata, 1);
00247 
00248   *data = pdata;
00249 
00250   if (status_int != 0)
00251   {
00252     Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00253   }
00254 
00255   return Status;
00256 }
00257 
00258 VL53L0X_Error VL53L0X_RdWord(VL53L0X_DEV Dev, uint8_t index, uint16_t *data)
00259 {
00260   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00261   int32_t   status_int;
00262   char      pdata[2];
00263   char      ind = index;
00264   uint16_t  tmp = 0;
00265 
00266   status_int = Dev->i2c_device->write((Dev->i2c_address << 1), &ind, 1, true);
00267   status_int = Dev->i2c_device->read((Dev->i2c_address << 1), pdata, 2);
00268   tmp |= pdata[1]<<0;
00269   tmp |= pdata[0]<<8;
00270   *data = tmp;
00271 
00272   if (status_int != 0)
00273   {
00274     Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00275   }
00276 
00277 
00278   return Status;
00279 }
00280 
00281 VL53L0X_Error VL53L0X_RdDWord(VL53L0X_DEV Dev, uint8_t index, uint32_t *data)
00282 {
00283   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
00284   int32_t   status_int;
00285   char      pdata[4];
00286   char      ind = index;
00287   uint32_t  tmp = 0;
00288 
00289   status_int = Dev->i2c_device->write((Dev->i2c_address << 1), &ind, 1, true);
00290   status_int = Dev->i2c_device->read((Dev->i2c_address << 1), pdata, 4);
00291   tmp |= pdata[3]<<0;
00292   tmp |= pdata[2]<<8;
00293   tmp |= pdata[1]<<16;
00294   tmp |= pdata[0]<<24;
00295   *data = tmp;
00296 
00297   if (status_int != 0)
00298   {
00299     Status = VL53L0X_ERROR_CONTROL_INTERFACE;
00300   }
00301 
00302   return Status;
00303 }
00304 
00305 #define VL53L0X_POLLINGDELAY_LOOPNB 250
00306 
00307 VL53L0X_Error VL53L0X_PollingDelay(VL53L0X_DEV Dev)
00308 {
00309   VL53L0X_Error status = VL53L0X_ERROR_NONE;
00310   volatile uint32_t i;
00311   for(i=0;i<VL53L0X_POLLINGDELAY_LOOPNB;i++){
00312     //Do nothing
00313     asm("nop");
00314   }
00315   return status;
00316 }