From 1bddb7e40499b54c2ea6656bcd7811b6af2c7d55 Mon Sep 17 00:00:00 2001 From: Yilin Sun Date: Mon, 3 Jul 2023 23:04:13 +0800 Subject: [PATCH] Added VL53L1X platform driver. Signed-off-by: Yilin Sun --- CMakeLists.txt | 2 + MX_Generated/Core/Src/i2c.c | 2 +- MX_Generated/STM32WLE5CBUx.ioc | 5 +- include/app_ranging_impl.h | 19 +++ lib/tof/CMakeLists.txt | 9 +- .../platform/inc/vl53l1_platform_user_data.h | 19 +++ lib/tof/platform/src/vl53l1_platform.c | 143 ++++++++++++++++++ src/app_ranging_impl.c | 38 +++++ src/app_syscalls.c | 7 + src/main.c | 53 ++++++- 10 files changed, 290 insertions(+), 7 deletions(-) create mode 100644 include/app_ranging_impl.h create mode 100644 lib/tof/platform/src/vl53l1_platform.c create mode 100644 src/app_ranging_impl.c create mode 100644 src/app_syscalls.c diff --git a/CMakeLists.txt b/CMakeLists.txt index a834bdb..0d24199 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,8 @@ set(TARGET_SOURCES "SDK/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc.c" "SDK/Drivers/STM32WLxx_HAL_Driver/Src/stm32wlxx_hal_rtc_ex.c" "src/app_sensors_impl.c" + "src/app_syscalls.c" + "src/app_ranging_impl.c" "src/main.c" ) diff --git a/MX_Generated/Core/Src/i2c.c b/MX_Generated/Core/Src/i2c.c index 45b9f4c..58e29c3 100644 --- a/MX_Generated/Core/Src/i2c.c +++ b/MX_Generated/Core/Src/i2c.c @@ -38,7 +38,7 @@ void MX_I2C1_Init(void) /* USER CODE END I2C1_Init 1 */ hi2c1.Instance = I2C1; - hi2c1.Init.Timing = 0x20303E5D; + hi2c1.Init.Timing = 0x2010091A; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; diff --git a/MX_Generated/STM32WLE5CBUx.ioc b/MX_Generated/STM32WLE5CBUx.ioc index cee3a5f..6f91a85 100644 --- a/MX_Generated/STM32WLE5CBUx.ioc +++ b/MX_Generated/STM32WLE5CBUx.ioc @@ -7,8 +7,9 @@ CAD.pinconfig= CAD.provider= File.Version=6 GPIO.groupedBy=Group By Peripherals -I2C1.IPParameters=Timing -I2C1.Timing=0x20303E5D +I2C1.I2C_Speed_Mode=I2C_Fast +I2C1.IPParameters=Timing,I2C_Speed_Mode +I2C1.Timing=0x2010091A KeepUserPlacement=false Mcu.CPN=STM32WLE5CBU6 Mcu.Family=STM32WL diff --git a/include/app_ranging_impl.h b/include/app_ranging_impl.h new file mode 100644 index 0000000..96953b7 --- /dev/null +++ b/include/app_ranging_impl.h @@ -0,0 +1,19 @@ +#ifndef APP_RANGING_IMPL_H +#define APP_RANGING_IMPL_H + +/* HAL Drivers */ +#include "stm32wlxx_hal.h" + +/* Ranging sensor */ +#include "vl53l1_platform.h" + +typedef struct { + I2C_HandleTypeDef *hi2c; + uint8_t dev_addr; +} app_ranging_impl_t; + +VL53L1_Error app_ranging_delay_us(void *pdev, uint32_t delay_usec); +VL53L1_Error app_ranging_delay_ms(void *pdev, uint32_t delay_msec); +VL53L1_Error app_ranging_i2c_xfer(void *pdev, VL53L1_Dev_Xfer_Desc_t *xfer); + +#endif // APP_RANGING_IMPL_H diff --git a/lib/tof/CMakeLists.txt b/lib/tof/CMakeLists.txt index 03f9a1b..23a463b 100644 --- a/lib/tof/CMakeLists.txt +++ b/lib/tof/CMakeLists.txt @@ -2,7 +2,10 @@ cmake_minimum_required(VERSION 3.10) project(vl53l1x) +option(VL53L1X_2V8_MODE "Enable 2V8 VDDIO support" ON) + set(VL53L1X_SRCS + "platform/src/vl53l1_platform.c" "STSW_IMG007/API/core/src/vl53l1_api.c" "STSW_IMG007/API/core/src/vl53l1_api_calibration.c" "STSW_IMG007/API/core/src/vl53l1_api_core.c" @@ -23,4 +26,8 @@ set(VL53L1X_INCS ) add_library(${PROJECT_NAME} ${VL53L1X_SRCS}) -target_include_directories(${PROJECT_NAME} PUBLIC ${VL53L1X_INCS}) \ No newline at end of file +target_include_directories(${PROJECT_NAME} PUBLIC ${VL53L1X_INCS}) + +if(VL53L1X_2V8_MODE) + target_compile_definitions(${PROJECT_NAME} PRIVATE "USE_I2C_2V8") +endif() \ No newline at end of file diff --git a/lib/tof/platform/inc/vl53l1_platform_user_data.h b/lib/tof/platform/inc/vl53l1_platform_user_data.h index ad438ea..10e1f5d 100644 --- a/lib/tof/platform/inc/vl53l1_platform_user_data.h +++ b/lib/tof/platform/inc/vl53l1_platform_user_data.h @@ -9,9 +9,28 @@ #define VL53L1DevDataGet(Dev, field) (Dev->Data.field) #define VL53L1DevDataSet(Dev, field, data) ((Dev->Data.field) = (data)) +typedef struct { + uint8_t *TxData; + uint8_t *RxData; + uint16_t TxSize; + uint16_t RxSize; +} VL53L1_Dev_Xfer_Desc_t; + +typedef VL53L1_Error (*VL53L1_Delay_Us_t)(void *pdev, uint32_t usec); +typedef VL53L1_Error (*VL53L1_Delay_Ms_t)(void *pdev, uint32_t msec); +typedef VL53L1_Error (*VL53L1_I2C_Xfer_t)(void *pdev, VL53L1_Dev_Xfer_Desc_t *desc); + +typedef struct { + VL53L1_Delay_Us_t Delay_Us; + VL53L1_Delay_Ms_t Delay_Ms; + VL53L1_I2C_Xfer_t I2C_Xfer; +} VL53L1_Dev_Ops_t; + typedef struct { VL53L1_DevData_t Data; + VL53L1_Dev_Ops_t Ops; + void *OpsData; } VL53L1_Dev_t; typedef VL53L1_Dev_t *VL53L1_DEV; diff --git a/lib/tof/platform/src/vl53l1_platform.c b/lib/tof/platform/src/vl53l1_platform.c new file mode 100644 index 0000000..1e20fdd --- /dev/null +++ b/lib/tof/platform/src/vl53l1_platform.c @@ -0,0 +1,143 @@ +/* Platform */ +#include "vl53l1_platform.h" + +#define PLATFORM_MAXIMUM_MULTI_WRITE_SIZE 256 + +VL53L1_Error VL53L1_WaitUs(VL53L1_Dev_t *pdev, int32_t wait_us) { + return pdev->Ops.Delay_Us(pdev->OpsData, wait_us); +} + +VL53L1_Error VL53L1_WaitMs(VL53L1_Dev_t *pdev, int32_t wait_ms) { + return pdev->Ops.Delay_Ms(pdev->OpsData, wait_ms); +} + +VL53L1_Error VL53L1_RdByte(VL53L1_Dev_t *pdev, uint16_t index, uint8_t *pdata) { + uint8_t tx_buf[2]; + + tx_buf[0] = (index >> 8U) & 0xFFU; + tx_buf[1] = (index & 0xFFU); + + VL53L1_Dev_Xfer_Desc_t xfer = { + .TxData = tx_buf, + .TxSize = 2, + .RxData = pdata, + .RxSize = 1, + }; + + return pdev->Ops.I2C_Xfer(pdev->OpsData, &xfer); +} + +VL53L1_Error VL53L1_RdWord(VL53L1_Dev_t *pdev, uint16_t index, uint16_t *pdata) { + uint8_t tx_buf[2]; + uint8_t rx_buf[2]; + + tx_buf[0] = (index >> 8U) & 0xFFU; + tx_buf[1] = (index & 0xFFU); + + VL53L1_Dev_Xfer_Desc_t xfer = { + .TxData = tx_buf, + .TxSize = 2, + .RxData = rx_buf, + .RxSize = 2, + }; + + VL53L1_Error ret = pdev->Ops.I2C_Xfer(pdev->OpsData, &xfer); + if (ret != VL53L1_ERROR_NONE) return ret; + + *pdata = (rx_buf[0] << 8U) | rx_buf[1]; + + return ret; +} + +VL53L1_Error VL53L1_ReadMulti(VL53L1_Dev_t *pdev, uint16_t index, uint8_t *pdata, uint32_t count) { + uint8_t tx_buf[2]; + + tx_buf[0] = (index >> 8U) & 0xFFU; + tx_buf[1] = (index & 0xFFU); + + VL53L1_Dev_Xfer_Desc_t xfer = { + .TxData = tx_buf, + .TxSize = 2, + .RxData = pdata, + .RxSize = count, + }; + + return pdev->Ops.I2C_Xfer(pdev->OpsData, &xfer); +} + +VL53L1_Error VL53L1_WrByte(VL53L1_Dev_t *pdev, uint16_t index, uint8_t data) { + uint8_t tx_buf[3]; + + tx_buf[0] = (index >> 8U) & 0xFFU; + tx_buf[1] = (index & 0xFFU); + tx_buf[2] = data; + + VL53L1_Dev_Xfer_Desc_t xfer = { + .TxData = tx_buf, + .TxSize = 3, + .RxData = NULL, + .RxSize = 0, + }; + + return pdev->Ops.I2C_Xfer(pdev->OpsData, &xfer); +} + +VL53L1_Error VL53L1_WriteMulti(VL53L1_Dev_t *pdev, uint16_t index, uint8_t *pdata, uint32_t count) { + if (count > PLATFORM_MAXIMUM_MULTI_WRITE_SIZE - 2) { + for (;;) { + /* -- */ + pdev->Ops.Delay_Ms(pdev->OpsData, 1000); + } + } + + uint8_t tx_buf[PLATFORM_MAXIMUM_MULTI_WRITE_SIZE]; + + tx_buf[0] = (index >> 8U) & 0xFFU; + tx_buf[1] = (index & 0xFFU); + + memcpy(&tx_buf[2], pdata, count); + + VL53L1_Dev_Xfer_Desc_t xfer = { + .TxData = tx_buf, + .TxSize = count + 2, + .RxData = NULL, + .RxSize = 0, + }; + + return pdev->Ops.I2C_Xfer(pdev->OpsData, &xfer); +} + +VL53L1_Error VL53L1_WaitValueMaskEx(VL53L1_Dev_t *pdev, uint32_t timeout_ms, uint16_t index, uint8_t value, + uint8_t mask, uint32_t poll_delay_ms) { + uint8_t tx_buf[2]; + uint8_t rx_buf[1]; + + tx_buf[0] = (index >> 8U) & 0xFFU; + tx_buf[1] = (index & 0xFFU); + + VL53L1_Dev_Xfer_Desc_t xfer = { + .TxData = tx_buf, + .TxSize = 2, + .RxData = rx_buf, + .RxSize = 1, + }; + + uint8_t ts_count = 0U; + + VL53L1_Error ret; + + do { + ret = pdev->Ops.I2C_Xfer(pdev->OpsData, &xfer); + if (ret != VL53L1_ERROR_NONE) return ret; + + ts_count += poll_delay_ms; + + pdev->Ops.Delay_Ms(pdev->OpsData, poll_delay_ms); + + if (ts_count > timeout_ms) { + return VL53L1_ERROR_TIME_OUT; + } + } while ((rx_buf[0] & mask) != value); + + return VL53L1_ERROR_NONE; +} diff --git a/src/app_ranging_impl.c b/src/app_ranging_impl.c new file mode 100644 index 0000000..6bbf5cb --- /dev/null +++ b/src/app_ranging_impl.c @@ -0,0 +1,38 @@ +#include "app_ranging_impl.h" + +#define APP_I2C_READ(addr) ((addr << 1U) | 0x01U) +#define APP_I2C_WRITE(addr) ((addr << 1U) & (~0x01U)) + +VL53L1_Error app_ranging_delay_us(void *pdev, uint32_t delay_usec) { + HAL_Delay(1); + + return VL53L1_ERROR_NONE; +} + +VL53L1_Error app_ranging_delay_ms(void *pdev, uint32_t delay_msec) { + HAL_Delay(delay_msec); + + return VL53L1_ERROR_NONE; +} + +VL53L1_Error app_ranging_i2c_xfer(void *pdev, VL53L1_Dev_Xfer_Desc_t *xfer) { + app_ranging_impl_t *impl = pdev; + + HAL_StatusTypeDef ret; + + if (xfer->TxSize) { + ret = HAL_I2C_Master_Transmit(impl->hi2c, APP_I2C_WRITE(impl->dev_addr), xfer->TxData, xfer->TxSize, 1000); + if (ret != HAL_OK) { + return VL53L1_ERROR_CONTROL_INTERFACE; + } + } + + if (xfer->RxSize) { + ret = HAL_I2C_Master_Receive(impl->hi2c, APP_I2C_READ(impl->dev_addr), xfer->RxData, xfer->RxSize, 1000); + if (ret != HAL_OK) { + return VL53L1_ERROR_CONTROL_INTERFACE; + } + } + + return VL53L1_ERROR_NONE; +} \ No newline at end of file diff --git a/src/app_syscalls.c b/src/app_syscalls.c new file mode 100644 index 0000000..0f10a36 --- /dev/null +++ b/src/app_syscalls.c @@ -0,0 +1,7 @@ +#include "stm32wlxx_hal.h" + +int _write(int file, char *ptr, int len) { + for (int i = 0; i < len; i++) { + } + return len; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 1512ce6..2ba7a09 100644 --- a/src/main.c +++ b/src/main.c @@ -14,8 +14,10 @@ /* Sensors */ #include "imsensors/als/als_ltr_303als.h" #include "imsensors/dht/dht_bme280.h" +#include "vl53l1_api.h" /* App */ +#include "app_ranging_impl.h" #include "app_sensors_impl.h" extern void SystemClock_Config(void); @@ -49,6 +51,21 @@ static ims_ltr_303als_t s_als = { }, }; +static app_ranging_impl_t s_ranging_impl = { + .hi2c = &hi2c1, + .dev_addr = 0x29, +}; + +static VL53L1_Dev_t s_ranging = { + .Ops = + { + .Delay_Us = app_ranging_delay_us, + .Delay_Ms = app_ranging_delay_ms, + .I2C_Xfer = app_ranging_i2c_xfer, + }, + .OpsData = &s_ranging_impl, +}; + int main(void) { /* HAL */ HAL_Init(); @@ -59,6 +76,8 @@ int main(void) { MX_RTC_Init(); MX_I2C1_Init(); + printf("Hello world\r\n"); + if (ims_bme280_init(&s_dht) != IMS_SUCCESS) { goto dead_loop; } @@ -84,11 +103,29 @@ int main(void) { goto dead_loop; } - ims_ltr_303als_result_t als_result; - ims_bme280_result_t dht_result; + HAL_GPIO_WritePin(TOF_XSHUT_GPIO_Port, TOF_XSHUT_Pin, 1U); + + HAL_Delay(5); + + VL53L1_SetDeviceAddress(&s_ranging, 0x6E); + + s_ranging_impl.dev_addr = 0x37U; + + VL53L1_WaitDeviceBooted(&s_ranging); + VL53L1_DataInit(&s_ranging); + VL53L1_StaticInit(&s_ranging); + VL53L1_SetDistanceMode(&s_ranging, VL53L1_DISTANCEMODE_LONG); + VL53L1_SetMeasurementTimingBudgetMicroSeconds(&s_ranging, 50000); + VL53L1_SetInterMeasurementPeriodMilliSeconds(&s_ranging, 500); + VL53L1_StartMeasurement(&s_ranging); + + ims_ltr_303als_result_t als_result; + ims_bme280_result_t dht_result; + VL53L1_RangingMeasurementData_t ranging_result; + + uint8_t ranging_ready = 0U; for (;;) { - HAL_Delay(500); HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); if (ims_bme280_measure(&s_dht, &dht_result) != IMS_SUCCESS) { goto dead_loop; @@ -98,7 +135,17 @@ int main(void) { goto dead_loop; } + VL53L1_GetMeasurementDataReady(&s_ranging, &ranging_ready); + if (ranging_ready) { + VL53L1_GetRangingMeasurementData(&s_ranging, &ranging_result); + if (VL53L1_ClearInterruptAndStartMeasurement(&s_ranging) != VL53L1_ERROR_NONE) { + goto dead_loop; + } + } + HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); + + HAL_Delay(500); } dead_loop: