diff --git a/vl53l1_api.c b/vl53l1_api.c index 062ff06..849d8ac 100755 --- a/vl53l1_api.c +++ b/vl53l1_api.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2017, STMicroelectronics - All Rights Reserved +* Modified by Pololu Corporation, 2018 * * This file is part of VL53L1 Core and is dual licensed, * either 'STMicroelectronics @@ -755,6 +756,8 @@ VL53L1_Error VL53L1_SetDeviceAddress(VL53L1_DEV Dev, uint8_t DeviceAddress) return Status; } +#define USE_I2C_2V8 + VL53L1_Error VL53L1_DataInit(VL53L1_DEV Dev) { VL53L1_Error Status = VL53L1_ERROR_NONE; diff --git a/vl53l1_core.c b/vl53l1_core.c index 8d93e66..2f74bf4 100755 --- a/vl53l1_core.c +++ b/vl53l1_core.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, STMicroelectronics - All Rights Reserved +* Modified by Pololu Corporation, 2018 * * This file is part of VL53L1 Core and is dual licensed, * either 'STMicroelectronics @@ -2297,7 +2298,7 @@ VL53L1_Error VL53L1_low_power_auto_update_DSS( /* get the target rate and shift up by 16 * format 9.23 */ - utemp32a = pdev->stat_cfg.dss_config__target_total_rate_mcps << + utemp32a = (uint32_t)pdev->stat_cfg.dss_config__target_total_rate_mcps << 16; /* check for divide by zero */ diff --git a/vl53l1_core_support.c b/vl53l1_core_support.c index 23a4615..3cbcd15 100755 --- a/vl53l1_core_support.c +++ b/vl53l1_core_support.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, STMicroelectronics - All Rights Reserved +* Modified by Pololu Corporation, 2018 * * This file is part of VL53L1 Core and is dual licensed, * either 'STMicroelectronics @@ -111,7 +112,7 @@ uint32_t VL53L1_calc_pll_period_us( LOG_FUNCTION_START(""); - pll_period_us = (0x01 << 30) / fast_osc_frequency; + pll_period_us = ((uint32_t)0x01 << 30) / fast_osc_frequency; #ifdef VL53L1_LOGGING trace_print(VL53L1_TRACE_LEVEL_DEBUG, diff --git a/vl53l1_platform.c b/vl53l1_platform.cpp similarity index 55% rename from vl53l1_platform.c rename to vl53l1_platform.cpp index fe5493e..f636cde 100755 --- a/vl53l1_platform.c +++ b/vl53l1_platform.cpp @@ -1,6 +1,11 @@ +/******************************************************************************* -/* +This file is derived from vl53l1_platform.c in the STSW-IMG007 VL53L1X API. + +******************************************************************************** +* * Copyright (c) 2017, STMicroelectronics - All Rights Reserved +* Copyright (c) 2018 Pololu Corporation * * This file is part of VL53L1 Core and is dual licensed, * either 'STMicroelectronics @@ -61,6 +66,8 @@ * */ +#include +#include #include "vl53l1_platform.h" // #include "vl53l1_platform_log.h" @@ -112,57 +119,136 @@ // return Status; // } -VL53L1_Error VL53L1_WriteMulti(VL53L1_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count) { - VL53L1_Error Status = VL53L1_ERROR_NONE; - return Status; +VL53L1_Error VL53L1_WriteMulti(VL53L1_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count) +{ + while (count > 0) + { + Wire.beginTransmission(Dev->I2cDevAddr >> 1); + Wire.write((index >> 8) & 0xff); + Wire.write(index & 0xff); + + uint8_t writing = 0; + + while (count > 0 && Wire.write(*pdata) != 0) + { + pdata++; + writing++; + count--; + } + + if (writing == 0 || Wire.endTransmission() != 0) { return VL53L1_ERROR_CONTROL_INTERFACE; } + index += writing; + } + + return VL53L1_ERROR_NONE; } -// the ranging_sensor_comms.dll will take care of the page selection -VL53L1_Error VL53L1_ReadMulti(VL53L1_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count) { - VL53L1_Error Status = VL53L1_ERROR_NONE; - return Status; +VL53L1_Error VL53L1_ReadMulti(VL53L1_DEV Dev, uint16_t index, uint8_t *pdata, uint32_t count) +{ + Wire.beginTransmission(Dev->I2cDevAddr >> 1); + Wire.write((index >> 8) & 0xff); + Wire.write(index & 0xff); + if (Wire.endTransmission() != 0) { return VL53L1_ERROR_CONTROL_INTERFACE; } + + while (count > 0) + { + uint8_t reading = Wire.requestFrom(Dev->I2cDevAddr >> 1, count); + + if (reading == 0) { return VL53L1_ERROR_CONTROL_INTERFACE; } + count -= reading; + + while (reading-- > 0) + { + *pdata++ = Wire.read(); + } + } + + return VL53L1_ERROR_NONE; } -VL53L1_Error VL53L1_WrByte(VL53L1_DEV Dev, uint16_t index, uint8_t data) { - VL53L1_Error Status = VL53L1_ERROR_NONE; - return Status; +VL53L1_Error VL53L1_WrByte(VL53L1_DEV Dev, uint16_t index, uint8_t data) +{ + Wire.beginTransmission(Dev->I2cDevAddr >> 1); + Wire.write((index >> 8) & 0xff); + Wire.write(index & 0xff); + Wire.write(data); + return (Wire.endTransmission() == 0 ? VL53L1_ERROR_NONE : VL53L1_ERROR_CONTROL_INTERFACE); } -VL53L1_Error VL53L1_WrWord(VL53L1_DEV Dev, uint16_t index, uint16_t data) { - VL53L1_Error Status = VL53L1_ERROR_NONE; - return Status; +VL53L1_Error VL53L1_WrWord(VL53L1_DEV Dev, uint16_t index, uint16_t data) +{ + Wire.beginTransmission(Dev->I2cDevAddr >> 1); + Wire.write((index >> 8) & 0xff); + Wire.write(index & 0xff); + Wire.write((data >> 8) & 0xff); + Wire.write(data & 0xff); + return (Wire.endTransmission() == 0 ? VL53L1_ERROR_NONE : VL53L1_ERROR_CONTROL_INTERFACE); } -VL53L1_Error VL53L1_WrDWord(VL53L1_DEV Dev, uint16_t index, uint32_t data) { - VL53L1_Error Status = VL53L1_ERROR_NONE; - return Status; +VL53L1_Error VL53L1_WrDWord(VL53L1_DEV Dev, uint16_t index, uint32_t data) +{ + Wire.beginTransmission(Dev->I2cDevAddr >> 1); + Wire.write((index >> 8) & 0xff); + Wire.write(index & 0xff); + Wire.write((data >> 24) & 0xff); + Wire.write((data >> 16) & 0xff); + Wire.write((data >> 8) & 0xff); + Wire.write(data & 0xff); + return (Wire.endTransmission() == 0 ? VL53L1_ERROR_NONE : VL53L1_ERROR_CONTROL_INTERFACE); } -VL53L1_Error VL53L1_UpdateByte(VL53L1_DEV Dev, uint16_t index, uint8_t AndData, uint8_t OrData) { - VL53L1_Error Status = VL53L1_ERROR_NONE; - return Status; +VL53L1_Error VL53L1_UpdateByte(VL53L1_DEV Dev, uint16_t index, uint8_t AndData, uint8_t OrData) +{ + uint8_t data; + VL53L1_Error status = VL53L1_RdByte(Dev, index, &data); + if (status != VL53L1_ERROR_NONE) { return status; } + data &= AndData; + data |= OrData; + return VL53L1_WrByte(Dev, index, data); } -VL53L1_Error VL53L1_RdByte(VL53L1_DEV Dev, uint16_t index, uint8_t *data) { - VL53L1_Error Status = VL53L1_ERROR_NONE; - return Status; +VL53L1_Error VL53L1_RdByte(VL53L1_DEV Dev, uint16_t index, uint8_t *data) +{ + Wire.beginTransmission(Dev->I2cDevAddr >> 1); + Wire.write((index >> 8) & 0xff); + Wire.write(index & 0xff); + if (Wire.endTransmission() != 0) { return VL53L1_ERROR_CONTROL_INTERFACE; } + if (Wire.requestFrom(Dev->I2cDevAddr >> 1, 1) != 1) { return VL53L1_ERROR_CONTROL_INTERFACE; } + *data = Wire.read(); + return VL53L1_ERROR_NONE; } -VL53L1_Error VL53L1_RdWord(VL53L1_DEV Dev, uint16_t index, uint16_t *data) { - VL53L1_Error Status = VL53L1_ERROR_NONE; - return Status; +VL53L1_Error VL53L1_RdWord(VL53L1_DEV Dev, uint16_t index, uint16_t *data) +{ + Wire.beginTransmission(Dev->I2cDevAddr >> 1); + Wire.write((index >> 8) & 0xff); + Wire.write(index & 0xff); + if (Wire.endTransmission() != 0) { return VL53L1_ERROR_CONTROL_INTERFACE; } + if (Wire.requestFrom(Dev->I2cDevAddr >> 1, 2) != 2) { return VL53L1_ERROR_CONTROL_INTERFACE; } + *data = (uint16_t)Wire.read() << 8; + *data |= Wire.read(); + return VL53L1_ERROR_NONE; } -VL53L1_Error VL53L1_RdDWord(VL53L1_DEV Dev, uint16_t index, uint32_t *data) { - VL53L1_Error Status = VL53L1_ERROR_NONE; - return Status; +VL53L1_Error VL53L1_RdDWord(VL53L1_DEV Dev, uint16_t index, uint32_t *data) +{ + Wire.beginTransmission(Dev->I2cDevAddr >> 1); + Wire.write((index >> 8) & 0xff); + Wire.write(index & 0xff); + if (Wire.endTransmission() != 0) { return VL53L1_ERROR_CONTROL_INTERFACE; } + if (Wire.requestFrom(Dev->I2cDevAddr >> 1, 4) != 4) { return VL53L1_ERROR_CONTROL_INTERFACE; } + *data = (uint32_t)Wire.read() << 24; + *data |= (uint32_t)Wire.read() << 16; + *data |= (uint16_t)Wire.read() << 8; + *data |= Wire.read(); + return VL53L1_ERROR_NONE; } VL53L1_Error VL53L1_GetTickCount( uint32_t *ptick_count_ms) { - VL53L1_Error status = VL53L1_ERROR_NONE; - return status; + *ptick_count_ms = millis(); + return VL53L1_ERROR_NONE; } //#define trace_print(level, ...) \ @@ -175,18 +261,19 @@ VL53L1_Error VL53L1_GetTickCount( VL53L1_Error VL53L1_GetTimerFrequency(int32_t *ptimer_freq_hz) { - VL53L1_Error status = VL53L1_ERROR_NONE; - return status; + return VL53L1_ERROR_NOT_IMPLEMENTED; } -VL53L1_Error VL53L1_WaitMs(VL53L1_Dev_t *pdev, int32_t wait_ms){ - VL53L1_Error status = VL53L1_ERROR_NONE; - return status; +VL53L1_Error VL53L1_WaitMs(VL53L1_Dev_t *pdev, int32_t wait_ms) +{ + delay(wait_ms); + return VL53L1_ERROR_NONE; } -VL53L1_Error VL53L1_WaitUs(VL53L1_Dev_t *pdev, int32_t wait_us){ - VL53L1_Error status = VL53L1_ERROR_NONE; - return status; +VL53L1_Error VL53L1_WaitUs(VL53L1_Dev_t *pdev, int32_t wait_us) +{ + delayMicroseconds(wait_us); + return VL53L1_ERROR_NONE; } VL53L1_Error VL53L1_WaitValueMaskEx( @@ -197,8 +284,19 @@ VL53L1_Error VL53L1_WaitValueMaskEx( uint8_t mask, uint32_t poll_delay_ms) { - VL53L1_Error status = VL53L1_ERROR_NONE; - return status; + uint8_t data; + VL53L1_Error status; + + while (timeout_ms > 0) + { + status = VL53L1_RdByte(pdev, index, &data); + if (status != VL53L1_ERROR_NONE) { return status; } + if ((data & mask) == value) { return VL53L1_ERROR_NONE; } + delay(poll_delay_ms); + timeout_ms -= min(poll_delay_ms, timeout_ms); + } + + return VL53L1_ERROR_TIME_OUT; } diff --git a/vl53l1x-st-api.ino b/vl53l1x-st-api.ino new file mode 100644 index 0000000..3f63c6d --- /dev/null +++ b/vl53l1x-st-api.ino @@ -0,0 +1,114 @@ +/******************************************************************************* + +This sketch file is derived from an example program +(Projects\Multi\Examples\VL53L1X\SimpleRangingExamples\Src\main.c) in the +X-CUBE-53L1A1 Long Distance Ranging sensor software expansion for STM32Cube +from ST, available here: + +http://www.st.com/content/st_com/en/products/ecosystems/stm32-open-development-environment/stm32cube-expansion-software/stm32-ode-sense-sw/x-cube-53l1a1.html + +The rest of the files in this sketch are from the STSW-IMG007 VL53L1X API from +ST, available here: + +http://www.st.com/content/st_com/en/products/embedded-software/proximity-sensors-software/stsw-img007.html + +******************************************************************************** + +COPYRIGHT(c) 2017 STMicroelectronics +COPYRIGHT(c) 2018 Pololu Corporation + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + 3. Neither the name of STMicroelectronics nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include +#include "vl53l1_api.h" + +VL53L1_Dev_t dev; +VL53L1_DEV Dev = &dev; +int status; + +void setup() +{ + uint8_t byteData; + uint16_t wordData; + + Wire.begin(); + Wire.setClock(400000); + + Dev->I2cDevAddr = 0x52; + + VL53L1_software_reset(Dev); + + VL53L1_RdByte(Dev, 0x010F, &byteData); + Serial.print(F("VL53L1X Model_ID: ")); + Serial.println(byteData, HEX); + VL53L1_RdByte(Dev, 0x0110, &byteData); + Serial.print(F("VL53L1X Module_Type: ")); + Serial.println(byteData, HEX); + VL53L1_RdWord(Dev, 0x010F, &wordData); + Serial.print(F("VL53L1X: ")); + Serial.println(wordData, HEX); + + Serial.println(F("Autonomous Ranging Test")); + status = VL53L1_WaitDeviceBooted(Dev); + status = VL53L1_DataInit(Dev); + status = VL53L1_StaticInit(Dev); + status = VL53L1_SetDistanceMode(Dev, VL53L1_DISTANCEMODE_LONG); + status = VL53L1_SetMeasurementTimingBudgetMicroSeconds(Dev, 50000); + status = VL53L1_SetInterMeasurementPeriodMilliSeconds(Dev, 50); // reduced to 50 ms from 500 ms in ST example + status = VL53L1_StartMeasurement(Dev); + + if(status) + { + Serial.println(F("VL53L1_StartMeasurement failed")); + while(1); + } +} + +void loop() +{ + static VL53L1_RangingMeasurementData_t RangingData; + + status = VL53L1_WaitMeasurementDataReady(Dev); + if(!status) + { + status = VL53L1_GetRangingMeasurementData(Dev, &RangingData); + if(status==0) + { + Serial.print(RangingData.RangeStatus); + Serial.print(F(",")); + Serial.print(RangingData.RangeMilliMeter); + Serial.print(F(",")); + Serial.print(RangingData.SignalRateRtnMegaCps/65536.0); + Serial.print(F(",")); + Serial.println(RangingData.AmbientRateRtnMegaCps/65336.0); + } + status = VL53L1_ClearInterruptAndStartMeasurement(Dev); + } + else + { + Serial.print(F("error waiting for data ready: ")); + Serial.println(status); + } +}