Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @file VL53L0X.h
- * @author Ryotaro Onuki ([email protected])
- * @brief C Library for VL53L0X as an ESP-IDF component
- * @copyright Copyright (c) 2018 Ryotaro Onuki
- */
- #ifndef VL53L0X_H
- #define VL53L0X_H
- #include "freertos/FreeRTOS.h"
- #include "freertos/semphr.h"
- #include "freertos/task.h"
- #include "driver/gpio.h"
- #include "driver/i2c.h"
- #include "vl53l0x_api.h"
- #include "vl53l0x_def.h"
- #include "vl53l0x_platform.h"
- #include "esp_log.h"
- #define VL53L0X_I2C_ADDRESS_DEFAULT 0x29
- typedef struct {
- i2c_port_t i2c_port;
- gpio_num_t gpio_xshut;
- gpio_num_t gpio_gpio1;
- VL53L0X_Dev_t vl53l0x_dev;
- SemaphoreHandle_t xSemaphore;
- int32_t TimingBudgetMicroSeconds;
- } VL53L0X;
- bool VL53L0X_Init(VL53L0X *dev);
- bool VL53L0X_Reset(VL53L0X *dev);
- bool VL53L0X_HardwareReset(VL53L0X *dev);
- bool VL53L0X_SoftwareReset(VL53L0X *dev);
- bool VL53L0X_SetDeviceAddress(VL53L0X *dev, uint8_t new_address);
- bool VL53L0X_Read(VL53L0X *dev, uint16_t *pRangeMilliMeter);
- bool VL53L0X_ReadSingleWithPolling(VL53L0X *dev, uint16_t *pRangeMilliMeter);
- bool VL53L0X_ReadSingleWithDelay(VL53L0X *dev, uint16_t *pRangeMilliMeter);
- bool VL53L0X_ReadSingleWithInterrupt(VL53L0X *dev, uint16_t *pRangeMilliMeter);
- void VL53L0X_I2CMasterInit(VL53L0X *dev, gpio_num_t pin_sda, gpio_num_t pin_scl, uint32_t freq);
- bool VL53L0X_SetTimingBudget(VL53L0X *dev, uint32_t TimingBudgetMicroSeconds);
- #endif // VL53L0X_H
- // Definitions
- #include <string.h>
- #include "esp_log.h"
- #define TAG "VL53L0X"
- static void IRAM_ATTR gpio1_isr(void *arg) {
- VL53L0X *obj = (VL53L0X *)arg;
- xSemaphoreGiveFromISR(obj->xSemaphore, NULL);
- }
- static VL53L0X_Error print_pal_error(VL53L0X_Error status, const char *method) {
- char buf[VL53L0X_MAX_STRING_LENGTH];
- VL53L0X_GetPalErrorString(status, buf);
- ESP_LOGE(TAG, "%s API status: %i : %s\n", method, status, buf);
- return status;
- }
- static VL53L0X_Error init_vl53l0x(VL53L0X_Dev_t *pDevice) {
- VL53L0X_Error status;
- uint8_t isApertureSpads;
- uint8_t PhaseCal;
- uint32_t refSpadCount;
- uint8_t VhvSettings;
- status = VL53L0X_DataInit(pDevice);
- if (status != VL53L0X_ERROR_NONE)
- return print_pal_error(status, "VL53L0X_DataInit");
- status = VL53L0X_StaticInit(pDevice);
- if (status != VL53L0X_ERROR_NONE)
- return print_pal_error(status, "VL53L0X_StaticInit");
- status = VL53L0X_PerformRefSpadManagement(pDevice, &refSpadCount, &isApertureSpads);
- ESP_LOGI(TAG, "refSpadCount = %" PRIu32 ", isApertureSpads = %" PRIu8 "\n", refSpadCount, isApertureSpads);
- if (status != VL53L0X_ERROR_NONE)
- return print_pal_error(status, "VL53L0X_PerformRefSpadManagement");
- status = VL53L0X_PerformRefCalibration(pDevice, &VhvSettings, &PhaseCal);
- if (status != VL53L0X_ERROR_NONE)
- return print_pal_error(status, "VL53L0X_PerformRefCalibration");
- status = VL53L0X_SetDeviceMode(pDevice, VL53L0X_DEVICEMODE_SINGLE_RANGING);
- if (status != VL53L0X_ERROR_NONE)
- return print_pal_error(status, "VL53L0X_SetDeviceMode");
- return status;
- }
- bool VL53L0X_Init(VL53L0X *dev) {
- if (dev->gpio_xshut != GPIO_NUM_MAX) {
- gpio_set_direction(dev->gpio_xshut, GPIO_MODE_OUTPUT);
- gpio_set_level(dev->gpio_xshut, 1);
- }
- if (dev->gpio_gpio1 != GPIO_NUM_MAX) {
- ESP_ERROR_CHECK(gpio_set_direction(dev->gpio_gpio1, GPIO_MODE_INPUT));
- ESP_ERROR_CHECK(gpio_set_pull_mode(dev->gpio_gpio1, GPIO_PULLUP_ONLY));
- ESP_ERROR_CHECK(gpio_pullup_en(dev->gpio_gpio1));
- ESP_ERROR_CHECK(gpio_set_intr_type(dev->gpio_gpio1, GPIO_INTR_POSEDGE));
- ESP_ERROR_CHECK(gpio_install_isr_service(0));
- ESP_ERROR_CHECK(gpio_isr_handler_add(dev->gpio_gpio1, gpio1_isr, dev));
- ESP_ERROR_CHECK(gpio_intr_enable(dev->gpio_gpio1));
- }
- dev->vl53l0x_dev.i2c_port_num = dev->i2c_port;
- dev->vl53l0x_dev.i2c_address = VL53L0X_I2C_ADDRESS_DEFAULT;
- VL53L0X_Reset(dev);
- if (init_vl53l0x(&dev->vl53l0x_dev) != VL53L0X_ERROR_NONE)
- return false;
- if (VL53L0X_ERROR_NONE !=
- VL53L0X_SetGpioConfig(&dev->vl53l0x_dev, 0, VL53L0X_DEVICEMODE_SINGLE_RANGING,
- VL53L0X_GPIOFUNCTIONALITY_NEW_MEASURE_READY,
- VL53L0X_INTERRUPTPOLARITY_LOW))
- return false;
- if (!VL53L0X_SetTimingBudget(dev, 33000))
- return false;
- return true;
- }
- bool VL53L0X_Reset(VL53L0X *dev) {
- if (!VL53L0X_SoftwareReset(dev))
- return VL53L0X_HardwareReset(dev);
- return true;
- }
- bool VL53L0X_HardwareReset(VL53L0X *dev) {
- if (dev->gpio_xshut == GPIO_NUM_MAX)
- return false;
- gpio_set_level(dev->gpio_xshut, 0);
- vTaskDelay(10 / portTICK_PERIOD_MS);
- gpio_set_level(dev->gpio_xshut, 1);
- vTaskDelay(10 / portTICK_PERIOD_MS);
- return true;
- }
- bool VL53L0X_SoftwareReset(VL53L0X *dev) {
- VL53L0X_Error status = VL53L0X_ResetDevice(&dev->vl53l0x_dev);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_ResetDevice");
- return false;
- }
- return true;
- }
- bool VL53L0X_SetDeviceAddress(VL53L0X *dev, uint8_t new_address) {
- VL53L0X_Error status =
- VL53L0X_SetDeviceAddress(&dev->vl53l0x_dev, new_address << 1);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_SetDeviceAddress");
- return false;
- }
- dev->vl53l0x_dev.i2c_address = new_address;
- return true;
- }
- bool VL53L0X_Read(VL53L0X *dev, uint16_t *pRangeMilliMeter) {
- if (dev->gpio_gpio1 != GPIO_NUM_MAX)
- return VL53L0X_ReadSingleWithInterrupt(dev, pRangeMilliMeter);
- return VL53L0X_ReadSingleWithPolling(dev, pRangeMilliMeter);
- }
- bool VL53L0X_ReadSingleWithPolling(VL53L0X *dev, uint16_t *pRangeMilliMeter) {
- VL53L0X_RangingMeasurementData_t MeasurementData;
- VL53L0X_Error status =
- VL53L0X_PerformSingleRangingMeasurement(&dev->vl53l0x_dev, &MeasurementData);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_PerformSingleRangingMeasurement");
- return false;
- }
- *pRangeMilliMeter = MeasurementData.RangeMilliMeter;
- if (MeasurementData.RangeStatus != 0)
- return false;
- return true;
- }
- bool VL53L0X_ReadSingleWithDelay(VL53L0X *dev, uint16_t *pRangeMilliMeter) {
- TickType_t xTicksToWait = dev->TimingBudgetMicroSeconds / 1000 / portTICK_PERIOD_MS;
- VL53L0X_Error status;
- status = VL53L0X_SetDeviceMode(&dev->vl53l0x_dev, VL53L0X_DEVICEMODE_SINGLE_RANGING);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_SetDeviceMode");
- return false;
- }
- status = VL53L0X_StartMeasurement(&dev->vl53l0x_dev);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_StartMeasurement");
- return false;
- }
- vTaskDelay(xTicksToWait);
- VL53L0X_RangingMeasurementData_t MeasurementData;
- status = VL53L0X_GetRangingMeasurementData(&dev->vl53l0x_dev, &MeasurementData);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_GetRangingMeasurementData");
- return false;
- }
- *pRangeMilliMeter = MeasurementData.RangeMilliMeter;
- if (MeasurementData.RangeStatus != 0)
- return false;
- VL53L0X_ClearInterruptMask(&dev->vl53l0x_dev, 0);
- if (status != VL53L0X_ERROR_NONE)
- return false;
- return true;
- }
- bool VL53L0X_ReadSingleWithInterrupt(VL53L0X *dev, uint16_t *pRangeMilliMeter) {
- if (dev->gpio_gpio1 == GPIO_NUM_MAX)
- return false;
- VL53L0X_Error status;
- status = VL53L0X_SetDeviceMode(&dev->vl53l0x_dev, VL53L0X_DEVICEMODE_SINGLE_RANGING);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_SetDeviceMode");
- return false;
- }
- xSemaphoreTake(dev->xSemaphore, 0);
- status = VL53L0X_StartMeasurement(&dev->vl53l0x_dev);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_StartMeasurement");
- return false;
- }
- xSemaphoreTake(dev->xSemaphore, 1000 / portMAX_DELAY);
- VL53L0X_RangingMeasurementData_t MeasurementData;
- status = VL53L0X_GetRangingMeasurementData(&dev->vl53l0x_dev, &MeasurementData);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_GetRangingMeasurementData");
- return false;
- }
- *pRangeMilliMeter = MeasurementData.RangeMilliMeter;
- if (MeasurementData.RangeStatus != 0)
- return false;
- VL53L0X_ClearInterruptMask(&dev->vl53l0x_dev, 0);
- if (status != VL53L0X_ERROR_NONE)
- return false;
- return true;
- }
- void VL53L0X_I2CMasterInit(VL53L0X *dev, gpio_num_t pin_sda, gpio_num_t pin_scl, uint32_t freq) {
- i2c_config_t conf;
- memset(&conf, 0, sizeof(i2c_config_t));
- conf.mode = I2C_MODE_MASTER;
- conf.sda_io_num = pin_sda;
- conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
- conf.scl_io_num = pin_scl;
- conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
- conf.master.clk_speed = freq;
- ESP_ERROR_CHECK(i2c_param_config(dev->i2c_port, &conf));
- ESP_ERROR_CHECK(i2c_driver_install(dev->i2c_port, conf.mode, 0, 0, 0));
- }
- bool VL53L0X_SetTimingBudget(VL53L0X *dev, uint32_t TimingBudgetMicroSeconds) {
- VL53L0X_Error status = VL53L0X_SetMeasurementTimingBudgetMicroSeconds(&dev->vl53l0x_dev, TimingBudgetMicroSeconds);
- if (status != VL53L0X_ERROR_NONE) {
- print_pal_error(status, "VL53L0X_SetMeasurementTimingBudgetMicroSeconds");
- return false;
- }
- dev->TimingBudgetMicroSeconds = TimingBudgetMicroSeconds;
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment