Added VL53L1X platform driver.
continuous-integration/drone/push Build is passing Details

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2023-07-03 23:04:13 +08:00
parent 7c522f09db
commit 1bddb7e404
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
10 changed files with 290 additions and 7 deletions

View File

@ -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"
)

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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})
target_include_directories(${PROJECT_NAME} PUBLIC ${VL53L1X_INCS})
if(VL53L1X_2V8_MODE)
target_compile_definitions(${PROJECT_NAME} PRIVATE "USE_I2C_2V8")
endif()

View File

@ -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;

View File

@ -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;
}

38
src/app_ranging_impl.c Normal file
View File

@ -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;
}

7
src/app_syscalls.c Normal file
View File

@ -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;
}

View File

@ -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: