From 2baa25acc7c7654b75a0051e3e1887a38e013f73 Mon Sep 17 00:00:00 2001 From: Phil Howard Date: Tue, 16 Apr 2024 15:19:17 +0100 Subject: [PATCH] VL53L8CX: MicroPython bindings. --- .../breakout_vl53l8cx/micropython.cmake | 29 ++ .../modules/breakout_vl53l8cx/vl53l8cx.c | 97 ++++++ .../modules/breakout_vl53l8cx/vl53l8cx.cpp | 282 ++++++++++++++++++ .../modules/breakout_vl53l8cx/vl53l8cx.h | 26 ++ .../micropython-common-breakouts.cmake | 3 +- 5 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 micropython/modules/breakout_vl53l8cx/micropython.cmake create mode 100644 micropython/modules/breakout_vl53l8cx/vl53l8cx.c create mode 100644 micropython/modules/breakout_vl53l8cx/vl53l8cx.cpp create mode 100644 micropython/modules/breakout_vl53l8cx/vl53l8cx.h diff --git a/micropython/modules/breakout_vl53l8cx/micropython.cmake b/micropython/modules/breakout_vl53l8cx/micropython.cmake new file mode 100644 index 00000000..a4006735 --- /dev/null +++ b/micropython/modules/breakout_vl53l8cx/micropython.cmake @@ -0,0 +1,29 @@ +add_library(usermod_vl53l8cx INTERFACE) + +target_sources(usermod_vl53l8cx INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/vl53l8cx.c + ${CMAKE_CURRENT_LIST_DIR}/vl53l8cx.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/vl53l8cx/vl53l8cx.cpp + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/vl53l8cx/platform.c + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/vl53l8cx/src/VL53L8CX_ULD_API/src/vl53l8cx_api.c + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/vl53l8cx/src/VL53L8CX_ULD_API/src/vl53l8cx_plugin_motion_indicator.c + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/vl53l8cx/src/VL53L8CX_ULD_API/src/vl53l8cx_plugin_detection_thresholds.c +) + +target_include_directories(usermod_vl53l8cx INTERFACE + ${CMAKE_CURRENT_LIST_DIR} + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/vl53l8cx/ + ${CMAKE_CURRENT_LIST_DIR}/../../../drivers/vl53l8cx/src/VL53L8CX_ULD_API/inc +) + +target_compile_definitions(usermod_vl53l8cx INTERFACE + MODULE_VL53L8CX_ENABLED=1 +) + +target_link_libraries(usermod INTERFACE usermod_vl53l8cx) + +set_source_files_properties( + ${CMAKE_CURRENT_LIST_DIR}/vl53l8cx.c + PROPERTIES COMPILE_FLAGS + "-Wno-discarded-qualifiers -Wno-implicit-int" +) \ No newline at end of file diff --git a/micropython/modules/breakout_vl53l8cx/vl53l8cx.c b/micropython/modules/breakout_vl53l8cx/vl53l8cx.c new file mode 100644 index 00000000..983c7ded --- /dev/null +++ b/micropython/modules/breakout_vl53l8cx/vl53l8cx.c @@ -0,0 +1,97 @@ +#include "vl53l8cx.h" + + +MP_DEFINE_CONST_FUN_OBJ_1(VL53L8CX___del___obj, VL53L8CX___del__); + +MP_DEFINE_CONST_FUN_OBJ_1(VL53L8CX_start_ranging_obj, VL53L8CX_start_ranging); +MP_DEFINE_CONST_FUN_OBJ_1(VL53L8CX_stop_ranging_obj, VL53L8CX_stop_ranging); + +MP_DEFINE_CONST_FUN_OBJ_2(VL53L8CX_enable_motion_indicator_obj, VL53L8CX_enable_motion_indicator); +MP_DEFINE_CONST_FUN_OBJ_3(VL53L8CX_set_motion_distance_obj, VL53L8CX_set_motion_distance); + +MP_DEFINE_CONST_FUN_OBJ_2(VL53L8CX_set_i2c_address_obj, VL53L8CX_set_i2c_address); +MP_DEFINE_CONST_FUN_OBJ_2(VL53L8CX_set_ranging_mode_obj, VL53L8CX_set_ranging_mode); +MP_DEFINE_CONST_FUN_OBJ_2(VL53L8CX_set_ranging_frequency_hz_obj, VL53L8CX_set_ranging_frequency_hz); +MP_DEFINE_CONST_FUN_OBJ_2(VL53L8CX_set_resolution_obj, VL53L8CX_set_resolution); +MP_DEFINE_CONST_FUN_OBJ_2(VL53L8CX_set_integration_time_ms_obj, VL53L8CX_set_integration_time_ms); +MP_DEFINE_CONST_FUN_OBJ_2(VL53L8CX_set_sharpener_percent_obj, VL53L8CX_set_sharpener_percent); +MP_DEFINE_CONST_FUN_OBJ_2(VL53L8CX_set_target_order_obj, VL53L8CX_set_target_order); +MP_DEFINE_CONST_FUN_OBJ_2(VL53L8CX_set_power_mode_obj, VL53L8CX_set_power_mode); + +MP_DEFINE_CONST_FUN_OBJ_1(VL53L8CX_data_ready_obj, VL53L8CX_data_ready); +MP_DEFINE_CONST_FUN_OBJ_1(VL53L8CX_get_data_obj, VL53L8CX_get_data); + + +/***** Binding of Methods *****/ +STATIC const mp_rom_map_elem_t VL53L8CX_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&VL53L8CX___del___obj) }, + + { MP_ROM_QSTR(MP_QSTR_start_ranging), MP_ROM_PTR(&VL53L8CX_start_ranging_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_ranging), MP_ROM_PTR(&VL53L8CX_stop_ranging_obj) }, + + { MP_ROM_QSTR(MP_QSTR_enable_motion_indicator), MP_ROM_PTR(&VL53L8CX_enable_motion_indicator_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_motion_distance), MP_ROM_PTR(&VL53L8CX_set_motion_distance_obj) }, + + { MP_ROM_QSTR(MP_QSTR_set_i2c_address), MP_ROM_PTR(&VL53L8CX_set_i2c_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_ranging_mode), MP_ROM_PTR(&VL53L8CX_set_ranging_mode_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_ranging_frequency_hz), MP_ROM_PTR(&VL53L8CX_set_ranging_frequency_hz_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_resolution), MP_ROM_PTR(&VL53L8CX_set_resolution_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_integration_time_ms), MP_ROM_PTR(&VL53L8CX_set_integration_time_ms_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_sharpener_percent), MP_ROM_PTR(&VL53L8CX_set_sharpener_percent_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_target_order), MP_ROM_PTR(&VL53L8CX_set_target_order_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_power_mode), MP_ROM_PTR(&VL53L8CX_set_power_mode_obj) }, + + { MP_ROM_QSTR(MP_QSTR_data_ready), MP_ROM_PTR(&VL53L8CX_data_ready_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_data), MP_ROM_PTR(&VL53L8CX_get_data_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(VL53L8CX_locals_dict, VL53L8CX_locals_dict_table); + +/***** Class Definition *****/ +#ifdef MP_DEFINE_CONST_OBJ_TYPE +MP_DEFINE_CONST_OBJ_TYPE( + VL53L8CX_type, + MP_QSTR_VL53L8CX, + MP_TYPE_FLAG_NONE, + make_new, VL53L8CX_make_new, + locals_dict, (mp_obj_dict_t*)&VL53L8CX_locals_dict +); +#else +const mp_obj_type_t VL53L8CX_type = { + { &mp_type_type }, + .name = MP_QSTR_VL53L8CX, + .make_new = VL53L8CX_make_new, + .locals_dict = (mp_obj_dict_t*)&VL53L8CX_locals_dict, +}; +#endif + +/***** Module Globals *****/ +STATIC const mp_map_elem_t vl53l8cx_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_breakout_vl53l8cx) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_VL53L8CX), (mp_obj_t)&VL53L8CX_type }, + + { MP_ROM_QSTR(MP_QSTR_TARGET_ORDER_CLOSEST), MP_ROM_INT(VL53L8CX_TARGET_ORDER_CLOSEST) }, + { MP_ROM_QSTR(MP_QSTR_TARGET_ORDER_STRONGEST), MP_ROM_INT(VL53L8CX_TARGET_ORDER_STRONGEST) }, + + { MP_ROM_QSTR(MP_QSTR_RESOLUTION_4X4), MP_ROM_INT(VL53L8CX_RESOLUTION_4X4) }, + { MP_ROM_QSTR(MP_QSTR_RESOLUTION_8X8), MP_ROM_INT(VL53L8CX_RESOLUTION_8X8) }, + + { MP_ROM_QSTR(MP_QSTR_RANGING_MODE_CONTINUOUS), MP_ROM_INT(VL53L8CX_RANGING_MODE_CONTINUOUS) }, + { MP_ROM_QSTR(MP_QSTR_RANGING_MODE_AUTONOMOUS), MP_ROM_INT(VL53L8CX_RANGING_MODE_AUTONOMOUS) }, + + { MP_ROM_QSTR(MP_QSTR_POWER_MODE_SLEEP), MP_ROM_INT(VL53L8CX_POWER_MODE_SLEEP) }, + { MP_ROM_QSTR(MP_QSTR_POWER_MODE_WAKEUP), MP_ROM_INT(VL53L8CX_POWER_MODE_WAKEUP) }, +}; +STATIC MP_DEFINE_CONST_DICT(mp_module_vl53l8cx_globals, vl53l8cx_globals_table); + +/***** Module Definition *****/ +const mp_obj_module_t vl53l8cx_user_cmodule = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&mp_module_vl53l8cx_globals, +}; + +/***** Module Registration: as "breakout_vl53l8cx" *****/ +#if MICROPY_VERSION <= 70144 +MP_REGISTER_MODULE(MP_QSTR_breakout_vl53l8cx, vl53l8cx_user_cmodule, MODULE_VL53L8CX_ENABLED); +#else +MP_REGISTER_MODULE(MP_QSTR_breakout_vl53l8cx, vl53l8cx_user_cmodule); +#endif diff --git a/micropython/modules/breakout_vl53l8cx/vl53l8cx.cpp b/micropython/modules/breakout_vl53l8cx/vl53l8cx.cpp new file mode 100644 index 00000000..9320e9fc --- /dev/null +++ b/micropython/modules/breakout_vl53l8cx/vl53l8cx.cpp @@ -0,0 +1,282 @@ +#include +#include "vl53l8cx.hpp" +#include "pico/multicore.h" +#include "micropython/modules/util.hpp" + + + +extern "C" { +#include "vl53l8cx.h" +#include "pimoroni_i2c.h" +#include "py/stream.h" +#include "py/reader.h" +#include "extmod/vfs.h" + +typedef struct _mp_obj_float_t { + mp_obj_base_t base; + mp_float_t value; +} mp_obj_float_t; + +const mp_obj_float_t const_float_1 = {{&mp_type_float}, 1.0f}; + +/***** Variables Struct *****/ +typedef struct _VL53L8CX_obj_t { + mp_obj_base_t base; + _PimoroniI2C_obj_t *i2c; + pimoroni::VL53L8CX* breakout; + void *configuration; + void *motion_configuration; + void *results; +} _VL53L8CX_obj_t; + + +/***** Destructor ******/ +mp_obj_t VL53L8CX___del__(mp_obj_t self_in) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + //self->breakout->stop_ranging(); // i2c object might have been deleted already? + // TODO: Since we're now holding a pointer to the I2C object it *should* still be available here? + m_del_class(VL53L8CX, self->breakout); + return mp_const_none; +} + +/***** Constructor *****/ +mp_obj_t VL53L8CX_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + _VL53L8CX_obj_t *self = nullptr; + + enum { + ARG_i2c, + ARG_addr, + ARG_firmware, + }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_i2c, MP_ARG_OBJ, {.u_obj = nullptr} }, + { MP_QSTR_addr, MP_ARG_INT, {.u_int = pimoroni::VL53L8CX::DEFAULT_ADDRESS} }, + { MP_QSTR_firmware, MP_ARG_OBJ, {.u_obj = nullptr} } + }; + + // Parse args. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int addr = args[ARG_addr].u_int; + + self = m_new_obj_with_finaliser(_VL53L8CX_obj_t); + self->base.type = &VL53L8CX_type; + + self->i2c = PimoroniI2C_from_machine_i2c_or_native(args[ARG_i2c].u_obj); + + self->configuration = m_new(VL53L8CX_Configuration, 1); + self->motion_configuration = m_new(VL53L8CX_Motion_Configuration, 1); + self->results = m_new(pimoroni::VL53L8CX::ResultsData, 1); + + mp_buffer_info_t bufinfo; + const size_t firmware_size = 84 * 1024; + + if(args[ARG_firmware].u_obj == nullptr) { + mp_obj_t args[2] = { + mp_obj_new_str("vl53l8cx_firmware.bin", strlen("vl53l8cx_firmware.bin")), + MP_OBJ_NEW_QSTR(MP_QSTR_r), + }; + bufinfo.buf = (void *)m_new(uint8_t, firmware_size); + mp_obj_t file = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map); + int errcode; + bufinfo.len = mp_stream_rw(file, bufinfo.buf, firmware_size, &errcode, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE); + if (errcode != 0) { + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("OSError reading vl53l8cx_firmware.bin")); + } + } else { + mp_get_buffer_raise(args[ARG_firmware].u_obj, &bufinfo, MP_BUFFER_READ); + } + + if(bufinfo.len != (size_t)(firmware_size)) { // firmware blob is always 84K + mp_raise_ValueError("Firmware must be 84k bytes!"); + } + + self->breakout = m_new_class(pimoroni::VL53L8CX, (pimoroni::I2C*)self->i2c->i2c, (uint8_t *)bufinfo.buf, addr, self->configuration, self->motion_configuration); + + if(!self->breakout->init()) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: init error"); + } + + if(args[ARG_firmware].u_obj == nullptr) { + m_free(bufinfo.buf); + } + + return MP_OBJ_FROM_PTR(self); +} + +mp_obj_t VL53L8CX_start_ranging(mp_obj_t self_in) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->start_ranging(); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: start_ranging error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_stop_ranging(mp_obj_t self_in) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->stop_ranging(); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: stop_ranging error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_enable_motion_indicator(mp_obj_t self_in, mp_obj_t value) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->enable_motion_indicator((pimoroni::VL53L8CX::Resolution)mp_obj_get_int(value)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: enable_motion_indicator error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_set_motion_distance(mp_obj_t self_in, mp_obj_t distance_min, mp_obj_t distance_max) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->set_motion_distance(mp_obj_get_int(distance_min), mp_obj_get_int(distance_max)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: set_motion_distance error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_set_i2c_address(mp_obj_t self_in, mp_obj_t value) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->set_i2c_address(mp_obj_get_int(value)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: set_i2c_address error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_set_ranging_mode(mp_obj_t self_in, mp_obj_t value) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->set_ranging_mode((pimoroni::VL53L8CX::RangingMode)mp_obj_get_int(value)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: set_ranging_mode error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_set_ranging_frequency_hz(mp_obj_t self_in, mp_obj_t value) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->set_ranging_frequency_hz(mp_obj_get_int(value)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: set_ranging_frequency_hz error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_set_resolution(mp_obj_t self_in, mp_obj_t value) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->set_resolution((pimoroni::VL53L8CX::Resolution)mp_obj_get_int(value)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: set_resolution error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_set_integration_time_ms(mp_obj_t self_in, mp_obj_t value) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->set_integration_time_ms(mp_obj_get_int(value)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: set_integration_time_ms error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_set_sharpener_percent(mp_obj_t self_in, mp_obj_t value) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->set_sharpener_percent(mp_obj_get_int(value)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: set_sharpener_percent error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_set_target_order(mp_obj_t self_in, mp_obj_t value) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->set_target_order((pimoroni::VL53L8CX::TargetOrder)mp_obj_get_int(value)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: set_target_order error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_set_power_mode(mp_obj_t self_in, mp_obj_t value) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + bool status = self->breakout->set_power_mode((pimoroni::VL53L8CX::PowerMode)mp_obj_get_int(value)); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: set_power_mode error"); + } + return mp_const_none; +} + +mp_obj_t VL53L8CX_data_ready(mp_obj_t self_in) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + return self->breakout->data_ready() ? mp_const_true : mp_const_false; +} + +mp_obj_t VL53L8CX_get_data(mp_obj_t self_in) { + _VL53L8CX_obj_t *self = MP_OBJ_TO_PTR2(self_in, _VL53L8CX_obj_t); + pimoroni::VL53L8CX::ResultsData *results = (pimoroni::VL53L8CX::ResultsData *)self->results; + bool status = self->breakout->get_data(results); + if(!status) { + mp_raise_msg(&mp_type_RuntimeError, "VL53L8CX: get_data error"); + } + + // Get the current resolution so we only look at valid results. + // This is so that our average distance works out and doesn't include bogus data. + int scale = (uint8_t)self->breakout->get_resolution(); + int tuple_size = scale * VL53L8CX_NB_TARGET_PER_ZONE; + + // TODO This doesn't really handle VL53L8CX_NB_TARGET_PER_ZONE > 1 gracefully + // the zone data should be split into separate tuples + + mp_obj_t tuple_distance_mm[tuple_size]; + mp_obj_t tuple_reflectance[tuple_size]; + + int32_t average_distance = 0; + int32_t average_reflectance = 0; + + // Build a tuple of motion data + for(int i = 0u; i < tuple_size; i++) { + tuple_distance_mm[i] = mp_obj_new_int(results->distance_mm[i]); + tuple_reflectance[i] = mp_obj_new_int(results->reflectance[i]); + average_distance += results->distance_mm[i]; + average_reflectance += results->reflectance[i]; + } + + average_distance /= tuple_size; + average_reflectance /= tuple_size; + + mp_obj_t tuple_motion_data[32]; + + for(int i = 0u; i < 32; i++) { + tuple_motion_data[i] = mp_obj_new_int(results->motion_indicator.motion[i]); + } + + STATIC const qstr tuple_motion_fields[] = {MP_QSTR_global_indicator_1, MP_QSTR_global_indicator_2, MP_QSTR_motion}; + + mp_obj_t tuple_motion[] = { + mp_obj_new_int(results->motion_indicator.global_indicator_1), + mp_obj_new_int(results->motion_indicator.global_indicator_2), + mp_obj_new_tuple(sizeof(tuple_motion_data) / sizeof(mp_obj_t), tuple_motion_data) + }; + + mp_obj_t tuple[] = { + mp_obj_new_int(average_distance), // Average distance + mp_obj_new_int(average_reflectance), // Average reflectance + mp_obj_new_attrtuple(tuple_motion_fields, sizeof(tuple_motion) / sizeof(mp_obj_t), tuple_motion), // Motion data + mp_obj_new_int(tuple_size), // Number of results + mp_obj_new_tuple(tuple_size, tuple_distance_mm), // Full distance results + mp_obj_new_tuple(tuple_size, tuple_reflectance) // Full reflectange results + }; + + STATIC const qstr tuple_fields[] = {MP_QSTR_distance_avg, MP_QSTR_reflectance_avg, MP_QSTR_motion_indicator, MP_QSTR_results, MP_QSTR_distance, MP_QSTR_reflectance}; + + return mp_obj_new_attrtuple(tuple_fields, sizeof(tuple) / sizeof(mp_obj_t), tuple); +} + +} \ No newline at end of file diff --git a/micropython/modules/breakout_vl53l8cx/vl53l8cx.h b/micropython/modules/breakout_vl53l8cx/vl53l8cx.h new file mode 100644 index 00000000..f60c37d5 --- /dev/null +++ b/micropython/modules/breakout_vl53l8cx/vl53l8cx.h @@ -0,0 +1,26 @@ +#include "py/runtime.h" +#include "drivers/vl53l8cx/src/VL53L8CX_ULD_API/inc/vl53l8cx_api.h" + +extern const mp_obj_type_t VL53L8CX_type; + + +extern mp_obj_t VL53L8CX___del__(mp_obj_t self_in); +extern mp_obj_t VL53L8CX_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args); + +extern mp_obj_t VL53L8CX_start_ranging(mp_obj_t self_in); +extern mp_obj_t VL53L8CX_stop_ranging(mp_obj_t self_in); + +extern mp_obj_t VL53L8CX_enable_motion_indicator(mp_obj_t self_in, mp_obj_t value); +extern mp_obj_t VL53L8CX_set_motion_distance(mp_obj_t self_in, mp_obj_t distance_min, mp_obj_t distance_max); + +extern mp_obj_t VL53L8CX_set_i2c_address(mp_obj_t self_in, mp_obj_t value); +extern mp_obj_t VL53L8CX_set_ranging_mode(mp_obj_t self_in, mp_obj_t value); +extern mp_obj_t VL53L8CX_set_ranging_frequency_hz(mp_obj_t self_in, mp_obj_t value); +extern mp_obj_t VL53L8CX_set_resolution(mp_obj_t self_in, mp_obj_t value); +extern mp_obj_t VL53L8CX_set_integration_time_ms(mp_obj_t self_in, mp_obj_t value); +extern mp_obj_t VL53L8CX_set_sharpener_percent(mp_obj_t self_in, mp_obj_t value); +extern mp_obj_t VL53L8CX_set_target_order(mp_obj_t self_in, mp_obj_t value); +extern mp_obj_t VL53L8CX_set_power_mode(mp_obj_t self_in, mp_obj_t value); + +extern mp_obj_t VL53L8CX_data_ready(mp_obj_t self_in); +extern mp_obj_t VL53L8CX_get_data(mp_obj_t self_in); \ No newline at end of file diff --git a/micropython/modules/micropython-common-breakouts.cmake b/micropython/modules/micropython-common-breakouts.cmake index f18c3fb0..eae74276 100644 --- a/micropython/modules/micropython-common-breakouts.cmake +++ b/micropython/modules/micropython-common-breakouts.cmake @@ -19,4 +19,5 @@ include(breakout_bme280/micropython) include(breakout_bmp280/micropython) include(breakout_icp10125/micropython) include(breakout_scd41/micropython) -include(breakout_vl53l5cx/micropython) \ No newline at end of file +#include(breakout_vl53l5cx/micropython) +include(breakout_vl53l8cx/micropython) \ No newline at end of file