Merge pull request #360 from pimoroni/patch-vl53l5cx-firmware-sideload

Sideload vl53l5cx firmware to avoid bloating MicroPython binary
This commit is contained in:
Philip Howard 2022-05-18 13:13:37 +01:00 committed by GitHub
commit 698dd4d2c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 59 additions and 11 deletions

2
.gitmodules vendored
View File

@ -20,4 +20,4 @@
[submodule "drivers/vl53l5cx/src"]
path = drivers/vl53l5cx/src
url = https://github.com/ST-mirror/VL53L5CX_ULD_driver
branch = lite/en
branch = no-fw/lite/en

View File

@ -84,6 +84,7 @@ typedef struct
/* Example for most standard platform : I2C address of sensor */
uint16_t address;
i2c_inst_t *i2c;
uint8_t *firmware;
} VL53L5CX_Platform;

@ -1 +1 @@
Subproject commit 834fa4e53119b987ae9357afc9dfacc6ef8261f8
Subproject commit 80de451b3c50ef998e8a4a745e9fe8ef29314650

View File

@ -33,11 +33,12 @@ namespace pimoroni {
// 7-bit version of the default address (0x52)
static const uint8_t DEFAULT_ADDRESS = VL53L5CX_DEFAULT_I2C_ADDRESS >> 1;
VL53L5CX(I2C *i2c, uint8_t i2c_addr=DEFAULT_ADDRESS) {
VL53L5CX(I2C *i2c, uint8_t *firmware, uint8_t i2c_addr=DEFAULT_ADDRESS) {
configuration = new VL53L5CX_Configuration{
.platform = VL53L5CX_Platform{
.address = i2c_addr,
.i2c = i2c->get_i2c()
.i2c = i2c->get_i2c(),
.firmware = firmware
},
};
motion_configuration = new VL53L5CX_Motion_Configuration{};

View File

@ -1,14 +1,15 @@
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "drivers/vl53l5cx/vl53l5cx.hpp"
#include "vl53l5cx.hpp"
#include "src/vl53l5cx_firmware.h"
#include "common/pimoroni_i2c.hpp"
using namespace pimoroni;
I2C i2c(4, 5);
VL53L5CX vl53l5cx(&i2c);
VL53L5CX vl53l5cx(&i2c, (uint8_t *)&vl53l5cx_firmware_bin);
int main() {
stdio_init_all();

View File

@ -2,6 +2,10 @@ import pimoroni_i2c
import breakout_vl53l5cx
import time
# The VL53L5CX requires a firmware blob to start up.
# Make sure you upload "vl53l5cx_firmware.bin" via Thonny to the root of your filesystem
# You can find it here: https://github.com/ST-mirror/VL53L5CX_ULD_driver/blob/no-fw/lite/en/vl53l5cx_firmware.bin
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}

View File

@ -3,6 +3,10 @@ import breakout_vl53l5cx
import time
from ulab import numpy
# The VL53L5CX requires a firmware blob to start up.
# Make sure you upload "vl53l5cx_firmware.bin" via Thonny to the root of your filesystem
# You can find it here: https://github.com/ST-mirror/VL53L5CX_ULD_driver/blob/no-fw/lite/en/vl53l5cx_firmware.bin
PINS_BREAKOUT_GARDEN = {"sda": 4, "scl": 5}
PINS_PICO_EXPLORER = {"sda": 20, "scl": 21}

View File

@ -3,6 +3,10 @@ import breakout_vl53l5cx
import time
from ulab import numpy
# The VL53L5CX requires a firmware blob to start up.
# Make sure you upload "vl53l5cx_firmware.bin" via Thonny to the root of your filesystem
# You can find it here: https://github.com/ST-mirror/VL53L5CX_ULD_driver/blob/no-fw/lite/en/vl53l5cx_firmware.bin
# This example attempts to track a "bright" object (such as a white business card)
# It uses reflectance to identify the target and compute the X/Y coordinates
# of its "center of mass" in the sensors view.

View File

@ -8,6 +8,9 @@
extern "C" {
#include "vl53l5cx.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;
@ -61,11 +64,13 @@ mp_obj_t VL53L5CX_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw
enum {
ARG_i2c,
ARG_addr
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::VL53L5CX::DEFAULT_ADDRESS} }
{ MP_QSTR_addr, MP_ARG_INT, {.u_int = pimoroni::VL53L5CX::DEFAULT_ADDRESS} },
{ MP_QSTR_firmware, MP_ARG_OBJ, {.u_obj = nullptr} }
};
// Parse args.
@ -83,10 +88,38 @@ mp_obj_t VL53L5CX_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw
self = m_new_obj_with_finaliser(_VL53L5CX_obj_t);
self->base.type = &VL53L5CX_type;
self->i2c = i2c;
self->breakout = new pimoroni::VL53L5CX(i2c->i2c, addr);
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("vl53l5cx_firmware.bin", strlen("vl53l5cx_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 vl53l5cx_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 = new pimoroni::VL53L5CX(i2c->i2c, (uint8_t *)bufinfo.buf, addr);
if(!self->breakout->init()) {
mp_raise_msg(&mp_type_RuntimeError, "VL53L5CX: error initialising");
mp_raise_msg(&mp_type_RuntimeError, "VL53L5CX: init error");
}
if(args[ARG_firmware].u_obj == nullptr) {
m_free(bufinfo.buf);
}
return MP_OBJ_FROM_PTR(self);

View File

@ -29,7 +29,7 @@ include(breakout_bme280/micropython)
include(breakout_bmp280/micropython)
include(breakout_icp10125/micropython)
include(breakout_scd41/micropython)
# include(breakout_vl53l5cx/micropython)
include(breakout_vl53l5cx/micropython)
include(pico_scroll/micropython)
include(pico_rgb_keypad/micropython)