Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bricks/_common/sources.mk
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ PYBRICKS_PYBRICKS_SRC_C = $(addprefix pybricks/,\
robotics/pb_type_spikebase.c \
tools/pb_module_tools.c \
tools/pb_type_app_data.c \
tools/pb_type_awaitable.c \
tools/pb_type_async.c \
tools/pb_type_matrix.c \
tools/pb_type_stopwatch.c \
tools/pb_type_task.c \
Expand Down
1 change: 0 additions & 1 deletion bricks/primehub/manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@
include("../_common/manifest.py")

freeze_as_mpy("../primehub/modules", "_imu_calibrate.py")
freeze_as_mpy("../primehub/modules", "_light_matrix.py")
9 changes: 0 additions & 9 deletions bricks/primehub/modules/_light_matrix.py

This file was deleted.

5 changes: 3 additions & 2 deletions pybricks/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <pybricks/parameters/pb_type_button.h>
#include <pybricks/pupdevices.h>
#include <pybricks/tools.h>
#include <pybricks/tools/pb_type_awaitable.h>
#include <pybricks/tools/pb_type_async.h>
#include <pybricks/common/pb_type_device.h>

void pb_package_pybricks_init(bool import_all);
Expand Down Expand Up @@ -104,10 +104,11 @@ mp_obj_t common_Logger_obj_make_new(pbio_log_t *log, uint8_t num_values);

// pybricks.common.DCMotor and pybricks.common.Motor
typedef struct {
pb_type_device_obj_base_t device_base;
mp_obj_base_t base;
pbio_servo_t *srv;
pbio_dcmotor_t *dcmotor;
pbio_port_id_t port_id;
pb_type_async_t *last_awaitable;
#if PYBRICKS_PY_COMMON_MOTOR_MODEL
mp_obj_t model;
#endif
Expand Down
43 changes: 15 additions & 28 deletions pybricks/common/pb_type_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,11 @@ void *pb_type_device_get_data_blocking(mp_obj_t self_in, uint8_t mode) {
* data has been written to the device, including the neccessary delays for
* discarding stale data or the time needed to externally process written data.
*
* @param [in] self_in The sensor object instance.
* @param [in] end_time Not used.
* @return True if operation is complete (device ready),
* false otherwise.
* See ::pbio_port_lump_is_ready for details.
*/
static bool pb_pup_device_test_completion(mp_obj_t self_in, uint32_t end_time) {
static pbio_error_t pb_pup_device_iter_once(pbio_os_state_t *state, mp_obj_t self_in) {
pb_type_device_obj_base_t *sensor = MP_OBJ_TO_PTR(self_in);
pbio_error_t err = pbio_port_lump_is_ready(sensor->lump_dev);
if (err == PBIO_ERROR_AGAIN) {
return false;
}
pb_assert(err);
return true;
return pbio_port_lump_is_ready(sensor->lump_dev);
}

/**
Expand All @@ -100,14 +92,12 @@ mp_obj_t pb_type_device_method_call(mp_obj_t self_in, size_t n_args, size_t n_kw
pb_type_device_obj_base_t *sensor = MP_OBJ_TO_PTR(sensor_in);
pb_assert(pbio_port_lump_set_mode(sensor->lump_dev, method->mode));

return pb_type_awaitable_await_or_wait(
sensor_in,
sensor->awaitables,
pb_type_awaitable_end_time_none,
pb_pup_device_test_completion,
method->get_values,
pb_type_awaitable_cancel_none,
PB_TYPE_AWAITABLE_OPT_NONE);
pb_type_async_t config = {
.iter_once = pb_pup_device_iter_once,
.parent_obj = sensor_in,
.return_map = method->get_values,
};
return pb_type_async_wait_or_await(&config, &sensor->last_awaitable, false);
}

/**
Expand All @@ -132,14 +122,11 @@ MP_DEFINE_CONST_OBJ_TYPE(
*/
mp_obj_t pb_type_device_set_data(pb_type_device_obj_base_t *sensor, uint8_t mode, const void *data, uint8_t size) {
pb_assert(pbio_port_lump_set_mode_with_data(sensor->lump_dev, mode, data, size));
return pb_type_awaitable_await_or_wait(
MP_OBJ_FROM_PTR(sensor),
sensor->awaitables,
pb_type_awaitable_end_time_none,
pb_pup_device_test_completion,
pb_type_awaitable_return_none,
pb_type_awaitable_cancel_none,
PB_TYPE_AWAITABLE_OPT_RAISE_ON_BUSY);
pb_type_async_t config = {
.iter_once = pb_pup_device_iter_once,
.parent_obj = MP_OBJ_FROM_PTR(sensor),
};
return pb_type_async_wait_or_await(&config, &sensor->last_awaitable, false);
}

void pb_device_set_lego_mode(pbio_port_t *port) {
Expand Down Expand Up @@ -174,7 +161,7 @@ lego_device_type_id_t pb_type_device_init_class(pb_type_device_obj_base_t *self,
mp_hal_delay_ms(50);
}
pb_assert(err);
self->awaitables = mp_obj_new_list(0, NULL);
self->last_awaitable = NULL;
return actual_id;
}

Expand Down
6 changes: 3 additions & 3 deletions pybricks/common/pb_type_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


#include <pbio/port_lump.h>
#include <pybricks/tools/pb_type_awaitable.h>
#include <pybricks/tools/pb_type_async.h>

/**
* Used in place of mp_obj_base_t in all pupdevices. This lets us share
Expand All @@ -19,7 +19,7 @@
typedef struct _pb_type_device_obj_base_t {
mp_obj_base_t base;
pbio_port_lump_dev_t *lump_dev;
mp_obj_t awaitables;
pb_type_async_t *last_awaitable;
} pb_type_device_obj_base_t;

#if PYBRICKS_PY_DEVICES
Expand All @@ -33,7 +33,7 @@ typedef struct _pb_type_device_obj_base_t {
*/
typedef struct {
mp_obj_base_t base;
pb_type_awaitable_return_t get_values;
pb_type_async_return_map_t get_values;
uint8_t mode;
} pb_type_device_method_obj_t;

Expand Down
98 changes: 58 additions & 40 deletions pybricks/common/pb_type_lightmatrix.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "py/objstr.h"

#include <pybricks/common.h>
#include <pybricks/tools/pb_type_async.h>
#include <pybricks/tools/pb_type_matrix.h>
#include <pybricks/parameters.h>

Expand All @@ -20,15 +21,23 @@
#include <pybricks/util_mp/pb_kwarg_helper.h>
#include <pybricks/util_mp/pb_type_enum.h>

typedef struct {
const char *data;
size_t len;
pbio_os_timer_t timer;
uint32_t idx;
uint32_t on_time;
uint32_t off_time;
} text_animation_state_t;

// pybricks._common.LightMatrix class object
typedef struct _common_LightMatrix_obj_t {
mp_obj_base_t base;
pbio_light_matrix_t *light_matrix;
uint8_t *data;
uint8_t frames;
// Frozen Python implementation of the async text() method.
mp_obj_t async_text_method;
pb_type_async_t *text_iter;
text_animation_state_t text;
} common_LightMatrix_obj_t;

// Renews memory for a given number of frames
Expand Down Expand Up @@ -273,53 +282,62 @@ static mp_obj_t common_LightMatrix_pixel(size_t n_args, const mp_obj_t *pos_args
}
static MP_DEFINE_CONST_FUN_OBJ_KW(common_LightMatrix_pixel_obj, 1, common_LightMatrix_pixel);

// pybricks._common.LightMatrix.text
static mp_obj_t common_LightMatrix_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
PB_PARSE_ARGS_METHOD(n_args, pos_args, kw_args,
common_LightMatrix_obj_t, self,
PB_ARG_REQUIRED(text),
PB_ARG_DEFAULT_INT(on, 500),
PB_ARG_DEFAULT_INT(off, 50));
static pbio_error_t pb_type_lightmatrix_text_iterate_once(pbio_os_state_t *state, mp_obj_t parent_obj) {

if (pb_module_tools_run_loop_is_active()) {
if (self->async_text_method == MP_OBJ_NULL) {
self->async_text_method = pb_function_import_helper(MP_QSTR__light_matrix, MP_QSTR_light_matrix_text_async);
common_LightMatrix_obj_t *self = MP_OBJ_TO_PTR(parent_obj);
text_animation_state_t *text = &self->text;
pbio_error_t err;

PBIO_OS_ASYNC_BEGIN(state);

for (text->idx = 0; text->idx < text->len; text->idx++) {

// Raise on invalid character.
if (text->data[text->idx] < 32 || text->data[text->idx] > 126) {
return PBIO_ERROR_INVALID_ARG;
}
mp_obj_t args[] = {
MP_OBJ_FROM_PTR(self),
text_in,
on_in,
off_in,
};
return mp_call_function_n_kw(self->async_text_method, MP_ARRAY_SIZE(args), 0, args);
}

// Assert that the input is a single text
GET_STR_DATA_LEN(text_in, text, text_len);
// On time.
err = pbio_light_matrix_set_rows(self->light_matrix, pb_font_5x5[text->data[text->idx] - 32]);
if (err != PBIO_SUCCESS) {
return err;
}
PBIO_OS_AWAIT_MS(state, &text->timer, text->on_time);

// Make sure all characters are valid
for (size_t i = 0; i < text_len; i++) {
if (text[0] < 32 || text[0] > 126) {
pb_assert(PBIO_ERROR_INVALID_ARG);
// Off time so we can see multiple of the same characters.
if (text->off_time > 0 || text->idx == text->len - 1) {
err = pbio_light_matrix_clear(self->light_matrix);
if (err != PBIO_SUCCESS) {
return err;
}
PBIO_OS_AWAIT_MS(state, &text->timer, text->off_time);
}
}

mp_int_t on = pb_obj_get_int(on_in);
mp_int_t off = pb_obj_get_int(off_in);
PBIO_OS_ASYNC_END(PBIO_SUCCESS);
}

// Display all characters one by one
for (size_t i = 0; i < text_len; i++) {
pb_assert(pbio_light_matrix_set_rows(self->light_matrix, pb_font_5x5[text[i] - 32]));
mp_hal_delay_ms(on);
// pybricks._common.LightMatrix.text
static mp_obj_t common_LightMatrix_text(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
PB_PARSE_ARGS_METHOD(n_args, pos_args, kw_args,
common_LightMatrix_obj_t, self,
PB_ARG_REQUIRED(text),
PB_ARG_DEFAULT_INT(on, 500),
PB_ARG_DEFAULT_INT(off, 50));

// Some off time so we can see multiple of the same characters
if (off > 0 || i == text_len - 1) {
pb_assert(pbio_light_matrix_clear(self->light_matrix));
mp_hal_delay_ms(off);
}
}
text_animation_state_t *text = &self->text;

return mp_const_none;
text->on_time = pb_obj_get_int(on_in);
text->off_time = pb_obj_get_int(off_in);
text->idx = 0;
text->data = mp_obj_str_get_data(text_in, &text->len);

pb_type_async_t config = {
.parent_obj = MP_OBJ_FROM_PTR(self),
.iter_once = pb_type_lightmatrix_text_iterate_once,
};
// New operation always wins; ongoing animation is cancelled.
return pb_type_async_wait_or_await(&config, &self->text_iter, true);
}
static MP_DEFINE_CONST_FUN_OBJ_KW(common_LightMatrix_text_obj, 1, common_LightMatrix_text);

Expand Down Expand Up @@ -348,7 +366,7 @@ mp_obj_t pb_type_LightMatrix_obj_new(pbio_light_matrix_t *light_matrix) {
common_LightMatrix_obj_t *self = mp_obj_malloc(common_LightMatrix_obj_t, &pb_type_LightMatrix);
self->light_matrix = light_matrix;
pbio_light_matrix_set_orientation(light_matrix, PBIO_GEOMETRY_SIDE_TOP);
self->async_text_method = MP_OBJ_NULL;
self->text_iter = NULL;
return MP_OBJ_FROM_PTR(self);
}

Expand Down
Loading