From 0afd863224c743914beaee948d4449fa896325dd Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sat, 31 Jul 2021 16:22:21 -0700 Subject: [PATCH 01/63] vectorio: palettes don't color dirty rectangles This is a breaking change with previous palette semantic with respect to python code that uses vectorio. Displayio has breaking changes in cpy 7 for Group's removal of max_size parameter so this is as good a time as any to break everything. Currently: To color vectorio shapes correctly you have to pass in a palette with length 2. Palette[0] must be set transparent and palette[1] must be the color you want. New: To color vectorio shapes correctly you pass in a palette with length >= 1. Palette[0] will be the color of the shape. Also improves pixels per second when skipping areas that aren't covered by the shape. --- shared-bindings/vectorio/VectorShape.c | 2 +- shared-module/vectorio/VectorShape.c | 30 ++++++++++++++++++-------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index ae8532eb95..be24a056c9 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -21,7 +21,7 @@ //| class VectorShape: //| def __init__(self, shape: Union[Polygon, Rectangle, Circle], pixel_shader: Union[displayio.ColorConverter, displayio.Palette], x: int=0, y: int=0) -> None: -//| """Binds a vector shape to a location and pixel color +//| """Binds a vector shape to a location and pixel shader. The shader can be a displayio.Palette(1); it will be asked to color pixel value 0. //| //| :param shape: The shape to draw. //| :param pixel_shader: The pixel shader that produces colors from values diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index f0b6a725c1..87dc78d0c8 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -214,18 +214,30 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ #endif VECTORIO_SHAPE_PIXEL_DEBUG(" -> %d", input_pixel.pixel); - output_pixel.opaque = true; - if (self->pixel_shader == mp_const_none) { - output_pixel.pixel = input_pixel.pixel; - } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { - output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); - } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { - displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); - } - if (!output_pixel.opaque) { + // vectorio shapes use 0 to mean "area is not covered." + // We can skip all the rest of the work for this pixel if it's not currently covered by the shape. + if (input_pixel.pixel == 0) { VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel; input area is not fully covered)\n"); full_coverage = false; } else { + // Pixel is not transparent. Let's pull the pixel value index down to 0-base for more error-resistant palettes. + input_pixel.pixel -= 1; + output_pixel.opaque = true; + + if (self->pixel_shader == mp_const_none) { + output_pixel.pixel = input_pixel.pixel; + } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { + output_pixel.opaque = displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel.pixel, &output_pixel.pixel); + } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { + displayio_colorconverter_convert(self->pixel_shader, colorspace, &input_pixel, &output_pixel); + } + + // We double-check this to fast-path the case when a pixel is not covered by the shape & not call the color converter unnecessarily. + if (output_pixel.opaque) { + VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel from colorconverter; input area is not fully covered)\n"); + full_coverage = false; + } + *mask_doubleword |= 1u << mask_bit; if (colorspace->depth == 16) { VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %04x 16\n", output_pixel.pixel); From 1b67b91eddfc4222d2db3882fb889338b161d87b Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sat, 31 Jul 2021 16:59:44 -0700 Subject: [PATCH 02/63] fix inverted logic --- shared-module/vectorio/VectorShape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index 87dc78d0c8..fb8ce963f1 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -233,7 +233,7 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ } // We double-check this to fast-path the case when a pixel is not covered by the shape & not call the color converter unnecessarily. - if (output_pixel.opaque) { + if (!output_pixel.opaque) { VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel from colorconverter; input area is not fully covered)\n"); full_coverage = false; } From 8607cdd7830220f5ad30fc62e367b0fc01596855 Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sun, 1 Aug 2021 13:01:57 -0700 Subject: [PATCH 03/63] vectorio: add draw protocol * Removes VectorShape from user python interactions * Re-integrates vectorio with displayio behind draw protocol implementations * Implements draw protocol with VectorShape * Composes VectorShape behaviors into Rectangle, Circle and Polygon * Fixes terrible pixel garbage being left behind * Improves redraw performance (heuristically) by tracking dirty area separately from current area. Known Issues: It does not work with transposed views. --- shared-bindings/vectorio/Circle.c | 36 ++++- shared-bindings/vectorio/Circle.h | 2 + shared-bindings/vectorio/Polygon.c | 36 ++++- shared-bindings/vectorio/Polygon.h | 2 + shared-bindings/vectorio/Rectangle.c | 36 ++++- shared-bindings/vectorio/Rectangle.h | 2 + shared-bindings/vectorio/VectorShape.c | 84 ++++++------ shared-bindings/vectorio/VectorShape.h | 14 +- shared-bindings/vectorio/__init__.c | 2 +- shared-bindings/vectorio/__init__.h | 41 ++++++ shared-module/displayio/Group.c | 51 ++++--- shared-module/vectorio/Circle.c | 5 + shared-module/vectorio/Circle.h | 1 + shared-module/vectorio/Polygon.c | 22 +-- shared-module/vectorio/Polygon.h | 1 + shared-module/vectorio/Rectangle.c | 11 +- shared-module/vectorio/Rectangle.h | 1 + shared-module/vectorio/VectorShape.c | 180 ++++++++++++++++--------- shared-module/vectorio/VectorShape.h | 3 +- 19 files changed, 374 insertions(+), 156 deletions(-) create mode 100644 shared-bindings/vectorio/__init__.h diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c index 673a976687..d6edba7063 100644 --- a/shared-bindings/vectorio/Circle.c +++ b/shared-bindings/vectorio/Circle.c @@ -1,5 +1,6 @@ - +#include "shared-bindings/vectorio/__init__.h" #include "shared-bindings/vectorio/Circle.h" +#include "shared-bindings/vectorio/VectorShape.h" #include @@ -11,15 +12,21 @@ //| class Circle: //| -//| def __init__(self, radius: int) -> None: +//| def __init__(self, pixel_shader: Union[ColorConverter, Palette] radius: int, x: int, y: int) -> None: //| """Circle is positioned on screen by its center point. //| -//| :param radius: The radius of the circle in pixels""" +//| :param pixel_shader: The pixel shader that produces colors from values +//| :param radius: The radius of the circle in pixels +//| :param x: Initial x position of the axis. +//| :param y: Initial y position of the axis.""" //| static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_radius }; + enum { ARG_pixel_shader, ARG_radius, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_radius, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -33,9 +40,22 @@ static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_arg self->base.type = &vectorio_circle_type; common_hal_vectorio_circle_construct(self, radius); + // VectorShape parts + mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + mp_obj_t vector_shape = vectorio_vector_shape_make_new(self, pixel_shader, x, y); + self->draw_protocol_instance = vector_shape; + return MP_OBJ_FROM_PTR(self); } +STATIC const vectorio_draw_protocol_t circle_draw_protocol = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_draw) + .draw_get_protocol_self = (draw_get_protocol_self_fun)common_hal_vectorio_circle_get_draw_protocol, + .draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl +}; + //| radius : int //| """The radius of the circle in pixels.""" @@ -62,13 +82,21 @@ const mp_obj_property_t vectorio_circle_radius_obj = { STATIC const mp_rom_map_elem_t vectorio_circle_locals_dict_table[] = { + // Properties { MP_ROM_QSTR(MP_QSTR_radius), MP_ROM_PTR(&vectorio_circle_radius_obj) }, + { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_circle_locals_dict, vectorio_circle_locals_dict_table); const mp_obj_type_t vectorio_circle_type = { { &mp_type_type }, .name = MP_QSTR_Circle, + .flags = MP_TYPE_FLAG_EXTENDED, .make_new = vectorio_circle_make_new, .locals_dict = (mp_obj_dict_t *)&vectorio_circle_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .protocol = &circle_draw_protocol, + ), }; diff --git a/shared-bindings/vectorio/Circle.h b/shared-bindings/vectorio/Circle.h index e8fc048eb8..37bbe9e65b 100644 --- a/shared-bindings/vectorio/Circle.h +++ b/shared-bindings/vectorio/Circle.h @@ -19,4 +19,6 @@ void common_hal_vectorio_circle_get_area(void *circle, displayio_area_t *out_are int16_t common_hal_vectorio_circle_get_radius(void *circle); void common_hal_vectorio_circle_set_radius(void *circle, int16_t radius); +mp_obj_t common_hal_vectorio_circle_get_draw_protocol(void *circle); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_CIRCLE_H diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c index 23c7961ec7..261e7ae55e 100644 --- a/shared-bindings/vectorio/Polygon.c +++ b/shared-bindings/vectorio/Polygon.c @@ -1,6 +1,7 @@ - +#include "shared-bindings/vectorio/__init__.h" #include "shared-module/vectorio/__init__.h" #include "shared-bindings/vectorio/Polygon.h" +#include "shared-bindings/vectorio/VectorShape.h" #include @@ -16,15 +17,21 @@ //| class Polygon: -//| def __init__(self, points: List[Tuple[int, int]]) -> None: +//| def __init__(self, pixel_shader: Union[ColorConverter, Palette], points: List[Tuple[int, int]], x: int, y: int) -> None: //| """Represents a closed shape by ordered vertices //| -//| :param points: Vertices for the polygon""" +//| :param pixel_shader: The pixel shader that produces colors from values +//| :param points: Vertices for the polygon +//| :param x: Initial screen x position of the 0,0 origin in the points list. +//| :param y: Initial screen y position of the 0,0 origin in the points list.""" //| static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_points_list }; + enum { ARG_pixel_shader, ARG_points_list, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_points, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -38,9 +45,22 @@ static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_ar common_hal_vectorio_polygon_construct(self, args[ARG_points_list].u_obj); + // VectorShape parts + mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + mp_obj_t vector_shape = vectorio_vector_shape_make_new(self, pixel_shader, x, y); + self->draw_protocol_instance = vector_shape; + return MP_OBJ_FROM_PTR(self); } +STATIC const vectorio_draw_protocol_t polygon_draw_protocol = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_draw) + .draw_get_protocol_self = (draw_get_protocol_self_fun)common_hal_vectorio_polygon_get_draw_protocol, + .draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl +}; + //| points: List[Tuple[int, int]] //| """Set a new look and shape for this polygon""" @@ -67,13 +87,21 @@ const mp_obj_property_t vectorio_polygon_points_obj = { }; STATIC const mp_rom_map_elem_t vectorio_polygon_locals_dict_table[] = { + // Properties { MP_ROM_QSTR(MP_QSTR_points), MP_ROM_PTR(&vectorio_polygon_points_obj) }, + { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_polygon_locals_dict, vectorio_polygon_locals_dict_table); const mp_obj_type_t vectorio_polygon_type = { { &mp_type_type }, .name = MP_QSTR_Polygon, + .flags = MP_TYPE_FLAG_EXTENDED, .make_new = vectorio_polygon_make_new, .locals_dict = (mp_obj_dict_t *)&vectorio_polygon_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .protocol = &polygon_draw_protocol, + ), }; diff --git a/shared-bindings/vectorio/Polygon.h b/shared-bindings/vectorio/Polygon.h index 5594fbec4a..68136be6bd 100644 --- a/shared-bindings/vectorio/Polygon.h +++ b/shared-bindings/vectorio/Polygon.h @@ -20,5 +20,7 @@ void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *out_a mp_obj_t common_hal_vectorio_polygon_get_points(vectorio_polygon_t *self); void common_hal_vectorio_polygon_set_points(vectorio_polygon_t *self, mp_obj_t points_list); +mp_obj_t common_hal_vectorio_polygon_get_draw_protocol(void *polygon); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_POLYGON_H diff --git a/shared-bindings/vectorio/Rectangle.c b/shared-bindings/vectorio/Rectangle.c index a50a8a14b3..98e38f0c6b 100644 --- a/shared-bindings/vectorio/Rectangle.c +++ b/shared-bindings/vectorio/Rectangle.c @@ -1,5 +1,7 @@ - +#include "shared-bindings/vectorio/__init__.h" #include "shared-bindings/vectorio/Rectangle.h" +#include "shared-module/vectorio/VectorShape.h" +#include "shared-bindings/vectorio/VectorShape.h" #include @@ -8,17 +10,23 @@ #include "supervisor/shared/translate.h" //| class Rectangle: -//| def __init__(self, width: int, height: int) -> None: +//| def __init__(self, pixel_shader: Union[ColorConverter, Palette], width: int, height: int, x: int, y: int) -> None: //| """Represents a rectangle by defining its bounds //| +//| :param pixel_shader: The pixel shader that produces colors from values //| :param width: The number of pixels wide -//| :param height: The number of pixels high""" +//| :param height: The number of pixels high +//| :param x: Initial x position of the top left corner. +//| :param y: Initial y position of the top left corner.""" //| static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_width, ARG_height }; + enum { ARG_pixel_shader, ARG_width, ARG_height, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, { MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, + { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -36,17 +44,37 @@ static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_ self->base.type = &vectorio_rectangle_type; common_hal_vectorio_rectangle_construct(self, width, height); + // VectorShape parts + mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; + int16_t x = args[ARG_x].u_int; + int16_t y = args[ARG_y].u_int; + mp_obj_t vector_shape = vectorio_vector_shape_make_new(self, pixel_shader, x, y); + self->draw_protocol_instance = vector_shape; + return MP_OBJ_FROM_PTR(self); } +STATIC const vectorio_draw_protocol_t rectangle_draw_protocol = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_draw) + .draw_get_protocol_self = (draw_get_protocol_self_fun)common_hal_vectorio_rectangle_get_draw_protocol, + .draw_protocol_impl = &vectorio_vector_shape_draw_protocol_impl +}; STATIC const mp_rom_map_elem_t vectorio_rectangle_locals_dict_table[] = { + // Properties + { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_rectangle_locals_dict, vectorio_rectangle_locals_dict_table); const mp_obj_type_t vectorio_rectangle_type = { { &mp_type_type }, .name = MP_QSTR_Rectangle, + .flags = MP_TYPE_FLAG_EXTENDED, .make_new = vectorio_rectangle_make_new, .locals_dict = (mp_obj_dict_t *)&vectorio_rectangle_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .protocol = &rectangle_draw_protocol, + ), }; diff --git a/shared-bindings/vectorio/Rectangle.h b/shared-bindings/vectorio/Rectangle.h index bb461ed9d5..24b103c26e 100644 --- a/shared-bindings/vectorio/Rectangle.h +++ b/shared-bindings/vectorio/Rectangle.h @@ -12,4 +12,6 @@ uint32_t common_hal_vectorio_rectangle_get_pixel(void *rectangle, int16_t x, int void common_hal_vectorio_rectangle_get_area(void *rectangle, displayio_area_t *out_area); +mp_obj_t common_hal_vectorio_rectangle_get_draw_protocol(void *rectangle); + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_RECTANGLE_H diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index be24a056c9..fc46eceec7 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -19,37 +19,16 @@ #include "supervisor/shared/translate.h" -//| class VectorShape: -//| def __init__(self, shape: Union[Polygon, Rectangle, Circle], pixel_shader: Union[displayio.ColorConverter, displayio.Palette], x: int=0, y: int=0) -> None: -//| """Binds a vector shape to a location and pixel shader. The shader can be a displayio.Palette(1); it will be asked to color pixel value 0. -//| -//| :param shape: The shape to draw. -//| :param pixel_shader: The pixel shader that produces colors from values -//| :param x: Initial x position of the center axis of the shape within the parent. -//| :param y: Initial y position of the center axis of the shape within the parent.""" -//| ... -//| -STATIC mp_obj_t vectorio_vector_shape_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_shape, ARG_pixel_shader, ARG_x, ARG_y }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_shape, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, - { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, - { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, - { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; +// shape: The shape implementation to draw. +// pixel_shader: The pixel shader that produces colors from values. The shader can be a displayio.Palette(1); it will be asked to color pixel value 0. +// x: Initial x position of the center axis of the shape within the parent. +// y: Initial y position of the center axis of the shape within the parent.""" +mp_obj_t vectorio_vector_shape_make_new(const mp_obj_t shape, const mp_obj_t pixel_shader, int16_t x, int16_t y) { if (!mp_obj_is_type(pixel_shader, &displayio_colorconverter_type) && !mp_obj_is_type(pixel_shader, &displayio_palette_type)) { mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_pixel_shader); } - int16_t x = args[ARG_x].u_int; - int16_t y = args[ARG_y].u_int; - - mp_obj_t shape = args[ARG_shape].u_obj; vectorio_ishape_t ishape; // Wire up shape functions if (mp_obj_is_type(shape, &vectorio_polygon_type)) { @@ -92,18 +71,31 @@ STATIC mp_obj_t vectorio_vector_shape_make_new(const mp_obj_type_t *type, size_t return MP_OBJ_FROM_PTR(self); } +vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl = { + .draw_fill_area = (draw_fill_area_fun)vectorio_vector_shape_fill_area, + .draw_get_dirty_area = (draw_get_dirty_area_fun)vectorio_vector_shape_get_dirty_area, + .draw_update_transform = (draw_update_transform_fun)vectorio_vector_shape_update_transform, + .draw_finish_refresh = (draw_finish_refresh_fun)vectorio_vector_shape_finish_refresh, + .draw_get_refresh_areas = (draw_get_refresh_areas_fun)vectorio_vector_shape_get_refresh_areas, +}; + //| x: int //| """X position of the center point of the shape in the parent.""" //| -STATIC mp_obj_t vectorio_vector_shape_obj_get_x(mp_obj_t self_in) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t vectorio_vector_shape_obj_get_x(mp_obj_t wrapper_shape) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + return MP_OBJ_NEW_SMALL_INT(common_hal_vectorio_vector_shape_get_x(self)); } MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_x_obj, vectorio_vector_shape_obj_get_x); -STATIC mp_obj_t vectorio_vector_shape_obj_set_x(mp_obj_t self_in, mp_obj_t x_obj) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t vectorio_vector_shape_obj_set_x(mp_obj_t wrapper_shape, mp_obj_t x_obj) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); mp_int_t x = mp_obj_get_int(x_obj); common_hal_vectorio_vector_shape_set_x(self, x); @@ -122,14 +114,19 @@ const mp_obj_property_t vectorio_vector_shape_x_obj = { //| y: int //| """Y position of the center point of the shape in the parent.""" //| -STATIC mp_obj_t vectorio_vector_shape_obj_get_y(mp_obj_t self_in) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t vectorio_vector_shape_obj_get_y(mp_obj_t wrapper_shape) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + return MP_OBJ_NEW_SMALL_INT(common_hal_vectorio_vector_shape_get_y(self)); } MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_y_obj, vectorio_vector_shape_obj_get_y); -STATIC mp_obj_t vectorio_vector_shape_obj_set_y(mp_obj_t self_in, mp_obj_t y_obj) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t vectorio_vector_shape_obj_set_y(mp_obj_t wrapper_shape, mp_obj_t y_obj) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); mp_int_t y = mp_obj_get_int(y_obj); common_hal_vectorio_vector_shape_set_y(self, y); @@ -148,14 +145,20 @@ const mp_obj_property_t vectorio_vector_shape_y_obj = { //| pixel_shader: Union[displayio.ColorConverter, displayio.Palette] //| """The pixel shader of the shape.""" //| -STATIC mp_obj_t vectorio_vector_shape_obj_get_pixel_shader(mp_obj_t self_in) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t vectorio_vector_shape_obj_get_pixel_shader(mp_obj_t wrapper_shape) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + return common_hal_vectorio_vector_shape_get_pixel_shader(self); } MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_pixel_shader_obj, vectorio_vector_shape_obj_get_pixel_shader); -STATIC mp_obj_t vectorio_vector_shape_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) { - vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t vectorio_vector_shape_obj_set_pixel_shader(mp_obj_t wrapper_shape, mp_obj_t pixel_shader) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) { mp_raise_TypeError(translate("pixel_shader must be displayio.Palette or displayio.ColorConverter")); } @@ -175,16 +178,11 @@ const mp_obj_property_t vectorio_vector_shape_pixel_shader_obj = { STATIC const mp_rom_map_elem_t vectorio_vector_shape_locals_dict_table[] = { - // Properties - { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, - { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, - { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_vector_shape_locals_dict, vectorio_vector_shape_locals_dict_table); const mp_obj_type_t vectorio_vector_shape_type = { { &mp_type_type }, .name = MP_QSTR_VectorShape, - .make_new = vectorio_vector_shape_make_new, .locals_dict = (mp_obj_dict_t *)&vectorio_vector_shape_locals_dict, }; diff --git a/shared-bindings/vectorio/VectorShape.h b/shared-bindings/vectorio/VectorShape.h index fa11f73ffd..4cf2ae373b 100644 --- a/shared-bindings/vectorio/VectorShape.h +++ b/shared-bindings/vectorio/VectorShape.h @@ -1,11 +1,18 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H +#include "py/objproperty.h" + +#include "shared-bindings/vectorio/__init__.h" #include "shared-module/vectorio/VectorShape.h" #include "shared-module/displayio/area.h" extern const mp_obj_type_t vectorio_vector_shape_type; +// Python shared bindings constructor +mp_obj_t vectorio_vector_shape_make_new(const mp_obj_t shape, const mp_obj_t pixel_shader, int16_t x, int16_t y); + +// C data constructor void common_hal_vectorio_vector_shape_construct(vectorio_vector_shape_t *self, vectorio_ishape_t ishape, mp_obj_t pixel_shader, uint16_t x, uint16_t y); @@ -21,7 +28,12 @@ void common_hal_vectorio_vector_shape_set_y(vectorio_vector_shape_t *self, mp_in mp_obj_t common_hal_vectorio_vector_shape_get_pixel_shader(vectorio_vector_shape_t *self); void common_hal_vectorio_vector_shape_set_pixel_shader(vectorio_vector_shape_t *self, mp_obj_t pixel_shader); - void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displayio_buffer_transform_t *group_transform); +// Composable property definition for shapes that use VectorShape +extern vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl; +extern const mp_obj_property_t vectorio_vector_shape_x_obj; +extern const mp_obj_property_t vectorio_vector_shape_y_obj; +extern const mp_obj_property_t vectorio_vector_shape_pixel_shader_obj; + #endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H diff --git a/shared-bindings/vectorio/__init__.c b/shared-bindings/vectorio/__init__.c index 12fb4d72b1..556bfe59ec 100644 --- a/shared-bindings/vectorio/__init__.c +++ b/shared-bindings/vectorio/__init__.c @@ -16,7 +16,7 @@ STATIC const mp_rom_map_elem_t vectorio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Circle), MP_ROM_PTR(&vectorio_circle_type) }, { MP_ROM_QSTR(MP_QSTR_Polygon), MP_ROM_PTR(&vectorio_polygon_type) }, { MP_ROM_QSTR(MP_QSTR_Rectangle), MP_ROM_PTR(&vectorio_rectangle_type) }, - { MP_ROM_QSTR(MP_QSTR_VectorShape), MP_ROM_PTR(&vectorio_vector_shape_type) }, +// { MP_ROM_QSTR(MP_QSTR_VectorShape), MP_ROM_PTR(&vectorio_vector_shape_type) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_module_globals, vectorio_module_globals_table); diff --git a/shared-bindings/vectorio/__init__.h b/shared-bindings/vectorio/__init__.h new file mode 100644 index 0000000000..a221224058 --- /dev/null +++ b/shared-bindings/vectorio/__init__.h @@ -0,0 +1,41 @@ +#ifndef SHARED_MODULE_VECTORIO__INIT__H +#define SHARED_MODULE_VECTORIO__INIT__H + +#include +#include + +#include "py/obj.h" +#include "py/proto.h" + +#include "shared-module/displayio/area.h" +#include "shared-module/displayio/Palette.h" + +// Returns the object on which the rest of the draw protocol methods are invoked. +typedef mp_obj_t (*draw_get_protocol_self_fun)(mp_obj_t protocol_container); + +typedef bool (*draw_fill_area_fun)(mp_obj_t draw_protocol_self, const _displayio_colorspace_t *colorspace, const displayio_area_t *area, uint32_t *mask, uint32_t *buffer); +typedef bool (*draw_get_dirty_area_fun)(mp_obj_t draw_protocol_self, displayio_area_t *current_dirty_area); +typedef void (*draw_update_transform_fun)(mp_obj_t draw_protocol_self, displayio_buffer_transform_t *group_transform); +typedef void (*draw_finish_refresh_fun)(mp_obj_t draw_protocol_self); +typedef displayio_area_t *(*draw_get_refresh_areas_fun)(mp_obj_t draw_protocol_self, displayio_area_t *tail); + +typedef struct _vectorio_draw_protocol_impl_t { + draw_fill_area_fun draw_fill_area; + draw_get_dirty_area_fun draw_get_dirty_area; + draw_update_transform_fun draw_update_transform; + draw_finish_refresh_fun draw_finish_refresh; + draw_get_refresh_areas_fun draw_get_refresh_areas; +} vectorio_draw_protocol_impl_t; + +// Draw protocol +typedef struct _vectorio_draw_protocol_t { + MP_PROTOCOL_HEAD // MP_QSTR_protocol_draw + + // Instance of the draw protocol + draw_get_protocol_self_fun draw_get_protocol_self; + + // Implementation functions for the draw protocol + vectorio_draw_protocol_impl_t *draw_protocol_impl; +} vectorio_draw_protocol_t; + +#endif diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index ec8ad7ba5a..b9179f0a00 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -144,10 +144,10 @@ static void _update_child_transforms(displayio_group_t *self) { for (size_t i = 0; i < self->members->len; i++) { mp_obj_t layer; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[i], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - vectorio_vector_shape_update_transform(layer, &self->absolute_transform); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[i]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[i]); + draw_protocol->draw_protocol_impl->draw_update_transform(layer, &self->absolute_transform); continue; } #endif @@ -241,15 +241,14 @@ void common_hal_displayio_group_set_y(displayio_group_t *self, mp_int_t y) { } static void _add_layer(displayio_group_t *self, mp_obj_t layer) { - mp_obj_t native_layer; #if CIRCUITPY_VECTORIO - native_layer = mp_obj_cast_to_native_base(layer, &vectorio_vector_shape_type); - if (native_layer != MP_OBJ_NULL) { - vectorio_vector_shape_update_transform(native_layer, &self->absolute_transform); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, layer); + if (draw_protocol != NULL) { + draw_protocol->draw_protocol_impl->draw_update_transform(draw_protocol->draw_get_protocol_self(layer), &self->absolute_transform); return; } #endif - native_layer = mp_obj_cast_to_native_base(layer, &displayio_tilegrid_type); + mp_obj_t native_layer = mp_obj_cast_to_native_base(layer, &displayio_tilegrid_type); if (native_layer != MP_OBJ_NULL) { displayio_tilegrid_t *tilegrid = native_layer; if (tilegrid->in_group) { @@ -283,12 +282,12 @@ static void _remove_layer(displayio_group_t *self, size_t index) { displayio_area_t layer_area; bool rendered_last_frame = false; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[index], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - bool has_dirty_area = vectorio_vector_shape_get_dirty_area(layer, &layer_area); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[index]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[index]); + bool has_dirty_area = draw_protocol->draw_protocol_impl->draw_get_dirty_area(layer, &layer_area); rendered_last_frame = has_dirty_area; - vectorio_vector_shape_update_transform(layer, NULL); + draw_protocol->draw_protocol_impl->draw_update_transform(layer, NULL); } #endif layer = mp_obj_cast_to_native_base( @@ -362,10 +361,10 @@ bool displayio_group_fill_area(displayio_group_t *self, const _displayio_colorsp for (int32_t i = self->members->len - 1; i >= 0; i--) { mp_obj_t layer; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[i], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - if (vectorio_vector_shape_fill_area(layer, colorspace, area, mask, buffer)) { + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[i]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[i]); + if (draw_protocol->draw_protocol_impl->draw_fill_area(layer, colorspace, area, mask, buffer)) { return true; } continue; @@ -396,10 +395,10 @@ void displayio_group_finish_refresh(displayio_group_t *self) { for (int32_t i = self->members->len - 1; i >= 0; i--) { mp_obj_t layer; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[i], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - vectorio_vector_shape_finish_refresh(layer); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[i]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[i]); + draw_protocol->draw_protocol_impl->draw_finish_refresh(layer); continue; } #endif @@ -427,10 +426,10 @@ displayio_area_t *displayio_group_get_refresh_areas(displayio_group_t *self, dis for (int32_t i = self->members->len - 1; i >= 0; i--) { mp_obj_t layer; #if CIRCUITPY_VECTORIO - layer = mp_obj_cast_to_native_base( - self->members->items[i], &vectorio_vector_shape_type); - if (layer != MP_OBJ_NULL) { - tail = vectorio_vector_shape_get_refresh_areas(layer, tail); + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, self->members->items[i]); + if (draw_protocol != NULL) { + layer = draw_protocol->draw_get_protocol_self(self->members->items[i]); + tail = draw_protocol->draw_protocol_impl->draw_get_refresh_areas(layer, tail); continue; } #endif diff --git a/shared-module/vectorio/Circle.c b/shared-module/vectorio/Circle.c index 9c74580650..6b4c441620 100644 --- a/shared-module/vectorio/Circle.c +++ b/shared-module/vectorio/Circle.c @@ -59,3 +59,8 @@ void common_hal_vectorio_circle_set_radius(void *obj, int16_t radius) { self->on_dirty.event(self->on_dirty.obj); } } + +mp_obj_t common_hal_vectorio_circle_get_draw_protocol(void *circle) { + vectorio_circle_t *self = circle; + return self->draw_protocol_instance; +} diff --git a/shared-module/vectorio/Circle.h b/shared-module/vectorio/Circle.h index d6a77b1667..106bca6a71 100644 --- a/shared-module/vectorio/Circle.h +++ b/shared-module/vectorio/Circle.h @@ -11,6 +11,7 @@ typedef struct { mp_obj_base_t base; uint16_t radius; vectorio_event_t on_dirty; + mp_obj_t draw_protocol_instance; } vectorio_circle_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_CIRCLE_H diff --git a/shared-module/vectorio/Polygon.c b/shared-module/vectorio/Polygon.c index 00af1e0d7e..db3deced2a 100644 --- a/shared-module/vectorio/Polygon.c +++ b/shared-module/vectorio/Polygon.c @@ -1,4 +1,3 @@ - #include "shared-module/vectorio/__init__.h" #include "shared-bindings/vectorio/Polygon.h" #include "shared-module/displayio/area.h" @@ -108,17 +107,17 @@ void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *area) int x = self->points_list[i]; ++i; int y = self->points_list[i]; - if (x <= area->x1) { - area->x1 = x - 1; + if (x < area->x1) { + area->x1 = x; } - if (y <= area->y1) { - area->y1 = y - 1; + if (y < area->y1) { + area->y1 = y; } - if (x >= area->x2) { - area->x2 = x + 1; + if (x > area->x2) { + area->x2 = x; } - if (y >= area->y2) { - area->y2 = y + 1; + if (y > area->y2) { + area->y2 = y; } } } @@ -167,3 +166,8 @@ uint32_t common_hal_vectorio_polygon_get_pixel(void *obj, int16_t x, int16_t y) } return winding_number == 0 ? 0 : 1; } + +mp_obj_t common_hal_vectorio_polygon_get_draw_protocol(void *polygon) { + vectorio_polygon_t *self = polygon; + return self->draw_protocol_instance; +} diff --git a/shared-module/vectorio/Polygon.h b/shared-module/vectorio/Polygon.h index 70de9036d7..21d32d3581 100644 --- a/shared-module/vectorio/Polygon.h +++ b/shared-module/vectorio/Polygon.h @@ -12,6 +12,7 @@ typedef struct { int *points_list; size_t len; vectorio_event_t on_dirty; + mp_obj_t draw_protocol_instance; } vectorio_polygon_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_POLYGON_H diff --git a/shared-module/vectorio/Rectangle.c b/shared-module/vectorio/Rectangle.c index 56be5ebb5e..17185ec7ab 100644 --- a/shared-module/vectorio/Rectangle.c +++ b/shared-module/vectorio/Rectangle.c @@ -12,10 +12,10 @@ void common_hal_vectorio_rectangle_construct(vectorio_rectangle_t *self, uint32_ uint32_t common_hal_vectorio_rectangle_get_pixel(void *obj, int16_t x, int16_t y) { vectorio_rectangle_t *self = obj; - if (x < 0 || x >= self->width || y >= self->height || y < 0) { - return 0; + if (x >= 0 && y >= 0 && x < self->width && y < self->height ) { + return 1; } - return 1; + return 0; } @@ -32,3 +32,8 @@ uint32_t common_hal_vectorio_rectangle_get_height(void *rectangle) { vectorio_rectangle_t *self = rectangle; return self->height; } + +mp_obj_t common_hal_vectorio_rectangle_get_draw_protocol(void *rectangle) { + vectorio_rectangle_t *self = rectangle; + return self->draw_protocol_instance; +} diff --git a/shared-module/vectorio/Rectangle.h b/shared-module/vectorio/Rectangle.h index 56342a6d76..e3cfbb2676 100644 --- a/shared-module/vectorio/Rectangle.h +++ b/shared-module/vectorio/Rectangle.h @@ -9,6 +9,7 @@ typedef struct { mp_obj_base_t base; uint16_t width; uint16_t height; + mp_obj_t draw_protocol_instance; } vectorio_rectangle_t; #endif // MICROPY_INCLUDED_SHARED_MODULE_VECTORIO_RECTANGLE_H diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index fb8ce963f1..929be46c0f 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -15,16 +15,16 @@ // Lifecycle actions. #define VECTORIO_SHAPE_DEBUG(...) (void)0 -// #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) +// #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Used in both logging and ifdefs, for extra variables -// #define VECTORIO_PERF(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) +// #define VECTORIO_PERF(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Really verbose. #define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 -// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) +// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) inline __attribute__((always_inline)) @@ -32,6 +32,11 @@ static int32_t max(int32_t a, int32_t b) { return a > b ? a : b; } +inline __attribute__((always_inline)) +static int32_t min(int32_t a, int32_t b) { + return a < b ? a : b; +} + inline __attribute__((always_inline)) static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *out_area) { @@ -39,48 +44,67 @@ static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *ou self->absolute_transform->x, self->absolute_transform->y, self->absolute_transform->dx, self->absolute_transform->dy, self->absolute_transform->scale, self->absolute_transform->width, self->absolute_transform->height, self->absolute_transform->mirror_x, self->absolute_transform->mirror_y, self->absolute_transform->transpose_xy ); - self->ishape.get_area(self->ishape.shape, out_area); - VECTORIO_SHAPE_DEBUG(" in:{(%5d,%5d), (%5d,%5d)}", out_area->x1, out_area->y1, out_area->x2, out_area->y2); - if (self->absolute_transform->transpose_xy) { - int16_t swap = out_area->x1; - out_area->x1 = (out_area->y1 + self->y) * self->absolute_transform->dx + self->absolute_transform->x; - out_area->y1 = (swap + self->x) * self->absolute_transform->dy + self->absolute_transform->y; - swap = out_area->x2; - out_area->x2 = (out_area->y2 + self->y) * self->absolute_transform->dx + self->absolute_transform->x; - out_area->y2 = (swap + self->x) * self->absolute_transform->dy + self->absolute_transform->y; - } else { - out_area->x1 = (out_area->x1 + self->x) * self->absolute_transform->dx + self->absolute_transform->x; - out_area->y1 = (out_area->y1 + self->y) * self->absolute_transform->dy + self->absolute_transform->y; - out_area->x2 = (out_area->x2 + self->x) * self->absolute_transform->dx + self->absolute_transform->x; - out_area->y2 = (out_area->y2 + self->y) * self->absolute_transform->dy + self->absolute_transform->y; - } - // We might have mirrored due to dx - displayio_area_canon(out_area); + displayio_area_t shape_area; + self->ishape.get_area(self->ishape.shape, &shape_area); + VECTORIO_SHAPE_DEBUG(" in:{(%5d,%5d), (%5d,%5d)}", shape_area.x1, shape_area.y1, shape_area.x2, shape_area.y2); + + displayio_area_shift( + &shape_area, + self->x * self->absolute_transform->dx + min(0, self->absolute_transform->dx * displayio_area_width(&shape_area)), + self->y * self->absolute_transform->dy + min(0, self->absolute_transform->dy * displayio_area_height(&shape_area)) + ); + + displayio_area_transform_within( + false, + false, + self->absolute_transform->transpose_xy, + &shape_area, &shape_area, out_area + ); + + displayio_area_shift( + out_area, + self->absolute_transform->x, + self->absolute_transform->y + ); + VECTORIO_SHAPE_DEBUG(" out:{(%5d,%5d), (%5d,%5d)}\n", out_area->x1, out_area->y1, out_area->x2, out_area->y2); } // For use by Group to know where it needs to redraw on layer removal. bool vectorio_vector_shape_get_dirty_area(vectorio_vector_shape_t *self, displayio_area_t *out_area) { - displayio_area_copy(&self->ephemeral_dirty_area, out_area); + out_area->x1 = out_area->x2; + displayio_area_union( + &self->ephemeral_dirty_area, + &self->current_area, + out_area + ); return true; // For now just always redraw. } -// This must be invoked each time a shape changes its position or its shape in any way. +// This must be invoked after each time a shape changes its position, shape or appearance in any way. void common_hal_vectorio_vector_shape_set_dirty(void *vector_shape) { vectorio_vector_shape_t *self = vector_shape; // In screen space. Need to offset the shape space. displayio_area_t current_area; _get_screen_area(self, ¤t_area); - VECTORIO_SHAPE_DEBUG("%p shape_dirty current:{(%3d,%3d), (%3d,%3d)} dirty:{(%3d,%3d), (%3d,%3d)}", + VECTORIO_SHAPE_DEBUG("%p shape_dirty new:{(%3d,%3d), (%3d,%3d)} dirty:{(%3d,%3d), (%3d,%3d)}", self, current_area.x1, current_area.y1, current_area.x2, current_area.y2, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); - self->dirty = true; - // Dirty area tracks the shape's footprint between draws. It's reset on refresh finish, - displayio_area_union(&self->ephemeral_dirty_area, ¤t_area, &self->ephemeral_dirty_area); - VECTORIO_SHAPE_DEBUG(" -> expanded:{(%3d,%3d), (%3d,%3d)}\n", self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); + + bool moved = !displayio_area_equal(¤t_area, &self->current_area); + if (moved) { + displayio_area_union(&self->current_area, &self->ephemeral_dirty_area, &self->ephemeral_dirty_area); + VECTORIO_SHAPE_DEBUG(" stale:{(%3d,%3d), (%3d,%3d)} -> expanded:{(%3d,%3d), (%3d,%3d)}\n", + self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2, + self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); + + // Dirty area tracks the shape's footprint between draws. It's reset on refresh finish. + displayio_area_copy(¤t_area, &self->current_area); + } + self->current_area_dirty = true; } @@ -92,10 +116,11 @@ void common_hal_vectorio_vector_shape_construct(vectorio_vector_shape_t *self, self->y = y; self->pixel_shader = pixel_shader; self->ishape = ishape; - self->dirty = true; self->absolute_transform = &null_transform; // Critical to have a valid transform before getting screen area. - _get_screen_area(self, &self->ephemeral_dirty_area); + self->ephemeral_dirty_area.x1 = self->ephemeral_dirty_area.x2; // Cheat to set area to 0 self->ephemeral_dirty_area.next = NULL; + self->current_area_dirty = true; + _get_screen_area(self, &self->current_area); } @@ -153,13 +178,12 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ uint64_t start = common_hal_time_monotonic_ns(); uint64_t pixel_time = 0; #endif - displayio_area_t overlap; - VECTORIO_SHAPE_DEBUG("%p fill_area dirty:%d fill: {(%5d,%5d), (%5d,%5d)} dirty: {(%5d,%5d), (%5d,%5d)}", - self, self->dirty, - area->x1, area->y1, area->x2, area->y2, - self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2 + VECTORIO_SHAPE_DEBUG("%p fill_area: fill: {(%5d,%5d), (%5d,%5d)}", + self, + area->x1, area->y1, area->x2, area->y2 ); - if (!displayio_area_compute_overlap(area, &self->ephemeral_dirty_area, &overlap)) { + displayio_area_t overlap; + if (!displayio_area_compute_overlap(area, &self->current_area, &overlap)) { VECTORIO_SHAPE_DEBUG(" no overlap\n"); return false; } @@ -168,6 +192,11 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ bool full_coverage = displayio_area_equal(area, &overlap); uint8_t pixels_per_byte = 8 / colorspace->depth; + VECTORIO_SHAPE_DEBUG(" xy:(%3d %3d) tform:{x:%d y:%d dx:%d dy:%d scl:%d w:%d h:%d mx:%d my:%d tr:%d}", + self->x, self->y, + self->absolute_transform->x, self->absolute_transform->y, self->absolute_transform->dx, self->absolute_transform->dy, self->absolute_transform->scale, + self->absolute_transform->width, self->absolute_transform->height, self->absolute_transform->mirror_x, self->absolute_transform->mirror_y, self->absolute_transform->transpose_xy + ); uint32_t linestride_px = displayio_area_width(area); uint32_t line_dirty_offset_px = (overlap.y1 - area->y1) * linestride_px; @@ -178,6 +207,25 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ displayio_input_pixel_t input_pixel; displayio_output_pixel_t output_pixel; + int16_t math_transform_offset_x; + int16_t math_transform_offset_y; + int16_t math_shape_offset_x; + int16_t math_shape_offset_y; + if (self->absolute_transform->transpose_xy) { + math_transform_offset_x = self->absolute_transform->dy * self->y; + math_transform_offset_y = self->absolute_transform->dx * self->x; + math_shape_offset_x = min(0, self->absolute_transform->dy * displayio_area_width(&self->current_area)); + math_shape_offset_y = min(0, self->absolute_transform->dx * displayio_area_height(&self->current_area)); + } else { + math_transform_offset_x = self->absolute_transform->dx * self->x; + math_transform_offset_y = self->absolute_transform->dy * self->y; + math_shape_offset_x = min(0, self->absolute_transform->dx * displayio_area_width(&self->current_area)); + math_shape_offset_y = min(0, self->absolute_transform->dy * displayio_area_height(&self->current_area)); + } + + VECTORIO_SHAPE_DEBUG(", transform_offset: (%3d,%3d), shape_offset: (%3d,%3d)", math_transform_offset_x, math_transform_offset_y, math_shape_offset_x, math_shape_offset_y); + + uint32_t mask_start_px = line_dirty_offset_px; for (input_pixel.y = overlap.y1; input_pixel.y < overlap.y2; ++input_pixel.y) { mask_start_px += column_dirty_offset_px; @@ -186,9 +234,9 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ uint32_t pixel_index = mask_start_px + (input_pixel.x - overlap.x1); uint32_t *mask_doubleword = &(mask[pixel_index / 32]); uint8_t mask_bit = pixel_index % 32; - VECTORIO_SHAPE_PIXEL_DEBUG("%p pixel_index: %5u mask_bit: %2u", self, pixel_index, mask_bit); + VECTORIO_SHAPE_PIXEL_DEBUG("\n%p pixel_index: %5u mask_bit: %2u", self, pixel_index, mask_bit); if ((*mask_doubleword & (1u << mask_bit)) != 0) { - VECTORIO_SHAPE_PIXEL_DEBUG(" masked\n"); + VECTORIO_SHAPE_PIXEL_DEBUG(" masked"); continue; } output_pixel.pixel = 0; @@ -197,11 +245,11 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ int16_t pixel_to_get_x; int16_t pixel_to_get_y; if (self->absolute_transform->transpose_xy) { - pixel_to_get_x = (input_pixel.y - self->absolute_transform->dy * self->x - self->absolute_transform->y) / self->absolute_transform->dy; - pixel_to_get_y = (input_pixel.x - self->absolute_transform->dx * self->y - self->absolute_transform->x) / self->absolute_transform->dx; + pixel_to_get_x = (input_pixel.y - math_transform_offset_y - self->absolute_transform->y) - math_shape_offset_y; + pixel_to_get_y = (input_pixel.x - math_transform_offset_x - self->absolute_transform->x) - math_shape_offset_x; } else { - pixel_to_get_x = (input_pixel.x - self->absolute_transform->dx * self->x - self->absolute_transform->x) / self->absolute_transform->dx; - pixel_to_get_y = (input_pixel.y - self->absolute_transform->dy * self->y - self->absolute_transform->y) / self->absolute_transform->dy; + pixel_to_get_x = (input_pixel.x - math_transform_offset_x - self->absolute_transform->x) - math_shape_offset_x; + pixel_to_get_y = (input_pixel.y - math_transform_offset_y - self->absolute_transform->y) - math_shape_offset_y; } VECTORIO_SHAPE_PIXEL_DEBUG(" get_pixel %p (%3d, %3d) -> ( %3d, %3d )", self->ishape.shape, input_pixel.x, input_pixel.y, pixel_to_get_x, pixel_to_get_y); #ifdef VECTORIO_PERF @@ -217,7 +265,7 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ // vectorio shapes use 0 to mean "area is not covered." // We can skip all the rest of the work for this pixel if it's not currently covered by the shape. if (input_pixel.pixel == 0) { - VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel; input area is not fully covered)\n"); + VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel; input area is not fully covered)"); full_coverage = false; } else { // Pixel is not transparent. Let's pull the pixel value index down to 0-base for more error-resistant palettes. @@ -234,16 +282,16 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ // We double-check this to fast-path the case when a pixel is not covered by the shape & not call the color converter unnecessarily. if (!output_pixel.opaque) { - VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel from colorconverter; input area is not fully covered)\n"); + VECTORIO_SHAPE_PIXEL_DEBUG(" (encountered transparent pixel from colorconverter; input area is not fully covered)"); full_coverage = false; } *mask_doubleword |= 1u << mask_bit; if (colorspace->depth == 16) { - VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %04x 16\n", output_pixel.pixel); + VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %04x 16", output_pixel.pixel); *(((uint16_t *)buffer) + pixel_index) = output_pixel.pixel; } else if (colorspace->depth == 8) { - VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %02x 8\n", output_pixel.pixel); + VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %02x 8", output_pixel.pixel); *(((uint8_t *)buffer) + pixel_index) = output_pixel.pixel; } else if (colorspace->depth < 8) { // Reorder the offsets to pack multiple rows into a byte (meaning they share a column). @@ -258,7 +306,7 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ // Reverse the shift by subtracting it from the leftmost shift. shift = (pixels_per_byte - 1) * colorspace->depth - shift; } - VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %2d %d\n", output_pixel.pixel, colorspace->depth); + VECTORIO_SHAPE_PIXEL_DEBUG(" buffer = %2d %d", output_pixel.pixel, colorspace->depth); ((uint8_t *)buffer)[pixel_index / pixels_per_byte] |= output_pixel.pixel << shift; } } @@ -277,20 +325,23 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ (double)(pixel_time / 1000.0 / pixels) ); #endif - VECTORIO_SHAPE_DEBUG(" -> pixels:%4d\n"); + VECTORIO_SHAPE_DEBUG(" -> pixels:%4d\n", (overlap.x2 - overlap.x1) * (overlap.y2 - overlap.y1)); return full_coverage; } void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self) { - if (!self->dirty) { + if (displayio_area_empty(&self->ephemeral_dirty_area)) { return; } VECTORIO_SHAPE_DEBUG("%p finish_refresh was:{(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); - self->dirty = false; - // Reset dirty area tracking to current footprint - _get_screen_area(self, &self->ephemeral_dirty_area); + // Reset dirty area to nothing + self->ephemeral_dirty_area.x1 = self->ephemeral_dirty_area.x2; // Cheat to set area to empty self->ephemeral_dirty_area.next = NULL; + + self->current_area_dirty = false; // We don't clear current area so we can remember what to clean up if we move + self->current_area.next = NULL; + VECTORIO_SHAPE_DEBUG("%p finish_refresh now:{(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { @@ -303,21 +354,30 @@ void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self) { // Assembles a singly linked list of dirty areas from all components on the display. displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t *tail) { - if (self->dirty + displayio_area_t *new_tail = tail; + if (!displayio_area_empty(&self->ephemeral_dirty_area)) { + // vector.add_to_head + self->ephemeral_dirty_area.next = tail; + new_tail = &self->ephemeral_dirty_area; + VECTORIO_SHAPE_DEBUG("%p get_refresh_area dirty: {(%3d,%3d), (%3d,%3d)}", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); + } + if (self->current_area_dirty || (mp_obj_is_type(self->pixel_shader, &displayio_palette_type) && displayio_palette_needs_refresh(self->pixel_shader)) || (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type) && displayio_colorconverter_needs_refresh(self->pixel_shader)) ) { - VECTORIO_SHAPE_DEBUG("%p get_refresh_area dirty:%d {(%3d,%3d), (%3d,%3d)}", self, self->dirty, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); - common_hal_vectorio_vector_shape_set_dirty(self); - // vector.add_to_head - self->ephemeral_dirty_area.next = tail; - VECTORIO_SHAPE_DEBUG(" this_area: %p next: %p after: %p\n", &self->ephemeral_dirty_area, tail, tail == NULL ? NULL : tail->next); - return &self->ephemeral_dirty_area; + self->current_area.next = new_tail; + new_tail = &self->current_area; + VECTORIO_SHAPE_DEBUG(" redrawing current: {(%3d,%3d), (%3d,%3d)}", self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2); } - return tail; +#ifdef VECTORIO_SHAPE_DEBUG + if (new_tail != tail) { + VECTORIO_SHAPE_DEBUG("\n"); + } +#endif + return new_tail; } void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displayio_buffer_transform_t *group_transform) { - self->absolute_transform = group_transform == NULL ? &null_transform : group_transform; common_hal_vectorio_vector_shape_set_dirty(self); + self->absolute_transform = group_transform == NULL ? &null_transform : group_transform; } diff --git a/shared-module/vectorio/VectorShape.h b/shared-module/vectorio/VectorShape.h index 1896c72d6e..fdbae964a8 100644 --- a/shared-module/vectorio/VectorShape.h +++ b/shared-module/vectorio/VectorShape.h @@ -31,11 +31,12 @@ typedef struct { int16_t x; int16_t y; displayio_buffer_transform_t *absolute_transform; - bool dirty; // True if we need to draw // Tracks current shape footprint and expands outward as the shape dirties and changes. // This is suboptimal if you move your shape far. Could add more state to only redraw // exactly what we left behind. displayio_area_t ephemeral_dirty_area; + displayio_area_t current_area; + bool current_area_dirty; } vectorio_vector_shape_t; displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t *tail); From 8c22993e284d234afe60376d752cfe5f239377fd Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Mon, 2 Aug 2021 20:38:37 -0700 Subject: [PATCH 04/63] fix linter --- shared-module/vectorio/Rectangle.c | 2 +- shared-module/vectorio/VectorShape.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shared-module/vectorio/Rectangle.c b/shared-module/vectorio/Rectangle.c index 17185ec7ab..2471daa608 100644 --- a/shared-module/vectorio/Rectangle.c +++ b/shared-module/vectorio/Rectangle.c @@ -12,7 +12,7 @@ void common_hal_vectorio_rectangle_construct(vectorio_rectangle_t *self, uint32_ uint32_t common_hal_vectorio_rectangle_get_pixel(void *obj, int16_t x, int16_t y) { vectorio_rectangle_t *self = obj; - if (x >= 0 && y >= 0 && x < self->width && y < self->height ) { + if (x >= 0 && y >= 0 && x < self->width && y < self->height) { return 1; } return 0; diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index 929be46c0f..4406f20120 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -60,7 +60,7 @@ static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *ou self->absolute_transform->transpose_xy, &shape_area, &shape_area, out_area ); - + displayio_area_shift( out_area, self->absolute_transform->x, @@ -100,7 +100,7 @@ void common_hal_vectorio_vector_shape_set_dirty(void *vector_shape) { VECTORIO_SHAPE_DEBUG(" stale:{(%3d,%3d), (%3d,%3d)} -> expanded:{(%3d,%3d), (%3d,%3d)}\n", self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); - + // Dirty area tracks the shape's footprint between draws. It's reset on refresh finish. displayio_area_copy(¤t_area, &self->current_area); } @@ -369,11 +369,11 @@ displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_ new_tail = &self->current_area; VECTORIO_SHAPE_DEBUG(" redrawing current: {(%3d,%3d), (%3d,%3d)}", self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2); } -#ifdef VECTORIO_SHAPE_DEBUG + #ifdef VECTORIO_SHAPE_DEBUG if (new_tail != tail) { VECTORIO_SHAPE_DEBUG("\n"); } -#endif + #endif return new_tail; } From 6663dacedb042c2f7aedc17ad2fd83fc7ca06906 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Tue, 3 Aug 2021 14:01:56 +0100 Subject: [PATCH 05/63] Added board configurations for Plasma and Interstate --- .github/workflows/build.yml | 2 + .../boards/pimoroni_interstate75/board.c | 40 +++++++++++++++ .../pimoroni_interstate75/mpconfigboard.h | 15 ++++++ .../pimoroni_interstate75/mpconfigboard.mk | 11 ++++ .../pico-sdk-configboard.h | 1 + .../boards/pimoroni_interstate75/pins.c | 50 +++++++++++++++++++ .../boards/pimoroni_plasma2040/board.c | 40 +++++++++++++++ .../pimoroni_plasma2040/mpconfigboard.h | 26 ++++++++++ .../pimoroni_plasma2040/mpconfigboard.mk | 11 ++++ .../pico-sdk-configboard.h | 1 + .../boards/pimoroni_plasma2040/pins.c | 37 ++++++++++++++ 11 files changed, 234 insertions(+) create mode 100644 ports/raspberrypi/boards/pimoroni_interstate75/board.c create mode 100644 ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h create mode 100644 ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk create mode 100644 ports/raspberrypi/boards/pimoroni_interstate75/pico-sdk-configboard.h create mode 100644 ports/raspberrypi/boards/pimoroni_interstate75/pins.c create mode 100644 ports/raspberrypi/boards/pimoroni_plasma2040/board.c create mode 100644 ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h create mode 100644 ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk create mode 100644 ports/raspberrypi/boards/pimoroni_plasma2040/pico-sdk-configboard.h create mode 100644 ports/raspberrypi/boards/pimoroni_plasma2040/pins.c diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3cd9f6650e..473c81acd0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -321,11 +321,13 @@ jobs: - "pewpew10" - "pewpew_m4" - "picoplanet" + - "pimoroni_interstate75" - "pimoroni_keybow2040" - "pimoroni_pga2040" - "pimoroni_picolipo_16mb" - "pimoroni_picolipo_4mb" - "pimoroni_picosystem" + - "pimoroni_plasma2040" - "pimoroni_tiny2040" - "pitaya_go" - "pyb_nano_v2" diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/board.c b/ports/raspberrypi/boards/pimoroni_interstate75/board.c new file mode 100644 index 0000000000..de6e424ed9 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_interstate75/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h new file mode 100644 index 0000000000..968f69ad7e --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h @@ -0,0 +1,15 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni Interstate 75" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_RGB_STATUS_INVERTED_PWM +#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) +#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) +#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) + +#define MICROPY_HW_USER_SW (&pin_GPIO23) + +// These pins are unconnected +#define IGNORE_PIN_GPIO15 1 +#define IGNORE_PIN_GPIO22 1 +#define IGNORE_PIN_GPIO24 1 +#define IGNORE_PIN_GPIO25 1 diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk new file mode 100644 index 0000000000..a513a1df11 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x16D0 +USB_PID = 0x08C7 +USB_PRODUCT = "Interstate 75" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_interstate75/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_interstate75/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/pins.c b/ports/raspberrypi/boards/pimoroni_interstate75/pins.c new file mode 100644 index 0000000000..db20e6ea52 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_interstate75/pins.c @@ -0,0 +1,50 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_R0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_B0), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_R1), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_B1), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_ROW_A), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_ROW_B), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_ROW_C), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_ROW_D), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_ROW_E), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LED_STB), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LED_OE), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_CURRENT_SENSE), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/board.c b/ports/raspberrypi/boards/pimoroni_plasma2040/board.c new file mode 100644 index 0000000000..de6e424ed9 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/board.c @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { +} + +void board_deinit(void) { +} diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h new file mode 100644 index 0000000000..967267a8b4 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h @@ -0,0 +1,26 @@ +#define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_RGB_STATUS_INVERTED_PWM +#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) +#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) +#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) + +#define MICROPY_HW_USER_SW (&pin_GPIO23) + +// These pins are unconnected +#define IGNORE_PIN_GPIO0 1 +#define IGNORE_PIN_GPIO1 1 +#define IGNORE_PIN_GPIO2 1 +#define IGNORE_PIN_GPIO3 1 +#define IGNORE_PIN_GPIO4 1 +#define IGNORE_PIN_GPIO5 1 +#define IGNORE_PIN_GPIO6 1 +#define IGNORE_PIN_GPIO7 1 +#define IGNORE_PIN_GPIO8 1 +#define IGNORE_PIN_GPIO9 1 +#define IGNORE_PIN_GPIO10 1 +#define IGNORE_PIN_GPIO11 1 +#define IGNORE_PIN_GPIO22 1 +#define IGNORE_PIN_GPIO24 1 +#define IGNORE_PIN_GPIO25 1 diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk new file mode 100644 index 0000000000..3b2ef47fe8 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x16D0 +USB_PID = 0x08C7 +USB_PRODUCT = "Plasma 2040" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_plasma2040/pico-sdk-configboard.h new file mode 100644 index 0000000000..36da55d457 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c b/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c new file mode 100644 index 0000000000..799683378c --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c @@ -0,0 +1,37 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SW_B), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_DATA), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_CURRENT_SENSE), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); From 464281b881d6a1ff09919be23c16f1a5ae2f66de Mon Sep 17 00:00:00 2001 From: Kenny Date: Tue, 3 Aug 2021 08:08:11 -0700 Subject: [PATCH 06/63] Stub comma --- shared-bindings/vectorio/Circle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c index d6edba7063..cf4e643662 100644 --- a/shared-bindings/vectorio/Circle.c +++ b/shared-bindings/vectorio/Circle.c @@ -12,7 +12,7 @@ //| class Circle: //| -//| def __init__(self, pixel_shader: Union[ColorConverter, Palette] radius: int, x: int, y: int) -> None: +//| def __init__(self, pixel_shader: Union[ColorConverter, Palette], radius: int, x: int, y: int) -> None: //| """Circle is positioned on screen by its center point. //| //| :param pixel_shader: The pixel shader that produces colors from values From 739ef92fc95f48d98b77a4746b83022b8382685e Mon Sep 17 00:00:00 2001 From: Kenny Date: Tue, 3 Aug 2021 09:20:02 -0700 Subject: [PATCH 07/63] Update __init__.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit More random spaces. Why isn’t this in a pre-commit check --- shared-bindings/vectorio/__init__.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/vectorio/__init__.h b/shared-bindings/vectorio/__init__.h index a221224058..a34195de26 100644 --- a/shared-bindings/vectorio/__init__.h +++ b/shared-bindings/vectorio/__init__.h @@ -30,7 +30,7 @@ typedef struct _vectorio_draw_protocol_impl_t { // Draw protocol typedef struct _vectorio_draw_protocol_t { MP_PROTOCOL_HEAD // MP_QSTR_protocol_draw - + // Instance of the draw protocol draw_get_protocol_self_fun draw_get_protocol_self; From 48ea81e2f1660e6bdf05252ee059a79c84097881 Mon Sep 17 00:00:00 2001 From: Kenny Date: Tue, 3 Aug 2021 11:25:31 -0700 Subject: [PATCH 09/63] Vexing pedantry Spaces deleted from phone Eternal chore, lint --- shared-bindings/vectorio/VectorShape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index fc46eceec7..979651bd4a 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -87,7 +87,7 @@ STATIC mp_obj_t vectorio_vector_shape_obj_get_x(mp_obj_t wrapper_shape) { // Relies on the fact that only vector_shape impl gets matched with a VectorShape. const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); - + return MP_OBJ_NEW_SMALL_INT(common_hal_vectorio_vector_shape_get_x(self)); } MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_x_obj, vectorio_vector_shape_obj_get_x); From 85bf3d074f4355d70c2477e0d3987c653f401c81 Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Wed, 4 Aug 2021 23:55:03 -0700 Subject: [PATCH 10/63] stub checker does not approve of shared vectorshape properties --- shared-bindings/vectorio/VectorShape.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index 979651bd4a..8d6c2b71db 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -80,9 +80,10 @@ vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl = { }; -//| x: int -//| """X position of the center point of the shape in the parent.""" -//| +// Stub checker does not approve of these shared properties. +// x: int +// """X position of the center point of the shape in the parent.""" +// STATIC mp_obj_t vectorio_vector_shape_obj_get_x(mp_obj_t wrapper_shape) { // Relies on the fact that only vector_shape impl gets matched with a VectorShape. const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); @@ -111,9 +112,9 @@ const mp_obj_property_t vectorio_vector_shape_x_obj = { }; -//| y: int -//| """Y position of the center point of the shape in the parent.""" -//| +// y: int +// """Y position of the center point of the shape in the parent.""" +// STATIC mp_obj_t vectorio_vector_shape_obj_get_y(mp_obj_t wrapper_shape) { // Relies on the fact that only vector_shape impl gets matched with a VectorShape. const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); @@ -142,9 +143,9 @@ const mp_obj_property_t vectorio_vector_shape_y_obj = { }; -//| pixel_shader: Union[displayio.ColorConverter, displayio.Palette] -//| """The pixel shader of the shape.""" -//| +// pixel_shader: Union[displayio.ColorConverter, displayio.Palette] +// """The pixel shader of the shape.""" +// STATIC mp_obj_t vectorio_vector_shape_obj_get_pixel_shader(mp_obj_t wrapper_shape) { // Relies on the fact that only vector_shape impl gets matched with a VectorShape. const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); From 6be952d3bae45b1ff81203f464616bc986dd280a Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Thu, 5 Aug 2021 00:13:10 -0700 Subject: [PATCH 11/63] found more documentation dependencies that needed updating --- docs/redirects.txt | 1 - shared-bindings/displayio/Group.c | 14 +++++++------- shared-bindings/vectorio/Circle.c | 2 +- shared-bindings/vectorio/Polygon.c | 2 +- shared-bindings/vectorio/Rectangle.c | 2 +- shared-bindings/vectorio/VectorShape.c | 2 +- shared-bindings/vectorio/__init__.c | 2 -- 7 files changed, 11 insertions(+), 14 deletions(-) diff --git a/docs/redirects.txt b/docs/redirects.txt index 6eb7ddc4d8..d8fc46b358 100644 --- a/docs/redirects.txt +++ b/docs/redirects.txt @@ -152,7 +152,6 @@ shared-bindings/ustack/__init__.rst shared-bindings/ustack/ shared-bindings/vectorio/Circle.rst shared-bindings/vectorio/#vectorio.Circle shared-bindings/vectorio/Polygon.rst shared-bindings/vectorio/#vectorio.Polygon shared-bindings/vectorio/Rectangle.rst shared-bindings/vectorio/#vectorio.Rectangle -shared-bindings/vectorio/VectorShape.rst shared-bindings/vectorio/#vectorio.VectorShape shared-bindings/vectorio/__init__.rst shared-bindings/vectorio/ shared-bindings/watchdog/WatchDogMode.rst shared-bindings/watchdog/#watchdog.WatchDogMode shared-bindings/watchdog/WatchDogTimer.rst shared-bindings/watchdog/#watchdog.WatchDogTimer diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index d636ee335b..4783c97453 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -183,7 +183,7 @@ const mp_obj_property_t displayio_group_y_obj = { MP_ROM_NONE}, }; -//| def append(self, layer: Union[vectorio.VectorShape, Group, TileGrid]) -> None: +//| def append(self, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: //| """Append a layer to the group. It will be drawn above other layers.""" //| ... //| @@ -194,7 +194,7 @@ STATIC mp_obj_t displayio_group_obj_append(mp_obj_t self_in, mp_obj_t layer) { } MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_append_obj, displayio_group_obj_append); -//| def insert(self, index: int, layer: Union[vectorio.VectorShape, Group, TileGrid]) -> None: +//| def insert(self, index: int, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: //| """Insert a layer into the group.""" //| ... //| @@ -210,7 +210,7 @@ STATIC mp_obj_t displayio_group_obj_insert(mp_obj_t self_in, mp_obj_t index_obj, MP_DEFINE_CONST_FUN_OBJ_3(displayio_group_insert_obj, displayio_group_obj_insert); -//| def index(self, layer: Union[vectorio.VectorShape, Group, TileGrid]) -> int: +//| def index(self, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> int: //| """Returns the index of the first copy of layer. Raises ValueError if not found.""" //| ... //| @@ -224,7 +224,7 @@ STATIC mp_obj_t displayio_group_obj_index(mp_obj_t self_in, mp_obj_t layer) { } MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_index_obj, displayio_group_obj_index); -//| def pop(self, i: int = -1) -> Union[vectorio.VectorShape, Group, TileGrid]: +//| def pop(self, i: int = -1) -> Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]: //| """Remove the ith item and return it.""" //| ... //| @@ -247,7 +247,7 @@ STATIC mp_obj_t displayio_group_obj_pop(size_t n_args, const mp_obj_t *pos_args, MP_DEFINE_CONST_FUN_OBJ_KW(displayio_group_pop_obj, 1, displayio_group_obj_pop); -//| def remove(self, layer: Union[vectorio.VectorShape, Group, TileGrid]) -> None: +//| def remove(self, layer: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: //| """Remove the first copy of layer. Raises ValueError if it is not present.""" //| ... //| @@ -280,7 +280,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { } } -//| def __getitem__(self, index: int) -> Union[vectorio.VectorShape, Group, TileGrid]: +//| def __getitem__(self, index: int) -> Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]: //| """Returns the value at the given index. //| //| This allows you to:: @@ -288,7 +288,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| print(group[0])""" //| ... //| -//| def __setitem__(self, index: int, value: Union[vectorio.VectorShape, Group, TileGrid]) -> None: +//| def __setitem__(self, index: int, value: Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]) -> None: //| """Sets the value at the given index. //| //| This allows you to:: diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c index cf4e643662..37780b5562 100644 --- a/shared-bindings/vectorio/Circle.c +++ b/shared-bindings/vectorio/Circle.c @@ -12,7 +12,7 @@ //| class Circle: //| -//| def __init__(self, pixel_shader: Union[ColorConverter, Palette], radius: int, x: int, y: int) -> None: +//| def __init__(self, pixel_shader: Union[displayio.ColorConverter, displayio.Palette], radius: int, x: int, y: int) -> None: //| """Circle is positioned on screen by its center point. //| //| :param pixel_shader: The pixel shader that produces colors from values diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c index 261e7ae55e..551954f98d 100644 --- a/shared-bindings/vectorio/Polygon.c +++ b/shared-bindings/vectorio/Polygon.c @@ -17,7 +17,7 @@ //| class Polygon: -//| def __init__(self, pixel_shader: Union[ColorConverter, Palette], points: List[Tuple[int, int]], x: int, y: int) -> None: +//| def __init__(self, pixel_shader: Union[displayio.ColorConverter, displayio.Palette], points: List[Tuple[int, int]], x: int, y: int) -> None: //| """Represents a closed shape by ordered vertices //| //| :param pixel_shader: The pixel shader that produces colors from values diff --git a/shared-bindings/vectorio/Rectangle.c b/shared-bindings/vectorio/Rectangle.c index 98e38f0c6b..1e885064ff 100644 --- a/shared-bindings/vectorio/Rectangle.c +++ b/shared-bindings/vectorio/Rectangle.c @@ -10,7 +10,7 @@ #include "supervisor/shared/translate.h" //| class Rectangle: -//| def __init__(self, pixel_shader: Union[ColorConverter, Palette], width: int, height: int, x: int, y: int) -> None: +//| def __init__(self, pixel_shader: Union[displayio.ColorConverter, displayio.Palette], width: int, height: int, x: int, y: int) -> None: //| """Represents a rectangle by defining its bounds //| //| :param pixel_shader: The pixel shader that produces colors from values diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index 8d6c2b71db..f59ff26213 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -143,7 +143,7 @@ const mp_obj_property_t vectorio_vector_shape_y_obj = { }; -// pixel_shader: Union[displayio.ColorConverter, displayio.Palette] +// pixel_shader: Union[ColorConverter, Palette] // """The pixel shader of the shape.""" // STATIC mp_obj_t vectorio_vector_shape_obj_get_pixel_shader(mp_obj_t wrapper_shape) { diff --git a/shared-bindings/vectorio/__init__.c b/shared-bindings/vectorio/__init__.c index 556bfe59ec..5a3729573e 100644 --- a/shared-bindings/vectorio/__init__.c +++ b/shared-bindings/vectorio/__init__.c @@ -6,7 +6,6 @@ #include "shared-bindings/vectorio/Circle.h" #include "shared-bindings/vectorio/Polygon.h" #include "shared-bindings/vectorio/Rectangle.h" -#include "shared-bindings/vectorio/VectorShape.h" //| """Lightweight 2d shapes for displays""" //| @@ -16,7 +15,6 @@ STATIC const mp_rom_map_elem_t vectorio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Circle), MP_ROM_PTR(&vectorio_circle_type) }, { MP_ROM_QSTR(MP_QSTR_Polygon), MP_ROM_PTR(&vectorio_polygon_type) }, { MP_ROM_QSTR(MP_QSTR_Rectangle), MP_ROM_PTR(&vectorio_rectangle_type) }, -// { MP_ROM_QSTR(MP_QSTR_VectorShape), MP_ROM_PTR(&vectorio_vector_shape_type) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_module_globals, vectorio_module_globals_table); From 11ed759cf94074ac387655fd647e6ffdfb70ecbe Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Thu, 5 Aug 2021 13:01:50 +0100 Subject: [PATCH 12/63] Tweaks to Plasma2040 pinout --- .../boards/pimoroni_plasma2040/mpconfigboard.h | 13 +++++++++++++ ports/raspberrypi/boards/pimoroni_plasma2040/pins.c | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h index 967267a8b4..6d1e137906 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h @@ -1,13 +1,26 @@ #define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2040" #define MICROPY_HW_MCU_NAME "rp2040" +#define MICROPY_HW_SW_A (&pin_GPIO12) +#define MICROPY_HW_SW_B (&pin_GPIO13) + +#define MICROPY_HW_CLK (&pin_GPIO14) +#define MICROPY_HW_DATA (&pin_GPIO15) + #define CIRCUITPY_RGB_STATUS_INVERTED_PWM #define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) #define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) #define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) +#define MICROPY_HW_I2C_INT (&pin_GPIO19) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) + #define MICROPY_HW_USER_SW (&pin_GPIO23) +#define MICROPY_HW_CURRENT_SENSE (&pin_GPIO29) + // These pins are unconnected #define IGNORE_PIN_GPIO0 1 #define IGNORE_PIN_GPIO1 1 diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c b/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c index 799683378c..e4e686da9d 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/pins.c @@ -5,15 +5,20 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_SW_B), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_DATA), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, @@ -29,7 +34,6 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_CURRENT_SENSE), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, From f707fa107ade84102536f3feb4300b0fa8a6f9e0 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Thu, 5 Aug 2021 15:00:47 +0100 Subject: [PATCH 13/63] Tweaks to Interstate75 pinout --- .../pimoroni_interstate75/mpconfigboard.h | 26 +++++++++++++++++++ .../boards/pimoroni_interstate75/pins.c | 12 +++++---- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h index 968f69ad7e..1ce8e1e7e1 100644 --- a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h @@ -1,13 +1,39 @@ #define MICROPY_HW_BOARD_NAME "Pimoroni Interstate 75" #define MICROPY_HW_MCU_NAME "rp2040" +#define MICROPY_HW_R0 (&pin_GPIO0) +#define MICROPY_HW_G0 (&pin_GPIO1) +#define MICROPY_HW_B0 (&pin_GPIO2) +#define MICROPY_HW_R1 (&pin_GPIO3) +#define MICROPY_HW_G1 (&pin_GPIO4) +#define MICROPY_HW_B1 (&pin_GPIO5) + +#define MICROPY_HW_ROW_A (&pin_GPIO6) +#define MICROPY_HW_ROW_B (&pin_GPIO7) +#define MICROPY_HW_ROW_C (&pin_GPIO8) +#define MICROPY_HW_ROW_D (&pin_GPIO9) +#define MICROPY_HW_ROW_E (&pin_GPIO10) + +#define MICROPY_HW_CLK (&pin_GPIO11) +#define MICROPY_HW_LAT (&pin_GPIO12) +#define MICROPY_HW_OE (&pin_GPIO13) + +#define MICROPY_HW_SW_A (&pin_GPIO14) + #define CIRCUITPY_RGB_STATUS_INVERTED_PWM #define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) #define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) #define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) +#define MICROPY_HW_I2C_INT (&pin_GPIO19) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) + #define MICROPY_HW_USER_SW (&pin_GPIO23) +#define MICROPY_HW_CURRENT_SENSE (&pin_GPIO29) + // These pins are unconnected #define IGNORE_PIN_GPIO15 1 #define IGNORE_PIN_GPIO22 1 diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/pins.c b/ports/raspberrypi/boards/pimoroni_interstate75/pins.c index db20e6ea52..6e3e1a57b7 100644 --- a/ports/raspberrypi/boards/pimoroni_interstate75/pins.c +++ b/ports/raspberrypi/boards/pimoroni_interstate75/pins.c @@ -14,19 +14,22 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_ROW_D), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_ROW_E), MP_ROM_PTR(&pin_GPIO10) }, - { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_LED_STB), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_LED_OE), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LAT), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_OE), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO18) }, - + { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO23) }, @@ -42,7 +45,6 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_CURRENT_SENSE), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, From b5837b157df0329d3c18e5e9f23a33a093cf8d2f Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sat, 7 Aug 2021 17:47:57 -0700 Subject: [PATCH 14/63] improve transpose and mirror * add heuristic to avoid drawing area unnecessarily * fix Polygon.points * fix transpose * fix mirror x and y Known broken: Polygon with negative Y coordinates does not work right. --- shared-module/vectorio/Polygon.c | 61 +++++--- shared-module/vectorio/Polygon.h | 4 +- shared-module/vectorio/VectorShape.c | 216 ++++++++++++++++++--------- 3 files changed, 185 insertions(+), 96 deletions(-) diff --git a/shared-module/vectorio/Polygon.c b/shared-module/vectorio/Polygon.c index db3deced2a..6cc99a6096 100644 --- a/shared-module/vectorio/Polygon.c +++ b/shared-module/vectorio/Polygon.c @@ -10,7 +10,7 @@ #define VECTORIO_POLYGON_DEBUG(...) (void)0 -// #define VECTORIO_POLYGON_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) +// #define VECTORIO_POLYGON_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Converts a list of points tuples to a flat list of ints for speedier internal use. @@ -30,12 +30,12 @@ static void _clobber_points_list(vectorio_polygon_t *self, mp_obj_t points_tuple VECTORIO_POLYGON_DEBUG("free(%d), ", sizeof(self->points_list)); gc_free(self->points_list); } - self->points_list = gc_alloc(2 * len * sizeof(int), false, false); - VECTORIO_POLYGON_DEBUG("alloc(%p, %d)", self->points_list, 2 * len * sizeof(int)); + self->points_list = gc_alloc(2 * len * sizeof(uint16_t), false, false); + VECTORIO_POLYGON_DEBUG("alloc(%p, %d)", self->points_list, 2 * len * sizeof(uint16_t)); } self->len = 2 * len; - for (size_t i = 0; i < len; ++i) { + for (uint16_t i = 0; i < len; ++i) { size_t tuple_len = 0; mp_obj_t *tuple_items; mp_obj_tuple_get(items[i], &tuple_len, &tuple_items); @@ -43,14 +43,19 @@ static void _clobber_points_list(vectorio_polygon_t *self, mp_obj_t points_tuple if (tuple_len != 2) { mp_raise_ValueError_varg(translate("%q must be a tuple of length 2"), MP_QSTR_point); } - if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &self->points_list[2 * i ]) - || !mp_obj_get_int_maybe(tuple_items[ 1 ], &self->points_list[2 * i + 1]) + mp_int_t x; + mp_int_t y; + if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &x) + || !mp_obj_get_int_maybe(tuple_items[ 1 ], &y) + || x < SHRT_MIN || x > SHRT_MAX || y < SHRT_MIN || y > SHRT_MAX ) { - self->len = 0; gc_free(self->points_list); self->points_list = NULL; mp_raise_ValueError_varg(translate("unsupported %q type"), MP_QSTR_point); + self->len = 0; } + self->points_list[2 * i ] = (int16_t)x; + self->points_list[2 * i + 1] = (int16_t)y; } } @@ -68,16 +73,23 @@ void common_hal_vectorio_polygon_construct(vectorio_polygon_t *self, mp_obj_t po mp_obj_t common_hal_vectorio_polygon_get_points(vectorio_polygon_t *self) { VECTORIO_POLYGON_DEBUG("%p common_hal_vectorio_polygon_get_points {len: %d, points_list: %p}\n", self, self->len, self->points_list); - mp_obj_t list = mp_obj_new_list(self->len / 2, NULL); + mp_obj_list_t *list = MP_OBJ_TO_PTR(mp_obj_new_list(0, NULL)); + + VECTORIO_POLYGON_DEBUG(" >points\n"); + for (uint16_t i = 0; i < self->len; i += 2) { + VECTORIO_POLYGON_DEBUG(" (%4d, %4d)\n", self->points_list[i], self->points_list[i + 1]); + + mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + pair->items[0] = mp_obj_new_int((mp_int_t) self->points_list[i ]); + pair->items[1] = mp_obj_new_int((mp_int_t) self->points_list[i + 1]); - for (size_t i = 0; i < self->len; i += 2) { - mp_obj_t tuple[] = { mp_obj_new_int(self->points_list[i]), mp_obj_new_int(self->points_list[i + 1]) }; mp_obj_list_append( list, - mp_obj_new_tuple(2, tuple) + pair ); } - return list; + VECTORIO_POLYGON_DEBUG(" x1 = SHRT_MAX; area->y1 = SHRT_MAX; area->x2 = SHRT_MIN; area->y2 = SHRT_MIN; - for (size_t i = 0; i < self->len; ++i) { - int x = self->points_list[i]; + for (uint16_t i = 0; i < self->len; ++i) { + int16_t x = self->points_list[i]; ++i; - int y = self->points_list[i]; + int16_t y = self->points_list[i]; if (x < area->x1) { + VECTORIO_POLYGON_DEBUG(" x1: %d\n", x); area->x1 = x; } if (y < area->y1) { + VECTORIO_POLYGON_DEBUG(" y1: %d\n", y); area->y1 = y; } if (x > area->x2) { + VECTORIO_POLYGON_DEBUG(" x2: %d\n", x); area->x2 = x; } if (y > area->y2) { + VECTORIO_POLYGON_DEBUG(" y2: %d\n", y); area->y2 = y; } } @@ -126,7 +143,7 @@ void common_hal_vectorio_polygon_get_area(void *polygon, displayio_area_t *area) // <0 if the point is to the left of the line vector // 0 if the point is on the line // >0 if the point is to the right of the line vector -__attribute__((always_inline)) static inline int line_side(mp_int_t x1, mp_int_t y1, mp_int_t x2, mp_int_t y2, int16_t px, int16_t py) { +__attribute__((always_inline)) static inline int line_side(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t px, int16_t py) { return (px - x1) * (y2 - y1) - (py - y1) * (x2 - x1); } @@ -140,14 +157,14 @@ uint32_t common_hal_vectorio_polygon_get_pixel(void *obj, int16_t x, int16_t y) return 0; } - int winding_number = 0; - int x1 = self->points_list[0]; - int y1 = self->points_list[1]; - for (size_t i = 2; i <= self->len + 1; ++i) { + int16_t winding_number = 0; + int16_t x1 = self->points_list[0]; + int16_t y1 = self->points_list[1]; + for (uint16_t i = 2; i <= self->len + 1; ++i) { VECTORIO_POLYGON_DEBUG(" {(%3d, %3d),", x1, y1); - int x2 = self->points_list[i % self->len]; + int16_t x2 = self->points_list[i % self->len]; ++i; - int y2 = self->points_list[i % self->len]; + int16_t y2 = self->points_list[i % self->len]; VECTORIO_POLYGON_DEBUG(" (%3d, %3d)}\n", x2, y2); if (y1 <= y) { if (y2 > y && line_side(x1, y1, x2, y2, x, y) < 0) { diff --git a/shared-module/vectorio/Polygon.h b/shared-module/vectorio/Polygon.h index 21d32d3581..e1d94f9f97 100644 --- a/shared-module/vectorio/Polygon.h +++ b/shared-module/vectorio/Polygon.h @@ -9,8 +9,8 @@ typedef struct { mp_obj_base_t base; // An int array[ x, y, ... ] - int *points_list; - size_t len; + int16_t *points_list; + uint16_t len; vectorio_event_t on_dirty; mp_obj_t draw_protocol_instance; } vectorio_polygon_t; diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index 4406f20120..64c1b94c0d 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -14,8 +14,8 @@ #include "shared-bindings/vectorio/Rectangle.h" // Lifecycle actions. -#define VECTORIO_SHAPE_DEBUG(...) (void)0 -// #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) +// #define VECTORIO_SHAPE_DEBUG(...) (void)0 +#define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Used in both logging and ifdefs, for extra variables @@ -23,8 +23,43 @@ // Really verbose. -#define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 -// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) +// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 +#define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) + +#define U32_TO_BINARY_FMT "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" +#define U32_TO_BINARY(u32) \ + (u32 & 0x80000000 ? '1' : '0'), \ + (u32 & 0x40000000 ? '1' : '0'), \ + (u32 & 0x20000000 ? '1' : '0'), \ + (u32 & 0x10000000 ? '1' : '0'), \ + (u32 & 0x8000000 ? '1' : '0'), \ + (u32 & 0x4000000 ? '1' : '0'), \ + (u32 & 0x2000000 ? '1' : '0'), \ + (u32 & 0x1000000 ? '1' : '0'), \ + (u32 & 0x800000 ? '1' : '0'), \ + (u32 & 0x400000 ? '1' : '0'), \ + (u32 & 0x200000 ? '1' : '0'), \ + (u32 & 0x100000 ? '1' : '0'), \ + (u32 & 0x80000 ? '1' : '0'), \ + (u32 & 0x40000 ? '1' : '0'), \ + (u32 & 0x20000 ? '1' : '0'), \ + (u32 & 0x10000 ? '1' : '0'), \ + (u32 & 0x8000 ? '1' : '0'), \ + (u32 & 0x4000 ? '1' : '0'), \ + (u32 & 0x2000 ? '1' : '0'), \ + (u32 & 0x1000 ? '1' : '0'), \ + (u32 & 0x800 ? '1' : '0'), \ + (u32 & 0x400 ? '1' : '0'), \ + (u32 & 0x200 ? '1' : '0'), \ + (u32 & 0x100 ? '1' : '0'), \ + (u32 & 0x80 ? '1' : '0'), \ + (u32 & 0x40 ? '1' : '0'), \ + (u32 & 0x20 ? '1' : '0'), \ + (u32 & 0x10 ? '1' : '0'), \ + (u32 & 0x8 ? '1' : '0'), \ + (u32 & 0x4 ? '1' : '0'), \ + (u32 & 0x2 ? '1' : '0'), \ + (u32 & 0x1 ? '1' : '0') inline __attribute__((always_inline)) @@ -33,39 +68,41 @@ static int32_t max(int32_t a, int32_t b) { } inline __attribute__((always_inline)) -static int32_t min(int32_t a, int32_t b) { +static uint32_t min(uint32_t a, uint32_t b) { return a < b ? a : b; } +inline __attribute__((always_inline)) +static void area_transpose(displayio_area_t *to_transpose) { + int16_t swap = to_transpose->y1; + to_transpose->y1 = to_transpose->x1; + to_transpose->x1 = swap; + swap = to_transpose->y2; + to_transpose->y2 = to_transpose->x2; + to_transpose->x2 = swap; +} inline __attribute__((always_inline)) static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *out_area) { - VECTORIO_SHAPE_DEBUG("%p get_screen_area tform:{x:%d y:%d dx:%d dy:%d scl:%d w:%d h:%d mx:%d my:%d tr:%d}", self, + VECTORIO_SHAPE_DEBUG("%p get_screen_area (%3d,%3d) tform:{x:%d y:%d dx:%d dy:%d scl:%d w:%d h:%d mx:%d my:%d tr:%d}", self, self->x, self->y, self->absolute_transform->x, self->absolute_transform->y, self->absolute_transform->dx, self->absolute_transform->dy, self->absolute_transform->scale, self->absolute_transform->width, self->absolute_transform->height, self->absolute_transform->mirror_x, self->absolute_transform->mirror_y, self->absolute_transform->transpose_xy ); - displayio_area_t shape_area; - self->ishape.get_area(self->ishape.shape, &shape_area); - VECTORIO_SHAPE_DEBUG(" in:{(%5d,%5d), (%5d,%5d)}", shape_area.x1, shape_area.y1, shape_area.x2, shape_area.y2); + self->ishape.get_area(self->ishape.shape, out_area); + VECTORIO_SHAPE_DEBUG(" in:{(%5d,%5d), (%5d,%5d)}", out_area->x1, out_area->y1, out_area->x2, out_area->y2); - displayio_area_shift( - &shape_area, - self->x * self->absolute_transform->dx + min(0, self->absolute_transform->dx * displayio_area_width(&shape_area)), - self->y * self->absolute_transform->dy + min(0, self->absolute_transform->dy * displayio_area_height(&shape_area)) - ); - - displayio_area_transform_within( - false, - false, - self->absolute_transform->transpose_xy, - &shape_area, &shape_area, out_area - ); - - displayio_area_shift( - out_area, - self->absolute_transform->x, - self->absolute_transform->y - ); + int16_t x; + int16_t y; + if (self->absolute_transform->transpose_xy) { + x = self->absolute_transform->x + self->absolute_transform->dx * self->y; + y = self->absolute_transform->y + self->absolute_transform->dy * self->x; + area_transpose(out_area); + displayio_area_canon(out_area); + } else { + x = self->absolute_transform->x + self->absolute_transform->dx * self->x; + y = self->absolute_transform->y + self->absolute_transform->dy * self->y; + } + displayio_area_shift(out_area, x, y); VECTORIO_SHAPE_DEBUG(" out:{(%5d,%5d), (%5d,%5d)}\n", out_area->x1, out_area->y1, out_area->x2, out_area->y2); } @@ -198,43 +235,34 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ self->absolute_transform->width, self->absolute_transform->height, self->absolute_transform->mirror_x, self->absolute_transform->mirror_y, self->absolute_transform->transpose_xy ); - uint32_t linestride_px = displayio_area_width(area); - uint32_t line_dirty_offset_px = (overlap.y1 - area->y1) * linestride_px; - uint32_t column_dirty_offset_px = overlap.x1 - area->x1; + uint16_t linestride_px = displayio_area_width(area); + uint16_t line_dirty_offset_px = (overlap.y1 - area->y1) * linestride_px; + uint16_t column_dirty_offset_px = overlap.x1 - area->x1; VECTORIO_SHAPE_DEBUG(", linestride:%3d line_offset:%3d col_offset:%3d depth:%2d ppb:%2d shape:%s", linestride_px, line_dirty_offset_px, column_dirty_offset_px, colorspace->depth, pixels_per_byte, mp_obj_get_type_str(self->ishape.shape)); displayio_input_pixel_t input_pixel; displayio_output_pixel_t output_pixel; - int16_t math_transform_offset_x; - int16_t math_transform_offset_y; - int16_t math_shape_offset_x; - int16_t math_shape_offset_y; + uint16_t width_px_indices; + uint16_t height_px_indices; if (self->absolute_transform->transpose_xy) { - math_transform_offset_x = self->absolute_transform->dy * self->y; - math_transform_offset_y = self->absolute_transform->dx * self->x; - math_shape_offset_x = min(0, self->absolute_transform->dy * displayio_area_width(&self->current_area)); - math_shape_offset_y = min(0, self->absolute_transform->dx * displayio_area_height(&self->current_area)); + width_px_indices = displayio_area_height(&self->current_area) - 1; + height_px_indices = displayio_area_width(&self->current_area) - 1; } else { - math_transform_offset_x = self->absolute_transform->dx * self->x; - math_transform_offset_y = self->absolute_transform->dy * self->y; - math_shape_offset_x = min(0, self->absolute_transform->dx * displayio_area_width(&self->current_area)); - math_shape_offset_y = min(0, self->absolute_transform->dy * displayio_area_height(&self->current_area)); + width_px_indices = displayio_area_width(&self->current_area) - 1; + height_px_indices = displayio_area_height(&self->current_area) - 1; } - VECTORIO_SHAPE_DEBUG(", transform_offset: (%3d,%3d), shape_offset: (%3d,%3d)", math_transform_offset_x, math_transform_offset_y, math_shape_offset_x, math_shape_offset_y); - - - uint32_t mask_start_px = line_dirty_offset_px; + uint16_t mask_start_px = line_dirty_offset_px; for (input_pixel.y = overlap.y1; input_pixel.y < overlap.y2; ++input_pixel.y) { mask_start_px += column_dirty_offset_px; for (input_pixel.x = overlap.x1; input_pixel.x < overlap.x2; ++input_pixel.x) { // Check the mask first to see if the pixel has already been set. - uint32_t pixel_index = mask_start_px + (input_pixel.x - overlap.x1); + uint16_t pixel_index = mask_start_px + (input_pixel.x - overlap.x1); uint32_t *mask_doubleword = &(mask[pixel_index / 32]); uint8_t mask_bit = pixel_index % 32; - VECTORIO_SHAPE_PIXEL_DEBUG("\n%p pixel_index: %5u mask_bit: %2u", self, pixel_index, mask_bit); + VECTORIO_SHAPE_PIXEL_DEBUG("\n%p pixel_index: %5u mask_bit: %2u mask: "U32_TO_BINARY_FMT, self, pixel_index, mask_bit, U32_TO_BINARY(*mask_doubleword)); if ((*mask_doubleword & (1u << mask_bit)) != 0) { VECTORIO_SHAPE_PIXEL_DEBUG(" masked"); continue; @@ -245,12 +273,27 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ int16_t pixel_to_get_x; int16_t pixel_to_get_y; if (self->absolute_transform->transpose_xy) { - pixel_to_get_x = (input_pixel.y - math_transform_offset_y - self->absolute_transform->y) - math_shape_offset_y; - pixel_to_get_y = (input_pixel.x - math_transform_offset_x - self->absolute_transform->x) - math_shape_offset_x; + pixel_to_get_x = input_pixel.y - self->absolute_transform->y - self->absolute_transform->dy * self->x; + pixel_to_get_y = input_pixel.x - self->absolute_transform->x - self->absolute_transform->dx * self->y; + + if (self->absolute_transform->mirror_x) { + pixel_to_get_y = height_px_indices - pixel_to_get_y; + } + if (self->absolute_transform->mirror_y) { + pixel_to_get_x = width_px_indices - pixel_to_get_x; + } } else { - pixel_to_get_x = (input_pixel.x - math_transform_offset_x - self->absolute_transform->x) - math_shape_offset_x; - pixel_to_get_y = (input_pixel.y - math_transform_offset_y - self->absolute_transform->y) - math_shape_offset_y; + pixel_to_get_x = input_pixel.x - self->absolute_transform->x - self->absolute_transform->dx * self->x; + pixel_to_get_y = input_pixel.y - self->absolute_transform->y - self->absolute_transform->dy * self->y; + + if (self->absolute_transform->mirror_x) { + pixel_to_get_x = width_px_indices - pixel_to_get_x; + } + if (self->absolute_transform->mirror_y) { + pixel_to_get_y = height_px_indices - pixel_to_get_y; + } } + VECTORIO_SHAPE_PIXEL_DEBUG(" get_pixel %p (%3d, %3d) -> ( %3d, %3d )", self->ishape.shape, input_pixel.x, input_pixel.y, pixel_to_get_x, pixel_to_get_y); #ifdef VECTORIO_PERF uint64_t pre_pixel = common_hal_time_monotonic_ns(); @@ -296,10 +339,9 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ } else if (colorspace->depth < 8) { // Reorder the offsets to pack multiple rows into a byte (meaning they share a column). if (!colorspace->pixels_in_byte_share_row) { - uint16_t width = linestride_px; - uint16_t row = pixel_index / width; - uint16_t col = pixel_index % width; - pixel_index = col * pixels_per_byte + (row / pixels_per_byte) * pixels_per_byte * width + row % pixels_per_byte; + uint16_t row = pixel_index / linestride_px; + uint16_t col = pixel_index % linestride_px; + pixel_index = col * pixels_per_byte + (row / pixels_per_byte) * pixels_per_byte * linestride_px + row % pixels_per_byte; } uint8_t shift = (pixel_index % pixels_per_byte) * colorspace->depth; if (colorspace->reverse_pixels_in_byte) { @@ -354,27 +396,57 @@ void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self) { // Assembles a singly linked list of dirty areas from all components on the display. displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t *tail) { - displayio_area_t *new_tail = tail; - if (!displayio_area_empty(&self->ephemeral_dirty_area)) { - // vector.add_to_head - self->ephemeral_dirty_area.next = tail; - new_tail = &self->ephemeral_dirty_area; - VECTORIO_SHAPE_DEBUG("%p get_refresh_area dirty: {(%3d,%3d), (%3d,%3d)}", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); - } if (self->current_area_dirty || (mp_obj_is_type(self->pixel_shader, &displayio_palette_type) && displayio_palette_needs_refresh(self->pixel_shader)) || (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type) && displayio_colorconverter_needs_refresh(self->pixel_shader)) ) { - self->current_area.next = new_tail; - new_tail = &self->current_area; - VECTORIO_SHAPE_DEBUG(" redrawing current: {(%3d,%3d), (%3d,%3d)}", self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2); + if (!displayio_area_empty(&self->ephemeral_dirty_area)) { + // Both are dirty, check if we should combine the areas or draw separately + // Draws as few pixels as possible both when animations move short distances and large distances. + // The display core implementation currently doesn't combine areas to reduce redrawing of masked areas. If it does, + // this could be simplified to just return the 2 possibly overlapping areas. + displayio_area_t area_swap; + displayio_area_compute_overlap(&self->ephemeral_dirty_area, &self->current_area, &area_swap); + uint32_t overlap_size = displayio_area_size(&area_swap); + displayio_area_union(&self->ephemeral_dirty_area, &self->current_area, &area_swap); // Leave area_swap as the union area for later. + uint32_t union_size = displayio_area_size(&area_swap); + uint32_t current_size = displayio_area_size(&self->current_area); + uint32_t dirty_size = displayio_area_size(&self->ephemeral_dirty_area); + + VECTORIO_SHAPE_DEBUG("%p get_refresh_area: dirty{(%3d,%3d), (%3d,%3d)} + current{(%3d,%3d), (%3d,%3d)} = union{(%3d,%3d), (%3d,%3d)}: union%d - dirty%d - curr%d + overlap%d = excluded%d : ", self, + self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2, + self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2, + area_swap.x1, area_swap.y1, area_swap.x2, area_swap.y2, + union_size, dirty_size, current_size, overlap_size, (int32_t)union_size - dirty_size - current_size + overlap_size + ); + + if ((int32_t)union_size - dirty_size - current_size + overlap_size <= min(dirty_size, current_size)) { + // The excluded / non-overlapping area from the disjoint dirty and current areas is smaller + // than the smallest area we need to draw. Redrawing the overlapping area would cost more + // than just drawing the union disjoint area once. + VECTORIO_SHAPE_DEBUG("combining to take disjoint area\n"); + displayio_area_copy(&area_swap, &self->ephemeral_dirty_area); + } else { + // The excluded area between the 2 dirty areas is larger than the smallest dirty area. It would be + // more costly to combine these areas than possibly redraw some overlap. + VECTORIO_SHAPE_DEBUG("excluded area too large, drawing separate area\n"); + self->current_area.next = tail; + tail = &self->current_area; + } + + self->ephemeral_dirty_area.next = tail; + tail = &self->ephemeral_dirty_area; + } else { + self->current_area.next = tail; + tail = &self->current_area; + VECTORIO_SHAPE_DEBUG("%p get_refresh_area: redrawing current: {(%3d,%3d), (%3d,%3d)}\n", self, self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2); + } + } else if (!displayio_area_empty(&self->ephemeral_dirty_area)) { + self->ephemeral_dirty_area.next = tail; + tail = &self->ephemeral_dirty_area; + VECTORIO_SHAPE_DEBUG("%p get_refresh_area redrawing dirty: {(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); } - #ifdef VECTORIO_SHAPE_DEBUG - if (new_tail != tail) { - VECTORIO_SHAPE_DEBUG("\n"); - } - #endif - return new_tail; + return tail; } void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displayio_buffer_transform_t *group_transform) { From 051d7a970ef23b349f5b63e39f1c56f460c484e5 Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sat, 7 Aug 2021 19:32:02 -0700 Subject: [PATCH 15/63] fix rotation and mirroring now works with all vector shapes, even those with internal reference locations that are negative. All shape locations are anchored to their 0,0 but they can display pixels from negative coordinates if the shape's location on the screen would have room for it. --- shared-module/vectorio/VectorShape.c | 29 ++++++++++++---------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index 64c1b94c0d..b18460868d 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -14,8 +14,8 @@ #include "shared-bindings/vectorio/Rectangle.h" // Lifecycle actions. -// #define VECTORIO_SHAPE_DEBUG(...) (void)0 -#define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) +#define VECTORIO_SHAPE_DEBUG(...) (void)0 +// #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Used in both logging and ifdefs, for extra variables @@ -23,8 +23,8 @@ // Really verbose. -// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 -#define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) +#define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 +// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) #define U32_TO_BINARY_FMT "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" #define U32_TO_BINARY(u32) \ @@ -244,15 +244,8 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ displayio_input_pixel_t input_pixel; displayio_output_pixel_t output_pixel; - uint16_t width_px_indices; - uint16_t height_px_indices; - if (self->absolute_transform->transpose_xy) { - width_px_indices = displayio_area_height(&self->current_area) - 1; - height_px_indices = displayio_area_width(&self->current_area) - 1; - } else { - width_px_indices = displayio_area_width(&self->current_area) - 1; - height_px_indices = displayio_area_height(&self->current_area) - 1; - } + displayio_area_t shape_area; + self->ishape.get_area(self->ishape.shape, &shape_area); uint16_t mask_start_px = line_dirty_offset_px; for (input_pixel.y = overlap.y1; input_pixel.y < overlap.y2; ++input_pixel.y) { @@ -275,22 +268,24 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ if (self->absolute_transform->transpose_xy) { pixel_to_get_x = input_pixel.y - self->absolute_transform->y - self->absolute_transform->dy * self->x; pixel_to_get_y = input_pixel.x - self->absolute_transform->x - self->absolute_transform->dx * self->y; + VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); if (self->absolute_transform->mirror_x) { - pixel_to_get_y = height_px_indices - pixel_to_get_y; + pixel_to_get_y = shape_area.y2 - 1 - (pixel_to_get_y - shape_area.y1); } if (self->absolute_transform->mirror_y) { - pixel_to_get_x = width_px_indices - pixel_to_get_x; + pixel_to_get_x = shape_area.x2 - 1 - (pixel_to_get_x - shape_area.x1); } } else { pixel_to_get_x = input_pixel.x - self->absolute_transform->x - self->absolute_transform->dx * self->x; pixel_to_get_y = input_pixel.y - self->absolute_transform->y - self->absolute_transform->dy * self->y; + VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); if (self->absolute_transform->mirror_x) { - pixel_to_get_x = width_px_indices - pixel_to_get_x; + pixel_to_get_x = shape_area.x2 - 1 - (pixel_to_get_x - shape_area.x1); } if (self->absolute_transform->mirror_y) { - pixel_to_get_y = height_px_indices - pixel_to_get_y; + pixel_to_get_y = shape_area.y2 - 1 - (pixel_to_get_y - shape_area.y1); } } From bb25aeee510e41bb0e3ea7df5442af4782c30077 Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sat, 7 Aug 2021 19:40:07 -0700 Subject: [PATCH 16/63] fix code formatting that pre-commit --all-files did not locally report --- shared-module/vectorio/Polygon.c | 4 +- shared-module/vectorio/VectorShape.c | 66 ++++++++++++++-------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/shared-module/vectorio/Polygon.c b/shared-module/vectorio/Polygon.c index 6cc99a6096..f7199c7f83 100644 --- a/shared-module/vectorio/Polygon.c +++ b/shared-module/vectorio/Polygon.c @@ -80,8 +80,8 @@ mp_obj_t common_hal_vectorio_polygon_get_points(vectorio_polygon_t *self) { VECTORIO_POLYGON_DEBUG(" (%4d, %4d)\n", self->points_list[i], self->points_list[i + 1]); mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); - pair->items[0] = mp_obj_new_int((mp_int_t) self->points_list[i ]); - pair->items[1] = mp_obj_new_int((mp_int_t) self->points_list[i + 1]); + pair->items[0] = mp_obj_new_int((mp_int_t)self->points_list[i ]); + pair->items[1] = mp_obj_new_int((mp_int_t)self->points_list[i + 1]); mp_obj_list_append( list, diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index b18460868d..bf7cd7dc42 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -28,38 +28,38 @@ #define U32_TO_BINARY_FMT "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" #define U32_TO_BINARY(u32) \ - (u32 & 0x80000000 ? '1' : '0'), \ - (u32 & 0x40000000 ? '1' : '0'), \ - (u32 & 0x20000000 ? '1' : '0'), \ - (u32 & 0x10000000 ? '1' : '0'), \ - (u32 & 0x8000000 ? '1' : '0'), \ - (u32 & 0x4000000 ? '1' : '0'), \ - (u32 & 0x2000000 ? '1' : '0'), \ - (u32 & 0x1000000 ? '1' : '0'), \ - (u32 & 0x800000 ? '1' : '0'), \ - (u32 & 0x400000 ? '1' : '0'), \ - (u32 & 0x200000 ? '1' : '0'), \ - (u32 & 0x100000 ? '1' : '0'), \ - (u32 & 0x80000 ? '1' : '0'), \ - (u32 & 0x40000 ? '1' : '0'), \ - (u32 & 0x20000 ? '1' : '0'), \ - (u32 & 0x10000 ? '1' : '0'), \ - (u32 & 0x8000 ? '1' : '0'), \ - (u32 & 0x4000 ? '1' : '0'), \ - (u32 & 0x2000 ? '1' : '0'), \ - (u32 & 0x1000 ? '1' : '0'), \ - (u32 & 0x800 ? '1' : '0'), \ - (u32 & 0x400 ? '1' : '0'), \ - (u32 & 0x200 ? '1' : '0'), \ - (u32 & 0x100 ? '1' : '0'), \ - (u32 & 0x80 ? '1' : '0'), \ - (u32 & 0x40 ? '1' : '0'), \ - (u32 & 0x20 ? '1' : '0'), \ - (u32 & 0x10 ? '1' : '0'), \ - (u32 & 0x8 ? '1' : '0'), \ - (u32 & 0x4 ? '1' : '0'), \ - (u32 & 0x2 ? '1' : '0'), \ - (u32 & 0x1 ? '1' : '0') + (u32 & 0x80000000 ? '1' : '0'), \ + (u32 & 0x40000000 ? '1' : '0'), \ + (u32 & 0x20000000 ? '1' : '0'), \ + (u32 & 0x10000000 ? '1' : '0'), \ + (u32 & 0x8000000 ? '1' : '0'), \ + (u32 & 0x4000000 ? '1' : '0'), \ + (u32 & 0x2000000 ? '1' : '0'), \ + (u32 & 0x1000000 ? '1' : '0'), \ + (u32 & 0x800000 ? '1' : '0'), \ + (u32 & 0x400000 ? '1' : '0'), \ + (u32 & 0x200000 ? '1' : '0'), \ + (u32 & 0x100000 ? '1' : '0'), \ + (u32 & 0x80000 ? '1' : '0'), \ + (u32 & 0x40000 ? '1' : '0'), \ + (u32 & 0x20000 ? '1' : '0'), \ + (u32 & 0x10000 ? '1' : '0'), \ + (u32 & 0x8000 ? '1' : '0'), \ + (u32 & 0x4000 ? '1' : '0'), \ + (u32 & 0x2000 ? '1' : '0'), \ + (u32 & 0x1000 ? '1' : '0'), \ + (u32 & 0x800 ? '1' : '0'), \ + (u32 & 0x400 ? '1' : '0'), \ + (u32 & 0x200 ? '1' : '0'), \ + (u32 & 0x100 ? '1' : '0'), \ + (u32 & 0x80 ? '1' : '0'), \ + (u32 & 0x40 ? '1' : '0'), \ + (u32 & 0x20 ? '1' : '0'), \ + (u32 & 0x10 ? '1' : '0'), \ + (u32 & 0x8 ? '1' : '0'), \ + (u32 & 0x4 ? '1' : '0'), \ + (u32 & 0x2 ? '1' : '0'), \ + (u32 & 0x1 ? '1' : '0') inline __attribute__((always_inline)) @@ -413,7 +413,7 @@ displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_ self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2, area_swap.x1, area_swap.y1, area_swap.x2, area_swap.y2, union_size, dirty_size, current_size, overlap_size, (int32_t)union_size - dirty_size - current_size + overlap_size - ); + ); if ((int32_t)union_size - dirty_size - current_size + overlap_size <= min(dirty_size, current_size)) { // The excluded / non-overlapping area from the disjoint dirty and current areas is smaller From 5ed585d3f463f6a5a7f4205a9e19314068877175 Mon Sep 17 00:00:00 2001 From: Wellington Terumi Uemura Date: Sat, 7 Aug 2021 05:13:55 +0000 Subject: [PATCH 17/63] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1013 of 1013 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pt_BR/ --- locale/pt_BR.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index cad52558af..c120f92ec0 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-07-24 15:35+0000\n" +"PO-Revision-Date: 2021-08-08 05:33+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -14,7 +14,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 4.7.2-dev\n" +"X-Generator: Weblate 4.8-dev\n" #: main.c msgid "" @@ -3164,7 +3164,7 @@ msgstr "o arquivo deve ser um arquivo aberto no modo byte" #: shared-bindings/traceback/__init__.c msgid "file write is not available" -msgstr "" +msgstr "a gravação de arquivos não está disponível" #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" @@ -3456,7 +3456,7 @@ msgstr "element_size %d é inválido, deve ser, 1, 2, ou 4" #: shared-bindings/traceback/__init__.c msgid "invalid exception" -msgstr "" +msgstr "exceção inválida" #: extmod/modframebuf.c msgid "invalid format" @@ -3497,7 +3497,7 @@ msgstr "sintaxe inválida para o número" #: py/objexcept.c shared-bindings/traceback/__init__.c msgid "invalid traceback" -msgstr "" +msgstr "rastreamento inválido" #: py/objtype.c msgid "issubclass() arg 1 must be a class" @@ -3548,7 +3548,7 @@ msgstr "o lhs e rhs devem ser compatíveis" #: shared-bindings/traceback/__init__.c msgid "limit should be an int" -msgstr "" +msgstr "o limite deve ser um inteiro" #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" From a1fff320fb4b827dc59c6295d09bd749f6fcf7dd Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sun, 8 Aug 2021 00:14:53 -0700 Subject: [PATCH 18/63] add location property to vectorshape and all composed shapes --- locale/circuitpython.pot | 23 +++++++------- shared-bindings/vectorio/Circle.c | 1 + shared-bindings/vectorio/Polygon.c | 1 + shared-bindings/vectorio/Rectangle.c | 1 + shared-bindings/vectorio/VectorShape.c | 30 ++++++++++++++++++ shared-bindings/vectorio/VectorShape.h | 5 +++ shared-module/vectorio/VectorShape.c | 43 ++++++++++++++++++++++---- 7 files changed, 86 insertions(+), 18 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 81531c0cbd..885f596776 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -318,6 +318,10 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -1185,11 +1189,6 @@ msgstr "" msgid "Input/output error" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, c-format -msgid "Missing jmp_pin. Instruction %d jumps on pin" -msgstr "" - #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #, c-format msgid "Instruction %d shifts in more bits than pin count" @@ -1506,6 +1505,11 @@ msgstr "" msgid "Missing first_set_pin. Instruction %d sets pin(s)" msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, c-format +msgid "Missing jmp_pin. Instruction %d jumps on pin" +msgstr "" + #: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -2063,7 +2067,6 @@ msgid "Size not supported" msgstr "" #: ports/raspberrypi/common-hal/alarm/SleepMemory.c -#: ports/stm/common-hal/alarm/SleepMemory.c msgid "Sleep Memory not available" msgstr "" @@ -2510,7 +2513,7 @@ msgid "argument name reused" msgstr "" #: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c shared-bindings/gamepad/GamePad.c +#: shared-bindings/digitalio/DigitalInOut.c msgid "argument num/types mismatch" msgstr "" @@ -3594,10 +3597,6 @@ msgstr "" msgid "no active exception to reraise" msgstr "" -#: shared-bindings/socket/__init__.c shared-module/network/__init__.c -msgid "no available NIC" -msgstr "" - #: py/compile.c msgid "no binding for nonlocal found" msgstr "" @@ -4299,7 +4298,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c index 37780b5562..c0cc0bbcc2 100644 --- a/shared-bindings/vectorio/Circle.c +++ b/shared-bindings/vectorio/Circle.c @@ -86,6 +86,7 @@ STATIC const mp_rom_map_elem_t vectorio_circle_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_radius), MP_ROM_PTR(&vectorio_circle_radius_obj) }, { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_location), MP_ROM_PTR(&vectorio_vector_shape_location_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_circle_locals_dict, vectorio_circle_locals_dict_table); diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c index 551954f98d..5d493a30b6 100644 --- a/shared-bindings/vectorio/Polygon.c +++ b/shared-bindings/vectorio/Polygon.c @@ -91,6 +91,7 @@ STATIC const mp_rom_map_elem_t vectorio_polygon_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_points), MP_ROM_PTR(&vectorio_polygon_points_obj) }, { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_location), MP_ROM_PTR(&vectorio_vector_shape_location_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_polygon_locals_dict, vectorio_polygon_locals_dict_table); diff --git a/shared-bindings/vectorio/Rectangle.c b/shared-bindings/vectorio/Rectangle.c index 1e885064ff..aa2c166a6d 100644 --- a/shared-bindings/vectorio/Rectangle.c +++ b/shared-bindings/vectorio/Rectangle.c @@ -64,6 +64,7 @@ STATIC const mp_rom_map_elem_t vectorio_rectangle_locals_dict_table[] = { // Properties { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&vectorio_vector_shape_x_obj) }, { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&vectorio_vector_shape_y_obj) }, + { MP_ROM_QSTR(MP_QSTR_location), MP_ROM_PTR(&vectorio_vector_shape_location_obj) }, { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&vectorio_vector_shape_pixel_shader_obj) }, }; STATIC MP_DEFINE_CONST_DICT(vectorio_rectangle_locals_dict, vectorio_rectangle_locals_dict_table); diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index f59ff26213..6e4299a6d3 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -143,6 +143,36 @@ const mp_obj_property_t vectorio_vector_shape_y_obj = { }; +// location: Tuple[int, int] +// """location of the center point of the shape in the parent.""" +// +STATIC mp_obj_t vectorio_vector_shape_obj_get_location(mp_obj_t wrapper_shape) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + + return MP_OBJ_TO_PTR(common_hal_vectorio_vector_shape_get_location(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(vectorio_vector_shape_get_location_obj, vectorio_vector_shape_obj_get_location); + +STATIC mp_obj_t vectorio_vector_shape_obj_set_location(mp_obj_t wrapper_shape, mp_obj_t location_obj) { + // Relies on the fact that only vector_shape impl gets matched with a VectorShape. + const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, wrapper_shape); + vectorio_vector_shape_t *self = MP_OBJ_TO_PTR(draw_protocol->draw_get_protocol_self(wrapper_shape)); + + common_hal_vectorio_vector_shape_set_location(self, location_obj); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(vectorio_vector_shape_set_location_obj, vectorio_vector_shape_obj_set_location); + +const mp_obj_property_t vectorio_vector_shape_location_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&vectorio_vector_shape_get_location_obj, + (mp_obj_t)&vectorio_vector_shape_set_location_obj, + MP_ROM_NONE}, +}; + + // pixel_shader: Union[ColorConverter, Palette] // """The pixel shader of the shape.""" // diff --git a/shared-bindings/vectorio/VectorShape.h b/shared-bindings/vectorio/VectorShape.h index 4cf2ae373b..9ac6906000 100644 --- a/shared-bindings/vectorio/VectorShape.h +++ b/shared-bindings/vectorio/VectorShape.h @@ -2,6 +2,7 @@ #define MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H #include "py/objproperty.h" +#include "py/objtuple.h" #include "shared-bindings/vectorio/__init__.h" #include "shared-module/vectorio/VectorShape.h" @@ -22,6 +23,9 @@ void common_hal_vectorio_vector_shape_set_dirty(void *self); mp_int_t common_hal_vectorio_vector_shape_get_x(vectorio_vector_shape_t *self); void common_hal_vectorio_vector_shape_set_x(vectorio_vector_shape_t *self, mp_int_t x); +mp_obj_tuple_t *common_hal_vectorio_vector_shape_get_location(vectorio_vector_shape_t *self); +void common_hal_vectorio_vector_shape_set_location(vectorio_vector_shape_t *self, mp_obj_t xy); + mp_int_t common_hal_vectorio_vector_shape_get_y(vectorio_vector_shape_t *self); void common_hal_vectorio_vector_shape_set_y(vectorio_vector_shape_t *self, mp_int_t y); @@ -34,6 +38,7 @@ void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displ extern vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl; extern const mp_obj_property_t vectorio_vector_shape_x_obj; extern const mp_obj_property_t vectorio_vector_shape_y_obj; +extern const mp_obj_property_t vectorio_vector_shape_location_obj; extern const mp_obj_property_t vectorio_vector_shape_pixel_shader_obj; #endif // MICROPY_INCLUDED_SHARED_BINDINGS_VECTORIO_SHAPE_H diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index bf7cd7dc42..a6a63a498a 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -14,8 +14,8 @@ #include "shared-bindings/vectorio/Rectangle.h" // Lifecycle actions. -#define VECTORIO_SHAPE_DEBUG(...) (void)0 -// #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) +//#define VECTORIO_SHAPE_DEBUG(...) (void)0 +#define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Used in both logging and ifdefs, for extra variables @@ -23,8 +23,8 @@ // Really verbose. -#define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 -// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) +//#define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 +#define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) #define U32_TO_BINARY_FMT "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" #define U32_TO_BINARY(u32) \ @@ -192,6 +192,37 @@ void common_hal_vectorio_vector_shape_set_y(vectorio_vector_shape_t *self, mp_in common_hal_vectorio_vector_shape_set_dirty(self); } +mp_obj_tuple_t *common_hal_vectorio_vector_shape_get_location(vectorio_vector_shape_t *self) { + VECTORIO_SHAPE_DEBUG("%p get_location\n", self); + mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + pair->items[0] = mp_obj_new_int((mp_int_t)self->x); + pair->items[1] = mp_obj_new_int((mp_int_t)self->y); + return pair; +} + + +void common_hal_vectorio_vector_shape_set_location(vectorio_vector_shape_t *self, mp_obj_t xy) { + VECTORIO_SHAPE_DEBUG("%p set_location\n", self); + size_t tuple_len = 0; + mp_obj_t *tuple_items; + mp_obj_tuple_get(xy, &tuple_len, &tuple_items); + if (tuple_len != 2) { + mp_raise_TypeError_varg(translate("(x,y) integers required")); + } + + mp_int_t x; + mp_int_t y; + if (!mp_obj_get_int_maybe(tuple_items[ 0 ], &x) + || !mp_obj_get_int_maybe(tuple_items[ 1 ], &y) + || x < SHRT_MIN || x > SHRT_MAX || y < SHRT_MIN || y > SHRT_MAX + ) { + mp_raise_ValueError_varg(translate("unsupported %q type"), MP_QSTR_point); + } + self->x = (int16_t)x; + self->y = (int16_t)y; + common_hal_vectorio_vector_shape_set_dirty(self); +} + mp_obj_t common_hal_vectorio_vector_shape_get_pixel_shader(vectorio_vector_shape_t *self) { VECTORIO_SHAPE_DEBUG("%p get_pixel_shader\n", self); @@ -271,10 +302,10 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); if (self->absolute_transform->mirror_x) { - pixel_to_get_y = shape_area.y2 - 1 - (pixel_to_get_y - shape_area.y1); + pixel_to_get_y = shape_area.y2 - 1 - pixel_to_get_y; } if (self->absolute_transform->mirror_y) { - pixel_to_get_x = shape_area.x2 - 1 - (pixel_to_get_x - shape_area.x1); + pixel_to_get_x = shape_area.x2 - 1 - pixel_to_get_x; } } else { pixel_to_get_x = input_pixel.x - self->absolute_transform->x - self->absolute_transform->dx * self->x; From 9897ac6b5cf8d48219cbb05c37f3334e86cc08c7 Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sun, 8 Aug 2021 00:25:17 -0700 Subject: [PATCH 19/63] yet more failures of local pre-commit to find that which github pre-commit does --- shared-module/vectorio/VectorShape.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index a6a63a498a..259ab87251 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -14,7 +14,7 @@ #include "shared-bindings/vectorio/Rectangle.h" // Lifecycle actions. -//#define VECTORIO_SHAPE_DEBUG(...) (void)0 +// #define VECTORIO_SHAPE_DEBUG(...) (void)0 #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) @@ -23,7 +23,7 @@ // Really verbose. -//#define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 +// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) #define U32_TO_BINARY_FMT "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" From a15ac65fa02cf5bb1c4dec9aae5c627750efedfb Mon Sep 17 00:00:00 2001 From: Nathan Young <77929198+NathanY3G@users.noreply.github.com> Date: Sun, 8 Aug 2021 21:43:12 +0200 Subject: [PATCH 20/63] Add board.LED for Grand Central M4 Express Fixes #5111 --- ports/atmel-samd/boards/grandcentral_m4_express/pins.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c index b125aca086..cb683db0bd 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c @@ -137,6 +137,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PC24) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB01) }, { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PC31) }, { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PC30) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, From 7eece7d959b44247335b2c9fa192cc9a2f8bbd8f Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sun, 8 Aug 2021 15:35:36 -0700 Subject: [PATCH 21/63] dirty area computed for non-transposed but at least d-1 --- shared-module/vectorio/VectorShape.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index 259ab87251..bd0684670a 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -97,11 +97,19 @@ static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *ou x = self->absolute_transform->x + self->absolute_transform->dx * self->y; y = self->absolute_transform->y + self->absolute_transform->dy * self->x; area_transpose(out_area); - displayio_area_canon(out_area); } else { + if (self->absolute_transform->dx < 1) { + out_area->x1 = out_area->x1 * -1 + 1; + out_area->x2 = out_area->x2 * -1 + 1; + } + if (self->absolute_transform->dy < 1) { + out_area->y1 = out_area->y1 * -1 + 1; + out_area->y2 = out_area->y2 * -1 + 1; + } x = self->absolute_transform->x + self->absolute_transform->dx * self->x; y = self->absolute_transform->y + self->absolute_transform->dy * self->y; } + displayio_area_canon(out_area); displayio_area_shift(out_area, x, y); VECTORIO_SHAPE_DEBUG(" out:{(%5d,%5d), (%5d,%5d)}\n", out_area->x1, out_area->y1, out_area->x2, out_area->y2); @@ -313,10 +321,10 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); if (self->absolute_transform->mirror_x) { - pixel_to_get_x = shape_area.x2 - 1 - (pixel_to_get_x - shape_area.x1); + pixel_to_get_x = (shape_area.x2 - shape_area.x1) - (pixel_to_get_x + shape_area.x1) + shape_area.x1 - 1; } if (self->absolute_transform->mirror_y) { - pixel_to_get_y = shape_area.y2 - 1 - (pixel_to_get_y - shape_area.y1); + pixel_to_get_y = (shape_area.y2 - shape_area.y1) - (pixel_to_get_y + shape_area.y1) + +shape_area.y1 - 1; } } From cf2712d23f5c12694305c6ecbc3673c3aba37ef1 Mon Sep 17 00:00:00 2001 From: Kenny <3454741+WarriorOfWire@users.noreply.github.com> Date: Sun, 8 Aug 2021 17:01:36 -0700 Subject: [PATCH 22/63] transposing and mirroring work * fix absolute_transform dirtying early instead of after the change, missing the draw * fix transpose and mirror. (0,0) -> location in all vector shapes now in all rotations. --- shared-module/vectorio/VectorShape.c | 55 +++++++++++++++++++--------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index bd0684670a..9d0279cf14 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -14,8 +14,8 @@ #include "shared-bindings/vectorio/Rectangle.h" // Lifecycle actions. -// #define VECTORIO_SHAPE_DEBUG(...) (void)0 -#define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) +#define VECTORIO_SHAPE_DEBUG(...) (void)0 +// #define VECTORIO_SHAPE_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) // Used in both logging and ifdefs, for extra variables @@ -23,8 +23,8 @@ // Really verbose. -// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 -#define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) +#define VECTORIO_SHAPE_PIXEL_DEBUG(...) (void)0 +// #define VECTORIO_SHAPE_PIXEL_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) #define U32_TO_BINARY_FMT "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c" #define U32_TO_BINARY(u32) \ @@ -96,8 +96,19 @@ static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *ou if (self->absolute_transform->transpose_xy) { x = self->absolute_transform->x + self->absolute_transform->dx * self->y; y = self->absolute_transform->y + self->absolute_transform->dy * self->x; + if (self->absolute_transform->dx < 1) { + out_area->y1 = out_area->y1 * -1 + 1; + out_area->y2 = out_area->y2 * -1 + 1; + } + if (self->absolute_transform->dy < 1) { + out_area->x1 = out_area->x1 * -1 + 1; + out_area->x2 = out_area->x2 * -1 + 1; + } area_transpose(out_area); } else { + x = self->absolute_transform->x + self->absolute_transform->dx * self->x; + y = self->absolute_transform->y + self->absolute_transform->dy * self->y; + if (self->absolute_transform->dx < 1) { out_area->x1 = out_area->x1 * -1 + 1; out_area->x2 = out_area->x2 * -1 + 1; @@ -106,8 +117,6 @@ static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *ou out_area->y1 = out_area->y1 * -1 + 1; out_area->y2 = out_area->y2 * -1 + 1; } - x = self->absolute_transform->x + self->absolute_transform->dx * self->x; - y = self->absolute_transform->y + self->absolute_transform->dy * self->y; } displayio_area_canon(out_area); displayio_area_shift(out_area, x, y); @@ -307,25 +316,35 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ if (self->absolute_transform->transpose_xy) { pixel_to_get_x = input_pixel.y - self->absolute_transform->y - self->absolute_transform->dy * self->x; pixel_to_get_y = input_pixel.x - self->absolute_transform->x - self->absolute_transform->dx * self->y; - VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); - if (self->absolute_transform->mirror_x) { - pixel_to_get_y = shape_area.y2 - 1 - pixel_to_get_y; + VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); + if (self->absolute_transform->dx < 1) { + pixel_to_get_y *= -1; } - if (self->absolute_transform->mirror_y) { - pixel_to_get_x = shape_area.x2 - 1 - pixel_to_get_x; + if (self->absolute_transform->dy < 1) { + pixel_to_get_x *= -1; } + VECTORIO_SHAPE_PIXEL_DEBUG(" b(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); } else { pixel_to_get_x = input_pixel.x - self->absolute_transform->x - self->absolute_transform->dx * self->x; pixel_to_get_y = input_pixel.y - self->absolute_transform->y - self->absolute_transform->dy * self->y; - VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); - if (self->absolute_transform->mirror_x) { - pixel_to_get_x = (shape_area.x2 - shape_area.x1) - (pixel_to_get_x + shape_area.x1) + shape_area.x1 - 1; + VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); + if (self->absolute_transform->dx < 1) { + pixel_to_get_x *= -1; } - if (self->absolute_transform->mirror_y) { - pixel_to_get_y = (shape_area.y2 - shape_area.y1) - (pixel_to_get_y + shape_area.y1) + +shape_area.y1 - 1; + if (self->absolute_transform->dy < 1) { + pixel_to_get_y *= -1; } + VECTORIO_SHAPE_PIXEL_DEBUG(" b(%3d, %3d)", pixel_to_get_x, pixel_to_get_y); + + // It's mirrored via dx. Maybe we need to add support for also separately mirroring? + // if (self->absolute_transform->mirror_x) { + // pixel_to_get_x = (shape_area.x2 - shape_area.x1) - (pixel_to_get_x - shape_area.x1) + shape_area.x1 - 1; + // } + // if (self->absolute_transform->mirror_y) { + // pixel_to_get_y = (shape_area.y2 - shape_area.y1) - (pixel_to_get_y - shape_area.y1) + +shape_area.y1 - 1; + // } } VECTORIO_SHAPE_PIXEL_DEBUG(" get_pixel %p (%3d, %3d) -> ( %3d, %3d )", self->ishape.shape, input_pixel.x, input_pixel.y, pixel_to_get_x, pixel_to_get_y); @@ -407,7 +426,7 @@ bool vectorio_vector_shape_fill_area(vectorio_vector_shape_t *self, const _displ void vectorio_vector_shape_finish_refresh(vectorio_vector_shape_t *self) { - if (displayio_area_empty(&self->ephemeral_dirty_area)) { + if (displayio_area_empty(&self->ephemeral_dirty_area) && !self->current_area_dirty) { return; } VECTORIO_SHAPE_DEBUG("%p finish_refresh was:{(%3d,%3d), (%3d,%3d)}\n", self, self->ephemeral_dirty_area.x1, self->ephemeral_dirty_area.y1, self->ephemeral_dirty_area.x2, self->ephemeral_dirty_area.y2); @@ -484,6 +503,6 @@ displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_ } void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displayio_buffer_transform_t *group_transform) { - common_hal_vectorio_vector_shape_set_dirty(self); self->absolute_transform = group_transform == NULL ? &null_transform : group_transform; + common_hal_vectorio_vector_shape_set_dirty(self); } From 45d40589810970e6057350fff4d82734e6c3aef4 Mon Sep 17 00:00:00 2001 From: Pierre Date: Sun, 8 Aug 2021 21:25:54 -0600 Subject: [PATCH 23/63] adding initial files for BlueMicro840 Board --- .github/workflows/build.yml | 1 + ports/nrf/boards/bluemicro840/board.c | 38 ++++++++ ports/nrf/boards/bluemicro840/mpconfigboard.h | 46 ++++++++++ .../nrf/boards/bluemicro840/mpconfigboard.mk | 8 ++ ports/nrf/boards/bluemicro840/pins.c | 90 +++++++++++++++++++ 5 files changed, 183 insertions(+) create mode 100644 ports/nrf/boards/bluemicro840/board.c create mode 100644 ports/nrf/boards/bluemicro840/mpconfigboard.h create mode 100644 ports/nrf/boards/bluemicro840/mpconfigboard.mk create mode 100644 ports/nrf/boards/bluemicro840/pins.c diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 744ef02f48..6d567ca9e2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -232,6 +232,7 @@ jobs: - "bdmicro_vina_d51_pcb7" - "bless_dev_board_multi_sensor" - "blm_badge" + - "bluemicro840" - "capablerobot_usbhub" - "catwan_usbstick" - "circuitbrains_basic_m0" diff --git a/ports/nrf/boards/bluemicro840/board.c b/ports/nrf/boards/bluemicro840/board.c new file mode 100644 index 0000000000..688cfb4ded --- /dev/null +++ b/ports/nrf/boards/bluemicro840/board.c @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/nrf/boards/bluemicro840/mpconfigboard.h b/ports/nrf/boards/bluemicro840/mpconfigboard.h new file mode 100644 index 0000000000..99a1e0bfbe --- /dev/null +++ b/ports/nrf/boards/bluemicro840/mpconfigboard.h @@ -0,0 +1,46 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2021 Pierre Constantineau + * + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "BlueMicro840" +#define MICROPY_HW_MCU_NAME "nRF52840" + +#define BOARD_HAS_CRYSTAL 1 + +#define MICROPY_HW_LED_STATUS (&pin_P1_04) // RED + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_17) // 0.17 - same position as Pro Micro +#define DEFAULT_I2C_BUS_SDA (&pin_P0_15) // 0.15 - same position as Pro Micro + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_24) // 0.24 - same position as Pro Micro +#define DEFAULT_SPI_BUS_MOSI (&pin_P0_10) // 0.10 - same position as Pro Micro +#define DEFAULT_SPI_BUS_MISO (&pin_P0_09) // 0.09 - same position as Pro Micro + +#define DEFAULT_UART_BUS_RX (&pin_P0_08) // 0.08 - same position as Pro Micro +#define DEFAULT_UART_BUS_TX (&pin_P0_06) // 0.06 - same position as Pro Micro diff --git a/ports/nrf/boards/bluemicro840/mpconfigboard.mk b/ports/nrf/boards/bluemicro840/mpconfigboard.mk new file mode 100644 index 0000000000..a95662f5fd --- /dev/null +++ b/ports/nrf/boards/bluemicro840/mpconfigboard.mk @@ -0,0 +1,8 @@ +USB_VID = 0x1D50 +USB_PID = 0x6160 +USB_PRODUCT = "BlueMicro840" +USB_MANUFACTURER = "nrf52.jpconstantineau.com" + +MCU_CHIP = nrf52840 + +INTERNAL_FLASH_FILESYSTEM = 1 diff --git a/ports/nrf/boards/bluemicro840/pins.c b/ports/nrf/boards/bluemicro840/pins.c new file mode 100644 index 0000000000..76020cab53 --- /dev/null +++ b/ports/nrf/boards/bluemicro840/pins.c @@ -0,0 +1,90 @@ +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + // XTAL { MP_ROM_QSTR(MP_QSTR_P0_00), MP_ROM_PTR(&pin_P0_00) }, + // XTAL { MP_ROM_QSTR(MP_QSTR_P0_01), MP_ROM_PTR(&pin_P0_01) }, + { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P0_03), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P0_05), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P0_06), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P0_07), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P0_08), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, //Vcc Enable + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + // RESET { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, + { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_P1_00), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, //RED LED + { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, //BLUE LED + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_17) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_24) }, + + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_P1_10) }, + + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_31) }, + + { MP_ROM_QSTR(MP_QSTR_VCC_ON), MP_ROM_PTR(&pin_P0_12) }, // Turn on external VCC - connected to enable pin of second regulator + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); + + From 9de8045dcae8ac60b9d8af4177c8aa8bc2feb22d Mon Sep 17 00:00:00 2001 From: Pierre Date: Sun, 8 Aug 2021 21:31:07 -0600 Subject: [PATCH 24/63] foromatting updates to pins.c --- ports/nrf/boards/bluemicro840/pins.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ports/nrf/boards/bluemicro840/pins.c b/ports/nrf/boards/bluemicro840/pins.c index 76020cab53..9b1a78182f 100644 --- a/ports/nrf/boards/bluemicro840/pins.c +++ b/ports/nrf/boards/bluemicro840/pins.c @@ -13,7 +13,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, - { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, //Vcc Enable + + //Vcc Enable + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, @@ -38,13 +40,17 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, - { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, //RED LED + + //RED LED + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, - { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, //BLUE LED + + //BLUE LED + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, @@ -78,7 +84,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_31) }, { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_VCC_ON), MP_ROM_PTR(&pin_P0_12) }, // Turn on external VCC - connected to enable pin of second regulator + // Turn on external VCC - connected to enable pin of second regulator + { MP_ROM_QSTR(MP_QSTR_VCC_ON), MP_ROM_PTR(&pin_P0_12) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, From 579194a543ca407f20a6d88a641cf2f487feee3a Mon Sep 17 00:00:00 2001 From: Nathan Young <77929198+NathanY3G@users.noreply.github.com> Date: Mon, 9 Aug 2021 05:35:38 +0200 Subject: [PATCH 25/63] Colocated board.LED and D13 together (GCM4) --- ports/atmel-samd/boards/grandcentral_m4_express/pins.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c index cb683db0bd..7db9491dd3 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c @@ -52,6 +52,8 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB22) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB23) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB00) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB01) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB01) }, { MP_OBJ_NEW_QSTR(MP_QSTR_TX3), MP_ROM_PTR(&pin_PB16) }, @@ -137,7 +139,6 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PC24) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB01) }, { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PC31) }, { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PC30) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, From b1d5b50551ef37633dce078b62c25d4c1b0add1e Mon Sep 17 00:00:00 2001 From: Pierre Date: Sun, 8 Aug 2021 21:38:23 -0600 Subject: [PATCH 26/63] fromatting updates to pins.c --- ports/nrf/boards/bluemicro840/pins.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/ports/nrf/boards/bluemicro840/pins.c b/ports/nrf/boards/bluemicro840/pins.c index 9b1a78182f..755429b31e 100644 --- a/ports/nrf/boards/bluemicro840/pins.c +++ b/ports/nrf/boards/bluemicro840/pins.c @@ -1,8 +1,6 @@ #include "shared-bindings/board/__init__.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { - // XTAL { MP_ROM_QSTR(MP_QSTR_P0_00), MP_ROM_PTR(&pin_P0_00) }, - // XTAL { MP_ROM_QSTR(MP_QSTR_P0_01), MP_ROM_PTR(&pin_P0_01) }, { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, { MP_ROM_QSTR(MP_QSTR_P0_03), MP_ROM_PTR(&pin_P0_03) }, { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, @@ -13,15 +11,12 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, - - //Vcc Enable { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, - // RESET { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, @@ -35,28 +30,22 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_P1_00), MP_ROM_PTR(&pin_P1_00) }, { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, - - //RED LED { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, - - //BLUE LED { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_04) }, @@ -65,28 +54,20 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_15) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_17) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_08) }, { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_06) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_09) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_10) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_24) }, - { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P1_04) }, { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_P1_10) }, - { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_04) }, { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_31) }, { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_31) }, - - // Turn on external VCC - connected to enable pin of second regulator { MP_ROM_QSTR(MP_QSTR_VCC_ON), MP_ROM_PTR(&pin_P0_12) }, - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, From 1a7cad6562a9ed0716627cd31a07724f1d203794 Mon Sep 17 00:00:00 2001 From: Pierre Date: Sun, 8 Aug 2021 21:43:03 -0600 Subject: [PATCH 27/63] removed trailing spaces in pins.c --- ports/nrf/boards/bluemicro840/pins.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/nrf/boards/bluemicro840/pins.c b/ports/nrf/boards/bluemicro840/pins.c index 755429b31e..f4041585d0 100644 --- a/ports/nrf/boards/bluemicro840/pins.c +++ b/ports/nrf/boards/bluemicro840/pins.c @@ -11,7 +11,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, - { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, @@ -34,13 +34,13 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, - { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, - { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, @@ -67,7 +67,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_10) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_31) }, { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_VCC_ON), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_VCC_ON), MP_ROM_PTR(&pin_P0_12) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, From 7d02fd42f8e04537b70d477630378f5405a59d36 Mon Sep 17 00:00:00 2001 From: Pierre Date: Sun, 8 Aug 2021 21:56:24 -0600 Subject: [PATCH 28/63] removed trailing spaces at end of pins.c --- ports/nrf/boards/bluemicro840/pins.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ports/nrf/boards/bluemicro840/pins.c b/ports/nrf/boards/bluemicro840/pins.c index f4041585d0..e33aff2bfa 100644 --- a/ports/nrf/boards/bluemicro840/pins.c +++ b/ports/nrf/boards/bluemicro840/pins.c @@ -74,5 +74,3 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); - - From 51f86037837b57e404a5acd5d8851d4b1d9756ac Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Sun, 8 Aug 2021 15:15:15 +0530 Subject: [PATCH 29/63] add getpass module --- locale/circuitpython.pot | 14 +-- .../mpconfigboard.mk | 2 + .../boards/sensebox_mcu/mpconfigboard.mk | 2 + py/circuitpy_defns.mk | 4 + py/circuitpy_mpconfig.h | 8 ++ py/circuitpy_mpconfig.mk | 3 + shared-bindings/getpass/__init__.c | 86 +++++++++++++++++++ shared-module/getpass/__init__.c | 61 +++++++++++++ shared-module/getpass/__init__.h | 34 ++++++++ 9 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 shared-bindings/getpass/__init__.c create mode 100644 shared-module/getpass/__init__.c create mode 100644 shared-module/getpass/__init__.h diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index f10f7fd019..0659588ae0 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -35,11 +35,11 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c shared-module/traceback/__init__.c msgid " File \"%q\"" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c shared-module/traceback/__init__.c msgid " File \"%q\", line %d" msgstr "" @@ -322,7 +322,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c shared-module/traceback/__init__.c msgid ", in %q\n" msgstr "" @@ -2211,7 +2211,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c shared-module/traceback/__init__.c msgid "Traceback (most recent call last):\n" msgstr "" @@ -3903,6 +3903,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4101,7 +4105,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk index cf9afb3d21..3ef6dafac6 100644 --- a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk @@ -19,6 +19,8 @@ CIRCUITPY_PWMIO = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 CIRCUITPY_USB_MIDI = 0 + +CIRCUITPY_GETPASS = 0 CIRCUITPY_TRACEBACK = 0 CIRCUITPY_PIXELBUF = 1 diff --git a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk index 196d36816f..94a255529f 100644 --- a/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sensebox_mcu/mpconfigboard.mk @@ -9,3 +9,5 @@ CHIP_FAMILY = samd21 INTERNAL_FLASH_FILESYSTEM = 1 LONGINT_IMPL = NONE CIRCUITPY_FULL_BUILD = 0 + +CIRCUITPY_GETPASS = 0 diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 92bd3b4d1f..84c8e22b2b 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -188,6 +188,9 @@ endif ifeq ($(CIRCUITPY_GAMEPADSHIFT),1) SRC_PATTERNS += gamepadshift/% endif +ifeq ($(CIRCUITPY_GETPASS),1) +SRC_PATTERNS += getpass/% +endif ifeq ($(CIRCUITPY_GNSS),1) SRC_PATTERNS += gnss/% endif @@ -519,6 +522,7 @@ SRC_SHARED_MODULE_ALL = \ fontio/__init__.c \ framebufferio/FramebufferDisplay.c \ framebufferio/__init__.c \ + getpass/__init__.c \ ipaddress/IPv4Address.c \ ipaddress/__init__.c \ keypad/__init__.c \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 5a7be5b79e..b8dbcd6de2 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -483,6 +483,13 @@ extern const struct _mp_obj_module_t gamepadshift_module; #define GAMEPAD_ROOT_POINTERS #endif +#if CIRCUITPY_GETPASS +extern const struct _mp_obj_module_t getpass_module; +#define GETPASS_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_getpass), (mp_obj_t)&getpass_module }, +#else +#define GETPASS_MODULE +#endif + #if CIRCUITPY_GNSS extern const struct _mp_obj_module_t gnss_module; #define GNSS_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_gnss), (mp_obj_t)&gnss_module }, @@ -896,6 +903,7 @@ extern const struct _mp_obj_module_t msgpack_module; FRAMEBUFFERIO_MODULE \ FREQUENCYIO_MODULE \ GAMEPADSHIFT_MODULE \ + GETPASS_MODULE \ GNSS_MODULE \ I2CPERIPHERAL_MODULE \ IPADDRESS_MODULE \ diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 45bc2e8fed..4df9432efa 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -184,6 +184,9 @@ CFLAGS += -DCIRCUITPY_FREQUENCYIO=$(CIRCUITPY_FREQUENCYIO) CIRCUITPY_GAMEPADSHIFT ?= 0 CFLAGS += -DCIRCUITPY_GAMEPADSHIFT=$(CIRCUITPY_GAMEPADSHIFT) +CIRCUITPY_GETPASS ?= 1 +CFLAGS += -DCIRCUITPY_GETPASS=$(CIRCUITPY_GETPASS) + CIRCUITPY_GNSS ?= 0 CFLAGS += -DCIRCUITPY_GNSS=$(CIRCUITPY_GNSS) diff --git a/shared-bindings/getpass/__init__.c b/shared-bindings/getpass/__init__.c new file mode 100644 index 0000000000..d627087aae --- /dev/null +++ b/shared-bindings/getpass/__init__.c @@ -0,0 +1,86 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/stream.h" +#include "shared-module/getpass/__init__.h" + +//| """Getpass Module +//| +//| This module provides a way to get input from user without echoing it. +//| +//| """ +//| ... +//| + +//| def getpass(prompt: Optional[str] = 'Password: ', stream: Optional[io.FileIO] = None) -> str: +//| +//| """Prompt the user without echoing. +//| +//| :param str prompt: The user is prompted using the string ``prompt``, which defaults to ``'Password: '``. +//| :param io.FileIO stream: The ``prompt`` is written to the file-like object ``stream`` if provided. +//| +//| """ +//| ... +//| +STATIC mp_obj_t getpass_getpass(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_prompt, ARG_stream }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_prompt, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_stream, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const char *prompt = (args[ARG_prompt].u_obj == mp_const_none) ? "Password: " : mp_obj_str_get_str(args[ARG_prompt].u_obj); + + mp_print_t print = {.data = NULL}; + if (args[ARG_stream].u_obj != mp_const_none) { + #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES + mp_get_stream_raise(args[ARG_stream].u_obj, MP_STREAM_OP_WRITE); + print.data = MP_OBJ_TO_PTR(args[ARG_stream].u_obj); + print.print_strn = mp_stream_write_adaptor; + #else + mp_raise_NotImplementedError(translate("stream operation not supported")); + #endif + } + + return shared_module_getpass_getpass(prompt, ((print.data) ? &print : NULL)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(getpass_getpass_obj, 0, getpass_getpass); + +STATIC const mp_rom_map_elem_t getpass_module_globals_table[] = { + // module name + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_getpass) }, + // module functions + { MP_ROM_QSTR(MP_QSTR_getpass), MP_ROM_PTR(&getpass_getpass_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(getpass_module_globals, getpass_module_globals_table); + +const mp_obj_module_t getpass_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&getpass_module_globals, +}; diff --git a/shared-module/getpass/__init__.c b/shared-module/getpass/__init__.c new file mode 100644 index 0000000000..f7ab96c378 --- /dev/null +++ b/shared-module/getpass/__init__.c @@ -0,0 +1,61 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mphal.h" +#include "lib/mp-readline/readline.h" +#include "shared-module/getpass/__init__.h" + +mp_obj_t shared_module_getpass_getpass(const char *prompt, mp_print_t *print) { + vstr_t vstr; + vstr_init(&vstr, 16); + + if (print == NULL) { + mp_hal_stdout_tx_str(prompt); + } else { + mp_printf(print, prompt); + } + + for (;;) { + int c = mp_hal_stdin_rx_chr(); + if (c == CHAR_CTRL_C) { + mp_raise_type(&mp_type_KeyboardInterrupt); + } else if (c == CHAR_CTRL_D && vstr.len == 0) { + mp_raise_type(&mp_type_EOFError); + } else if (c == 8 || c == 127) { + // backspace + vstr_cut_tail_bytes(&vstr, 1); + } else if (c >= 32) { + // printable character + vstr_ins_char(&vstr, vstr.len, c); + } else if (c == '\r') { + // newline + mp_hal_stdout_tx_str("\r\n"); + break; + } + } + + return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); +} diff --git a/shared-module/getpass/__init__.h b/shared-module/getpass/__init__.h new file mode 100644 index 0000000000..80595d41ba --- /dev/null +++ b/shared-module/getpass/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 microDev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_GETPASS___INIT___H +#define MICROPY_INCLUDED_SHARED_MODULE_GETPASS___INIT___H + +#include "py/runtime.h" + +extern mp_obj_t shared_module_getpass_getpass(const char *prompt, mp_print_t *print); + +#endif // MICROPY_INCLUDED_SHARED_MODULE_GETPASS___INIT___H From bfea6947e510e5a20bd46db4946f9ae524077b47 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 8 Aug 2021 10:27:50 -0500 Subject: [PATCH 30/63] Improve mp_printf with support for compressed strings * The new nonstandard '%S' format takes a pointer to compressed_string_t and prints it * The new mp_cprintf and mp_vcprintf take a format string that is a compressed_string_t --- locale/circuitpython.pot | 12 ++++++--- py/builtinhelp.c | 25 +++++------------- py/mpprint.c | 42 +++++++++++++++++++++++++----- py/mpprint.h | 6 +++++ py/obj.c | 16 +++--------- py/objexcept.c | 5 +--- shared-module/traceback/__init__.c | 14 +++------- supervisor/shared/translate.c | 5 ++-- supervisor/shared/translate.h | 2 +- 9 files changed, 67 insertions(+), 60 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index f10f7fd019..720f52d40b 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -35,11 +35,11 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr "" @@ -322,7 +322,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr "" @@ -2211,7 +2211,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "" @@ -3903,6 +3903,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/py/builtinhelp.c b/py/builtinhelp.c index 344ded80b0..8590c4beea 100644 --- a/py/builtinhelp.c +++ b/py/builtinhelp.c @@ -131,10 +131,7 @@ STATIC void mp_help_print_modules(void) { #if MICROPY_ENABLE_EXTERNAL_IMPORT // let the user know there may be other modules available from the filesystem - const compressed_string_t *compressed = translate("Plus any modules on the filesystem\n"); - char decompressed[decompress_length(compressed)]; - decompress(compressed, decompressed); - mp_print_str(MP_PYTHON_PRINTER, decompressed); + mp_printf(MP_PYTHON_PRINTER, "%S", translate("Plus any modules on the filesystem\n")); #endif } #endif @@ -150,18 +147,10 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) { const mp_obj_type_t *type = mp_obj_get_type(obj); // try to print something sensible about the given object - const compressed_string_t *compressed = translate("object "); - char decompressed_object[decompress_length(compressed)]; - decompress(compressed, decompressed_object); - - mp_print_str(MP_PYTHON_PRINTER, decompressed_object); + mp_cprintf(MP_PYTHON_PRINTER, translate("object ")); mp_obj_print(obj, PRINT_STR); - compressed = translate(" is of type %q\n"); - char decompressed_typestring[decompress_length(compressed)]; - decompress(compressed, decompressed_typestring); - - mp_printf(MP_PYTHON_PRINTER, decompressed_typestring, type->name); + mp_cprintf(MP_PYTHON_PRINTER, translate(" is of type %q\n"), type->name); mp_map_t *map = NULL; if (type == &mp_type_module) { @@ -186,11 +175,9 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) { STATIC mp_obj_t mp_builtin_help(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { // print a general help message. Translate only works on single strings on one line. - const compressed_string_t *compressed = - translate("Welcome to Adafruit CircuitPython %s!\n\nPlease visit learn.adafruit.com/category/circuitpython for project guides.\n\nTo list built-in modules please do `help(\"modules\")`.\n"); - char decompressed[decompress_length(compressed)]; - decompress(compressed, decompressed); - mp_printf(MP_PYTHON_PRINTER, decompressed, MICROPY_GIT_TAG); + mp_cprintf(MP_PYTHON_PRINTER, + translate("Welcome to Adafruit CircuitPython %s!\n\nPlease visit learn.adafruit.com/category/circuitpython for project guides.\n\nTo list built-in modules please do `help(\"modules\")`.\n"), + MICROPY_GIT_TAG); } else { // try to print something sensible about the given object mp_help_print_obj(args[0]); diff --git a/py/mpprint.c b/py/mpprint.c index b99b5d658d..af485a50f2 100644 --- a/py/mpprint.c +++ b/py/mpprint.c @@ -376,6 +376,13 @@ int mp_print_float(const mp_print_t *print, mp_float_t f, char fmt, int flags, c } #endif +static int print_str_common(const mp_print_t *print, const char *str, int prec, size_t len, int flags, int fill, int width) { + if (prec >= 0 && (size_t)prec < len) { + len = prec; + } + return mp_print_strn(print, str, len, flags, fill, width); +} + int mp_printf(const mp_print_t *print, const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -484,19 +491,24 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { qstr qst = va_arg(args, qstr); size_t len; const char *str = (const char *)qstr_data(qst, &len); - if (prec >= 0 && (size_t)prec < len) { - len = prec; - } - chrs += mp_print_strn(print, str, len, flags, fill, width); + chrs += print_str_common(print, str, prec, len, flags, fill, width); + break; + } + case 'S': { + compressed_string_t *arg = va_arg(args, compressed_string_t *); + size_t len_with_nul = decompress_length(arg); + size_t len = len_with_nul - 1; + char str[len_with_nul]; + decompress(arg, str); + chrs += print_str_common(print, str, prec, len, flags, fill, width); break; } case 's': { const char *str = va_arg(args, const char *); #ifndef NDEBUG // With debugging enabled, catch printing of null string pointers - if (prec != 0 && str == NULL) { - chrs += mp_print_strn(print, "(null)", 6, flags, fill, width); - break; + if (str == NULL) { + str = "(null)"; } #endif size_t len = strlen(str); @@ -574,3 +586,19 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { } return chrs; } + +int mp_cprintf(const mp_print_t *print, const compressed_string_t *compressed_fmt, ...) { + va_list ap; + va_start(ap, compressed_fmt); + int ret = mp_vcprintf(print, compressed_fmt, ap); + va_end(ap); + return ret; +} + +int mp_vcprintf(const mp_print_t *print, const compressed_string_t *compressed_fmt, va_list args) { + char fmt[decompress_length(compressed_fmt)]; + // TODO: Optimise this to format-while-decompressing (and not require the temp stack space). + decompress(compressed_fmt, fmt); + + return mp_vprintf(print, fmt, args); +} diff --git a/py/mpprint.h b/py/mpprint.h index 4458ea883b..9284935f96 100644 --- a/py/mpprint.h +++ b/py/mpprint.h @@ -71,4 +71,10 @@ int mp_printf(const mp_print_t *print, const char *fmt, ...); int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args); #endif +struct compressed_string; +int mp_cprintf(const mp_print_t *print, const struct compressed_string *compressed_fmt, ...); +#ifdef va_start +int mp_vcprintf(const mp_print_t *print, const struct compressed_string *compressed_fmt, va_list args); +#endif + #endif // MICROPY_INCLUDED_PY_MPPRINT_H diff --git a/py/obj.c b/py/obj.c index c8a1106a3d..dcf48b81ae 100644 --- a/py/obj.c +++ b/py/obj.c @@ -149,35 +149,27 @@ void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { mp_obj_exception_get_traceback(exc, &n, &values); if (n > 0) { assert(n % 3 == 0); - // Decompress the format strings - const compressed_string_t *traceback = MP_ERROR_TEXT("Traceback (most recent call last):\n"); - char decompressed[decompress_length(traceback)]; - decompress(traceback, decompressed); #if MICROPY_ENABLE_SOURCE_LINE const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\", line %d"); #else const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\""); #endif - char decompressed_frame[decompress_length(frame)]; - decompress(frame, decompressed_frame); const compressed_string_t *block_fmt = MP_ERROR_TEXT(", in %q\n"); - char decompressed_block[decompress_length(block_fmt)]; - decompress(block_fmt, decompressed_block); // Print the traceback - mp_print_str(print, decompressed); + mp_cprintf(print, MP_ERROR_TEXT("Traceback (most recent call last):\n")); for (int i = n - 3; i >= 0; i -= 3) { #if MICROPY_ENABLE_SOURCE_LINE - mp_printf(print, decompressed_frame, values[i], (int)values[i + 1]); + mp_cprintf(print, frame, values[i], (int)values[i + 1]); #else - mp_printf(print, decompressed_frame, values[i]); + mp_printf(print, frame, values[i]); #endif // the block name can be NULL if it's unknown qstr block = values[i + 2]; if (block == MP_QSTRnull) { mp_print_str(print, "\n"); } else { - mp_printf(print, decompressed_block, block); + mp_cprintf(print, block_fmt, block); } } } diff --git a/py/objexcept.c b/py/objexcept.c index 6488413115..e572225bbc 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -465,12 +465,9 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const com o_str->data = NULL; } else { // We have some memory to format the string. - // TODO: Optimise this to format-while-decompressing (and not require the temp stack space). struct _exc_printer_t exc_pr = {!used_emg_buf, o_str_alloc, 0, o_str_buf}; mp_print_t print = {&exc_pr, exc_add_strn}; - char fmt_decompressed[decompress_length(fmt)]; - decompress(fmt, fmt_decompressed); - mp_vprintf(&print, fmt_decompressed, ap); + mp_vcprintf(&print, fmt, ap); exc_pr.buf[exc_pr.len] = '\0'; o_str->len = exc_pr.len; o_str->data = exc_pr.buf; diff --git a/shared-module/traceback/__init__.c b/shared-module/traceback/__init__.c index 388b1c18de..11237edb5c 100644 --- a/shared-module/traceback/__init__.c +++ b/shared-module/traceback/__init__.c @@ -35,18 +35,12 @@ void shared_module_traceback_print_exception(mp_obj_exception_t *exc, mp_print_t assert(n % 3 == 0); // Decompress the format strings const compressed_string_t *traceback = MP_ERROR_TEXT("Traceback (most recent call last):\n"); - char decompressed[decompress_length(traceback)]; - decompress(traceback, decompressed); #if MICROPY_ENABLE_SOURCE_LINE const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\", line %d"); #else const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\""); #endif - char decompressed_frame[decompress_length(frame)]; - decompress(frame, decompressed_frame); const compressed_string_t *block_fmt = MP_ERROR_TEXT(", in %q\n"); - char decompressed_block[decompress_length(block_fmt)]; - decompress(block_fmt, decompressed_block); // Set traceback formatting // Default: Print full traceback @@ -69,20 +63,20 @@ void shared_module_traceback_print_exception(mp_obj_exception_t *exc, mp_print_t } // Print the traceback - mp_print_str(print, decompressed); + mp_cprintf(print, traceback); for (; i >= limit; i -= 3) { j = (i < 0) ? -i : i; #if MICROPY_ENABLE_SOURCE_LINE - mp_printf(print, decompressed_frame, values[j], (int)values[j + 1]); + mp_cprintf(print, frame, values[j], (int)values[j + 1]); #else - mp_printf(print, decompressed_frame, values[j]); + mp_printf(print, frame, values[j]); #endif // The block name can be NULL if it's unknown qstr block = values[j + 2]; if (block == MP_QSTRnull) { mp_print_str(print, "\n"); } else { - mp_printf(print, decompressed_block, block); + mp_printf(print, block_fmt, block); } } } diff --git a/supervisor/shared/translate.c b/supervisor/shared/translate.c index 4d899ad6d0..a14fa5c728 100644 --- a/supervisor/shared/translate.c +++ b/supervisor/shared/translate.c @@ -35,12 +35,11 @@ #endif #include "py/misc.h" +#include "py/mpprint.h" #include "supervisor/serial.h" void serial_write_compressed(const compressed_string_t *compressed) { - char decompressed[decompress_length(compressed)]; - decompress(compressed, decompressed); - serial_write(decompressed); + mp_printf(MP_PYTHON_PRINTER, "%S", compressed); } STATIC void get_word(int n, const mchar_t **pos, const mchar_t **end) { diff --git a/supervisor/shared/translate.h b/supervisor/shared/translate.h index 26a961a3ed..da58e1eb78 100644 --- a/supervisor/shared/translate.h +++ b/supervisor/shared/translate.h @@ -69,7 +69,7 @@ // flexible array}, but is also future-proofed against strings with // UTF-8 length above 256, with a savings of about 1.375 bytes per // string. -typedef struct { +typedef struct compressed_string { uint8_t data; const uint8_t tail[]; } compressed_string_t; From c1ffab7476d9bdb042eae89abecf46344ee34301 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 8 Aug 2021 10:36:25 -0500 Subject: [PATCH 31/63] Reduce code duplication in traceback module --- py/obj.c | 38 ++++++++++++++++---- py/obj.h | 1 + shared-module/traceback/__init__.c | 58 +----------------------------- 3 files changed, 34 insertions(+), 63 deletions(-) diff --git a/py/obj.c b/py/obj.c index dcf48b81ae..fa3cd0c51c 100644 --- a/py/obj.c +++ b/py/obj.c @@ -143,7 +143,7 @@ void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) { } // helper function to print an exception with traceback -void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { +void mp_obj_print_exception_with_limit(const mp_print_t *print, mp_obj_t exc, mp_int_t limit) { if (mp_obj_is_exception_instance(exc) && stack_ok()) { size_t n, *values; mp_obj_exception_get_traceback(exc, &n, &values); @@ -156,16 +156,38 @@ void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { #endif const compressed_string_t *block_fmt = MP_ERROR_TEXT(", in %q\n"); + // Set traceback formatting + // Default: Print full traceback + limit = limit * 3; + mp_int_t i = n - 3, j; + if (limit > 0) { + // Print upto limit traceback + // entries from caller's frame + if ((unsigned)limit > n) { + limit = n; + } + limit = n - limit; + } else if (limit < 0) { + // Print upto limit traceback + // entries from last + if ((unsigned)-limit > n) { + limit = -n; + } + i = 0, limit = limit + 3; + } + // Print the traceback mp_cprintf(print, MP_ERROR_TEXT("Traceback (most recent call last):\n")); - for (int i = n - 3; i >= 0; i -= 3) { + + for (; i >= limit; i -= 3) { + j = (i < 0) ? -i : i; #if MICROPY_ENABLE_SOURCE_LINE - mp_cprintf(print, frame, values[i], (int)values[i + 1]); + mp_cprintf(print, frame, values[j], (int)values[j + 1]); #else - mp_printf(print, frame, values[i]); + mp_cprintf(print, frame, values[j]); #endif - // the block name can be NULL if it's unknown - qstr block = values[i + 2]; + // The block name can be NULL if it's unknown + qstr block = values[j + 2]; if (block == MP_QSTRnull) { mp_print_str(print, "\n"); } else { @@ -178,6 +200,10 @@ void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { mp_print_str(print, "\n"); } +void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc) { + mp_obj_print_exception_with_limit(print, exc, 0); +} + bool PLACE_IN_ITCM(mp_obj_is_true)(mp_obj_t arg) { if (arg == mp_const_false) { return 0; diff --git a/py/obj.h b/py/obj.h index b91932b11e..a043154ada 100644 --- a/py/obj.h +++ b/py/obj.h @@ -888,6 +888,7 @@ mp_obj_t mp_obj_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); void mp_obj_print(mp_obj_t o, mp_print_kind_t kind); void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc); +void mp_obj_print_exception_with_limit(const mp_print_t *print, mp_obj_t exc, mp_int_t limit); bool mp_obj_is_true(mp_obj_t arg); bool mp_obj_is_callable(mp_obj_t o_in); diff --git a/shared-module/traceback/__init__.c b/shared-module/traceback/__init__.c index 11237edb5c..a29bd5743f 100644 --- a/shared-module/traceback/__init__.c +++ b/shared-module/traceback/__init__.c @@ -27,61 +27,5 @@ #include "shared-module/traceback/__init__.h" void shared_module_traceback_print_exception(mp_obj_exception_t *exc, mp_print_t *print, mp_int_t limit) { - // Print traceback - if (exc->traceback != NULL) { - size_t n = exc->traceback->len; - size_t *values = exc->traceback->data; - if (n > 0) { - assert(n % 3 == 0); - // Decompress the format strings - const compressed_string_t *traceback = MP_ERROR_TEXT("Traceback (most recent call last):\n"); - #if MICROPY_ENABLE_SOURCE_LINE - const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\", line %d"); - #else - const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\""); - #endif - const compressed_string_t *block_fmt = MP_ERROR_TEXT(", in %q\n"); - - // Set traceback formatting - // Default: Print full traceback - limit = limit * 3; - mp_int_t i = n - 3, j; - if (limit > 0) { - // Print upto limit traceback - // entries from caller's frame - if ((unsigned)limit > n) { - limit = n; - } - limit = n - limit; - } else if (limit < 0) { - // Print upto limit traceback - // entries from last - if ((unsigned)-limit > n) { - limit = -n; - } - i = 0, limit = limit + 3; - } - - // Print the traceback - mp_cprintf(print, traceback); - for (; i >= limit; i -= 3) { - j = (i < 0) ? -i : i; - #if MICROPY_ENABLE_SOURCE_LINE - mp_cprintf(print, frame, values[j], (int)values[j + 1]); - #else - mp_printf(print, frame, values[j]); - #endif - // The block name can be NULL if it's unknown - qstr block = values[j + 2]; - if (block == MP_QSTRnull) { - mp_print_str(print, "\n"); - } else { - mp_printf(print, block_fmt, block); - } - } - } - } - // Print exception - mp_obj_print_helper(print, exc, PRINT_EXC); - mp_print_str(print, "\n"); + mp_obj_print_exception_with_limit(print, exc, limit); } From 9a932a5a48487e511461940b3082c7125351c539 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Sun, 8 Aug 2021 11:03:03 -0500 Subject: [PATCH 32/63] traceback: Implement format_exception --- locale/circuitpython.pot | 4 -- shared-bindings/traceback/__init__.c | 96 +++++++++++++++++++++------- 2 files changed, 72 insertions(+), 28 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 720f52d40b..c7c4dfd098 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -3453,10 +3453,6 @@ msgstr "" msgid "lhs and rhs should be compatible" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "" diff --git a/shared-bindings/traceback/__init__.c b/shared-bindings/traceback/__init__.c index d5290559ca..828d6bc28e 100644 --- a/shared-bindings/traceback/__init__.c +++ b/shared-bindings/traceback/__init__.c @@ -38,6 +38,75 @@ //| ... //| +STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj_t tb_obj, mp_obj_t limit_obj) { + if (!mp_obj_is_exception_instance(value)) { + mp_raise_TypeError(translate("invalid exception")); + } + mp_obj_exception_t exc = *(mp_obj_exception_t *)MP_OBJ_TO_PTR(value); + + mp_int_t limit = 0; + bool print_tb = true; + if (limit_obj != mp_const_none) { + limit = mp_obj_get_int(limit_obj); + print_tb = (limit != 0); + } + + if (tb_obj != mp_const_none && print_tb) { + if (!mp_obj_is_type(tb_obj, &mp_type_traceback)) { + mp_raise_TypeError(translate("invalid traceback")); + } + exc.traceback = MP_OBJ_TO_PTR(tb_obj); + } else { + exc.traceback = NULL; + } + + shared_module_traceback_print_exception(&exc, print, limit); +} + +//| def format_exception(etype: Type[BaseException], value: BaseException, tb: TracebackType, +//| limit: Optional[int] = None, chain: Optional[bool] = True) -> None: +//| """Format a stack trace and the exception information. +//| +//| The arguments have the same meaning as the corresponding arguments +//| to print_exception(). The return value is a list of strings, each +//| ending in a newline and some containing internal newlines. When +//| these lines are concatenated and printed, exactly the same text is +//| printed as does print_exception(). +//| +//| .. note: Setting `chain` will have no effect as chained exceptions are not yet implemented. +//| +//| :param Type[BaseException] etype: This is ignored and inferred from the type of ``value``. +//| :param BaseException value: The exception. Must be an instance of `BaseException`. +//| :param TracebackType tb: The traceback object. If `None`, the traceback will not be printed. +//| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive. +//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed. +//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented). +//| +//| """ +//| ... +//| +STATIC mp_obj_t traceback_format_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_etype, ARG_value, ARG_tb, ARG_limit, ARG_chain }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_etype, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_value, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_tb, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_limit, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_chain, MP_ARG_BOOL, {.u_bool = true} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_print_t print; + vstr_t vstr; + vstr_init_print(&vstr, 0, &print); + traceback_exception_common(&print, args[ARG_value].u_obj, args[ARG_tb].u_obj, args[ARG_limit].u_obj); + return mp_obj_new_str_from_vstr(&mp_type_str, &vstr); +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 3, traceback_format_exception); + //| def print_exception(etype: Type[BaseException], value: BaseException, tb: TracebackType, //| limit: Optional[int] = None, file: Optional[io.FileIO] = None, chain: Optional[bool] = True) -> None: //| @@ -57,6 +126,7 @@ //| """ //| ... //| + STATIC mp_obj_t traceback_print_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_etype, ARG_value, ARG_tb, ARG_limit, ARG_file, ARG_chain }; static const mp_arg_t allowed_args[] = { @@ -71,11 +141,6 @@ STATIC mp_obj_t traceback_print_exception(size_t n_args, const mp_obj_t *pos_arg mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - if (!mp_obj_is_exception_instance(args[ARG_value].u_obj)) { - mp_raise_TypeError(translate("invalid exception")); - } - mp_obj_exception_t exc = *(mp_obj_exception_t *)MP_OBJ_TO_PTR(args[ARG_value].u_obj); - mp_print_t print = mp_plat_print; if (args[ARG_file].u_obj != mp_const_none) { #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES @@ -87,25 +152,7 @@ STATIC mp_obj_t traceback_print_exception(size_t n_args, const mp_obj_t *pos_arg #endif } - mp_int_t limit = 0; - bool print_tb = true; - if (args[ARG_limit].u_obj != mp_const_none) { - if (!mp_obj_get_int_maybe(args[ARG_limit].u_obj, &limit)) { - mp_raise_TypeError(translate("limit should be an int")); - } - print_tb = (limit != 0); - } - - if (args[ARG_tb].u_obj != mp_const_none && print_tb) { - if (!mp_obj_is_type(args[ARG_tb].u_obj, &mp_type_traceback)) { - mp_raise_TypeError(translate("invalid traceback")); - } - exc.traceback = MP_OBJ_TO_PTR(args[ARG_tb].u_obj); - } else { - exc.traceback = NULL; - } - - shared_module_traceback_print_exception(&exc, &print, limit); + traceback_exception_common(&print, args[ARG_value].u_obj, args[ARG_tb].u_obj, args[ARG_limit].u_obj); return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_print_exception_obj, 3, traceback_print_exception); @@ -114,6 +161,7 @@ STATIC const mp_rom_map_elem_t traceback_module_globals_table[] = { // module name { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_traceback) }, // module functions + { MP_ROM_QSTR(MP_QSTR_format_exception), MP_ROM_PTR(&traceback_format_exception_obj) }, { MP_ROM_QSTR(MP_QSTR_print_exception), MP_ROM_PTR(&traceback_print_exception_obj) }, }; STATIC MP_DEFINE_CONST_DICT(traceback_module_globals, traceback_module_globals_table); From fd71d924d24e87401faca283843bdb5125d9e91e Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 28 Jul 2021 22:19:41 -0400 Subject: [PATCH 33/63] partial buffer mgmt fix --- ports/atmel-samd/audio_dma.c | 24 +++++++------ .../atmel-samd/common-hal/audiobusio/I2SOut.c | 9 +++-- ports/raspberrypi/audio_dma.c | 35 ++++++++++++------- .../common-hal/audiobusio/I2SOut.c | 3 +- 4 files changed, 42 insertions(+), 29 deletions(-) diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c index 7f1260973d..fc57e404f7 100644 --- a/ports/atmel-samd/audio_dma.c +++ b/ports/atmel-samd/audio_dma.c @@ -214,21 +214,23 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, if (output_signed != samples_signed) { output_spacing = 1; max_buffer_length /= dma->spacing; - dma->first_buffer = (uint8_t *)m_realloc(dma->first_buffer, max_buffer_length); - if (dma->first_buffer == NULL) { + } + + dma->first_buffer = (uint8_t *)m_realloc(dma->first_buffer, max_buffer_length); + if (dma->first_buffer == NULL) { + return AUDIO_DMA_MEMORY_ERROR; + } + dma->first_buffer_free = true; + if (!single_buffer) { + dma->second_buffer = (uint8_t *)m_realloc(dma->second_buffer, max_buffer_length); + if (dma->second_buffer == NULL) { return AUDIO_DMA_MEMORY_ERROR; } - dma->first_buffer_free = true; - if (!single_buffer) { - dma->second_buffer = (uint8_t *)m_realloc(dma->second_buffer, max_buffer_length); - if (dma->second_buffer == NULL) { - return AUDIO_DMA_MEMORY_ERROR; - } - } - dma->signed_to_unsigned = !output_signed && samples_signed; - dma->unsigned_to_signed = output_signed && !samples_signed; } + dma->signed_to_unsigned = !output_signed && samples_signed; + dma->unsigned_to_signed = output_signed && !samples_signed; + dma->event_channel = 0xff; if (!single_buffer) { dma->second_descriptor = (DmacDescriptor *)m_malloc(sizeof(DmacDescriptor), false); diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c index 2488b7b922..7a10ea81d7 100644 --- a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c +++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -71,7 +71,7 @@ void i2sout_reset(void) { // Make sure the I2S peripheral is running so we can see if the resources we need are free. #ifdef SAM_D5X_E5X - // Connect the clock units to the 2mhz clock. It can't disable without it. + // Connect the clock units to the 2MHz clock. It can't disable without it. connect_gclk_to_peripheral(5, I2S_GCLK_ID_0); connect_gclk_to_peripheral(5, I2S_GCLK_ID_1); #endif @@ -83,7 +83,7 @@ void i2sout_reset(void) { // Make sure the I2S peripheral is running so we can see if the resources we need are free. #ifdef SAM_D5X_E5X - // Connect the clock units to the 2mhz clock by default. They can't reset without it. + // Connect the clock units to the 2MHz clock by default. They can't reset without it. disconnect_gclk_from_peripheral(5, I2S_GCLK_ID_0); disconnect_gclk_from_peripheral(5, I2S_GCLK_ID_1); @@ -222,7 +222,6 @@ void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t *self) { reset_pin_number(self->word_select->number); self->word_select = NULL; reset_pin_number(self->data->number); - self->data = NULL; } void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, @@ -288,7 +287,7 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, I2S->TXCTRL.reg = serctrl; #endif - // The DFLL is always a 48mhz clock + // The DFLL is always a 48MHz clock enable_clock_generator(self->gclk, CLOCK_48MHZ, divisor); connect_gclk_to_peripheral(self->gclk, I2S_GCLK_ID_0 + self->clock_unit); @@ -380,7 +379,7 @@ void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t *self) { } #endif disconnect_gclk_from_peripheral(self->gclk, I2S_GCLK_ID_0 + self->clock_unit); - disable_clock_generator(self->gclk); + disable_gclk(self->gclk); #ifdef SAM_D5X_E5X connect_gclk_to_peripheral(5, I2S_GCLK_ID_0 + self->clock_unit); diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index 52b1c84b91..d3c041a84d 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -135,12 +135,21 @@ void audio_dma_load_next_block(audio_dma_t *dma) { audio_dma_stop(dma); return; } + bool busy0 = dma_channel_is_busy(dma->channel[0]); + bool busy1 = dma_channel_is_busy(dma->channel[1]); + if (busy0 == busy1) { + mp_printf(&mp_plat_print, "busy: %d %d\n", busy0, busy1); + } + if (buffer_length < 256) { + mp_printf(&mp_plat_print, "%d length: %d\n", dma->first_channel_free, buffer_length); + } audio_dma_convert_signed(dma, buffer, buffer_length, &output_buffer, &output_buffer_length); // If we don't have an output buffer, save the pointer to first_buffer for use in the single // buffer special case. if (dma->first_buffer == NULL) { + mp_printf(&mp_plat_print,"no first buffer\n"); dma->first_buffer = output_buffer; } @@ -210,22 +219,24 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, dma->sample_spacing > 1 || (dma->sample_resolution != dma->output_resolution)) { max_buffer_length /= dma->sample_spacing; - dma->first_buffer = (uint8_t *)m_realloc(dma->first_buffer, max_buffer_length); - if (dma->first_buffer == NULL) { + } + + dma->first_buffer = (uint8_t *)m_realloc(dma->first_buffer, max_buffer_length); + if (dma->first_buffer == NULL) { + return AUDIO_DMA_MEMORY_ERROR; + } + + dma->first_buffer_free = true; + if (!single_buffer) { + dma->second_buffer = (uint8_t *)m_realloc(dma->second_buffer, max_buffer_length); + if (dma->second_buffer == NULL) { return AUDIO_DMA_MEMORY_ERROR; } - - dma->first_buffer_free = true; - if (!single_buffer) { - dma->second_buffer = (uint8_t *)m_realloc(dma->second_buffer, max_buffer_length); - if (dma->second_buffer == NULL) { - return AUDIO_DMA_MEMORY_ERROR; - } - } - dma->signed_to_unsigned = !output_signed && samples_signed; - dma->unsigned_to_signed = output_signed && !samples_signed; } + dma->signed_to_unsigned = !output_signed && samples_signed; + dma->unsigned_to_signed = output_signed && !samples_signed; + if (output_resolution > 8) { dma->output_size = 2; } else { diff --git a/ports/raspberrypi/common-hal/audiobusio/I2SOut.c b/ports/raspberrypi/common-hal/audiobusio/I2SOut.c index 15a7cd523b..425b65e601 100644 --- a/ports/raspberrypi/common-hal/audiobusio/I2SOut.c +++ b/ports/raspberrypi/common-hal/audiobusio/I2SOut.c @@ -117,7 +117,8 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, } // Use the state machine to manage pins. - common_hal_rp2pio_statemachine_construct(&self->state_machine, + common_hal_rp2pio_statemachine_construct( + &self->state_machine, program, program_len, 44100 * 32 * 6, // Clock at 44.1 khz to warm the DAC up. NULL, 0, From 2cd80d10748335a5cdf1812675a2b81a8d596aff Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 29 Jul 2021 13:26:10 -0400 Subject: [PATCH 34/63] wip, with debugging printf's --- locale/circuitpython.pot | 8 ++++++++ ports/raspberrypi/audio_dma.c | 23 +++++++++++++++++++++-- ports/raspberrypi/audio_dma.h | 2 ++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index f10f7fd019..a33a4cca6c 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -489,6 +489,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1213,6 +1217,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index d3c041a84d..c2ff957622 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -51,11 +51,16 @@ void audio_dma_reset(void) { void audio_dma_convert_signed(audio_dma_t *dma, uint8_t *buffer, uint32_t buffer_length, uint8_t **output_buffer, uint32_t *output_buffer_length) { + + size_t output_buffer_max_length; if (dma->first_buffer_free) { *output_buffer = dma->first_buffer; + output_buffer_max_length = dma->first_buffer_length; } else { *output_buffer = dma->second_buffer; + output_buffer_max_length = dma->second_buffer_length; } + #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" if (dma->signed_to_unsigned || @@ -65,6 +70,12 @@ void audio_dma_convert_signed(audio_dma_t *dma, uint8_t *buffer, uint32_t buffer *output_buffer_length = buffer_length / dma->sample_spacing; uint32_t out_i = 0; if (dma->sample_resolution <= 8 && dma->output_resolution > 8) { + // reading bytes, writing 16-bit samples + *output_buffer_length = *output_buffer_length * 2; + if (*output_buffer_length > output_buffer_max_length) { + mp_raise_RuntimeError(translate("Internal audio buffer too small")); + } + size_t shift = dma->output_resolution - dma->sample_resolution; for (uint32_t i = 0; i < buffer_length; i += dma->sample_spacing) { @@ -107,6 +118,10 @@ void audio_dma_convert_signed(audio_dma_t *dma, uint8_t *buffer, uint32_t buffer } out_i += 1; } + } else { + // (dma->sample_resolution > 8 && dma->output_resolution <= 8) + // Not currently used, but might be in the future. + mp_raise_RuntimeError(translate("Audio conversion not implemented")); } } else { *output_buffer = buffer; @@ -149,7 +164,6 @@ void audio_dma_load_next_block(audio_dma_t *dma) { // If we don't have an output buffer, save the pointer to first_buffer for use in the single // buffer special case. if (dma->first_buffer == NULL) { - mp_printf(&mp_plat_print,"no first buffer\n"); dma->first_buffer = output_buffer; } @@ -210,8 +224,11 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, uint32_t max_buffer_length; audiosample_get_buffer_structure(sample, single_channel_output, &single_buffer, &samples_signed, &max_buffer_length, &dma->sample_spacing); - + mp_printf(&mp_plat_print, "single_buffer: %d, samples_signed: %d, max_buffer_length: %d, dma->sample_spacing: %d\n", + single_buffer, samples_signed, max_buffer_length, dma->sample_spacing); //// // Check to see if we have to scale the resolution up. + mp_printf(&mp_plat_print, "dma->sample_resolution: %d, dma->output_resolution: %d, output_signed: %d, single_channel_output: %d\n", + dma->sample_resolution, dma->output_resolution, output_signed, single_channel_output); if (dma->sample_resolution <= 8 && dma->output_resolution > 8) { max_buffer_length *= 2; } @@ -222,6 +239,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, } dma->first_buffer = (uint8_t *)m_realloc(dma->first_buffer, max_buffer_length); + dma->first_buffer_length = max_buffer_length; if (dma->first_buffer == NULL) { return AUDIO_DMA_MEMORY_ERROR; } @@ -229,6 +247,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, dma->first_buffer_free = true; if (!single_buffer) { dma->second_buffer = (uint8_t *)m_realloc(dma->second_buffer, max_buffer_length); + dma->second_buffer_length = max_buffer_length; if (dma->second_buffer == NULL) { return AUDIO_DMA_MEMORY_ERROR; } diff --git a/ports/raspberrypi/audio_dma.h b/ports/raspberrypi/audio_dma.h index f84f6debeb..9df19d2299 100644 --- a/ports/raspberrypi/audio_dma.h +++ b/ports/raspberrypi/audio_dma.h @@ -48,7 +48,9 @@ typedef struct { uint8_t output_resolution; // in bits uint8_t sample_resolution; // in bits uint8_t *first_buffer; + size_t first_buffer_length; uint8_t *second_buffer; + size_t second_buffer_length; background_callback_t callback; } audio_dma_t; From 59b89fdc5c6a47737d69b3aa11c3c5f0b0d8a008 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 30 Jul 2021 13:54:33 -0400 Subject: [PATCH 35/63] Fix various audio DMA issues: RP2040 and SAMD51: - Detect when DMA has finished, and stop DMA audio explicitly. - Do not accidentally reuse `first_buffer` supplied by WaveFile or RawSample. Always realloc `first_buffer` and `second_buffer` RP2040: - When audio playing is stopped, write a final zero to the output register. This prevents residual PWM tones. - Handle buffer size for 8-bit samples properly for 16-bit output. - Fail on some edge cases (which may not be possible at the moment). --- ports/atmel-samd/audio_dma.c | 8 +++- .../atmel-samd/common-hal/audiobusio/I2SOut.c | 4 +- ports/raspberrypi/audio_dma.c | 37 +++++++++++-------- ports/raspberrypi/audio_dma.h | 1 + 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c index fc57e404f7..e03800f202 100644 --- a/ports/atmel-samd/audio_dma.c +++ b/ports/atmel-samd/audio_dma.c @@ -157,7 +157,13 @@ void audio_dma_load_next_block(audio_dma_t *dma) { if (dma->loop) { audiosample_reset_buffer(dma->sample, dma->single_channel_output, dma->audio_channel); } else { - descriptor->DESCADDR.reg = 0; + if ((output_buffer_length == 0) && dma_transfer_status(SHARED_RX_CHANNEL) & 0x3) { + // Nothing further to read and previous buffer is finished. + audio_dma_stop(dma); + } else { + // Break descriptor chain. + descriptor->DESCADDR.reg = 0; + } } } descriptor->BTCTRL.bit.VALID = true; diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c index 7a10ea81d7..15a22744f1 100644 --- a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c +++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -44,7 +44,7 @@ #include "atmel_start_pins.h" #include "hal/include/hal_gpio.h" -#include "hpl/gclk/hpl_gclk_base.h" +#include "hpl//hpl_gclk_base.h" #include "peripheral_clk_config.h" #ifdef SAMD21 @@ -379,7 +379,7 @@ void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t *self) { } #endif disconnect_gclk_from_peripheral(self->gclk, I2S_GCLK_ID_0 + self->clock_unit); - disable_gclk(self->gclk); + disable_clock_generator(self->gclk); #ifdef SAM_D5X_E5X connect_gclk_to_peripheral(5, I2S_GCLK_ID_0 + self->clock_unit); diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index c2ff957622..e55f4e0dc6 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -150,15 +150,7 @@ void audio_dma_load_next_block(audio_dma_t *dma) { audio_dma_stop(dma); return; } - bool busy0 = dma_channel_is_busy(dma->channel[0]); - bool busy1 = dma_channel_is_busy(dma->channel[1]); - if (busy0 == busy1) { - mp_printf(&mp_plat_print, "busy: %d %d\n", busy0, busy1); - } - if (buffer_length < 256) { - mp_printf(&mp_plat_print, "%d length: %d\n", dma->first_channel_free, buffer_length); - } audio_dma_convert_signed(dma, buffer, buffer_length, &output_buffer, &output_buffer_length); // If we don't have an output buffer, save the pointer to first_buffer for use in the single @@ -169,13 +161,21 @@ void audio_dma_load_next_block(audio_dma_t *dma) { dma_channel_set_trans_count(dma_channel, output_buffer_length / dma->output_size, false /* trigger */); dma_channel_set_read_addr(dma_channel, output_buffer, false /* trigger */); + if (get_buffer_result == GET_BUFFER_DONE) { if (dma->loop) { audiosample_reset_buffer(dma->sample, dma->single_channel_output, dma->audio_channel); } else { - // Set channel trigger to ourselves so we don't keep going. - dma_channel_hw_t *c = &dma_hw->ch[dma_channel]; - c->al1_ctrl = (c->al1_ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (dma_channel << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB); + if (output_buffer_length == 0 && + !dma_channel_is_busy(dma->channel[0]) && + !dma_channel_is_busy(dma->channel[1])) { + // No data has been read, and both DMA channels have now finished, so it's safe to stop. + audio_dma_stop(dma); + } else { + // Set channel trigger to ourselves so we don't keep going. + dma_channel_hw_t *c = &dma_hw->ch[dma_channel]; + c->al1_ctrl = (c->al1_ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (dma_channel << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB); + } } } } @@ -217,6 +217,8 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, dma->first_channel_free = true; dma->output_resolution = output_resolution; dma->sample_resolution = audiosample_bits_per_sample(sample); + dma->output_register_address = output_register_address; + audiosample_reset_buffer(sample, single_channel_output, audio_channel); bool single_buffer; @@ -224,11 +226,8 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, uint32_t max_buffer_length; audiosample_get_buffer_structure(sample, single_channel_output, &single_buffer, &samples_signed, &max_buffer_length, &dma->sample_spacing); - mp_printf(&mp_plat_print, "single_buffer: %d, samples_signed: %d, max_buffer_length: %d, dma->sample_spacing: %d\n", - single_buffer, samples_signed, max_buffer_length, dma->sample_spacing); //// + // Check to see if we have to scale the resolution up. - mp_printf(&mp_plat_print, "dma->sample_resolution: %d, dma->output_resolution: %d, output_signed: %d, single_channel_output: %d\n", - dma->sample_resolution, dma->output_resolution, output_signed, single_channel_output); if (dma->sample_resolution <= 8 && dma->output_resolution > 8) { max_buffer_length *= 2; } @@ -343,6 +342,14 @@ void audio_dma_stop(audio_dma_t *dma) { if (dma_channel_is_busy(channel)) { dma_channel_abort(channel); } + + // Write a zero as the last sample. This stops any PWM output. + if (dma->output_resolution <= 8) { + *((uint8_t *)dma->output_register_address) = 0; + } else { + *((uint16_t *)dma->output_register_address) = 0; + } + dma_channel_set_read_addr(channel, NULL, false /* trigger */); dma_channel_set_write_addr(channel, NULL, false /* trigger */); dma_channel_set_trans_count(channel, 0, false /* trigger */); diff --git a/ports/raspberrypi/audio_dma.h b/ports/raspberrypi/audio_dma.h index 9df19d2299..c3c0344096 100644 --- a/ports/raspberrypi/audio_dma.h +++ b/ports/raspberrypi/audio_dma.h @@ -51,6 +51,7 @@ typedef struct { size_t first_buffer_length; uint8_t *second_buffer; size_t second_buffer_length; + uint32_t output_register_address; background_callback_t callback; } audio_dma_t; From 2451c788f42146d26dc9ae9bfd944a5734c5b985 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 3 Aug 2021 19:12:14 -0400 Subject: [PATCH 36/63] valid channels in audio_dma_stop; cleaner supervisor_ticks mgmt in keypad --- .../atmel-samd/common-hal/audiobusio/I2SOut.c | 2 +- ports/raspberrypi/audio_dma.c | 29 ++++++++++++------- ports/raspberrypi/audio_dma.h | 1 + .../common-hal/audiopwmio/PWMAudioOut.c | 1 - shared-module/keypad/KeyMatrix.c | 2 -- shared-module/keypad/Keys.c | 2 -- shared-module/keypad/ShiftRegisterKeys.c | 2 -- shared-module/keypad/__init__.c | 13 +++++---- 8 files changed, 28 insertions(+), 24 deletions(-) diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c index 15a22744f1..a434e2541b 100644 --- a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c +++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -44,7 +44,7 @@ #include "atmel_start_pins.h" #include "hal/include/hal_gpio.h" -#include "hpl//hpl_gclk_base.h" +#include "hpl/gclk/hpl_gclk_base.h" #include "peripheral_clk_config.h" #ifdef SAMD21 diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index e55f4e0dc6..da3d851392 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -37,10 +37,8 @@ #if CIRCUITPY_AUDIOPWMIO || CIRCUITPY_AUDIOBUSIO -#define AUDIO_DMA_CHANNEL_COUNT NUM_DMA_CHANNELS - void audio_dma_reset(void) { - for (size_t channel = 0; channel < AUDIO_DMA_CHANNEL_COUNT; channel++) { + for (size_t channel = 0; channel < NUM_DMA_CHANNELS; channel++) { if (MP_STATE_PORT(playing_audio)[channel] == NULL) { continue; } @@ -171,6 +169,7 @@ void audio_dma_load_next_block(audio_dma_t *dma) { !dma_channel_is_busy(dma->channel[1])) { // No data has been read, and both DMA channels have now finished, so it's safe to stop. audio_dma_stop(dma); + dma->playing_in_progress = false; } else { // Set channel trigger to ourselves so we don't keep going. dma_channel_hw_t *c = &dma_hw->ch[dma_channel]; @@ -318,6 +317,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, irq_set_mask_enabled(1 << DMA_IRQ_0, true); } + dma->playing_in_progress = true; dma_channel_start(dma->channel[0]); return AUDIO_DMA_OK; @@ -325,7 +325,14 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, void audio_dma_stop(audio_dma_t *dma) { // Disable our interrupts. - dma_hw->inte0 &= ~((1 << dma->channel[0]) | (1 << dma->channel[1])); + uint32_t channel_mask = 0; + if (dma->channel[0] < NUM_DMA_CHANNELS) { + channel_mask |= 1 << dma->channel[0]; + } + if (dma->channel[1] < NUM_DMA_CHANNELS) { + channel_mask |= 1 << dma->channel[1]; + } + dma_hw->inte0 &= ~channel_mask; irq_set_mask_enabled(1 << DMA_IRQ_0, false); // Run any remaining audio tasks because we remove ourselves from @@ -334,6 +341,10 @@ void audio_dma_stop(audio_dma_t *dma) { for (size_t i = 0; i < 2; i++) { size_t channel = dma->channel[i]; + if (channel == NUM_DMA_CHANNELS) { + // Channel not in use. + continue; + } dma_channel_config c = dma_channel_get_default_config(dma->channel[i]); channel_config_set_enable(&c, false); @@ -357,6 +368,7 @@ void audio_dma_stop(audio_dma_t *dma) { MP_STATE_PORT(playing_audio)[channel] = NULL; dma->channel[i] = NUM_DMA_CHANNELS; } + dma->playing_in_progress = false; // Hold onto our buffers. } @@ -381,7 +393,7 @@ void audio_dma_resume(audio_dma_t *dma) { } bool audio_dma_get_paused(audio_dma_t *dma) { - if (dma->channel[0] >= AUDIO_DMA_CHANNEL_COUNT) { + if (dma->channel[0] >= NUM_DMA_CHANNELS) { return false; } uint32_t control = dma_hw->ch[dma->channel[0]].ctrl_trig; @@ -408,12 +420,7 @@ bool audio_dma_get_playing(audio_dma_t *dma) { if (dma->channel[0] == NUM_DMA_CHANNELS) { return false; } - if (!dma_channel_is_busy(dma->channel[0]) && - !dma_channel_is_busy(dma->channel[1])) { - return false; - } - - return true; + return dma->playing_in_progress; } // WARN(tannewt): DO NOT print from here, or anything it calls. Printing calls diff --git a/ports/raspberrypi/audio_dma.h b/ports/raspberrypi/audio_dma.h index c3c0344096..1ef1ca6d29 100644 --- a/ports/raspberrypi/audio_dma.h +++ b/ports/raspberrypi/audio_dma.h @@ -45,6 +45,7 @@ typedef struct { bool output_signed; bool first_channel_free; bool first_buffer_free; + bool playing_in_progress; uint8_t output_resolution; // in bits uint8_t sample_resolution; // in bits uint8_t *first_buffer; diff --git a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c index 3a8a7ef226..efaeb5ef35 100644 --- a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c @@ -38,7 +38,6 @@ #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" -#include "supervisor/shared/tick.h" #include "supervisor/shared/translate.h" #include "src/rp2040/hardware_structs/include/hardware/structs/dma.h" diff --git a/shared-module/keypad/KeyMatrix.c b/shared-module/keypad/KeyMatrix.c index 88e9d09a83..6db012d0f6 100644 --- a/shared-module/keypad/KeyMatrix.c +++ b/shared-module/keypad/KeyMatrix.c @@ -77,8 +77,6 @@ void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint // Add self to the list of active keypad scanners. keypad_register_scanner((keypad_scanner_obj_t *)self); - - supervisor_enable_tick(); } void common_hal_keypad_keymatrix_deinit(keypad_keymatrix_obj_t *self) { diff --git a/shared-module/keypad/Keys.c b/shared-module/keypad/Keys.c index 1f232a03ed..2880d18de5 100644 --- a/shared-module/keypad/Keys.c +++ b/shared-module/keypad/Keys.c @@ -63,8 +63,6 @@ void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pin // Add self to the list of active keypad scanners. keypad_register_scanner((keypad_scanner_obj_t *)self); - - supervisor_enable_tick(); } void common_hal_keypad_keys_deinit(keypad_keys_obj_t *self) { diff --git a/shared-module/keypad/ShiftRegisterKeys.c b/shared-module/keypad/ShiftRegisterKeys.c index 074f226998..5075437214 100644 --- a/shared-module/keypad/ShiftRegisterKeys.c +++ b/shared-module/keypad/ShiftRegisterKeys.c @@ -71,8 +71,6 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_ // Add self to the list of active keypad scanners. keypad_register_scanner((keypad_scanner_obj_t *)self); - - supervisor_enable_tick(); } void common_hal_keypad_shiftregisterkeys_deinit(keypad_shiftregisterkeys_obj_t *self) { diff --git a/shared-module/keypad/__init__.c b/shared-module/keypad/__init__.c index fc41396617..e239c56b61 100644 --- a/shared-module/keypad/__init__.c +++ b/shared-module/keypad/__init__.c @@ -57,12 +57,9 @@ void keypad_tick(void) { } void keypad_reset(void) { - if (MP_STATE_VM(keypad_scanners_linked_list)) { - supervisor_disable_tick(); + while (MP_STATE_VM(keypad_scanners_linked_list)) { + keypad_deregister_scanner(MP_STATE_VM(keypad_scanners_linked_list)); } - - MP_STATE_VM(keypad_scanners_linked_list) = NULL; - keypad_scanners_linked_list_lock = false; } // Register a Keys, KeyMatrix, etc. that will be scanned in the background @@ -71,10 +68,16 @@ void keypad_register_scanner(keypad_scanner_obj_t *scanner) { scanner->next = MP_STATE_VM(keypad_scanners_linked_list); MP_STATE_VM(keypad_scanners_linked_list) = scanner; supervisor_release_lock(&keypad_scanners_linked_list_lock); + + // One more request for ticks. + supervisor_enable_tick(); } // Remove scanner from the list of active scanners. void keypad_deregister_scanner(keypad_scanner_obj_t *scanner) { + // One less request for ticks. + supervisor_disable_tick(); + supervisor_acquire_lock(&keypad_scanners_linked_list_lock); if (MP_STATE_VM(keypad_scanners_linked_list) == scanner) { // Scanner is at the front; splice it out. From 6764af182a95cce1f106a2cbcbecc3c7d9595f3e Mon Sep 17 00:00:00 2001 From: Eddie Espinal Date: Mon, 9 Aug 2021 11:31:20 -0400 Subject: [PATCH 37/63] Fixes the MOSI and MISO pins. By mistake I added them backward in this mapping --- ports/esp32s2/boards/atmegazero_esp32s2/pins.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/esp32s2/boards/atmegazero_esp32s2/pins.c b/ports/esp32s2/boards/atmegazero_esp32s2/pins.c index cfc4ef6223..96dd940985 100644 --- a/ports/esp32s2/boards/atmegazero_esp32s2/pins.c +++ b/ports/esp32s2/boards/atmegazero_esp32s2/pins.c @@ -64,9 +64,9 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_DAC2), MP_ROM_PTR(&pin_GPIO18) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO40) }, From 32ee06b293b2ff2d619835bf4b9c25f0ec09d36e Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Mon, 9 Aug 2021 22:53:23 +0530 Subject: [PATCH 38/63] fix crash when traceback object is supplied --- shared-bindings/traceback/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/traceback/__init__.c b/shared-bindings/traceback/__init__.c index 828d6bc28e..dc5be20a88 100644 --- a/shared-bindings/traceback/__init__.c +++ b/shared-bindings/traceback/__init__.c @@ -57,7 +57,7 @@ STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj } exc.traceback = MP_OBJ_TO_PTR(tb_obj); } else { - exc.traceback = NULL; + exc.traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; } shared_module_traceback_print_exception(&exc, print, limit); From 185d0f2a24ddfdad831dd614325416b97039083a Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 9 Aug 2021 21:04:49 +0200 Subject: [PATCH 39/63] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 6 +++++- locale/cs.po | 6 +++++- locale/de_DE.po | 6 +++++- locale/el.po | 6 +++++- locale/en_GB.po | 6 +++++- locale/es.po | 6 +++++- locale/fil.po | 6 +++++- locale/fr.po | 6 +++++- locale/hi.po | 6 +++++- locale/it_IT.po | 6 +++++- locale/ja.po | 6 +++++- locale/ko.po | 6 +++++- locale/nl.po | 6 +++++- locale/pl.po | 6 +++++- locale/pt_BR.po | 6 +++++- locale/sv.po | 6 +++++- locale/zh_Latn_pinyin.po | 6 +++++- 17 files changed, 85 insertions(+), 17 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index dac73ad20c..9c5a6ebd87 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -325,6 +325,10 @@ msgstr "'yield from' di dalam fungsi async" msgid "'yield' outside function" msgstr "'yield' diluar fungsi" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x harus menjadi target assignment" @@ -4353,7 +4357,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index 63e7948ad8..dca71d3f83 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -321,6 +321,10 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -4313,7 +4317,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 7c47677538..f5635c2936 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -327,6 +327,10 @@ msgstr "'yield from' innerhalb einer async Funktion" msgid "'yield' outside function" msgstr "'yield' außerhalb einer Funktion" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x muss Zuordnungsziel sein" @@ -4389,7 +4393,7 @@ msgid "unreadable attribute" msgstr "nicht lesbares Attribut" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Nicht unterstützter %q-Typ" diff --git a/locale/el.po b/locale/el.po index 8bd093b1a5..2dd32e422c 100644 --- a/locale/el.po +++ b/locale/el.po @@ -318,6 +318,10 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -4310,7 +4314,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/en_GB.po b/locale/en_GB.po index f82ab09599..c0215dbec2 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -327,6 +327,10 @@ msgstr "'yield from' inside async function" msgid "'yield' outside function" msgstr "'yield' outside function" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x must be assignment target" @@ -4347,7 +4351,7 @@ msgid "unreadable attribute" msgstr "unreadable attribute" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "unsupported %q type" diff --git a/locale/es.po b/locale/es.po index 4107a1fd09..1f04cf018f 100644 --- a/locale/es.po +++ b/locale/es.po @@ -329,6 +329,10 @@ msgstr "'yield from' dentro de una función asincrónica" msgid "'yield' outside function" msgstr "'yield' fuera de una función" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x debe ser objetivo de la tarea" @@ -4402,7 +4406,7 @@ msgid "unreadable attribute" msgstr "atributo no legible" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo de %q no soportado" diff --git a/locale/fil.po b/locale/fil.po index c4c6a4c2b3..7cf59f900a 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -320,6 +320,10 @@ msgstr "" msgid "'yield' outside function" msgstr "'yield' sa labas ng function" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x ay dapat na assignment target" @@ -4361,7 +4365,7 @@ msgid "unreadable attribute" msgstr "hindi mabasa ang attribute" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Hindi supportadong tipo ng %q" diff --git a/locale/fr.po b/locale/fr.po index 7c70440b55..7c7bc0f7e0 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -329,6 +329,10 @@ msgstr "'yield from' dans une fonction async" msgid "'yield' outside function" msgstr "'yield' dehors d'une fonction" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x doit être la cible de l'assignement" @@ -4413,7 +4417,7 @@ msgid "unreadable attribute" msgstr "attribut illisible" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "type %q non pris on charge" diff --git a/locale/hi.po b/locale/hi.po index 4332db579e..1ba411f6bc 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -318,6 +318,10 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -4310,7 +4314,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index a7dc7c05e1..b89cbbbd26 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -329,6 +329,10 @@ msgstr "'yield from' è nella funzione sincronizzazione" msgid "'yield' outside function" msgstr "'yield' al di fuori della funzione" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x deve essere il bersaglio del assegnamento" @@ -4379,7 +4383,7 @@ msgid "unreadable attribute" msgstr "attributo non leggibile" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo di %q non supportato" diff --git a/locale/ja.po b/locale/ja.po index 2844e59dea..1e66015081 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -323,6 +323,10 @@ msgstr "" msgid "'yield' outside function" msgstr "関数外でのyield" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*xは代入先でなければなりません" @@ -4333,7 +4337,7 @@ msgid "unreadable attribute" msgstr "読み込み不可能な属性" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "非対応の型 %q" diff --git a/locale/ko.po b/locale/ko.po index 6f0f95e382..8f33e79adc 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -319,6 +319,10 @@ msgstr "" msgid "'yield' outside function" msgstr "'yield' 는 함수 외부에 존재합니다" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -4314,7 +4318,7 @@ msgid "unreadable attribute" msgstr "" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index c3cefa3327..3eb6d54b87 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -321,6 +321,10 @@ msgstr "'yield from' binnen asynchrone functie" msgid "'yield' outside function" msgstr "'yield' buiten de functie" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x moet een assignment target zijn" @@ -4358,7 +4362,7 @@ msgid "unreadable attribute" msgstr "onleesbaar attribuut" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "niet ondersteund %q type" diff --git a/locale/pl.po b/locale/pl.po index b1bbfaa015..290527b133 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -323,6 +323,10 @@ msgstr "'yield from' wewnątrz funkcji asynchronicznej" msgid "'yield' outside function" msgstr "'yield' poza funkcją" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x musi być obiektem przypisania" @@ -4330,7 +4334,7 @@ msgid "unreadable attribute" msgstr "nieczytelny atrybut" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "zły typ %q" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index c120f92ec0..be14ce3e28 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -331,6 +331,10 @@ msgstr "'yield a partir' de dentro da função async" msgid "'yield' outside function" msgstr "função externa 'yield'" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x deve ser o destino da atribuição" @@ -4412,7 +4416,7 @@ msgid "unreadable attribute" msgstr "atributo ilegível" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo %q não suportado" diff --git a/locale/sv.po b/locale/sv.po index aef7f24bd2..40bd71231c 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -326,6 +326,10 @@ msgstr "'yield from' i async-funktion" msgid "'yield' outside function" msgstr "'yield' utanför funktion" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x måste vara mål för tilldelning" @@ -4371,7 +4375,7 @@ msgid "unreadable attribute" msgstr "attribut kan inte läsas" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "typ %q stöds inte" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 67df4a18ba..802fa8cab0 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -328,6 +328,10 @@ msgstr "Yì bù hán shù zhōng de 'yield from'" msgid "'yield' outside function" msgstr "'yield' wàibù gōngnéng" +#: shared-module/vectorio/VectorShape.c +msgid "(x,y) integers required" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "*x bìxū shì rènwù mùbiāo" @@ -4371,7 +4375,7 @@ msgid "unreadable attribute" msgstr "bùkě dú shǔxìng" #: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -#: shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Polygon.c shared-module/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "bù zhīchí %q lèixíng" From 9fab48dad29c38d0db389ea4686e6009cdd4614b Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Mon, 9 Aug 2021 21:17:26 +0200 Subject: [PATCH 40/63] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 16 ++++++++-------- locale/cs.po | 16 ++++++++-------- locale/de_DE.po | 16 ++++++++-------- locale/el.po | 16 ++++++++-------- locale/en_GB.po | 16 ++++++++-------- locale/es.po | 16 ++++++++-------- locale/fil.po | 16 ++++++++-------- locale/fr.po | 16 ++++++++-------- locale/hi.po | 16 ++++++++-------- locale/it_IT.po | 16 ++++++++-------- locale/ja.po | 16 ++++++++-------- locale/ko.po | 16 ++++++++-------- locale/nl.po | 16 ++++++++-------- locale/pl.po | 16 ++++++++-------- locale/pt_BR.po | 19 +++++++++++-------- locale/sv.po | 19 +++++++++++-------- locale/zh_Latn_pinyin.po | 16 ++++++++-------- 17 files changed, 142 insertions(+), 136 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 9c5a6ebd87..15b6b6c1af 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -42,11 +42,11 @@ msgstr "" "Harap ajukan masalah dengan konten drive CIRCUITPY Anda di\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " File \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " File \"%q\", baris %d" @@ -333,7 +333,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x harus menjadi target assignment" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", dalam %q\n" @@ -2249,7 +2249,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (bagian terakhir dari panggilan terkini):\n" @@ -3499,10 +3499,6 @@ msgstr "" msgid "lhs and rhs should be compatible" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "" @@ -3950,6 +3946,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/cs.po b/locale/cs.po index dca71d3f83..cde1a48f52 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -38,11 +38,11 @@ msgstr "" "Založte prosím problém s obsahem vaší jednotky CIRCUITPY na adrese\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " Soubor \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " Soubor \"%q\", řádek %d" @@ -329,7 +329,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr "" @@ -2218,7 +2218,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "" @@ -3460,10 +3460,6 @@ msgstr "" msgid "lhs and rhs should be compatible" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "" @@ -3910,6 +3906,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/de_DE.po b/locale/de_DE.po index f5635c2936..921d509d2a 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -41,11 +41,11 @@ msgstr "" "Bitte melden Sie ein Problem mit dem Inhalt Ihres CIRCUITPY-Laufwerks unter\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " Datei \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " Datei \"%q\", Zeile %d" @@ -335,7 +335,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x muss Zuordnungsziel sein" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", in %q\n" @@ -2250,7 +2250,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Zurückverfolgung (jüngste Aufforderung zuletzt):\n" @@ -3523,10 +3523,6 @@ msgstr "Der Pegel muss zwischen 0 und 1 liegen" msgid "lhs and rhs should be compatible" msgstr "lhs und rhs sollten kompatibel sein" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "Lokales '%q' hat den Typ '%q', aber die Quelle ist '%q'" @@ -3979,6 +3975,10 @@ msgstr "pow () mit 3 Argumenten erfordert Integer" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/el.po b/locale/el.po index 2dd32e422c..0325c16161 100644 --- a/locale/el.po +++ b/locale/el.po @@ -35,11 +35,11 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr "" @@ -326,7 +326,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr "" @@ -2215,7 +2215,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "" @@ -3457,10 +3457,6 @@ msgstr "" msgid "lhs and rhs should be compatible" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "" @@ -3907,6 +3903,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/en_GB.po b/locale/en_GB.po index c0215dbec2..b24fd3b9fe 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -43,11 +43,11 @@ msgstr "" "Please file an issue with the contents of your CIRCUITPY drive at \n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " File \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " File \"%q\", line %d" @@ -335,7 +335,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x must be assignment target" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", in %q\n" @@ -2239,7 +2239,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (most recent call last):\n" @@ -3492,10 +3492,6 @@ msgstr "level must be between 0 and 1" msgid "lhs and rhs should be compatible" msgstr "lhs and rhs should be compatible" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "local '%q' has type '%q' but source is '%q'" @@ -3942,6 +3938,10 @@ msgstr "pow() with 3 arguments requires integers" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/es.po b/locale/es.po index 1f04cf018f..a0b4d585c6 100644 --- a/locale/es.po +++ b/locale/es.po @@ -44,11 +44,11 @@ msgstr "" "Presente un problema con el contenido de su unidad CIRCUITPY en\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " Archivo \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " Archivo \"%q\", línea %d" @@ -337,7 +337,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x debe ser objetivo de la tarea" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", en %q\n" @@ -2277,7 +2277,7 @@ msgstr "La cantidad total de datos es mas grande que %q" msgid "Touch alarms not available" msgstr "Alarmas táctiles no disponibles" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (ultima llamada reciente):\n" @@ -3542,10 +3542,6 @@ msgstr "el nivel debe ser entre 0 y 1" msgid "lhs and rhs should be compatible" msgstr "lhs y rhs deben ser compatibles" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "la variable local '%q' tiene el tipo '%q' pero la fuente es '%q'" @@ -3996,6 +3992,10 @@ msgstr "pow() con 3 argumentos requiere enteros" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/fil.po b/locale/fil.po index 7cf59f900a..14b9d5b6b0 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -34,11 +34,11 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " File \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " File \"%q\", line %d" @@ -328,7 +328,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x ay dapat na assignment target" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", sa %q\n" @@ -2235,7 +2235,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (pinakahuling huling tawag): \n" @@ -3502,10 +3502,6 @@ msgstr "" msgid "lhs and rhs should be compatible" msgstr "lhs at rhs ay dapat magkasundo" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "local '%q' ay may type '%q' pero ang source ay '%q'" @@ -3954,6 +3950,10 @@ msgstr "pow() na may 3 argumento kailangan ng integers" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/fr.po b/locale/fr.po index 7c7bc0f7e0..c004fd9c74 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -44,11 +44,11 @@ msgstr "" "l'adresse\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " Fichier \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " Fichier \"%q\", ligne %d" @@ -337,7 +337,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x doit être la cible de l'assignement" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", dans %q\n" @@ -2277,7 +2277,7 @@ msgstr "Quantité de données à écrire est plus que %q" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (appels les plus récents en dernier) :\n" @@ -3552,10 +3552,6 @@ msgstr "le niveau doit être compris entre 0 et 1" msgid "lhs and rhs should be compatible" msgstr "Les parties gauches et droites doivent être compatibles" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "la variable locale '%q' a le type '%q' mais la source est '%q'" @@ -4007,6 +4003,10 @@ msgstr "pow() avec 3 arguments nécessite des entiers" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/hi.po b/locale/hi.po index 1ba411f6bc..f84fa97fad 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -35,11 +35,11 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr "" @@ -326,7 +326,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr "" @@ -2215,7 +2215,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "" @@ -3457,10 +3457,6 @@ msgstr "" msgid "lhs and rhs should be compatible" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "" @@ -3907,6 +3903,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/it_IT.po b/locale/it_IT.po index b89cbbbd26..4a0593fd13 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -43,11 +43,11 @@ msgstr "" "Per favore, segnala il problema con il contenuto del tuo CIRCUITPY a\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " File \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " File \"%q\", riga %d" @@ -337,7 +337,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x deve essere il bersaglio del assegnamento" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", in %q\n" @@ -2256,7 +2256,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (chiamata più recente per ultima):\n" @@ -3516,10 +3516,6 @@ msgstr "" msgid "lhs and rhs should be compatible" msgstr "lhs e rhs devono essere compatibili" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "local '%q' ha tipo '%q' ma sorgente è '%q'" @@ -3972,6 +3968,10 @@ msgstr "pow() con 3 argomenti richiede interi" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/ja.po b/locale/ja.po index 1e66015081..74472f7973 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -40,11 +40,11 @@ msgstr "" "CIRCUITPYドライブの内容を添えて問題を以下で報告してください:\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " ファイル \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " ファイル \"%q\", 行 %d" @@ -331,7 +331,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*xは代入先でなければなりません" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr "" @@ -2229,7 +2229,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "トレースバック(最新の呼び出しが末尾):\n" @@ -3477,10 +3477,6 @@ msgstr "levelは0から1の間でなければなりません" msgid "lhs and rhs should be compatible" msgstr "左辺と右辺が互換でなければなりません" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "" @@ -3929,6 +3925,10 @@ msgstr "pow()の第3引数には整数が必要" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/ko.po b/locale/ko.po index 8f33e79adc..a87bd2dbb9 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -36,11 +36,11 @@ msgid "" "https://github.com/adafruit/circuitpython/issues\n" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " 파일 \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " 파일 \"%q\", 라인 %d" @@ -327,7 +327,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", 에서 %q\n" @@ -2218,7 +2218,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "" @@ -3461,10 +3461,6 @@ msgstr "" msgid "lhs and rhs should be compatible" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "" @@ -3911,6 +3907,10 @@ msgstr "" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/nl.po b/locale/nl.po index 3eb6d54b87..6b7f41a45f 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -38,11 +38,11 @@ msgstr "" "Meld een probleem met de inhoud van de CIRCUITPY drive op:\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " Bestand" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " Bestand \"%q\", regel %d" @@ -329,7 +329,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x moet een assignment target zijn" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", in %q\n" @@ -2241,7 +2241,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (meest recente call laatst):\n" @@ -3502,10 +3502,6 @@ msgstr "level moet tussen 0 en 1 liggen" msgid "lhs and rhs should be compatible" msgstr "lhs en rhs moeten compatibel zijn" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "lokale '%q' is van type '%q' maar bron is '%q'" @@ -3953,6 +3949,10 @@ msgstr "pow() met 3 argumenten vereist integers" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/pl.po b/locale/pl.po index 290527b133..e05513b947 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -40,11 +40,11 @@ msgstr "" "Zgłoś problem z zawartością dysku CIRCUITPY pod adresem\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " Plik \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " Plik \"%q\", linia %d" @@ -331,7 +331,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x musi być obiektem przypisania" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", w %q\n" @@ -2226,7 +2226,7 @@ msgstr "" msgid "Touch alarms not available" msgstr "" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Ślad wyjątku (najnowsze wywołanie na końcu):\n" @@ -3475,10 +3475,6 @@ msgstr "" msgid "lhs and rhs should be compatible" msgstr "lewa i prawa strona powinny być kompatybilne" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "local '%q' jest typu '%q' lecz źródło jest '%q'" @@ -3926,6 +3922,10 @@ msgstr "trzyargumentowe pow() wymaga liczb całkowitych" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h diff --git a/locale/pt_BR.po b/locale/pt_BR.po index be14ce3e28..f1ef5661b2 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -42,11 +42,11 @@ msgstr "" "Registre um problema com o conteúdo do seu controlador no CIRCUITPY\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " Arquivo \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " Arquivo \"%q\", linha %d" @@ -339,7 +339,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x deve ser o destino da atribuição" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", em %q\n" @@ -2280,7 +2280,7 @@ msgstr "O total dos dados que serão escritos é maior do que %q" msgid "Touch alarms not available" msgstr "Alarmes de toque não estão disponíveis" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (a última chamada mais recente):\n" @@ -3550,10 +3550,6 @@ msgstr "o nível deve estar entre 0 e 1" msgid "lhs and rhs should be compatible" msgstr "o lhs e rhs devem ser compatíveis" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "o limite deve ser um inteiro" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "o local '%q' tem o tipo '%q', porém a origem é '%q'" @@ -4007,6 +4003,10 @@ msgstr "o pow() com 3 argumentos requer números inteiros" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4537,6 +4537,9 @@ msgstr "zi deve ser de um tipo float" msgid "zi must be of shape (n_section, 2)" msgstr "zi deve estar na forma (n_section, 2)" +#~ msgid "limit should be an int" +#~ msgstr "o limite deve ser um inteiro" + #~ msgid "no available NIC" #~ msgstr "não há uma Placa de Rede disponível" diff --git a/locale/sv.po b/locale/sv.po index 40bd71231c..149ccc7213 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -42,11 +42,11 @@ msgstr "" "Vänligen skapa ett ärende med innehållet i din CIRCUITPY-enhet på\n" "https://github.com/adafruit/circuitpython/issues\n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " Filen \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " Fil \"%q\", rad %d" @@ -334,7 +334,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x måste vara mål för tilldelning" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", i %q\n" @@ -2255,7 +2255,7 @@ msgstr "Totala data att skriva är större än %q" msgid "Touch alarms not available" msgstr "Touchalarm är inte tillgängligt" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (senaste anrop):\n" @@ -3515,10 +3515,6 @@ msgstr "level ska ligga mellan 0 och 1" msgid "lhs and rhs should be compatible" msgstr "lhs och rhs måste vara kompatibla" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "limit måste vara en int" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "lokala '%q' har typ '%q' men källan är '%q'" @@ -3966,6 +3962,10 @@ msgstr "pow() med 3 argument kräver heltal" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h @@ -4496,6 +4496,9 @@ msgstr "zi måste vara av typ float" msgid "zi must be of shape (n_section, 2)" msgstr "zi måste vara i formen (n_section, 2)" +#~ msgid "limit should be an int" +#~ msgstr "limit måste vara en int" + #~ msgid "no available NIC" #~ msgstr "ingen tillgänglig NIC" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 802fa8cab0..ffb56a0efc 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -43,11 +43,11 @@ msgstr "" "Qǐng tōngguò https://github.com/adafruit/circuitpython/issues\n" "tíjiāo yǒuguān nín de CIRCUITPY qūdòngqì nèiróng de wèntí \n" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\"" msgstr " Wénjiàn \"%q\"" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid " File \"%q\", line %d" msgstr " Wénjiàn \"%q\", dì %d xíng" @@ -336,7 +336,7 @@ msgstr "" msgid "*x must be assignment target" msgstr "*x bìxū shì rènwù mùbiāo" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid ", in %q\n" msgstr ", zài %q\n" @@ -2256,7 +2256,7 @@ msgstr "yào biān xiě de zǒng shù jù dà yú %q" msgid "Touch alarms not available" msgstr "bù kě yòng chù mō bào jǐng qì" -#: py/obj.c shared-bindings/traceback/__init__.c +#: py/obj.c msgid "Traceback (most recent call last):\n" msgstr "Traceback (Zuìjìn yīcì dǎ diànhuà):\n" @@ -3516,10 +3516,6 @@ msgstr "Level bìxū jiè yú 0 hé 1 zhī jiān" msgid "lhs and rhs should be compatible" msgstr "lhs hé rhs yīnggāi jiānróng" -#: shared-bindings/traceback/__init__.c -msgid "limit should be an int" -msgstr "" - #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" msgstr "bendì '%q' bāohán lèixíng '%q' dàn yuán shì '%q'" @@ -3966,6 +3962,10 @@ msgstr "pow() yǒu 3 cānshù xūyào zhěngshù" #: ports/esp32s2/boards/espressif_saola_1_wrover/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wroom/mpconfigboard.h #: ports/esp32s2/boards/franzininho_wifi_wrover/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_m/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_ms/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_r/mpconfigboard.h +#: ports/esp32s2/boards/gravitech_cucumber_rs/mpconfigboard.h #: ports/esp32s2/boards/lilygo_ttgo_t8_s2_st7789/mpconfigboard.h #: ports/esp32s2/boards/microdev_micro_s2/mpconfigboard.h #: ports/esp32s2/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.h From aec965e6d9f69a2342810d5f29c021758b50e28a Mon Sep 17 00:00:00 2001 From: Pierre Constantineau Date: Mon, 9 Aug 2021 15:25:06 -0600 Subject: [PATCH 41/63] changed PID as suggested by Scott --- ports/nrf/boards/bluemicro840/mpconfigboard.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/nrf/boards/bluemicro840/mpconfigboard.mk b/ports/nrf/boards/bluemicro840/mpconfigboard.mk index a95662f5fd..16d36704a3 100644 --- a/ports/nrf/boards/bluemicro840/mpconfigboard.mk +++ b/ports/nrf/boards/bluemicro840/mpconfigboard.mk @@ -1,5 +1,5 @@ USB_VID = 0x1D50 -USB_PID = 0x6160 +USB_PID = 0x6161 USB_PRODUCT = "BlueMicro840" USB_MANUFACTURER = "nrf52.jpconstantineau.com" From 46ad22143adcb9d5ae3dc3fe1d42b9a39ccc4a9b Mon Sep 17 00:00:00 2001 From: Wellington Terumi Uemura Date: Mon, 9 Aug 2021 21:37:32 +0000 Subject: [PATCH 42/63] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1013 of 1013 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/pt_BR/ --- locale/pt_BR.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locale/pt_BR.po b/locale/pt_BR.po index f1ef5661b2..c2fe4e330f 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-08-08 05:33+0000\n" +"PO-Revision-Date: 2021-08-10 02:41+0000\n" "Last-Translator: Wellington Terumi Uemura \n" "Language-Team: \n" "Language: pt_BR\n" @@ -333,7 +333,7 @@ msgstr "função externa 'yield'" #: shared-module/vectorio/VectorShape.c msgid "(x,y) integers required" -msgstr "" +msgstr "(x,y) é obrigatório o uso de números inteiros" #: py/compile.c msgid "*x must be assignment target" From f38436708617c09e4b742935bbdf4eb3f4d1fc32 Mon Sep 17 00:00:00 2001 From: Jonny Bergdahl Date: Mon, 9 Aug 2021 20:00:10 +0000 Subject: [PATCH 43/63] Translated using Weblate (Swedish) Currently translated at 100.0% (1013 of 1013 strings) Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/sv/ --- locale/sv.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locale/sv.po b/locale/sv.po index 149ccc7213..6c5463e5d4 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2021-08-07 04:00+0000\n" +"PO-Revision-Date: 2021-08-10 02:41+0000\n" "Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" "Language: sv\n" @@ -328,7 +328,7 @@ msgstr "'yield' utanför funktion" #: shared-module/vectorio/VectorShape.c msgid "(x,y) integers required" -msgstr "" +msgstr "(x,y) heltal krävs" #: py/compile.c msgid "*x must be assignment target" From 10884e0a0d365b123c1c4bd069c2177d2ebedb17 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Tue, 10 Aug 2021 04:41:03 +0200 Subject: [PATCH 44/63] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 2 +- locale/cs.po | 2 +- locale/de_DE.po | 2 +- locale/el.po | 2 +- locale/en_GB.po | 2 +- locale/es.po | 2 +- locale/fil.po | 2 +- locale/fr.po | 2 +- locale/hi.po | 2 +- locale/it_IT.po | 2 +- locale/ja.po | 2 +- locale/ko.po | 2 +- locale/nl.po | 2 +- locale/pl.po | 2 +- locale/pt_BR.po | 2 +- locale/sv.po | 2 +- locale/zh_Latn_pinyin.po | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/locale/ID.po b/locale/ID.po index 15b6b6c1af..99b3fea4f8 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -4148,7 +4148,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index cde1a48f52..352bb822f4 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -4108,7 +4108,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 921d509d2a..1655db5150 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -4179,7 +4179,7 @@ msgstr "stop muss 1 oder 2 sein" msgid "stop not reachable from start" msgstr "stop ist von start aus nicht erreichbar" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream operation ist nicht unterstützt" diff --git a/locale/el.po b/locale/el.po index 0325c16161..fb84d25d23 100644 --- a/locale/el.po +++ b/locale/el.po @@ -4105,7 +4105,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" diff --git a/locale/en_GB.po b/locale/en_GB.po index b24fd3b9fe..99f8d4c16a 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -4142,7 +4142,7 @@ msgstr "stop must be 1 or 2" msgid "stop not reachable from start" msgstr "stop not reachable from start" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream operation not supported" diff --git a/locale/es.po b/locale/es.po index a0b4d585c6..4212d45df6 100644 --- a/locale/es.po +++ b/locale/es.po @@ -4196,7 +4196,7 @@ msgstr "stop debe ser 1 ó 2" msgid "stop not reachable from start" msgstr "stop no se puede alcanzar del principio" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "operación stream no soportada" diff --git a/locale/fil.po b/locale/fil.po index 14b9d5b6b0..b7bc9f8428 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -4155,7 +4155,7 @@ msgstr "stop dapat 1 o 2" msgid "stop not reachable from start" msgstr "stop hindi maabot sa simula" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream operation hindi sinusuportahan" diff --git a/locale/fr.po b/locale/fr.po index c004fd9c74..694e71b840 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -4207,7 +4207,7 @@ msgstr "stop doit être 1 ou 2" msgid "stop not reachable from start" msgstr "stop n'est pas accessible au démarrage" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "opération de flux non supportée" diff --git a/locale/hi.po b/locale/hi.po index f84fa97fad..2fb00e2272 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -4105,7 +4105,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index 4a0593fd13..a8786c7e32 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -4173,7 +4173,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "stop non raggiungibile dall'inizio" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "operazione di stream non supportata" diff --git a/locale/ja.po b/locale/ja.po index 74472f7973..cfe5556941 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -4128,7 +4128,7 @@ msgstr "stopは1または2のいずれか" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "ストリーム操作は非対応" diff --git a/locale/ko.po b/locale/ko.po index a87bd2dbb9..b46d9f5d11 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -4109,7 +4109,7 @@ msgstr "" msgid "stop not reachable from start" msgstr "" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index 6b7f41a45f..ec26087cd6 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -4153,7 +4153,7 @@ msgstr "stop moet 1 of 2 zijn" msgid "stop not reachable from start" msgstr "stop is niet bereikbaar vanaf start" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream operatie niet ondersteund" diff --git a/locale/pl.po b/locale/pl.po index e05513b947..9a0f6614b8 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -4125,7 +4125,7 @@ msgstr "stop musi być 1 lub 2" msgid "stop not reachable from start" msgstr "stop nie jest osiągalne ze start" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "operacja na strumieniu nieobsługiwana" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index c2fe4e330f..49f333678d 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -4207,7 +4207,7 @@ msgstr "o stop deve ser 1 ou 2" msgid "stop not reachable from start" msgstr "stop não está acessível a partir do início" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "a operação do fluxo não é compatível" diff --git a/locale/sv.po b/locale/sv.po index 6c5463e5d4..15cb50e88d 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -4166,7 +4166,7 @@ msgstr "stop måste vara 1 eller 2" msgid "stop not reachable from start" msgstr "stop kan inte nås från start" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "stream-åtgärd stöds inte" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index ffb56a0efc..8ff9e807ca 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -4166,7 +4166,7 @@ msgstr "tíngzhǐ bìxū wèi 1 huò 2" msgid "stop not reachable from start" msgstr "tíngzhǐ wúfǎ cóng kāishǐ zhōng zhǎodào" -#: py/stream.c +#: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" msgstr "bù zhīchí liú cāozuò" From e741330ca8281defd33b18ba728ab25aa8d07e86 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Aug 2021 22:53:16 -0700 Subject: [PATCH 45/63] Consistent pin naming for SparkFun MicroMod processor boards. --- .../sparkfun_samd51_micromod/mpconfigboard.h | 5 +- .../sparkfun_samd51_micromod/mpconfigboard.mk | 2 +- .../boards/sparkfun_samd51_micromod/pins.c | 281 ++++++++++++----- .../sparkfun_nrf52840_micromod/README.md | 62 ++-- .../mpconfigboard.h | 5 +- .../mpconfigboard.mk | 2 +- .../boards/sparkfun_nrf52840_micromod/pins.c | 292 ++++++++++++------ .../sparkfun_micromod_rp2040/mpconfigboard.h | 11 +- .../sparkfun_micromod_rp2040/mpconfigboard.mk | 4 +- .../boards/sparkfun_micromod_rp2040/pins.c | 288 ++++++++++++----- 10 files changed, 661 insertions(+), 291 deletions(-) diff --git a/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.h b/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.h index 1842629266..5344e3c1ca 100644 --- a/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.h +++ b/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.h @@ -1,8 +1,11 @@ -#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod SAMD51" +#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod SAMD51 Processor" #define MICROPY_HW_MCU_NAME "samd51j20" #define CIRCUITPY_MCU_FAMILY samd51 +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_PA23) + // On-board flash #define SPI_FLASH_MOSI_PIN &pin_PA09 #define SPI_FLASH_MISO_PIN &pin_PA10 diff --git a/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.mk index 63d52382a2..3ae3d8f5a9 100644 --- a/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_samd51_micromod/mpconfigboard.mk @@ -1,7 +1,7 @@ LD_FILE = boards/samd51x20-bootloader-external-flash.ld USB_VID = 0x1b4f USB_PID = 0x0020 # Used by uf2 bootloader -USB_PRODUCT = "SparkFun MicroMod SAMD51" +USB_PRODUCT = "SparkFun MicroMod SAMD51 Processor" USB_MANUFACTURER = "SparkFun Electronics" CHIP_VARIANT = SAMD51J20A diff --git a/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c b/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c index 49411217d7..2233635084 100644 --- a/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c +++ b/ports/atmel-samd/boards/sparkfun_samd51_micromod/pins.c @@ -1,97 +1,224 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Chris Wilson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "shared-bindings/board/__init__.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { - // D (digital only) pins (D0,D1) - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB04) }, - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB05) }, + // The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. + // The 0th peripheral is the default and the "0" is omitted from the + // peripheral name (e.g. "I2C" instead of "I2C0"). + // + // For more details, see https://www.sparkfun.com/micromod#tech-specs - // A (ADC) pins (A0-A4) - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB00) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB01) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB02) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB03) }, + // MicroMod built-in status LED pin + // Requirement from the "Designing with MicroMod" SparkFun article: + // "... every Processor Board shall include one status LED connected to a + // pin that is not connected to the board edge." + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA23) }, // MicroMod LED (PA23) - // DAC - { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pin_PA02) }, + // MicroMod USB bus input voltage (+5V) pin + // { MP_ROM_QSTR(MP_QSTR_USB_VIN), MP_ROM_PTR() }, // MicroMod USB_VIN (not connected) - // G (General/BUS) pins (G0-G9) - { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA15) }, - { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB08) }, - { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_PB08) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB09) }, - { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_PB09) }, - { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB10) }, - { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_PB10) }, - { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB11) }, - { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_PB11) }, - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB12) }, - { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_PB12) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB13) }, - { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_PB13) }, - { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA14) }, - { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_PA14) }, - { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA15) }, - { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_PA15) }, - { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_PB31) }, - { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_PB30) }, - { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_PB14) }, - { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_PB14) }, - { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_PB15) }, - { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_PB15) }, + // MicroMod +3.3V enable pin + { MP_ROM_QSTR(MP_QSTR_P3V3_EN), MP_ROM_PTR(&pin_PA19) }, // MicroMod 3.3V_EN (PA19) - // PWM pins (PWM0, PWM1) - { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_PB01) }, - { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_PB02) }, + // MicroMod battery voltage sense pin + { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_PB03) }, // MicroMod BATT_VIN/3 (PB03) - // AUD (audio) - { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR(&pin_PB17) }, - { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_PA21) }, - { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_PA22) }, - { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_PA20) }, - { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_PB16) }, + // MicroMod reset pin + // { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR() }, // MicroMod RESET# (SAMD51 has a dedicated HW RESETN pin) - // I2C - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA17) }, - { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_PA17) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA16) }, - { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_PA16) }, + // MicroMod boot pin + // { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR() }, // MicroMod BOOT (not connected) - { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_PA18) }, + // MicroMod USB device pins + // USB device is always used internally by CircuitPython, so skip creating + // the pin objects for it. See explicit ignores in mpconfigboard.h. + // { MP_ROM_QSTR(MP_QSTR_USB_DM), MP_ROM_PTR(&pin_PA24) }, // MicroMod USB_D- (PA24) + // { MP_ROM_QSTR(MP_QSTR_USB_DP), MP_ROM_PTR(&pin_PA25) }, // MicroMod USB_D+ (PA25) - // I2C2 - { MP_ROM_QSTR(MP_QSTR_SDA2), MP_ROM_PTR(&pin_PA13) }, - { MP_ROM_QSTR(MP_QSTR_SCL2), MP_ROM_PTR(&pin_PA12) }, + // MicroMod USB host pins + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DM), MP_ROM_PTR() }, // MicroMod USBHOST_D- (not connected) + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DP), MP_ROM_PTR() }, // MicroMod USBHOST_D+ (not connected) - // SPI - { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_PA04) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA04) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, - { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PA07) }, + // MicroMod CAN pins + { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB15) }, // MicroMod CAN_RX (PB15) + { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB14) }, // MicroMod CAN_TX (PB14) - // Status LED - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA23) }, + // Note: MicroMod UART (UART0) is not present in the edge connector pinout + // because the primary debug serial port is exposed as a virtual serial port + // over USB. - // UART - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB30) }, - { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PB30) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB31) }, - { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PB31) }, + // MicroMod UART1 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX1), MP_ROM_PTR(&pin_PB31) }, // MicroMod UART_TX1 | CircuitPython TX (PB31) + { MP_ROM_QSTR(MP_QSTR_UART_RX1), MP_ROM_PTR(&pin_PB30) }, // MicroMod UART_RX1 | CircuitPython RX (PB30) + // { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR() }, // MicroMod RTS1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR() }, // MicroMod CTS1 (not connected) - // UART2 - { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_PA13) }, - { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_PA12) }, + // CircuitPython default UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PB31) }, // CircuitPython TX | MicroMod UART_TX1 (PB31) + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PB30) }, // CircuitPython RX | MicroMod UART_RX1 (PB30) + // MicroMod UART2 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX2), MP_ROM_PTR(&pin_PA12) }, // MicroMod UART_TX2 (PA12) + { MP_ROM_QSTR(MP_QSTR_UART_RX2), MP_ROM_PTR(&pin_PA13) }, // MicroMod UART_RX2 (PA13) - // Board objects - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + // MicroMod I2C pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_PA17) }, // MicroMod I2C_SDA | CircuitPython SDA (PA17) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_PA16) }, // MicroMod I2C_SCL | CircuitPython SCL (PA16) + // CircuitPython default I2C pins + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA17) }, // CircuitPython SDA | MicroMod I2C_SDA (PA17) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA16) }, // CircuitPython SCL | MicroMod I2C_SCL (PA16) + + // MicroMod I2C interrupt pin + { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_PA18) }, // MicroMod I2C_INT (PA18) + + // MicroMod I2C1 pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA1), MP_ROM_PTR(&pin_PA13) }, // MicroMod I2C_SDA1 (PA13) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL1), MP_ROM_PTR(&pin_PA12) }, // MicroMod I2C_SCL1 (PA12) + + // MicroMod SPI pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO), MP_ROM_PTR(&pin_PA06) }, // MicroMod SPI_CIPO | CircuitPython CIPO (PA06) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_PA06) }, // MicroMod SPI_MISO | CircuitPython MISO (PA06) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI), MP_ROM_PTR(&pin_PA04) }, // MicroMod SPI_COPI | CircuitPython COPI | LED_DAT (PA04) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_PA04) }, // MicroMod SPI_MOSI | CircuitPython MOSI (PA04) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_PA05) }, // MicroMod SPI_SCK | CircuitPython SCK | LED_CLK (PA05) + { MP_ROM_QSTR(MP_QSTR_SPI_CS), MP_ROM_PTR(&pin_PA07) }, // MicroMod SPI_CS | CircuitPython CS (PA07) + + // CircuitPython default SPI pins + { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_PA06) }, // CircuitPython CIPO | MicroMod SPI_CIPO (PA06) + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) }, // CircuitPython MISO | MicroMod SPI_MISO (PA06) + { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_PA04) }, // CircuitPython COPI | MicroMod SPI_COPI | LED_DAT (PA04) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA04) }, // CircuitPython MOSI | MicroMod SPI_MOSI (PA04) + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, // CircuitPython SCK | MicroMod SPI_SCK | LED_CLK (PA05) + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PA07) }, // CircuitPython CS | MicroMod SPI_CS (PA07) + + // MicroMod 2-wire serial LED pins + { MP_ROM_QSTR(MP_QSTR_LED_DAT), MP_ROM_PTR(&pin_PA04) }, // MicroMod LED_DAT | SPI_COPI (PA04) + { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_PA05) }, // MicroMod LED_CLK | SPI_SCK (PA05) + + // MicroMod SDIO pins + // { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR() }, // MicroMod SDIO_SCK | SPI_SCK1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR() }, // MicroMod SDIO_CMD | SPI_COPI1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR() }, // MicroMod SDIO_DATA0 | SPI_CIPO1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR() }, // MicroMod SDIO_DATA1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR() }, // MicroMod SDIO_DATA2 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR() }, // MicroMod SDIO_DATA3 | SPI_CS1 (not connected) + + // MicroMod SPI1 pins + // { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR() }, // MicroMod SPI_CIPO1 | SDIO_DATA0 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_MISO1), MP_ROM_PTR() }, // MicroMod SPI_MISO1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR() }, // MicroMod SPI_COPI1 | SDIO_CMD (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_MOSI1), MP_ROM_PTR() }, // MicroMod SPI_MOSI1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR() }, // MicroMod SPI_SCK1 | SDIO_SCK (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR() }, // MicroMod SPI_CS1 | SDIO_DATA3 (not connected) + + // MicroMod audio pins + { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR(&pin_PB17) }, // MicroMod AUD_MCLK (PB17) + { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_PA21) }, // MicroMod AUD_OUT | I2S_OUT | PCM_OUT | CAM_MCLK (PA21) + { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_PA22) }, // MicroMod AUD_IN | I2S_IN | PCM_IN | CAM_PCLK (PA22) + { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_PA20) }, // MicroMod AUD_LRCLK | I2S_WS | PCM_SYNC | PDM_DATA (PA20) + { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_PB16) }, // MicroMod AUD_BCLK | I2S_SCK | PCM_CLK | PDM_CLK (PB16) + + // MicroMod I2S pins + { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR(&pin_PA21) }, // MicroMod I2S_OUT | AUD_OUT | PCM_OUT | CAM_MCLK (PA21) + { MP_ROM_QSTR(MP_QSTR_I2S_IN), MP_ROM_PTR(&pin_PA22) }, // MicroMod I2S_IN | AUD_IN | PCM_IN | CAM_PCLK (PA22) + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_PA20) }, // MicroMod I2S_WS | AUD_LRCLK | PCM_SYNC | PDM_DATA (PA20) + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_PB16) }, // MicroMod I2S_SCK | AUD_BCLK | PCM_CLK | PDM_CLK (PB16) + + // MicroMod PCM pins + { MP_ROM_QSTR(MP_QSTR_PCM_OUT), MP_ROM_PTR(&pin_PA21) }, // MicroMod PCM_OUT | AUD_OUT | I2S_OUT | CAM_MCLK (PA21) + { MP_ROM_QSTR(MP_QSTR_PCM_IN), MP_ROM_PTR(&pin_PA22) }, // MicroMod PCM_IN | AUD_IN | I2S_IN | CAM_PCLK (PA22) + { MP_ROM_QSTR(MP_QSTR_PCM_SYNC), MP_ROM_PTR(&pin_PA20) }, // MicroMod PCM_SYNC | AUD_LRCLK | I2S_WS | PDM_DATA (PA20) + { MP_ROM_QSTR(MP_QSTR_PCM_CLK), MP_ROM_PTR(&pin_PB16) }, // MicroMod PCM_CLK | AUD_BCLK | I2S_SCK | PDM_CLK (PB16) + + // MicroMod PDM pins + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_PA20) }, // MicroMod PDM_DATA | AUD_LRCLK | I2S_WS | PCM_SYNC (PA20) + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_PB16) }, // MicroMod PDM_CLK | AUD_BCLK | I2S_SCK | PCM_CLK (PB16) + + // MicroMod SWD pins + { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR(&pin_PA31) }, // MicroMod SWDIO (PA31) + { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR(&pin_PA30) }, // MicroMod SWDCK (PA30) + // { MP_ROM_QSTR(MP_QSTR_SWO), MP_ROM_PTR() }, // MicroMod SWO | G11 (not connected) + + // MicroMod ADC pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, // MicroMod A0 (PA02) + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB00) }, // MicroMod A1 (PB00) + + // MicroMod PWM pins + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_PB01) }, // MicroMod PWM0 (PB01) + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_PB02) }, // MicroMod PWM1 (PB02) + + // MicroMod digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB04) }, // MicroMod D0 (PB04) + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PB05) }, // MicroMod D1 | CAM_TRIG (PB05) + + // MicroMod general purpose pins + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_PB06) }, // MicroMod G0 | BUS0 (PB06) + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_PB07) }, // MicroMod G1 | BUS1 (PB07) + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_PB08) }, // MicroMod G2 | BUS2 (PB08) + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_PB09) }, // MicroMod G3 | BUS3 (PB09) + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_PB10) }, // MicroMod G4 | BUS4 (PB10) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_PB11) }, // MicroMod G5 | BUS5 (PB11) + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_PB12) }, // MicroMod G6 | BUS6 (PB12) + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_PB13) }, // MicroMod G7 | BUS7 (PB13) + { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_PA14) }, // MicroMod G8 (PA14) + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_PA15) }, // MicroMod G9 | ADC_D- | CAM_HSYNC (PA15) + // { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR() }, // MicroMod G10 | ADC_D+ | CAM_VSYNC (not connected) + { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_PA27) }, // MicroMod G11 | SWO (PA27) + + // MicroMod 8-bit bus pins + { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_PB06) }, // MicroMod BUS0 | G0 (PB06) + { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_PB07) }, // MicroMod BUS1 | G1 (PB07) + { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_PB08) }, // MicroMod BUS2 | G2 (PB08) + { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_PB09) }, // MicroMod BUS3 | G3 (PB09) + { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_PB10) }, // MicroMod BUS4 | G4 (PB10) + { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_PB11) }, // MicroMod BUS5 | G5 (PB11) + { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_PB12) }, // MicroMod BUS6 | G6 (PB12) + { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_PB13) }, // MicroMod BUS7 | G7 (PB13) + + // MicroMod differential ADC input pins + // { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_PA15) }, // MicroMod ADC_D- | G9 | CAM_HSYNC (PA15) + // { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR() }, // MicroMod ADC_D+ | G10 | CAM_VSYNC (not connected) + + // MicroMod camera pins + // { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR(&pin_PA21) }, // MicroMod CAM_MCLK | AUD_OUT | I2S_OUT | PCM_OUT (PA21) + // { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_PA22) }, // MicroMod CAM_PCLK | AUD_IN | I2S_IN | PCM_IN (PA22) + // { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_PB05) }, // MicroMod CAM_TRIG | D1 (PB05) + // { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_PA15 }, // MicroMod CAM_HSYNC | ADC_D- | G9 (PA15) + // { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR() }, // MicroMod CAM_VSYNC | ADC_D+ | G10 (not connected) + + // Module-specific aliases (not part of the MicroMod spec) + { MP_ROM_QSTR(MP_QSTR_HOST_ENABLE), MP_ROM_PTR(&pin_PA27) }, // HOST_ENABLE | G11 | SWO (PA27) + + // CircuitPython board objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, // CircuitPython I2C + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, // CircuitPython SPI + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, // CircuitPython UART }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md b/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md index 094102c277..5c41fdb7cf 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/README.md @@ -10,56 +10,64 @@ We've also routed two I2C buses, 2 SPI buses, eleven GPIO, dedicated CircuitPython pin definitions, while simialr to other boards represent a slight departure from just the typical `A` and `D` pin definitions. The majority of general pins are labled as `G` (or alternatively, `BUS`,) as the MicroMod system they build on uses those names to specify pins that may not be specficially analog or digital. -This can be somewhat confusing, especially around the analog pins. Here's a quick pin-map. This pin map will use the label either on the [SparkFun MicroMod ATP Carrier Board](https://www.sparkfun.com/products/16885), or the pin name on the [graphical datasheet](https://cdn.sparkfun.com/assets/learn_tutorials/1/4/0/1/MicroMod_nRF52840_v1.0_Graphical_Datasheet.pdf). Some of the aditional aliases are just names to make naming consistent (e.g.: RTS/CTS), but they also can refer to additional functionality a pin may have (e.g.: NFC pins) +This can be somewhat confusing, especially around the analog pins. Here's a quick pin-map: MicroMod Pin # | ATP Pin Label | Pin Definition | Additional Definitons | Pin/Port Reference | Notes :--------------|:--------------|:--------------|:-----------------------|:-------------------|:------ 8 | G11 | | | (Not Connected) | 10 | D0 | D0 | | P0_27 | -11 | BOOT | BOOT | BUTTON1 | P0_07 | -12 | SDA | SDA | | P0_08 | -13 | RTS1 | RTS | RTS1 | P1_02 | -14 | SCL | SCL | | P0_11 | -15 | CTS1 | CTS | CTS1 | P1_09 | -16 | /I2C INT | I2C_INT | P0_15 | -17 | TX | TX | TX1 | P1_03 | -18 | D1 | D1 | CAM_TRIG | P1_08 | -19 | RX | RX | RX1 | P1_10 | -20 | RX2 | RX2 | | P1_05 | -22 | TX2 | TX2 | | P1_07 | -32 | PWM0 | PWM0 | P0_06 | -34 | A0 | A0 | ADC0 | P0_04 | Attached to AIN2 -38 | A1 | A1 | ADC1 | P0_05 | Attached to AIN3 +11 | BOOT | BOOT | | P0_07 | +12 | SDA | I2C_SDA | SDA | P0_08 | +13 | RTS1 | UART_RTS1 | | P1_02 | +14 | SCL | I2C_SCL | SCL | P0_11 | +15 | CTS1 | UART_CTS1 | | P1_09 | +16 | /I2C INT | I2C_INT | |P0_15| +17 | TX | UART_TX1 | TX | P1_03 | +18 | D1 | D1 | | P1_08 | +19 | RX | UART_RX1 | RX | P1_10 | +20 | RX2 | UART_RX2 | | P1_05 | +22 | TX2 | UART_TX2 | | P1_07 | +32 | PWM0 | PWM0 | |P0_06| +34 | A0 | A0 | | P0_04 | Attached to AIN2 +38 | A1 | A1 | | P0_05 | Attached to AIN3 40 | G0 | G0 | BUS0 | P0_29 | Attached to AIN5 42 | G1 | G1 | BUS1 | P0_03 | Attached to AIN1 44 | G2 | G2 | BUS2 | P1_13 | 46 | G3 | G3 | BUS3 | P1_12 | -47 | PWM1 | PWM1 | P0_16 | +47 | PWM1 | PWM1 | |P0_16| 48 | G4 | G4 | BUS4 | P1_11 | -49 | BATT_VIN | BATT_VIN3 | | P0_30 | Attached to AIN6, will be battery voltage / 3. | +49 | BATT_VIN | BATT_VIN3 | | P0_30 | Attached to AIN6, will be battery voltage / 3. 50 | PDM_CLK | PDM_CLK | | P0_25 | -51 | SDA1 | SDA1 | | P1_01 | +51 | SDA1 | I2C_SDA1 | | P1_01 | 52 | PDM_DATA | PDM_DATA | | P0_26 | -53 | SCL1 | SCL1 | | P0_24 | -55 | /CS | CS | | P0_20 | -57 | SCK | SCK | | P0_28 | Attached to AIN4 -59 | COPI | COPI | MOSI | P0_31 | Attached to AIN7 -61 | CIPO | CIPO | MISO | P0_02 | -63 | G10 | G10 | NFC2, ADC_DP, CAM_VSYNC | P0_10 | Attached to NFC2 -65 | G9 | G9 | NFC1, ADC_DM, CAM_HSYNC | P0_09 | Attached to NFC1 +53 | SCL1 | I2C_SCL1 | | P0_24 | +55 | /CS | SPI_CS | | P0_20 | +57 | SCK | SPI_SCK | LED_CLK | P0_28 | Attached to AIN4 +59 | COPI | SPI_COPI | SPI_MOSI, LED_DAT | P0_31 | Attached to AIN7 +60 | SCK1 | SDIO_SCK | SPI_SCK1 | | +61 | CIPO | SPI_CIPO | SPI_MISO | P0_02 | +62 | COPI1 | SDIO_CMD | SPI_COPI1 | | +63 | G10 | G10 | | P0_10 | Attached to NFC2 +64 | CIPO1 | SDIO_DATA0 | SPI_CIPO1 | | +65 | G9 | G9 | | P0_09 | Attached to NFC1 +66 | DAT1 | SDIO_DATA1 | | | 67 | G8 | G8 | | P1_14 | +68 | DAT2 | SDIO_DATA2 | | | 69 | G7 | G7 | BUS7 | P1_04 | +70 | CS1 | SDIO_DATA3 | SPI_CS1 | | 71 | G6 | G6 | BUS6 | P1_06 | 73 | G5 | G5 | BUS5 | P0_15 | ## Peripheral Naming -CircuitPython attempts to stay in line with the naming of the serial peripheral naming in the MicroMod system. The bare UART pins are also named 1. The UART 2 pins are named 2. However, the I2C names on MicroMod are and 1. Perhaps this will change in the future, but as of [Interface v1](https://cdn.sparkfun.com/assets/learn_tutorials/1/2/0/6/SparkFun_MicroMod_Interface_v1.0_-_Pin_Descriptions.pdf), it may lead to some confusion. +The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. The 0th peripheral is the default and the "0" is omitted from the peripheral name. For example, the first I2C peripheral is named `I2C` (instead of `I2C0`) and the second I2C peripheral is named `I2C1`. Note: MicroMod `UART` is not present in the edge connector pinout because the primary debug serial port (i.e.`UART0`) is exposed as a virtual serial port over USB. As a result, the first UART peripheral in the edge connector pinout is `UART1` and the second UART peripheral is `UART2`. + +For more details, see https://www.sparkfun.com/micromod#tech-specs. ## Bootloader Notes -The MicroMod nRF52840 Processor needs to have the [Adafruit nRF52 UF2 bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader/pull/194) flashed on it. [[TODO: LINK TO BUILD]] +The MicroMod nRF52840 Processor needs to have the [Adafruit nRF52 UF2 bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases/latest) flashed on it. ## Hardware Reference diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.h b/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.h index c53fc45d22..fec1d5ae02 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.h +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.h @@ -27,9 +27,12 @@ #include "nrfx/hal/nrf_gpio.h" -#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod nRF52840" +#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod nRF52840 Processor" #define MICROPY_HW_MCU_NAME "nRF52840" +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_P0_13) + #define DEFAULT_I2C_BUS_SCL (&pin_P0_11) #define DEFAULT_I2C_BUS_SDA (&pin_P0_08) diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.mk b/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.mk index 21ca20825a..83d51ecc6d 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.mk +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/mpconfigboard.mk @@ -1,6 +1,6 @@ USB_VID = 0x1B4F USB_PID = 0x0021 -USB_PRODUCT = "SFE_nRF52840_MicroMod" +USB_PRODUCT = "SparkFun MicroMod nRF52840 Processor" USB_MANUFACTURER = "SparkFun Electronics" MCU_CHIP = nrf52840 diff --git a/ports/nrf/boards/sparkfun_nrf52840_micromod/pins.c b/ports/nrf/boards/sparkfun_nrf52840_micromod/pins.c index 65700f24e4..11ca39f28d 100644 --- a/ports/nrf/boards/sparkfun_nrf52840_micromod/pins.c +++ b/ports/nrf/boards/sparkfun_nrf52840_micromod/pins.c @@ -1,113 +1,221 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Chris Wilson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "shared-bindings/board/__init__.h" STATIC const mp_rom_map_elem_t board_module_globals_table[] = { - // D pins (D0-D1) - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_27) }, // 0.27 - D0 - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P1_08) }, // 1.08 - D1 | CAM_TRIG - { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_P1_08) }, // CAM_TRIG alias + // The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. + // The 0th peripheral is the default and the "0" is omitted from the + // peripheral name (e.g. "I2C" instead of "I2C0"). + // + // For more details, see https://www.sparkfun.com/micromod#tech-specs - // A pins (A0-A1) - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, // 0.04 - A0 | ADC0 (AIN2) - { MP_ROM_QSTR(MP_QSTR_ADC0), MP_ROM_PTR(&pin_P0_04) }, // ADC0 alias - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, // 0.05 - A1 | ADC1 (AIN3) - { MP_ROM_QSTR(MP_QSTR_ADC1), MP_ROM_PTR(&pin_P0_05) }, // ADC1 alias + // MicroMod built-in status LED pin + // Requirement from the "Designing with MicroMod" SparkFun article: + // "... every Processor Board shall include one status LED connected to a + // pin that is not connected to the board edge." + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_P0_13) }, // MicroMod LED (P0.13) - // G pins (G0-G11, G11 NC) - { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_P0_29) }, // 0.29 - G0 | GPIO0 | BUS0 (AIN5) - { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_P0_29) }, // BUS0 alias - { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_P0_03) }, // 0.03 - G1 | GPIO1 | BUS1 (AIN1) - { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_P0_03) }, // BUS1 alias - { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_P1_13) }, // 1.13 - G2 | GPIO2 | BUS2 - { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_P1_13) }, // BUS2 alias - { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_P1_12) }, // 1.12 - G3 | GPIO3 | BUS3 - { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_P1_12) }, // BUS3 alias - { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_P1_11) }, // 1.11 - G4 | GPIO4 | BUS4 - { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_P1_11) }, // BUS4 alias - { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_P0_17) }, // 0.17 - G5 | GPIO5 | BUS5 - { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_P0_17) }, // BUS5 alias - { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_P1_06) }, // 1.06 - G6 | GPIO6 | BUS6 - { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_P1_06) }, // BUS6 alias - { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_P1_04) }, // 1.04 - G7 | GPIO7 | BUS7 - { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_P1_04) }, // BUS7 alias - { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_P1_14) }, // 1.14 - G8 | GPIO8 - { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_P0_09) }, // 0.09 - G9 | GPIO9/NFC1 | ADC_D- | CAM_HSYNC (NFC1) - { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, // NFC1 alias - { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_P0_09) }, // ADC_DM alias - { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_P0_09) }, // CAM_HSYNC alias - { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_P0_10) }, // 0.10 - G10 | GPIO10/NFC2 | ADC_D+ | CAM_VSYNC (NFC2) - { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, // NFC2 alias - { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_P0_10) }, // ADC_DP alias - { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_P0_10) }, // CAM_VSYNC alias - // NC - G11 + // MicroMod USB bus input voltage (+5V) pin + // { MP_ROM_QSTR(MP_QSTR_USB_VIN), MP_ROM_PTR() }, // MicroMod USB_VIN (MDBT50Q-P1M has a dedicated HW VBUS pin) - // PWM pins (PWM0-PWM1) - { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_P0_06) }, // 0.06 - PWM0 - { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_P0_16) }, // 0.16 - PWM1 + // MicroMod +3.3V enable pin + { MP_ROM_QSTR(MP_QSTR_P3V3_EN), MP_ROM_PTR(&pin_P1_15) }, // MicroMod 3.3V_EN (P1.15) - // PDM - { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_P0_25) }, // 0.25 - PDM_CLK | AUD_BCLK - { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_P0_26) }, // 0.26 - PDM_DATA | AUD_LRCLK + // MicroMod battery voltage sense pin + { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_P0_30) }, // MicroMod BATT_VIN/3 (P0.30) - // Battery Voltage Monitor - { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_P0_30) }, // 0.30 - BATT_VIN/3 (AIN6) + // MicroMod reset pin + { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR(&pin_P0_18) }, // MicroMod RESET# (P0.18) - // I2C - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_08) }, // 0.08 - SDA - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, // 0.11 - SCL (TRACEDATA2) + // MicroMod boot pin + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_P0_07) }, // MicroMod BOOT (P0.07) - { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_P0_15) }, // 0.15 - I2C_INT + // MicroMod USB device pins + // USB device is always used internally by CircuitPython, so skip creating + // the pin objects for it. + // { MP_ROM_QSTR(MP_QSTR_USB_DM), MP_ROM_PTR() }, // MicroMod USB_D- (MDBT50Q-P1M has a dedicated HW D- pin) + // { MP_ROM_QSTR(MP_QSTR_USB_DP), MP_ROM_PTR() }, // MicroMod USB_D+ (MDBT50Q-P1M has a dedicated HW D+ pin) - { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_P1_01) }, // 1.01 - SDA1 - { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_P0_24) }, // 0.24 - SCL1 + // MicroMod USB host pins + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DM), MP_ROM_PTR() }, // MicroMod USBHOST_D- (not supported) + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DP), MP_ROM_PTR() }, // MicroMod USBHOST_D+ (not supported) - // SPI - { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_P0_02) }, // 0.02 - CIPO | SPI_CIPO - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_02) }, // MISO alias - { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_P0_31) }, // 0.31 - COPI | SPI_COPI (AIN7) - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_31) }, // MOSI alias - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_28) }, // 0.28 - SCK | SPI_SCK (AIN4) - { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_P0_20) }, // 0.20 - /CS | SPI_/CS + // MicroMod CAN pins + // { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR() }, // MicroMod CAN_RX (not supported) + // { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR() }, // MicroMod CAN_TX (not supported) - // QSPI, used by flash on this board, but is broken out - // on the MicroMod connector, to to the SDIO pins. - { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_P0_19) }, // 0.00 - SDIO SCK | Used as: QSPI flash SCK - { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR(&pin_P0_19) }, // SPI_SCK1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_P0_14) }, // 0.00 - SDIO CMD | Used as: QSPI flash D0 (or SDI) - { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR(&pin_P0_14) }, // SPI_COPI1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_P0_21) },// 0.00 - SDIO DATA0 | Used as: QSPI flash D1 (or SDO) - { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR(&pin_P0_21) }, // SPI_CIPO1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_P0_22) },// 0.00 - SDIO DATA1 | Unused for flash. - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_P0_23) },// 0.00 - SDIO DATA2 | Used as: QSPI flash D2 - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_P1_00) },// 0.00 - SDIO DATA3 | Use das: QSPI flash D3 (or /HOLD) - { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR(&pin_P1_00) }, // SPI_CS1 alias + // Note: MicroMod UART (UART0) is not present in the edge connector pinout + // because the primary debug serial port is exposed as a virtual serial port + // over USB. - // Reset Pin - { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR(&pin_P1_14) }, // 0.18 - /RESET (NRESET) + // MicroMod UART1 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX1), MP_ROM_PTR(&pin_P1_03) }, // MicroMod UART_TX1 | CircuitPython TX (P1.03) + { MP_ROM_QSTR(MP_QSTR_UART_RX1), MP_ROM_PTR(&pin_P1_10) }, // MicroMod UART_RX1 | CircuitPython RX (P1.10) + { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR(&pin_P1_02) }, // MicroMod RTS1 (P1.02) + { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR(&pin_P1_09) }, // MicroMod CTS1 (P1.09) - // LED - { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_13) }, // 0.13 - LED_BUILTIN | STAT | Blue LED + // CircuitPython default UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P1_03) }, // CircuitPython TX | MicroMod UART_TX1 (P1.03) + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P1_10) }, // CircuitPython RX | MicroMod UART_RX1 (P1.10) - // Button - { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_P0_07) }, // 0.07 - /BOOT [Active Low] (TRACECLK) - Is button on carriers. - { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_P0_07) }, // BOOT alias + // MicroMod UART2 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX2), MP_ROM_PTR(&pin_P1_07) }, // MicroMod UART_TX2 (P1.07) + { MP_ROM_QSTR(MP_QSTR_UART_RX2), MP_ROM_PTR(&pin_P1_05) }, // MicroMod UART_RX2 (P1.05) - // UART - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P1_10) }, // 1.10 - UART RX | RX1 - { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_P1_10) }, // RX1 alias - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P1_03) }, // 1.03 - UART TX | TX1 - { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_P1_03) }, // TX1 alias - { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_PTR(&pin_P1_09) }, // 1.09 - UART CTS | CTS1 (TRACEDATA3) - { MP_ROM_QSTR(MP_QSTR_CTS1), MP_ROM_PTR(&pin_P1_09) }, // CTS1 alias - { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_PTR(&pin_P1_02) }, // 1.02 - UART RTS | RTS1 - { MP_ROM_QSTR(MP_QSTR_RTS1), MP_ROM_PTR(&pin_P1_02) }, // RTS1 alias + // MicroMod I2C pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_P0_08) }, // MicroMod I2C_SDA (P0.08) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_P0_11) }, // MicroMod I2C_SCL (P0.11) - { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_P1_05) }, // 1.05 - UART RX | RX2 - { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_P1_07) }, // 1.07 - UART TX | TX2 + // CircuitPython default I2C pins + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_08) }, // CircuitPython SDA | MicroMod I2C_SDA (P0.08) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, // CircuitPython SCL | MicroMod I2C_SCL (P0.11) - // Board Objects - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + // MicroMod I2C interrupt pin + { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_P0_15) }, // MicroMod I2C_INT (P0.15) + + // MicroMod I2C1 pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA1), MP_ROM_PTR(&pin_P1_01) }, // MicroMod I2C_SDA1 (P1.01) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL1), MP_ROM_PTR(&pin_P0_24) }, // MicroMod I2C_SCL1 (P0.24) + + // MicroMod SPI pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO), MP_ROM_PTR(&pin_P0_02) }, // MicroMod SPI_CIPO | CircuitPython CIPO (P0.02) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_P0_02) }, // MicroMod SPI_MISO | CircuitPython MISO (P0.02) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI), MP_ROM_PTR(&pin_P0_31) }, // MicroMod SPI_COPI | CircuitPython COPI | LED_DAT (P0.31) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_P0_31) }, // MicroMod SPI_MOSI | CircuitPython MOSI (P0.31) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_P0_28) }, // MicroMod SPI_SCK | CircuitPython SCK | LED_CLK (P0.28) + { MP_ROM_QSTR(MP_QSTR_SPI_CS), MP_ROM_PTR(&pin_P0_20) }, // MicroMod SPI_CS | CircuitPython CS (P0.20) + + // CircuitPython default SPI pins + { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_P0_02) }, // CircuitPython CIPO | MicroMod SPI_CIPO (P0.02) + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_02) }, // CircuitPython MISO | MicroMod SPI_MISO (P0.02) + { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_P0_31) }, // CircuitPython COPI | MicroMod SPI_COPI | LED_DAT (P0.31) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_31) }, // CircuitPython MOSI | MicroMod SPI_MOSI (P0.31) + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_28) }, // CircuitPython SCK | MicroMod SPI_SCK | LED_CLK (P0.28) + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_P0_20) }, // CircuitPython CS | MicroMod SPI_CS (P0.20) + + // MicroMod 2-wire serial LED pins + { MP_ROM_QSTR(MP_QSTR_LED_DAT), MP_ROM_PTR(&pin_P0_31) }, // MicroMod LED_DAT | SPI_COPI (P0.31) + { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_P0_28) }, // MicroMod LED_CLK | SPI_SCK (P0.28) + + // MicroMod SDIO pins + { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_P0_19) }, // MicroMod SDIO_SCK | SPI_SCK1 (P0.19) + { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_P0_14) }, // MicroMod SDIO_CMD | SPI_COPI1 (P0.14) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_P0_21) }, // MicroMod SDIO_DATA0 | SPI_CIPO1 (P0.21) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_P0_22) }, // MicroMod SDIO_DATA1 (P0.22) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_P0_23) }, // MicroMod SDIO_DATA2 (P0.23) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_P1_00) }, // MicroMod SDIO_DATA3 | SPI_CS1 (P1.00) + + // MicroMod SPI1 pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR(&pin_P0_21) }, // MicroMod SPI_CIPO1 | SDIO_DATA0 (P0.21) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO1), MP_ROM_PTR(&pin_P0_21) }, // MicroMod SPI_MISO1 (P0.21) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR(&pin_P0_14) }, // MicroMod SPI_COPI1 | SDIO_CMD (P0.14) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI1), MP_ROM_PTR(&pin_P0_14) }, // MicroMod SPI_MOSI1 (P0.14) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR(&pin_P0_19) }, // MicroMod SPI_SCK1 | SDIO_SCK (P0.19) + { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR(&pin_P1_00) }, // MicroMod SPI_CS1 | SDIO_DATA3 (P1.00) + + // MicroMod audio pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR() }, // MicroMod AUD_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR() }, // MicroMod AUD_OUT | I2S_OUT | PCM_OUT | CAM_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR() }, // MicroMod AUD_IN | I2S_IN | PCM_IN | CAM_PCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_P0_26) },// MicroMod AUD_LRCLK | I2S_WS | PCM_SYNC | PDM_DATA (P0.26) + // { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_P0_25) }, // MicroMod AUD_BCLK | I2S_SCK | PCM_CLK | PDM_CLK (P0.25) + + // MicroMod I2S pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR() }, // MicroMod I2S_OUT | AUD_OUT | PCM_OUT | CAM_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_I2S_IN), MP_ROM_PTR() }, // MicroMod I2S_IN | AUD_IN | PCM_IN | CAM_PCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_P0_26) }, // MicroMod I2S_WS | AUD_LRCLK | PCM_SYNC | PDM_DATA (P0.26) + // { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_P0_25) }, // MicroMod I2S_SCK | AUD_BCLK | PCM_CLK | PDM_CLK (P0.25) + + // MicroMod PCM pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_PCM_OUT), MP_ROM_PTR() }, // MicroMod PCM_OUT | AUD_OUT | I2S_OUT | CAM_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_PCM_IN), MP_ROM_PTR() }, // MicroMod PCM_IN | AUD_IN | I2S_IN | CAM_PCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_PCM_SYNC), MP_ROM_PTR(&pin_P0_26) }, // MicroMod PCM_SYNC | AUD_LRCLK | I2S_WS | PDM_DATA (P0.26) + // { MP_ROM_QSTR(MP_QSTR_PCM_CLK), MP_ROM_PTR(&pin_P0_25) }, // MicroMod PCM_CLK | AUD_BCLK | I2S_SCK | PDM_CLK (P0.25) + + // MicroMod PDM pins + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_P0_26) }, // MicroMod PDM_DATA | AUD_LRCLK | I2S_WS | PCM_SYNC (P0.26) + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_P0_25) }, // MicroMod PDM_CLK | AUD_BCLK | I2S_SCK | PCM_CLK (P0.25) + + // MicroMod SWD pins + // { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR() }, // MicroMod SWDIO (MDBT50Q-P1M has a dedicated HW SWDIO pin) + // { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR() }, // MicroMod SWDCK (MDBT50Q-P1M has a dedicated HW SWDCLK pin) + // { MP_ROM_QSTR(MP_QSTR_SWO), MP_ROM_PTR() }, // MicroMod SWO | G11 (not supported) + + // MicroMod ADC pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_05) }, // MicroMod A0 (P0.05) + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_04) }, // MicroMod A1 (P0.04) + + // MicroMod PWM pins + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_P0_06) }, // MicroMod PWM0 (P0.06) + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_P0_16) }, // MicroMod PWM1 (P0.16) + + // MicroMod digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_P0_27) }, // MicroMod D0 (P0.27) + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_P1_08) }, // MicroMod D1 | CAM_TRIG (P1.08) + + // MicroMod general purpose pins + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_P0_29) }, // MicroMod G0 | BUS0 (P0.29) + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_P0_03) }, // MicroMod G1 | BUS1 (P0.03) + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_P1_13) }, // MicroMod G2 | BUS2 (P1.13) + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_P1_12) }, // MicroMod G3 | BUS3 (P1.12) + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_P1_11) }, // MicroMod G4 | BUS4 (P1.11) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_P0_17) }, // MicroMod G5 | BUS5 (P0.17) + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_P1_06) }, // MicroMod G6 | BUS6 (P1.06) + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_P1_04) }, // MicroMod G7 | BUS7 (P1.04) + { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_P1_14) }, // MicroMod G8 (P1.14) + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_P0_09) }, // MicroMod G9 | ADC_D- | CAM_HSYNC (P0.09) + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_P0_10) }, // MicroMod G10 | ADC_D+ | CAM_VSYNC (P0.10) + // { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR() }, // MicroMod G11 | SWO (not connected) + + // MicroMod 8-bit bus pins + { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_P0_29) }, // MicroMod BUS0 | G0 (P0.29) + { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_P0_03) }, // MicroMod BUS1 | G1 (P0.03) + { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_P1_13) }, // MicroMod BUS2 | G2 (P1.13) + { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_P1_12) }, // MicroMod BUS3 | G3 (P1.12) + { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_P1_11) }, // MicroMod BUS4 | G4 (P1.11) + { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_P0_17) }, // MicroMod BUS5 | G5 (P0.17) + { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_P1_06) }, // MicroMod BUS6 | G6 (P1.06) + { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_P1_04) }, // MicroMod BUS7 | G7 (P1.04) + + // MicroMod differential ADC input pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_P0_09) }, // MicroMod ADC_D- | G9 | CAM_HSYNC (P0.09) + // { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_P0_10) }, // MicroMod ADC_D+ | G10 | CAM_VSYNC (P0.10) + + // MicroMod camera pins (not supported by MDBT50Q-P1M) + // { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR() }, // MicroMod CAM_MCLK | AUD_OUT | I2S_OUT | PCM_OUT (not connected) + // { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR() }, // MicroMod CAM_PCLK | AUD_IN | I2S_IN | PCM_IN (not connected) + // { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_P1_08) }, // MicroMod CAM_TRIG | D1 (P1.08) + // { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_P0_09) },// MicroMod CAM_HSYNC | ADC_D- | G9 (P0.09) + // { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_P0_10) },// MicroMod CAM_VSYNC | ADC_D+ | G10 (P0.10) + + // CircuitPython board objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, // CircuitPython I2C + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, // CircuitPython SPI + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, // CircuitPython UART }; - MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h index d7dd7a6376..edeaf2e039 100644 --- a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.h @@ -1,12 +1,15 @@ -#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod ATP - RP2040" +#define MICROPY_HW_BOARD_NAME "SparkFun MicroMod RP2040 Processor" #define MICROPY_HW_MCU_NAME "rp2040" +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_GPIO25) + #define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO14) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO15) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO12) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk index 2ed559d8db..90f05a1754 100644 --- a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/mpconfigboard.mk @@ -1,7 +1,7 @@ USB_VID = 0x1B4F USB_PID = 0x0024 -USB_PRODUCT = "MicroMod RP2040" -USB_MANUFACTURER = "SparkFun" +USB_PRODUCT = "SparkFun MicroMod RP2040 Processor" +USB_MANUFACTURER = "SparkFun Electronics" CHIP_VARIANT = RP2040 CHIP_FAMILY = rp2 diff --git a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c index 90069a7e6f..ea9d38402c 100644 --- a/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c +++ b/ports/raspberrypi/boards/sparkfun_micromod_rp2040/pins.c @@ -1,105 +1,223 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * Copyright (c) 2021 Chris Wilson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "shared-bindings/board/__init__.h" STATIC const mp_rom_map_elem_t board_global_dict_table[] = { - // D (Digital only) pins (D0,D1) - { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO6) }, // GPIO6 - D0 - { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO7) }, // GPIO7 - D1 + // The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. + // The 0th peripheral is the default and the "0" is omitted from the + // peripheral name (e.g. "I2C" instead of "I2C0"). + // + // For more details, see https://www.sparkfun.com/micromod#tech-specs - // A (ADC) pins (A0,A1) - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, // GPIO26 - A0 | ADC0 - { MP_ROM_QSTR(MP_QSTR_ADC0), MP_ROM_PTR(&pin_GPIO26) }, // ADC0 alias - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, // GPIO27 - A1 | ADC1 - { MP_ROM_QSTR(MP_QSTR_ADC1), MP_ROM_PTR(&pin_GPIO27) }, // ADC1 alias + // MicroMod built-in status LED pin + // Requirement from the "Designing with MicroMod" SparkFun article: + // "... every Processor Board shall include one status LED connected to a + // pin that is not connected to the board edge." + // Note: GPIO25 is connected to both the status LED and edge connector pin + // G10, which doesn't comply with the requirement above... + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, // MicroMod LED (GPIO25) - // G (General/BUS) pins (G0-G7, G8 NC, G9-G10, G11 NC) - { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO16) }, // GPIO16 - G0 | BUS0 - { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_GPIO16) }, // BUS0 alias - { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO17) }, // GPIO17 - G1 | BUS1 - { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_GPIO17) }, // BUS1 alias - { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO18) }, // GPIO18 - G2 | BUS2 - { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_GPIO18) }, // BUS2 alias - { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_GPIO19) }, // GPIO19 - G3 | BUS3 - { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_GPIO19) }, // BUS3 alias - { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO20) }, // GPIO20 - G4 | BUS4 | SPI_CIPO - { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_GPIO20) }, // BUS4 alias - { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_GPIO21) }, // GPIO21 - G5 | BUS5 | SPI_CS - { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_GPIO21) }, // BUS5 alias - { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_GPIO22) }, // GPIO22 - G6 | BUS6 | SPI_SCK - { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_GPIO22) }, // BUS6 alias - { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_GPIO23) }, // GPIO23 - G7 | BUS7 | SPI_COPI - { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_GPIO23) }, // BUS7 alias - // NC - G8 - { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO28) }, // GPIO28- G9 | BUS9 | ADC_D- | CAM_HSYNC - { MP_ROM_QSTR(MP_QSTR_BUS9), MP_ROM_PTR(&pin_GPIO28) }, // BUS9 alias - { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_GPIO28) }, // ADC_DM alias - { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_GPIO28) }, // CAM_HSYNC alias - { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO25) }, // GPIO25 - G10 | BUS10 | ADC_D+ | CAM_VSYNC - { MP_ROM_QSTR(MP_QSTR_BUS10), MP_ROM_PTR(&pin_GPIO25) }, // BUS10 alias - { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_GPIO25) }, // ADC_DP alias - { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO25) }, // CAM_VSYNC alias - // NC - G11 + // MicroMod USB bus input voltage (+5V) pin + // { MP_ROM_QSTR(MP_QSTR_USB_VIN), MP_ROM_PTR() }, // MicroMod USB_VIN (not connected) - // PWM pins (PWM0,PWM1) - { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO13) }, // GPIO13 - PWM0 - { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO24) }, // GPIO24 - PWM1 | AUD_MCLK + // MicroMod +3.3V enable pin + // { MP_ROM_QSTR(MP_QSTR_P3V3_EN), MP_ROM_PTR() }, // MicroMod 3.3V_EN (not connected) - // AUD (audio) - { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR(&pin_GPIO24) }, // GPIO24 - AUD_MCLK | PWM1 - { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_GPIO10) }, // GPIO10 - AUD_OUT | SDIO_DAT2 - { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_GPIO11) }, // GPIO11 - AUD_IN | SDIO_DAT1 - { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_GPIO2) }, // GPIO2 - AUD_LRCLK | CTS1 - { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_GPIO3) }, // GPIO3 - AUD_BCLK | UART_RTS1 + // MicroMod battery voltage sense pin + { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_GPIO29) }, // MicroMod BATT_VIN/3 (GPIO29) - // Battery Voltage Monitor - { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_GPIO29) }, // GPIO29 - BATT_VIN/3 (ADC03) + // MicroMod reset pin + // { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR() }, // MicroMod RESET# (RP2040 has a dedicated HW RUN pin) + // MicroMod boot pin + // { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR() }, // MicroMod BOOT (RP2040 does not have a dedicated BOOT pin) - // I2C - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, // GPIO4 - SDA - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, // GPIO5 - SCL + // MicroMod USB device pins + // USB device is always used internally by CircuitPython, so skip creating + // the pin objects for it. + // { MP_ROM_QSTR(MP_QSTR_USB_DM), MP_ROM_PTR() }, // MicroMod USB_D- (RP2040 has a dedicated HW USB_DM pin) + // { MP_ROM_QSTR(MP_QSTR_USB_DP), MP_ROM_PTR() }, // MicroMod USB_D+ (RP2040 has a dedicated HW USB_DP pin) - { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_GPIO8) }, // GPIO9 - I2C_INT | TX2 + // MicroMod USB host pins + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DM), MP_ROM_PTR() }, // MicroMod USBHOST_D- (RP2040 has a dedicated HW USB_DM pin) + // { MP_ROM_QSTR(MP_QSTR_USBHOST_DP), MP_ROM_PTR() }, // MicroMod USBHOST_D+ (RP2040 has a dedicated HW USB_DP pin) - // SPI - { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_GPIO20) }, // GPIO20 - CIPO | SPI_CIPO | G4 - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, // MISO alias - { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_GPIO23) }, // GPIO23 - COPI | SPI_COPI | G7 - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, // MOSI alias - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, // GPIO22 - SCK | SPI_SCK | G6 - { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO21) }, // GPIO21 - /CS | SPI_/CS | G5 + // MicroMod CAN pins + // { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR() }, // MicroMod CAN_RX (not supported) + // { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR() }, // MicroMod CAN_TX (not supported) - // SDI/SPI1 - { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO14) }, // GPIO14 - SDIO SCK | SDIO_CLK - { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR(&pin_GPIO14) }, // SPI_SCK1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_GPIO15) }, // GPIO15 - SDIO CMD | SDIO_CMD - { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR(&pin_GPIO15) },// SPI_COPI1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO12) },// GPIO12 - SDIO DATA0 | SDIO_DATA0 - { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR(&pin_GPIO12) }, // SPI_CIPO1 alias - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO11) },// GPIO11 - SDIO DATA1 | SDIO_DATA1 | AUD_IN - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO10) },// GPIO10 - SDIO DATA2 | SDIO_DATA2 | AUD_OUT - { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO9) },// GPIO9 - SDIO DATA3 | SDIO_DATA3 | SPI_CS1 - { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR(&pin_GPIO9) }, // SPI_CS1 alias + // Note: MicroMod UART (UART0) is not present in the edge connector pinout + // because the primary debug serial port is exposed as a virtual serial port + // over USB. - // Status LED - { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_GPIO25) }, // GPIO25 - LED_BUILTIN | STAT | Blue LED | G10 + // MicroMod UART1 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX1), MP_ROM_PTR(&pin_GPIO0) }, // MicroMod UART_TX1 | CircuitPython TX (GPIO0) + { MP_ROM_QSTR(MP_QSTR_UART_RX1), MP_ROM_PTR(&pin_GPIO1) }, // MicroMod UART_RX1 | CircuitPython RX (GPIO1) + { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod RTS1 (GPIO3) + { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod CTS1 (GPIO2) - // UART - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, // GPIO1 - UART RX | UART_RX1 | RX1 - { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_GPIO1) }, // RX1 alias - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, // GPIO0 - UART TX | UART_TX1 | TX1 - { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_GPIO0) }, // TX1 alias - { MP_ROM_QSTR(MP_QSTR_CTS), MP_ROM_PTR(&pin_GPIO2) }, // GPIO2 - UART CTS | CTS1 (TRACEDATA3) - { MP_ROM_QSTR(MP_QSTR_CTS1), MP_ROM_PTR(&pin_GPIO2) }, // CTS1 alias - { MP_ROM_QSTR(MP_QSTR_RTS), MP_ROM_PTR(&pin_GPIO3) }, // GPIO3 - UART RTS | RTS1 - { MP_ROM_QSTR(MP_QSTR_RTS1), MP_ROM_PTR(&pin_GPIO3) }, // RTS1 alias + // CircuitPython default UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, // CircuitPython TX | MicroMod UART_TX1 (GPIO0) + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, // CircuitPython RX | MicroMod UART_RX1 (GPIO1) - { MP_ROM_QSTR(MP_QSTR_RX2), MP_ROM_PTR(&pin_GPIO9) }, // GPIO9 - UART RX | UART_RX2 | RX2 | SDIO_DAT3 | SPI_CS1 - { MP_ROM_QSTR(MP_QSTR_TX2), MP_ROM_PTR(&pin_GPIO8) }, // GPIO8 - UART TX | UART_TX2 | TX2 | I2C_INT + // MicroMod UART2 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX2), MP_ROM_PTR(&pin_GPIO8) }, // MicroMod UART_TX2 (GPIO8) + { MP_ROM_QSTR(MP_QSTR_UART_RX2), MP_ROM_PTR(&pin_GPIO9) }, // MicroMod UART_RX2 (GPIO9) - // Board objects - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + // MicroMod I2C pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_GPIO4) }, // MicroMod I2C_SDA | CircuitPython SDA (GPIO4) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO5) }, // MicroMod I2C_SCL | CircuitPython SCL (GPIO5) + // CircuitPython default I2C pins + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, // CircuitPython SDA | MicroMod I2C_SDA (GPIO4) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, // CircuitPython SCL | MicroMod I2C_SCL (GPIO5) + + // MicroMod I2C interrupt pin + { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_GPIO8) }, // MicroMod I2C_INT (GPIO8) + + // MicroMod I2C1 pins + // { MP_ROM_QSTR(MP_QSTR_I2C_SDA1), MP_ROM_PTR() }, // MicroMod I2C_SDA1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_I2C_SCL1), MP_ROM_PTR() }, // MicroMod I2C_SCL1 (not connected) + + // MicroMod SPI pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO), MP_ROM_PTR(&pin_GPIO20) }, // MicroMod SPI_CIPO | CircuitPython CIPO (GPIO20) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_GPIO20) }, // MicroMod SPI_MISO | CircuitPython MISO (GPIO20) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod SPI_COPI | CircuitPython COPI | LED_DAT (GPIO23) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod SPI_MOSI | CircuitPython MOSI (GPIO23) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_GPIO22) }, // MicroMod SPI_SCK | CircuitPython SCK | LED_CLK (GPIO22) + { MP_ROM_QSTR(MP_QSTR_SPI_CS), MP_ROM_PTR(&pin_GPIO21) }, // MicroMod SPI_CS | CircuitPython CS (GPIO21) + + // CircuitPython default SPI pins + { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_GPIO20) }, // CircuitPython CIPO | MicroMod SPI_CIPO (GPIO20) + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, // CircuitPython MISO | MicroMod SPI_MISO (GPIO20) + { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_GPIO23) }, // CircuitPython COPI | MicroMod SPI_COPI | LED_DAT (GPIO23) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, // CircuitPython MOSI | MicroMod SPI_MOSI (GPIO23) + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, // CircuitPython SCK | MicroMod SPI_SCK | LED_CLK (GPIO22) + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO21) }, // CircuitPython CS | MicroMod SPI_CS (GPIO21) + + // MicroMod 2-wire serial LED pins + { MP_ROM_QSTR(MP_QSTR_LED_DAT), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod LED_DAT | SPI_COPI + { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_GPIO22) }, // MicroMod LED_CLK | SPI_SCK + + // MicroMod SDIO pins + { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO14) }, // MicroMod SDIO_SCK | SPI_SCK1 (GPIO14) + { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_GPIO15) }, // MicroMod SDIO_CMD | SPI_COPI1 (GPIO15) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO12) }, // MicroMod SDIO_DATA0 | SPI_CIPO1 (GPIO12) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod SDIO_DATA1 (GPIO11) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod SDIO_DATA2 (GPIO10) + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO9) }, // MicroMod SDIO_DATA3 | SPI_CS1 (GPIO9) + + // MicroMod SPI1 pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR(&pin_GPIO12) }, // MicroMod SPI_CIPO1 | SDIO_DATA0 (GPIO12) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO1), MP_ROM_PTR(&pin_GPIO12) }, // MicroMod SPI_MISO1 (GPIO12) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR(&pin_GPIO15) }, // MicroMod SPI_COPI1 | SDIO_CMD (GPIO15) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI1), MP_ROM_PTR(&pin_GPIO15) }, // MicroMod SPI_MOSI1 (GPIO15) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR(&pin_GPIO14) }, // MicroMod SPI_SCK1 | SDIO_SCK (GPIO14) + { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR(&pin_GPIO9) }, // MicroMod SPI_CS1 | SDIO_DATA3 (GPIO9) + + // MicroMod audio pins + { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR(&pin_GPIO24) }, // MicroMod AUD_MCLK (GPIO24) + { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod AUD_OUT | I2S_OUT | PCM_OUT | CAM_MCLK (GPIO10) + { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod AUD_IN | I2S_IN | PCM_IN | CAM_PCLK (GPIO11) + { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod AUD_LRCLK | I2S_WS | PCM_SYNC | PDM_DATA (GPIO2) + { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod AUD_BCLK | I2S_SCK | PCM_CLK | PDM_CLK (GPIO3) + + // MicroMod I2S pins + { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod I2S_OUT | AUD_OUT | PCM_OUT | CAM_MCLK (GPIO10) + { MP_ROM_QSTR(MP_QSTR_I2S_IN), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod I2S_IN | AUD_IN | PCM_IN | CAM_PCLK (GPIO11) + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod I2S_WS | AUD_LRCLK | PCM_SYNC | PDM_DATA (GPIO2) + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod I2S_SCK | AUD_BCLK | PCM_CLK | PDM_CLK (GPIO3) + + // MicroMod PCM pins + { MP_ROM_QSTR(MP_QSTR_PCM_OUT), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod PCM_OUT | AUD_OUT | I2S_OUT | CAM_MCLK (GPIO10) + { MP_ROM_QSTR(MP_QSTR_PCM_IN), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod PCM_IN | AUD_IN | I2S_IN | CAM_PCLK (GPIO11) + { MP_ROM_QSTR(MP_QSTR_PCM_SYNC), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod PCM_SYNC | AUD_LRCLK | I2S_WS | PDM_DATA (GPIO2) + { MP_ROM_QSTR(MP_QSTR_PCM_CLK), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod PCM_CLK | AUD_BCLK | I2S_SCK | PDM_CLK (GPIO3) + + // MicroMod PDM pins + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_GPIO2) }, // MicroMod PDM_DATA | AUD_LRCLK | I2S_WS | PCM_SYNC (GPIO2) + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_GPIO3) }, // MicroMod PDM_CLK | AUD_BCLK | I2S_SCK | PCM_CLK (GPIO3) + + // MicroMod SWD pins + // { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR() }, // MicroMod SWDIO (RP2040 has a dedicated HW SWDIO pin) + // { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR() }, // MicroMod SWDCK (RP2040 has a dedicated HW SWCLK pin) + // { MP_ROM_QSTR(MP_QSTR_SWO), MP_ROM_PTR() }, // MicroMod SWO | G11 (not supported) + + // MicroMod ADC pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, // MicroMod A0 (GPIO26) + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, // MicroMod A1 (GPIO27) + + // MicroMod PWM pins + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_GPIO13) }, // MicroMod PWM0 (GPIO13) + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_GPIO24) }, // MicroMod PWM1 (GPIO24) + + // MicroMod digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO6) }, // MicroMod D0 (GPIO6) + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO7) }, // MicroMod D1 | CAM_TRIG (GPIO7) + + // MicroMod general purpose pins + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO16) }, // MicroMod G0 | BUS0 (GPIO16) + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO17) }, // MicroMod G1 | BUS1 (GPIO17) + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO18) }, // MicroMod G2 | BUS2 (GPIO18) + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_GPIO19) }, // MicroMod G3 | BUS3 (GPIO19) + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO20) }, // MicroMod G4 | BUS4 (GPIO20) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_GPIO21) }, // MicroMod G5 | BUS5 (GPIO21) + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_GPIO22) }, // MicroMod G6 | BUS6 (GPIO22) + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod G7 | BUS7 (GPIO23) + // { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR() }, // MicroMod G8 (not connected) + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO28) }, // MicroMod G9 | ADC_D- | CAM_HSYNC (GPIO28) + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO25) }, // MicroMod G10 | ADC_D+ | CAM_VSYNC (GPIO25) + // { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR() }, // MicroMod G11 | SWO (not connected) + + // MicroMod 8-bit bus pins + { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_GPIO16) }, // MicroMod BUS0 | G0 (GPIO16) + { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_GPIO17) }, // MicroMod BUS1 | G1 (GPIO17) + { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_GPIO18) }, // MicroMod BUS2 | G2 (GPIO18) + { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_GPIO19) }, // MicroMod BUS3 | G3 (GPIO19) + { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_GPIO20) }, // MicroMod BUS4 | G4 (GPIO20) + { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_GPIO21) }, // MicroMod BUS5 | G5 (GPIO21) + { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_GPIO22) }, // MicroMod BUS6 | G6 (GPIO22) + { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR(&pin_GPIO23) }, // MicroMod BUS7 | G7 (GPIO23) + + // MicroMod differential ADC input pins (not supported by RP2040) + // { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR(&pin_GPIO28) }, // MicroMod ADC_D- | G9 | CAM_HSYNC (GPIO28) + // { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_GPIO25) }, // MicroMod ADC_D+ | G10 | CAM_VSYNC (GPIO25) + + // MicroMod camera pins + { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR(&pin_GPIO10) }, // MicroMod CAM_MCLK | AUD_OUT | I2S_OUT | PCM_OUT (GPIO10) + { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO11) }, // MicroMod CAM_PCLK | AUD_IN | I2S_IN | PCM_IN (GPIO11) + { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_GPIO7) }, // MicroMod CAM_TRIG | D1 (GPIO7) + { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR(&pin_GPIO28) }, // MicroMod CAM_HSYNC | ADC_D- | G9 (GPIO28) + { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO25) }, // MicroMod CAM_VSYNC | ADC_D+ | G10 (GPIO25) + + // CircuitPython board objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, // CircuitPython I2C + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, // CircuitPython SPI + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, // CircuitPython UART }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); From c0902dade6c20c4106af8fbe54a96ba619e449d0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 9 Aug 2021 22:54:20 -0700 Subject: [PATCH 46/63] stm/boards: Add support for SparkFun STM32 MicroMod Processor board. --- .github/workflows/build.yml | 1 + .../sparkfun_stm32f405_micromod/board.c | 39 +++ .../mpconfigboard.h | 65 +++++ .../mpconfigboard.mk | 19 ++ .../boards/sparkfun_stm32f405_micromod/pins.c | 224 ++++++++++++++++++ 5 files changed, 348 insertions(+) create mode 100644 ports/stm/boards/sparkfun_stm32f405_micromod/board.c create mode 100644 ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.h create mode 100644 ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk create mode 100644 ports/stm/boards/sparkfun_stm32f405_micromod/pins.c diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 744ef02f48..606c9914cf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -369,6 +369,7 @@ jobs: - "sparkfun_samd21_mini" - "sparkfun_samd51_micromod" - "sparkfun_samd51_thing_plus" + - "sparkfun_stm32f405_micromod" - "sparkfun_thing_plus_rp2040" - "spresense" - "stackrduino_m0_pro" diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/board.c b/ports/stm/boards/sparkfun_stm32f405_micromod/board.c new file mode 100644 index 0000000000..f8e462f938 --- /dev/null +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/board.c @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" + +void board_init(void) { +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.h b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.h new file mode 100644 index 0000000000..ed3a643322 --- /dev/null +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.h @@ -0,0 +1,65 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Chris Wilson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "SparkFun STM32 MicroMod Processor" +#define MICROPY_HW_MCU_NAME "STM32F405RG" + +#define FLASH_SIZE (0x100000) +#define FLASH_PAGE_SIZE (0x4000) + +#define HSE_VALUE ((uint32_t)12000000) +#define LSE_VALUE ((uint32_t)32768) +#define BOARD_HAS_LOW_SPEED_CRYSTAL (1) + +// Status LED +#define MICROPY_HW_LED_STATUS (&pin_PA15) + +// On-board SPI flash +#define SPI_FLASH_MOSI_PIN (&pin_PC12) +#define SPI_FLASH_MISO_PIN (&pin_PC11) +#define SPI_FLASH_SCK_PIN (&pin_PC10) +#define SPI_FLASH_CS_PIN (&pin_PC03) + +// Bootloader only +#ifdef UF2_BOOTLOADER_ENABLED + #define BOARD_VTOR_DEFER (1) // Leave VTOR relocation to bootloader +#endif + +#define DEFAULT_I2C_BUS_SCL (&pin_PB10) +#define DEFAULT_I2C_BUS_SDA (&pin_PB11) + +#define DEFAULT_SPI_BUS_SCK (&pin_PA05) +#define DEFAULT_SPI_BUS_MOSI (&pin_PA07) +#define DEFAULT_SPI_BUS_MISO (&pin_PA06) + +#define DEFAULT_UART_BUS_RX (&pin_PA03) +#define DEFAULT_UART_BUS_TX (&pin_PA02) + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA11 (1) +#define IGNORE_PIN_PA12 (1) diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk new file mode 100644 index 0000000000..d1df685c67 --- /dev/null +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk @@ -0,0 +1,19 @@ +USB_VID = 0X1B4F +USB_PID = 0x0027 +USB_PRODUCT = "SparkFun STM32 MicroMod Processor" +USB_MANUFACTURER = "SparkFun Electronics" + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = W25Q128JVxM + +MCU_SERIES = F4 +MCU_VARIANT = STM32F405xx +MCU_PACKAGE = LQFP64 + +LD_COMMON = boards/common_default.ld +LD_DEFAULT = boards/STM32F405_default.ld +# UF2 boot option +LD_BOOT = boards/STM32F405_boot.ld +UF2_OFFSET = 0x8010000 + +CIRCUITPY_RGBMATRIX ?= 1 diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/pins.c b/ports/stm/boards/sparkfun_stm32f405_micromod/pins.c new file mode 100644 index 0000000000..2379e9a371 --- /dev/null +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/pins.c @@ -0,0 +1,224 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Chris Wilson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/board/__init__.h" + +STATIC const mp_rom_map_elem_t board_module_globals_table[] = { + // The SparkFun MicroMod spec uses a zero-based peripheral numbering scheme. + // The 0th peripheral is the default and the "0" is omitted from the + // peripheral name (e.g. "I2C" instead of "I2C0"). + // + // For more details, see https://www.sparkfun.com/micromod#tech-specs + + // MicroMod built-in status LED pin + // Requirement from the "Designing with MicroMod" SparkFun article: + // "... every Processor Board shall include one status LED connected to a + // pin that is not connected to the board edge." + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA15) }, // MicroMod LED (PA15) + + // MicroMod USB bus input voltage (+5V) pin + // { MP_ROM_QSTR(MP_QSTR_USB_VIN), MP_ROM_PTR() }, // MicroMod USB_VIN (not connected) + + // MicroMod +3.3V enable pin + // { MP_ROM_QSTR(MP_QSTR_P3V3_EN), MP_ROM_PTR() }, // MicroMod 3.3V_EN (not connected) + + // MicroMod battery voltage sense pin + { MP_ROM_QSTR(MP_QSTR_BATT_VIN3), MP_ROM_PTR(&pin_PA01) }, // MicroMod BATT_VIN/3 (PA1) + + // MicroMod reset pin + // { MP_ROM_QSTR(MP_QSTR_RESET), MP_ROM_PTR() }, // MicroMod RESET# (STM32 has a dedicated HW NRST pin) + + // MicroMod boot pin + // { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR() }, // MicroMod BOOT (STM32 has a dedicated HW BOOT0 pin) + + // MicroMod USB device pins + // USB device is always used internally by CircuitPython, so skip creating + // the pin objects for it. See explicit ignores in mpconfigboard.h. + // { MP_ROM_QSTR(MP_QSTR_USB_DM), MP_ROM_PTR(&pin_PA11) }, // MicroMod USB_D- (PA11) + // { MP_ROM_QSTR(MP_QSTR_USB_DP), MP_ROM_PTR(&pin_PA12) }, // MicroMod USB_D+ (PA12) + + // MicroMod USB host pins + { MP_ROM_QSTR(MP_QSTR_USBHOST_DM), MP_ROM_PTR(&pin_PB14) }, // MicroMod USBHOST_D- (PB14) + { MP_ROM_QSTR(MP_QSTR_USBHOST_DP), MP_ROM_PTR(&pin_PB15) }, // MicroMod USBHOST_D+ (PB15) + + // MicroMod CAN pins + { MP_ROM_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB08) }, // MicroMod CAN_RX (PB8) + { MP_ROM_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB09) }, // MicroMod CAN_TX (PB9) + + // Note: MicroMod UART (UART0) is not present in the edge connector pinout + // because the primary debug serial port is exposed as a virtual serial port + // over USB. + + // MicroMod UART1 pins + { MP_ROM_QSTR(MP_QSTR_UART_TX1), MP_ROM_PTR(&pin_PA02) }, // MicroMod UART_TX1 | CircuitPython TX (PA2) + { MP_ROM_QSTR(MP_QSTR_UART_RX1), MP_ROM_PTR(&pin_PA03) }, // MicroMod UART_RX1 | CircuitPython RX (PA3) + // { MP_ROM_QSTR(MP_QSTR_UART_RTS1), MP_ROM_PTR() }, // MicroMod RTS1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_UART_CTS1), MP_ROM_PTR() }, // MicroMod CTS1 (not connected) + + // CircuitPython default UART pins + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA02) }, // CircuitPython TX | MicroMod UART_TX1 (PA2) + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA03) }, // CircuitPython RX | MicroMod UART_RX1 (PA3) + + // MicroMod UART2 pins + // { MP_ROM_QSTR(MP_QSTR_UART_TX2), MP_ROM_PTR() }, // MicroMod UART_TX2 (not connected) + // { MP_ROM_QSTR(MP_QSTR_UART_RX2), MP_ROM_PTR() }, // MicroMod UART_RX2 (not connected) + + // MicroMod I2C pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_PB11) }, // MicroMod I2C_SDA | CircuitPython SDA (PB11) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_PB10) }, // MicroMod I2C_SCL | CircuitPython SCL (PB10) + + // CircuitPython default I2C pins + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB11) }, // CircuitPython SDA | MicroMod I2C_SDA (PB11) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB10) }, // CircuitPython SCL | MicroMod I2C_SCL (PB10) + + // MicroMod I2C interrupt pin + { MP_ROM_QSTR(MP_QSTR_I2C_INT), MP_ROM_PTR(&pin_PB01) }, // MicroMod I2C_INT (PB1) + + // MicroMod I2C1 pins + { MP_ROM_QSTR(MP_QSTR_I2C_SDA1), MP_ROM_PTR(&pin_PB07) }, // MicroMod I2C_SDA1 (PB7) + { MP_ROM_QSTR(MP_QSTR_I2C_SCL1), MP_ROM_PTR(&pin_PB06) }, // MicroMod I2C_SCL1 (PB6) + + // MicroMod SPI pins + { MP_ROM_QSTR(MP_QSTR_SPI_CIPO), MP_ROM_PTR(&pin_PA06) }, // MicroMod SPI_CIPO | CircuitPython CIPO (PA6) + { MP_ROM_QSTR(MP_QSTR_SPI_MISO), MP_ROM_PTR(&pin_PA06) }, // MicroMod SPI_MISO | CircuitPython MISO (PA6) + { MP_ROM_QSTR(MP_QSTR_SPI_COPI), MP_ROM_PTR(&pin_PA07) }, // MicroMod SPI_COPI | CircuitPython COPI | LED_DAT (PA7) + { MP_ROM_QSTR(MP_QSTR_SPI_MOSI), MP_ROM_PTR(&pin_PA07) }, // MicroMod SPI_MOSI | CircuitPython MOSI (PA7) + { MP_ROM_QSTR(MP_QSTR_SPI_SCK), MP_ROM_PTR(&pin_PA05) }, // MicroMod SPI_SCK | CircuitPython SCK | LED_CLK (PA5) + { MP_ROM_QSTR(MP_QSTR_SPI_CS), MP_ROM_PTR(&pin_PA04) }, // MicroMod SPI_CS | CircuitPython CS (PC4) + + // CircuitPython default SPI pins + { MP_ROM_QSTR(MP_QSTR_CIPO), MP_ROM_PTR(&pin_PA06) }, // CircuitPython CIPO | MicroMod SPI_CIPO (PA6) + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA06) }, // CircuitPython MISO | MicroMod SPI_MISO (PA6) + { MP_ROM_QSTR(MP_QSTR_COPI), MP_ROM_PTR(&pin_PA07) }, // CircuitPython COPI | MicroMod SPI_COPI | LED_DAT (PA7) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA07) }, // CircuitPython MOSI | MicroMod SPI_MOSI (PA7) + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA05) }, // CircuitPython SCK | MicroMod SPI_SCK | LED_CLK (PA5) + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PA04) }, // CircuitPython CS | MicroMod SPI_CS (PC4) + + // MicroMod 2-wire serial LED pins + { MP_ROM_QSTR(MP_QSTR_LED_DAT), MP_ROM_PTR(&pin_PA07) }, // MicroMod LED_DAT | SPI_COPI (PA7) + { MP_ROM_QSTR(MP_QSTR_LED_CLK), MP_ROM_PTR(&pin_PA05) }, // MicroMod LED_CLK | SPI_SCK (PA5) + + // MicroMod SDIO pins + // { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR() }, // MicroMod SDIO_SCK | SPI_SCK1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR() }, // MicroMod SDIO_CMD | SPI_COPI1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR() }, // MicroMod SDIO_DATA0 | SPI_CIPO1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR() }, // MicroMod SDIO_DATA1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR() }, // MicroMod SDIO_DATA2 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR() }, // MicroMod SDIO_DATA3 | SPI_CS1 (not connected) + + // MicroMod SPI1 pins + // { MP_ROM_QSTR(MP_QSTR_SPI_CIPO1), MP_ROM_PTR() }, // MicroMod SPI_CIPO1 | SDIO_DATA0 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_MISO1), MP_ROM_PTR() }, // MicroMod SPI_MISO1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_COPI1), MP_ROM_PTR() }, // MicroMod SPI_COPI1 | SDIO_CMD (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_MOSI1), MP_ROM_PTR() }, // MicroMod SPI_MOSI1 (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_SCK1), MP_ROM_PTR() }, // MicroMod SPI_SCK1 | SDIO_SCK (not connected) + // { MP_ROM_QSTR(MP_QSTR_SPI_CS1), MP_ROM_PTR() }, // MicroMod SPI_CS1 | SDIO_DATA3 (not connected) + + // MicroMod audio pins + // { MP_ROM_QSTR(MP_QSTR_AUD_MCLK), MP_ROM_PTR() }, // MicroMod AUD_MCLK (not connected) + // { MP_ROM_QSTR(MP_QSTR_AUD_OUT), MP_ROM_PTR(&pin_PB04) }, // MicroMod AUD_OUT | I2S_OUT | PCM_OUT | CAM_MCLK (PB4) + // { MP_ROM_QSTR(MP_QSTR_AUD_IN), MP_ROM_PTR(&pin_PB05) }, // MicroMod AUD_IN | I2S_IN | PCM_IN | CAM_PCLK (PB5) + // { MP_ROM_QSTR(MP_QSTR_AUD_LRCLK), MP_ROM_PTR(&pin_PA04) }, // MicroMod AUD_LRCLK | I2S_WS | PCM_SYNC | PDM_DATA (PA4) + // { MP_ROM_QSTR(MP_QSTR_AUD_BCLK), MP_ROM_PTR(&pin_PB03) }, // MicroMod AUD_BCLK | I2S_SCK | PCM_CLK | PDM_CLK (PB3) + + // MicroMod I2S pins + { MP_ROM_QSTR(MP_QSTR_I2S_OUT), MP_ROM_PTR(&pin_PB04) }, // MicroMod I2S_OUT | AUD_OUT | PCM_OUT | CAM_MCLK (PB4) + { MP_ROM_QSTR(MP_QSTR_I2S_IN), MP_ROM_PTR(&pin_PB05) }, // MicroMod I2S_IN | AUD_IN | PCM_IN | CAM_PCLK (PB5) + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_PA04) }, // MicroMod I2S_WS | AUD_LRCLK | PCM_SYNC | PDM_DATA (PA4) + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_PB03) }, // MicroMod I2S_SCK | AUD_BCLK | PCM_CLK | PDM_CLK (PB3) + + // MicroMod PCM pins + { MP_ROM_QSTR(MP_QSTR_PCM_OUT), MP_ROM_PTR(&pin_PB04) }, // MicroMod PCM_OUT | AUD_OUT | I2S_OUT | CAM_MCLK (PB4) + { MP_ROM_QSTR(MP_QSTR_PCM_IN), MP_ROM_PTR(&pin_PB05) }, // MicroMod PCM_IN | AUD_IN | I2S_IN | CAM_PCLK (PB5) + { MP_ROM_QSTR(MP_QSTR_PCM_SYNC), MP_ROM_PTR(&pin_PA04) }, // MicroMod PCM_SYNC | AUD_LRCLK | I2S_WS | PDM_DATA (PA4) + { MP_ROM_QSTR(MP_QSTR_PCM_CLK), MP_ROM_PTR(&pin_PB03) }, // MicroMod PCM_CLK | AUD_BCLK | I2S_SCK | PDM_CLK (PB3) + + // MicroMod PDM pins + { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_PA04) }, // MicroMod PDM_DATA | AUD_LRCLK | I2S_WS | PCM_SYNC (PA4) + { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_PB03) }, // MicroMod PDM_CLK | AUD_BCLK | I2S_SCK | PCM_CLK (PB3) + + // MicroMod SWD pins + { MP_ROM_QSTR(MP_QSTR_SWDIO), MP_ROM_PTR(&pin_PA13) }, // MicroMod SWDIO (PA13) + { MP_ROM_QSTR(MP_QSTR_SWCLK), MP_ROM_PTR(&pin_PA14) }, // MicroMod SWDCK (PA14) + // { MP_ROM_QSTR(MP_QSTR_SWO), MP_ROM_PTR() }, // MicroMod SWO | G11 (not connected) + + // MicroMod ADC pins + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PC05) }, // MicroMod A0 (PC5) + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB00) }, // MicroMod A1 (PB0) + + // MicroMod PWM pins + { MP_ROM_QSTR(MP_QSTR_PWM0), MP_ROM_PTR(&pin_PC06) }, // MicroMod PWM0 (PC6) + { MP_ROM_QSTR(MP_QSTR_PWM1), MP_ROM_PTR(&pin_PC07) }, // MicroMod PWM1 (PC7) + + // MicroMod digital pins + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PC00) }, // MicroMod D0 (PC0) + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PC01) }, // MicroMod D1 | CAM_TRIG (PC1) + + // MicroMod general purpose pins + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_PD02) }, // MicroMod G0 | BUS0 (PD2) + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_PA08) }, // MicroMod G1 | BUS1 (PA8) + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_PA00) }, // MicroMod G2 | BUS2 (PA0) + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_PC08) }, // MicroMod G3 | BUS3 (PC8) + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_PC09) }, // MicroMod G4 | BUS4 (PC9) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_PC13) }, // MicroMod G5 | BUS5 (PC13) + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_PC02) }, // MicroMod G6 | BUS6 (PC2) + // { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR() }, // MicroMod G7 | BUS7 (not connected) + // { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR() }, // MicroMod G8 (not connected) + // { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR() }, // MicroMod G9 | ADC_D- | CAM_HSYNC (not connected) + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_PB13) }, // MicroMod G10 | ADC_D+ | CAM_VSYNC (PB13) + { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_PB12) }, // MicroMod G11 | SWO (PB12) + + // MicroMod 8-bit bus pins + { MP_ROM_QSTR(MP_QSTR_BUS0), MP_ROM_PTR(&pin_PD02) }, // MicroMod BUS0 | G0 (PD2) + { MP_ROM_QSTR(MP_QSTR_BUS1), MP_ROM_PTR(&pin_PA08) }, // MicroMod BUS1 | G1 (PA8) + { MP_ROM_QSTR(MP_QSTR_BUS2), MP_ROM_PTR(&pin_PA00) }, // MicroMod BUS2 | G2 (PA0) + { MP_ROM_QSTR(MP_QSTR_BUS3), MP_ROM_PTR(&pin_PC08) }, // MicroMod BUS3 | G3 (PC8) + { MP_ROM_QSTR(MP_QSTR_BUS4), MP_ROM_PTR(&pin_PC09) }, // MicroMod BUS4 | G4 (PC9) + { MP_ROM_QSTR(MP_QSTR_BUS5), MP_ROM_PTR(&pin_PC13) }, // MicroMod BUS5 | G5 (PC13) + { MP_ROM_QSTR(MP_QSTR_BUS6), MP_ROM_PTR(&pin_PC02) }, // MicroMod BUS6 | G6 (PC2) + // { MP_ROM_QSTR(MP_QSTR_BUS7), MP_ROM_PTR() }, // MicroMod BUS7 | G7 (not connected) + + // MicroMod differential ADC input pins + // { MP_ROM_QSTR(MP_QSTR_ADC_DM), MP_ROM_PTR() }, // MicroMod ADC_D- | G9 | CAM_HSYNC (not connected) + // { MP_ROM_QSTR(MP_QSTR_ADC_DP), MP_ROM_PTR(&pin_PB13) }, // MicroMod ADC_D+ | G10 | CAM_VSYNC (PB13) + + // MicroMod camera pins + // { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR(&pin_PB04) }, // MicroMod CAM_MCLK | AUD_OUT | I2S_OUT | PCM_OUT (PB4) + // { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_PB05) }, // MicroMod CAM_PCLK | AUD_IN | I2S_IN | PCM_IN (PB5) + // { MP_ROM_QSTR(MP_QSTR_CAM_TRIG), MP_ROM_PTR(&pin_PC01) }, // MicroMod CAM_TRIG | D1 (PC1) + // { MP_ROM_QSTR(MP_QSTR_CAM_HSYNC), MP_ROM_PTR() }, // MicroMod CAM_HSYNC | ADC_D- | G9 (not connected) + // { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_PB13) }, // MicroMod CAM_VSYNC | ADC_D+ | G10 (PB13) + + // Module-specific aliases (not part of the MicroMod spec) + { MP_ROM_QSTR(MP_QSTR_HOST_VBUS), MP_ROM_PTR(&pin_PB13) }, // HOST_VBUS | G10 | ADC_D+ | CAM_VSYNC (PB13) + { MP_ROM_QSTR(MP_QSTR_HOST_ID), MP_ROM_PTR(&pin_PB12) }, // HOST_ID | G11 | SWO (PB12) + + // CircuitPython board objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, // CircuitPython I2C + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, // CircuitPython SPI + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, // CircuitPython UART +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); From e587bd7dc047716f6254f9e6f6368cfc28ab8152 Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Tue, 10 Aug 2021 11:17:06 +0100 Subject: [PATCH 47/63] Added final USB PIDs --- .../raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk | 4 ++-- ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk index a513a1df11..b52b31a9d9 100644 --- a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.mk @@ -1,5 +1,5 @@ -USB_VID = 0x16D0 -USB_PID = 0x08C7 +USB_VID = 0x2E8A +USB_PID = 0x1009 USB_PRODUCT = "Interstate 75" USB_MANUFACTURER = "Pimoroni" diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk index 3b2ef47fe8..10bfb5cc87 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.mk @@ -1,5 +1,5 @@ -USB_VID = 0x16D0 -USB_PID = 0x08C7 +USB_VID = 0x2E8A +USB_PID = 0x100a USB_PRODUCT = "Plasma 2040" USB_MANUFACTURER = "Pimoroni" From f0859ac954e71e00e298843dc7f9f9c09a9bf570 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 10 Aug 2021 15:23:45 -0700 Subject: [PATCH 48/63] Switch SAMD21 ticks to PER event The EVSYS is used to generate an interrupt from the event. This simplifies timing used in pulseio that conflicted with the auto-reload countdown. Fixes #3890 --- lib/utils/pyexec.c | 2 +- ports/atmel-samd/audio_dma.c | 30 +---- ports/atmel-samd/audio_dma.h | 2 + ports/atmel-samd/supervisor/port.c | 187 ++++++++++++++++++----------- 4 files changed, 126 insertions(+), 95 deletions(-) diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index 50f73fc170..bc47f61829 100644 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -149,7 +149,7 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input mp_hal_stdout_tx_strn("\x04", 1); } // check for SystemExit - if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { + if (mp_obj_is_subclass_fast(mp_obj_get_type((mp_obj_t)nlr.ret_val), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { // at the moment, the value of SystemExit is unused ret = pyexec_system_exit; #if CIRCUITPY_ALARM diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c index 7f1260973d..fca8c23a78 100644 --- a/ports/atmel-samd/audio_dma.c +++ b/ports/atmel-samd/audio_dma.c @@ -265,13 +265,13 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, #ifdef SAM_D5X_E5X int irq = dma->event_channel < 4 ? EVSYS_0_IRQn + dma->event_channel : EVSYS_4_IRQn; + // Only disable and clear on SAMD51 because the SAMD21 shares EVSYS with ticks. + NVIC_DisableIRQ(irq); + NVIC_ClearPendingIRQ(irq); #else int irq = EVSYS_IRQn; #endif - NVIC_DisableIRQ(irq); - NVIC_ClearPendingIRQ(irq); - DmacDescriptor *first_descriptor = dma_descriptor(dma_channel); setup_audio_descriptor(first_descriptor, dma->beat_size, output_spacing, output_register_address); if (single_buffer) { @@ -366,7 +366,7 @@ STATIC void dma_callback_fun(void *arg) { audio_dma_load_next_block(dma); } -void evsyshandler_common(void) { +void audio_evsys_handler(void) { for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) { audio_dma_t *dma = audio_dma_state[i]; if (dma == NULL) { @@ -380,26 +380,4 @@ void evsyshandler_common(void) { } } -#ifdef SAM_D5X_E5X -void EVSYS_0_Handler(void) { - evsyshandler_common(); -} -void EVSYS_1_Handler(void) { - evsyshandler_common(); -} -void EVSYS_2_Handler(void) { - evsyshandler_common(); -} -void EVSYS_3_Handler(void) { - evsyshandler_common(); -} -void EVSYS_4_Handler(void) { - evsyshandler_common(); -} -#else -void EVSYS_Handler(void) { - evsyshandler_common(); -} -#endif - #endif diff --git a/ports/atmel-samd/audio_dma.h b/ports/atmel-samd/audio_dma.h index bc5beb3bf5..d06b589759 100644 --- a/ports/atmel-samd/audio_dma.h +++ b/ports/atmel-samd/audio_dma.h @@ -99,4 +99,6 @@ void audio_dma_background(void); uint8_t find_sync_event_channel_raise(void); +void audio_evsys_handler(void); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_AUDIO_DMA_H diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index c03b79ce4f..73303a8218 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -91,26 +91,19 @@ #if CIRCUITPY_PEW #include "common-hal/_pew/PewPew.h" #endif -volatile bool hold_interrupt = false; +static volatile bool sleep_ok = true; #ifdef SAMD21 -static void rtc_set_continuous(bool continuous) { - while (RTC->MODE0.STATUS.bit.SYNCBUSY) { - ; - } - RTC->MODE0.READREQ.reg = (continuous ? RTC_READREQ_RCONT : 0) | 0x0010; - while (RTC->MODE0.STATUS.bit.SYNCBUSY) { - ; - } -} +static uint8_t _tick_event_channel = 0; +// Sleeping requires a register write that can stall interrupt handling. Turning +// off sleeps allows for more accurate interrupt timing. (Python still thinks +// it is sleeping though.) void rtc_start_pulse(void) { - rtc_set_continuous(true); - hold_interrupt = true; + sleep_ok = false; } void rtc_end_pulse(void) { - hold_interrupt = false; - rtc_set_continuous(false); + sleep_ok = true; } #endif @@ -161,6 +154,20 @@ static void save_usb_clock_calibration(void) { } #endif +static void rtc_continuous_mode(void) { + #ifdef SAMD21 + while (RTC->MODE0.STATUS.bit.SYNCBUSY) { + } + RTC->MODE0.READREQ.reg = RTC_READREQ_RCONT | 0x0010; + while (RTC->MODE0.STATUS.bit.SYNCBUSY) { + } + // Do the first request and wait for it. + RTC->MODE0.READREQ.reg = RTC_READREQ_RREQ | RTC_READREQ_RCONT | 0x0010; + while (RTC->MODE0.STATUS.bit.SYNCBUSY) { + } + #endif +} + static void rtc_init(void) { #ifdef SAMD21 _gclk_enable_channel(RTC_GCLK_ID, GCLK_CLKCTRL_GEN_GCLK2_Val); @@ -168,9 +175,17 @@ static void rtc_init(void) { while (RTC->MODE0.CTRL.bit.SWRST != 0) { } + // Turn on periodic events to use as tick. We control whether it interrupts + // us with the EVSYS INTEN register. + RTC->MODE0.EVCTRL.reg = RTC_MODE0_EVCTRL_PEREO2; + RTC->MODE0.CTRL.reg = RTC_MODE0_CTRL_ENABLE | RTC_MODE0_CTRL_MODE_COUNT32 | RTC_MODE0_CTRL_PRESCALER_DIV2; + + // Turn on continuous sync of the count register. This will speed up all + // tick reads. + rtc_continuous_mode(); #endif #ifdef SAM_D5X_E5X hri_mclk_set_APBAMASK_RTC_bit(MCLK); @@ -363,6 +378,9 @@ void reset_port(void) { #endif reset_event_system(); + #ifdef SAMD21 + _tick_event_channel = EVSYS_SYNCH_NUM; + #endif reset_all_pins(); @@ -430,21 +448,14 @@ uint32_t port_get_saved_word(void) { // TODO: Move this to an RTC backup register so we can preserve it when only the BACKUP power domain // is enabled. static volatile uint64_t overflowed_ticks = 0; -#ifdef SAMD21 -static volatile bool _ticks_enabled = false; -#endif static uint32_t _get_count(uint64_t *overflow_count) { #ifdef SAM_D5X_E5X while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COUNTSYNC | RTC_MODE0_SYNCBUSY_COUNT)) != 0) { } #endif - #ifdef SAMD21 - // Request a read so we don't stall the bus later. See section 14.3.1.5 Read Request - RTC->MODE0.READREQ.reg = RTC_READREQ_RREQ | 0x0010; - while (RTC->MODE0.STATUS.bit.SYNCBUSY != 0) { - } - #endif + // SAMD21 does continuous sync so we don't need to wait here. + // Disable interrupts so we can grab the count and the overflow. common_hal_mcu_disable_interrupts(); uint32_t count = RTC->MODE0.COUNT.reg; @@ -458,29 +469,6 @@ static uint32_t _get_count(uint64_t *overflow_count) { volatile bool _woken_up; -static void _port_interrupt_after_ticks(uint32_t ticks) { - uint32_t current_ticks = _get_count(NULL); - if (ticks > 1 << 28) { - // We'll interrupt sooner with an overflow. - return; - } - #ifdef SAMD21 - if (hold_interrupt) { - return; - } - #endif - uint32_t target = current_ticks + (ticks << 4); - RTC->MODE0.COMP[0].reg = target; - #ifdef SAM_D5X_E5X - while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COMP0)) != 0) { - } - #endif - RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; - RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0; - current_ticks = _get_count(NULL); - _woken_up = current_ticks >= target; -} - void RTC_Handler(void) { uint32_t intflag = RTC->MODE0.INTFLAG.reg; if (intflag & RTC_MODE0_INTFLAG_OVF) { @@ -497,19 +485,10 @@ void RTC_Handler(void) { } #endif if (intflag & RTC_MODE0_INTFLAG_CMP0) { - // Clear the interrupt because we may have hit a sleep and _ticks_enabled + // Clear the interrupt because we may have hit a sleep RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; _woken_up = true; - #ifdef SAMD21 - if (_ticks_enabled) { - // Do things common to all ports when the tick occurs. - supervisor_tick(); - // Check _ticks_enabled again because a tick handler may have turned it off. - if (_ticks_enabled) { - _port_interrupt_after_ticks(1); - } - } - #endif + // SAMD21 ticks are handled by EVSYS #ifdef SAM_D5X_E5X RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0; #endif @@ -526,6 +505,39 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) { return overflow_count + current_ticks / 16; } +void evsyshandler_common(void) { + #ifdef SAMD21 + if (_tick_event_channel < EVSYS_SYNCH_NUM && event_interrupt_active(_tick_event_channel)) { + supervisor_tick(); + } + #endif + #if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO + audio_evsys_handler(); + #endif +} + +#ifdef SAM_D5X_E5X +void EVSYS_0_Handler(void) { + evsyshandler_common(); +} +void EVSYS_1_Handler(void) { + evsyshandler_common(); +} +void EVSYS_2_Handler(void) { + evsyshandler_common(); +} +void EVSYS_3_Handler(void) { + evsyshandler_common(); +} +void EVSYS_4_Handler(void) { + evsyshandler_common(); +} +#else +void EVSYS_Handler(void) { + evsyshandler_common(); +} +#endif + // Enable 1/1024 second tick. void port_enable_tick(void) { #ifdef SAM_D5X_E5X @@ -533,9 +545,23 @@ void port_enable_tick(void) { RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_PER2; #endif #ifdef SAMD21 - // TODO: Switch to using the PER *event* from the RTC to generate an interrupt via EVSYS. - _ticks_enabled = true; - _port_interrupt_after_ticks(1); + // SAMD21 ticks won't survive port_reset(). This *should* be ok since it'll + // be triggered by ticks and no Python will be running. + if (_tick_event_channel >= EVSYS_SYNCH_NUM) { + turn_on_event_system(); + _tick_event_channel = find_sync_event_channel(); + } + // This turns on both the event detected interrupt (EVD) and overflow (OVR). + init_event_channel_interrupt(_tick_event_channel, CORE_GCLK, EVSYS_ID_GEN_RTC_PER_2); + // Disable overflow interrupt because we ignore it. + if (_tick_event_channel >= 8) { + uint8_t value = 1 << (_tick_event_channel - 8); + EVSYS->INTENCLR.reg = EVSYS_INTENSET_OVRp8(value); + } else { + uint8_t value = 1 << _tick_event_channel; + EVSYS->INTENCLR.reg = EVSYS_INTENSET_OVR(value); + } + NVIC_EnableIRQ(EVSYS_IRQn); #endif } @@ -545,21 +571,46 @@ void port_disable_tick(void) { RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_PER2; #endif #ifdef SAMD21 - _ticks_enabled = false; - RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0; + if (_tick_event_channel >= 8) { + uint8_t value = 1 << (_tick_event_channel - 8); + EVSYS->INTENCLR.reg = EVSYS_INTENSET_EVDp8(value); + } else { + uint8_t value = 1 << _tick_event_channel; + EVSYS->INTENCLR.reg = EVSYS_INTENSET_EVD(value); + } #endif } -// This is called by sleep, we ignore it when our ticks are enabled because -// they'll wake us up earlier. If we don't, we'll mess up ticks by overwriting -// the next RTC wake up time. void port_interrupt_after_ticks(uint32_t ticks) { + uint32_t current_ticks = _get_count(NULL); + if (ticks > 1 << 28) { + // We'll interrupt sooner with an overflow. + return; + } #ifdef SAMD21 - if (_ticks_enabled) { + if (!sleep_ok) { return; } #endif - _port_interrupt_after_ticks(ticks); + + uint32_t target = current_ticks + (ticks << 4); + // Try and avoid a bus stall when writing COMP by checking for an obvious + // existing sync. + while (RTC->MODE0.STATUS.bit.SYNCBUSY == 1) { + } + // Writing the COMP register can take up to 180us to synchronize. During + // this time, the bus will stall and no interrupts will be serviced. + RTC->MODE0.COMP[0].reg = target; + #ifdef SAM_D5X_E5X + while ((RTC->MODE0.SYNCBUSY.reg & (RTC_MODE0_SYNCBUSY_COMP0)) != 0) { + } + #endif + RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; + RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0; + // Set continuous mode again because setting COMP may disable it. + rtc_continuous_mode(); + current_ticks = _get_count(NULL); + _woken_up = current_ticks >= target; } void port_idle_until_interrupt(void) { @@ -571,7 +622,7 @@ void port_idle_until_interrupt(void) { } #endif common_hal_mcu_disable_interrupts(); - if (!tud_task_event_ready() && !hold_interrupt && !_woken_up) { + if (!tud_task_event_ready() && sleep_ok && !_woken_up) { __DSB(); __WFI(); } From 24e61a7da89795f6361c35fbc0f924dc4bcf63da Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Tue, 10 Aug 2021 22:00:09 -0400 Subject: [PATCH 49/63] Track more carefully which audio buffers to fill, based on interrupt channels --- ports/raspberrypi/audio_dma.c | 185 +++++++++++------- ports/raspberrypi/audio_dma.h | 9 +- .../common-hal/audiopwmio/PWMAudioOut.c | 42 ++-- shared-module/audiocore/WaveFile.c | 2 +- 4 files changed, 136 insertions(+), 102 deletions(-) diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index da3d851392..012d755e66 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -28,6 +28,7 @@ #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" +#include "shared-bindings/microcontroller/__init__.h" #include "supervisor/background_callback.h" #include "py/mpstate.h" @@ -47,71 +48,78 @@ void audio_dma_reset(void) { } } -void audio_dma_convert_signed(audio_dma_t *dma, uint8_t *buffer, uint32_t buffer_length, - uint8_t **output_buffer, uint32_t *output_buffer_length) { - size_t output_buffer_max_length; - if (dma->first_buffer_free) { - *output_buffer = dma->first_buffer; - output_buffer_max_length = dma->first_buffer_length; - } else { - *output_buffer = dma->second_buffer; - output_buffer_max_length = dma->second_buffer_length; - } +STATIC void audio_dma_convert_samples( + audio_dma_t *dma, + uint8_t *input, uint32_t input_length, + uint8_t *available_output_buffer, uint32_t available_output_buffer_length, + uint8_t **output, uint32_t *output_length) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" + + // Check whether a conversion is necessary if (dma->signed_to_unsigned || dma->unsigned_to_signed || dma->sample_spacing > 1 || (dma->sample_resolution != dma->output_resolution)) { - *output_buffer_length = buffer_length / dma->sample_spacing; + + // Must convert. + // Write the conversion into the passed-in output buffer + *output = available_output_buffer; + *output_length = input_length / dma->sample_spacing; + + if (*output_length > available_output_buffer_length) { + mp_raise_RuntimeError(translate("Internal audio buffer too small")); + } + uint32_t out_i = 0; if (dma->sample_resolution <= 8 && dma->output_resolution > 8) { - // reading bytes, writing 16-bit samples - *output_buffer_length = *output_buffer_length * 2; - if (*output_buffer_length > output_buffer_max_length) { + // reading bytes, writing 16-bit words, so output buffer will be bigger. + + *output_length = *output_length * 2; + if (*output_length > available_output_buffer_length) { mp_raise_RuntimeError(translate("Internal audio buffer too small")); } size_t shift = dma->output_resolution - dma->sample_resolution; - for (uint32_t i = 0; i < buffer_length; i += dma->sample_spacing) { + for (uint32_t i = 0; i < input_length; i += dma->sample_spacing) { if (dma->signed_to_unsigned) { - ((uint16_t *)*output_buffer)[out_i] = ((uint16_t)((int8_t *)buffer)[i] + 0x80) << shift; + ((uint16_t *)*output)[out_i] = ((uint16_t)((int8_t *)input)[i] + 0x80) << shift; } else if (dma->unsigned_to_signed) { - ((int16_t *)*output_buffer)[out_i] = ((int16_t)((uint8_t *)buffer)[i] - 0x80) << shift; + ((int16_t *)*output)[out_i] = ((int16_t)((uint8_t *)input)[i] - 0x80) << shift; } else { - ((uint16_t *)*output_buffer)[out_i] = ((uint16_t)((uint8_t *)buffer)[i]) << shift; + ((uint16_t *)*output)[out_i] = ((uint16_t)((uint8_t *)input)[i]) << shift; } out_i += 1; } } else if (dma->sample_resolution <= 8 && dma->output_resolution <= 8) { - for (uint32_t i = 0; i < buffer_length; i += dma->sample_spacing) { + for (uint32_t i = 0; i < input_length; i += dma->sample_spacing) { if (dma->signed_to_unsigned) { - ((uint8_t *)*output_buffer)[out_i] = ((int8_t *)buffer)[i] + 0x80; + ((uint8_t *)*output)[out_i] = ((int8_t *)input)[i] + 0x80; } else if (dma->unsigned_to_signed) { - ((int8_t *)*output_buffer)[out_i] = ((uint8_t *)buffer)[i] - 0x80; + ((int8_t *)*output)[out_i] = ((uint8_t *)input)[i] - 0x80; } else { - ((uint8_t *)*output_buffer)[out_i] = ((uint8_t *)buffer)[i]; + ((uint8_t *)*output)[out_i] = ((uint8_t *)input)[i]; } out_i += 1; } } else if (dma->sample_resolution > 8 && dma->output_resolution > 8) { size_t shift = 16 - dma->output_resolution; - for (uint32_t i = 0; i < buffer_length / 2; i += dma->sample_spacing) { + for (uint32_t i = 0; i < input_length / 2; i += dma->sample_spacing) { if (dma->signed_to_unsigned) { - ((uint16_t *)*output_buffer)[out_i] = ((int16_t *)buffer)[i] + 0x8000; + ((uint16_t *)*output)[out_i] = ((int16_t *)input)[i] + 0x8000; } else if (dma->unsigned_to_signed) { - ((int16_t *)*output_buffer)[out_i] = ((uint16_t *)buffer)[i] - 0x8000; + ((int16_t *)*output)[out_i] = ((uint16_t *)input)[i] - 0x8000; } else { - ((uint16_t *)*output_buffer)[out_i] = ((uint16_t *)buffer)[i]; + ((uint16_t *)*output)[out_i] = ((uint16_t *)input)[i]; } if (dma->output_resolution < 16) { if (dma->output_signed) { - ((int16_t *)*output_buffer)[out_i] = ((int16_t *)*output_buffer)[out_i] >> shift; + ((int16_t *)*output)[out_i] = ((int16_t *)*output)[out_i] >> shift; } else { - ((uint16_t *)*output_buffer)[out_i] = ((uint16_t *)*output_buffer)[out_i] >> shift; + ((uint16_t *)*output)[out_i] = ((uint16_t *)*output)[out_i] >> shift; } } out_i += 1; @@ -122,65 +130,70 @@ void audio_dma_convert_signed(audio_dma_t *dma, uint8_t *buffer, uint32_t buffer mp_raise_RuntimeError(translate("Audio conversion not implemented")); } } else { - *output_buffer = buffer; - *output_buffer_length = buffer_length; + // No conversion necessary. Designate the input buffer as the output buffer. + *output = input; + *output_length = input_length; } #pragma GCC diagnostic pop - dma->first_buffer_free = !dma->first_buffer_free; } -void audio_dma_load_next_block(audio_dma_t *dma) { - uint8_t dma_channel = dma->channel[1]; - if (dma->first_channel_free) { - dma_channel = dma->channel[0]; - } - dma->first_channel_free = !dma->first_channel_free; +// channel_idx is 0 or 1. +STATIC void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { + size_t dma_channel = dma->channel[buffer_idx]; - uint8_t *output_buffer; - uint32_t output_buffer_length; audioio_get_buffer_result_t get_buffer_result; - uint8_t *buffer; - uint32_t buffer_length; + uint8_t *sample_buffer; + uint32_t sample_buffer_length; get_buffer_result = audiosample_get_buffer(dma->sample, - dma->single_channel_output, dma->audio_channel, &buffer, &buffer_length); + dma->single_channel_output, dma->audio_channel, &sample_buffer, &sample_buffer_length); if (get_buffer_result == GET_BUFFER_ERROR) { audio_dma_stop(dma); return; } - audio_dma_convert_signed(dma, buffer, buffer_length, &output_buffer, &output_buffer_length); + // Convert the sample format resolution and signedness, as necessary. + // The input sample buffer is what was read from a file or a raw sample buffer. + // The output buffer is one of the DMA buffers (passed in), or if no conversion was done, + // the original sample buffer (to save copying). - // If we don't have an output buffer, save the pointer to first_buffer for use in the single - // buffer special case. - if (dma->first_buffer == NULL) { - dma->first_buffer = output_buffer; - } + // audio_dma_convert_samples() will write the converted samples into the given output + // buffer if necessary. If no conversion was needed, it will return the sample buffer + // as the output buffer. + uint8_t *output_buffer; + uint32_t output_buffer_length; + + audio_dma_convert_samples(dma, sample_buffer, sample_buffer_length, + dma->buffer[buffer_idx], dma->buffer_length[buffer_idx], + &output_buffer, &output_buffer_length); - dma_channel_set_trans_count(dma_channel, output_buffer_length / dma->output_size, false /* trigger */); dma_channel_set_read_addr(dma_channel, output_buffer, false /* trigger */); + dma_channel_set_trans_count(dma_channel, output_buffer_length / dma->output_size, false /* trigger */); if (get_buffer_result == GET_BUFFER_DONE) { if (dma->loop) { audiosample_reset_buffer(dma->sample, dma->single_channel_output, dma->audio_channel); } else { + // Set channel trigger to ourselves so we don't keep going. + dma_channel_hw_t *c = &dma_hw->ch[dma_channel]; + c->al1_ctrl = + (c->al1_ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | + (dma_channel << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB); + if (output_buffer_length == 0 && !dma_channel_is_busy(dma->channel[0]) && !dma_channel_is_busy(dma->channel[1])) { // No data has been read, and both DMA channels have now finished, so it's safe to stop. audio_dma_stop(dma); dma->playing_in_progress = false; - } else { - // Set channel trigger to ourselves so we don't keep going. - dma_channel_hw_t *c = &dma_hw->ch[dma_channel]; - c->al1_ctrl = (c->al1_ctrl & ~DMA_CH0_CTRL_TRIG_CHAIN_TO_BITS) | (dma_channel << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB); } } } } // Playback should be shutdown before calling this. -audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, +audio_dma_result audio_dma_setup_playback( + audio_dma_t *dma, mp_obj_t sample, bool loop, bool single_channel_output, @@ -189,6 +202,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, uint8_t output_resolution, uint32_t output_register_address, uint8_t dma_trigger_source) { + // Use two DMA channels to play because the DMA can't wrap to itself without the // buffer being power of two aligned. int dma_channel_0_maybe = dma_claim_unused_channel(false); @@ -213,14 +227,15 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, dma->unsigned_to_signed = false; dma->output_signed = output_signed; dma->sample_spacing = 1; - dma->first_channel_free = true; dma->output_resolution = output_resolution; dma->sample_resolution = audiosample_bits_per_sample(sample); dma->output_register_address = output_register_address; audiosample_reset_buffer(sample, single_channel_output, audio_channel); - bool single_buffer; + + bool single_buffer; // True if data fits in one single buffer. + bool samples_signed; uint32_t max_buffer_length; audiosample_get_buffer_structure(sample, single_channel_output, &single_buffer, &samples_signed, @@ -236,17 +251,16 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, max_buffer_length /= dma->sample_spacing; } - dma->first_buffer = (uint8_t *)m_realloc(dma->first_buffer, max_buffer_length); - dma->first_buffer_length = max_buffer_length; - if (dma->first_buffer == NULL) { + dma->buffer[0] = (uint8_t *)m_realloc(dma->buffer[0], max_buffer_length); + dma->buffer_length[0] = max_buffer_length; + if (dma->buffer[0] == NULL) { return AUDIO_DMA_MEMORY_ERROR; } - dma->first_buffer_free = true; if (!single_buffer) { - dma->second_buffer = (uint8_t *)m_realloc(dma->second_buffer, max_buffer_length); - dma->second_buffer_length = max_buffer_length; - if (dma->second_buffer == NULL) { + dma->buffer[1] = (uint8_t *)m_realloc(dma->buffer[1], max_buffer_length); + dma->buffer_length[1] = max_buffer_length; + if (dma->buffer[1] == NULL) { return AUDIO_DMA_MEMORY_ERROR; } } @@ -276,9 +290,11 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, channel_config_set_dreq(&c, dma_trigger_source); channel_config_set_read_increment(&c, true); channel_config_set_write_increment(&c, false); + // Chain to the other channel by default. channel_config_set_chain_to(&c, dma->channel[(i + 1) % 2]); dma_channel_set_config(dma->channel[i], &c, false /* trigger */); + dma_channel_set_write_addr(dma->channel[i], (void *)output_register_address, false /* trigger */); } @@ -288,9 +304,9 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, MP_STATE_PORT(playing_audio)[dma->channel[1]] = dma; // Load the first two blocks up front. - audio_dma_load_next_block(dma); + audio_dma_load_next_block(dma, 0); if (!single_buffer) { - audio_dma_load_next_block(dma); + audio_dma_load_next_block(dma, 1); } // Special case the DMA for a single buffer. It's commonly used for a single wave length of sound @@ -307,11 +323,11 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, channel_config_set_chain_to(&c, dma->channel[1]); // Chain to ourselves so we stop. dma_channel_configure(dma->channel[1], &c, &dma_hw->ch[dma->channel[0]].al3_read_addr_trig, // write address - &dma->first_buffer, // read address + &dma->buffer[0], // read address 1, // transaction count false); // trigger } else { - // Enable our DMA channels on DMA0 to the CPU. This will wake us up when + // Enable our DMA channels on DMA_IRQ_0 to the CPU. This will wake us up when // we're WFI. dma_hw->inte0 |= (1 << dma->channel[0]) | (1 << dma->channel[1]); irq_set_mask_enabled(1 << DMA_IRQ_0, true); @@ -402,18 +418,19 @@ bool audio_dma_get_paused(audio_dma_t *dma) { } void audio_dma_init(audio_dma_t *dma) { - dma->first_buffer = NULL; - dma->second_buffer = NULL; + dma->buffer[0] = NULL; + dma->buffer[1] = NULL; + dma->channel[0] = NUM_DMA_CHANNELS; dma->channel[1] = NUM_DMA_CHANNELS; } void audio_dma_deinit(audio_dma_t *dma) { - m_free(dma->first_buffer); - dma->first_buffer = NULL; + m_free(dma->buffer[0]); + dma->buffer[0] = NULL; - m_free(dma->second_buffer); - dma->second_buffer = NULL; + m_free(dma->buffer[1]); + dma->buffer[1] = NULL; } bool audio_dma_get_playing(audio_dma_t *dma) { @@ -433,7 +450,25 @@ STATIC void dma_callback_fun(void *arg) { return; } - audio_dma_load_next_block(dma); + common_hal_mcu_disable_interrupts(); + uint32_t channels_to_load_mask = dma->channels_to_load_mask; + dma->channels_to_load_mask = 0; + common_hal_mcu_enable_interrupts(); + + // Load the blocks for the requested channels. + uint32_t channel = 0; + while (channels_to_load_mask) { + if (channels_to_load_mask & 1) { + if (dma->channel[0] == channel) { + audio_dma_load_next_block(dma, 0); + } + if (dma->channel[1] == channel) { + audio_dma_load_next_block(dma, 1); + } + } + channels_to_load_mask >>= 1; + channel++; + } } void isr_dma_0(void) { @@ -441,6 +476,8 @@ void isr_dma_0(void) { uint32_t mask = 1 << i; if ((dma_hw->intr & mask) != 0 && MP_STATE_PORT(playing_audio)[i] != NULL) { audio_dma_t *dma = MP_STATE_PORT(playing_audio)[i]; + // Record all channels whose DMA has completed; they need loading. + dma->channels_to_load_mask |= mask; background_callback_add(&dma->callback, dma_callback_fun, (void *)dma); dma_hw->ints0 = mask; } diff --git a/ports/raspberrypi/audio_dma.h b/ports/raspberrypi/audio_dma.h index 1ef1ca6d29..0ca911d337 100644 --- a/ports/raspberrypi/audio_dma.h +++ b/ports/raspberrypi/audio_dma.h @@ -43,15 +43,12 @@ typedef struct { bool signed_to_unsigned; bool unsigned_to_signed; bool output_signed; - bool first_channel_free; - bool first_buffer_free; bool playing_in_progress; uint8_t output_resolution; // in bits uint8_t sample_resolution; // in bits - uint8_t *first_buffer; - size_t first_buffer_length; - uint8_t *second_buffer; - size_t second_buffer_length; + uint8_t *buffer[2]; + size_t buffer_length[2]; + uint32_t channels_to_load_mask; uint32_t output_register_address; background_callback_t callback; } audio_dma_t; diff --git a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c index efaeb5ef35..ea587867c0 100644 --- a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c @@ -157,27 +157,6 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, tx_register += self->left_pwm.channel * sizeof(uint16_t); } - audio_dma_result result = audio_dma_setup_playback( - &self->dma, - sample, - loop, - false, // single channel - 0, // audio channel - false, // output signed - BITS_PER_SAMPLE, - (uint32_t)tx_register, // output register: PWM cc register - 0x3b + pacing_timer); // data request line - - if (result == AUDIO_DMA_DMA_BUSY) { - common_hal_audiopwmio_pwmaudioout_stop(self); - mp_raise_RuntimeError(translate("No DMA channel found")); - } - if (result == AUDIO_DMA_MEMORY_ERROR) { - common_hal_audiopwmio_pwmaudioout_stop(self); - mp_raise_RuntimeError(translate("Unable to allocate buffers for signed conversion")); - } - - // OK! We got all of the resources we need and dma is ready. self->pacing_timer = pacing_timer; // Playback with two independent clocks. One is the sample rate which @@ -214,6 +193,27 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, } dma_hw->timer[pacing_timer] = best_numerator << 16 | best_denominator; + + audio_dma_result result = audio_dma_setup_playback( + &self->dma, + sample, + loop, + false, // single channel + 0, // audio channel + false, // output signed + BITS_PER_SAMPLE, + (uint32_t)tx_register, // output register: PWM cc register + 0x3b + pacing_timer); // data request line + + if (result == AUDIO_DMA_DMA_BUSY) { + common_hal_audiopwmio_pwmaudioout_stop(self); + mp_raise_RuntimeError(translate("No DMA channel found")); + } + if (result == AUDIO_DMA_MEMORY_ERROR) { + common_hal_audiopwmio_pwmaudioout_stop(self); + mp_raise_RuntimeError(translate("Unable to allocate buffers for signed conversion")); + } + // OK! We got all of the resources we need and dma is ready. } void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self) { diff --git a/shared-module/audiocore/WaveFile.c b/shared-module/audiocore/WaveFile.c index 6d42d27ddb..14c92ca411 100644 --- a/shared-module/audiocore/WaveFile.c +++ b/shared-module/audiocore/WaveFile.c @@ -206,7 +206,7 @@ audioio_get_buffer_result_t audioio_wavefile_get_buffer(audioio_wavefile_obj_t * } if (need_more_data) { - uint16_t num_bytes_to_load = self->len; + uint32_t num_bytes_to_load = self->len; if (num_bytes_to_load > self->bytes_remaining) { num_bytes_to_load = self->bytes_remaining; } From 35aac3d26b5c18edf6e1562dbd95020d5b9e2751 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 11 Aug 2021 10:48:53 -0400 Subject: [PATCH 50/63] display SPI now 10MHz; set PWM duty cycle to zero at stop to quiet output --- ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c | 2 +- ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c index 214662e331..2882e57922 100644 --- a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c @@ -69,7 +69,7 @@ void board_init(void) { &pin_GPIO24, // Command or data &pin_GPIO22, // Chip select &pin_GPIO23, // Reset - 1000000, // Baudrate + 10000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c index ea587867c0..05246ef1be 100644 --- a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c @@ -225,9 +225,11 @@ void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self) audio_dma_stop(&self->dma); // Set to quiescent level. - pwm_hw->slice[self->left_pwm.slice].cc = self->quiescent_value; + common_hal_pwmio_pwmout_set_duty_cycle(&self->left_pwm, self->quiescent_value); + pwmio_pwmout_set_top(&self->left_pwm, PWM_TOP); if (self->stereo) { - pwm_hw->slice[self->right_pwm.slice].cc = self->quiescent_value; + common_hal_pwmio_pwmout_set_duty_cycle(&self->right_pwm, self->quiescent_value); + pwmio_pwmout_set_top(&self->right_pwm, PWM_TOP); } } From 4608877c12f2a7a0d4ace4f7e656b352ccf15bfe Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 11 Aug 2021 12:10:49 -0400 Subject: [PATCH 51/63] address review comments --- ports/raspberrypi/audio_dma.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index 012d755e66..e9f62281cf 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -153,7 +153,7 @@ STATIC void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { } // Convert the sample format resolution and signedness, as necessary. - // The input sample buffer is what was read from a file or a raw sample buffer. + // The input sample buffer is what was read from a file, Mixer, or a raw sample buffer. // The output buffer is one of the DMA buffers (passed in), or if no conversion was done, // the original sample buffer (to save copying). @@ -370,13 +370,6 @@ void audio_dma_stop(audio_dma_t *dma) { dma_channel_abort(channel); } - // Write a zero as the last sample. This stops any PWM output. - if (dma->output_resolution <= 8) { - *((uint8_t *)dma->output_register_address) = 0; - } else { - *((uint16_t *)dma->output_register_address) = 0; - } - dma_channel_set_read_addr(channel, NULL, false /* trigger */); dma_channel_set_write_addr(channel, NULL, false /* trigger */); dma_channel_set_trans_count(channel, 0, false /* trigger */); From b56455ffbb3a73cd4e0ef4c965adddd7d2a5e6d7 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 11 Aug 2021 10:48:39 -0700 Subject: [PATCH 52/63] Allow sleep while paused --- ports/atmel-samd/common-hal/pulseio/PulseIn.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c index 49cef92478..507db7e437 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c @@ -272,6 +272,9 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t *self) { void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t *self) { uint32_t mask = 1 << self->channel; EIC->INTENCLR.reg = mask << EIC_INTENSET_EXTINT_Pos; + #ifdef SAMD21 + rtc_end_pulse(); + #endif } void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, @@ -299,6 +302,9 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, EIC->INTFLAG.reg = mask << EIC_INTFLAG_EXTINT_Pos; EIC->INTENSET.reg = mask << EIC_INTENSET_EXTINT_Pos; + #ifdef SAMD21 + rtc_start_pulse(); + #endif pulsein_set_config(self, true); } From b8e526be3b59b6c6d31df34b4efe4ea2549c25b8 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Wed, 11 Aug 2021 20:20:03 +0200 Subject: [PATCH 53/63] Update translation files Updated by "Update PO files to match POT (msgmerge)" hook in Weblate. Translation: CircuitPython/main Translate-URL: https://hosted.weblate.org/projects/circuitpython/main/ --- locale/ID.po | 8 ++++++++ locale/cs.po | 8 ++++++++ locale/de_DE.po | 8 ++++++++ locale/el.po | 8 ++++++++ locale/en_GB.po | 8 ++++++++ locale/es.po | 8 ++++++++ locale/fil.po | 8 ++++++++ locale/fr.po | 8 ++++++++ locale/hi.po | 8 ++++++++ locale/it_IT.po | 8 ++++++++ locale/ja.po | 8 ++++++++ locale/ko.po | 8 ++++++++ locale/nl.po | 8 ++++++++ locale/pl.po | 8 ++++++++ locale/pt_BR.po | 8 ++++++++ locale/sv.po | 8 ++++++++ locale/zh_Latn_pinyin.po | 8 ++++++++ 17 files changed, 136 insertions(+) diff --git a/locale/ID.po b/locale/ID.po index 99b3fea4f8..22518a63e0 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -500,6 +500,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1237,6 +1241,10 @@ msgstr "Otentikasi tidak cukup" msgid "Insufficient encryption" msgstr "Enkripsi tidak cukup" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Kesalahan definisi internal" diff --git a/locale/cs.po b/locale/cs.po index 352bb822f4..450c75e205 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -496,6 +496,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1220,6 +1224,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index 1655db5150..8f4de5386c 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -502,6 +502,10 @@ msgstr "Versuche %d Blöcke zu allokieren" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1237,6 +1241,10 @@ msgstr "Unzureichende Authentifizierung" msgid "Insufficient encryption" msgstr "Unzureichende Verschlüsselung" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Interner Definitionsfehler" diff --git a/locale/el.po b/locale/el.po index fb84d25d23..f011a09bb6 100644 --- a/locale/el.po +++ b/locale/el.po @@ -493,6 +493,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1217,6 +1221,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" diff --git a/locale/en_GB.po b/locale/en_GB.po index 99f8d4c16a..3400421b2a 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -502,6 +502,10 @@ msgstr "Attempt to allocate %d blocks" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1232,6 +1236,10 @@ msgstr "Insufficient authentication" msgid "Insufficient encryption" msgstr "Insufficient encryption" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Internal define error" diff --git a/locale/es.po b/locale/es.po index 4212d45df6..f53451c342 100644 --- a/locale/es.po +++ b/locale/es.po @@ -506,6 +506,10 @@ msgstr "Tratando de localizar %d bloques" msgid "Attempted heap allocation when VM not running." msgstr "Asignación del montículo mientras la VM no esta ejecutándose." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN no se usa con contraseña" @@ -1250,6 +1254,10 @@ msgstr "Autenticación insuficiente" msgid "Insufficient encryption" msgstr "Cifrado insuficiente" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Error interno de definición" diff --git a/locale/fil.po b/locale/fil.po index b7bc9f8428..78d8f09ea3 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -496,6 +496,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1232,6 +1236,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" diff --git a/locale/fr.po b/locale/fr.po index 694e71b840..d1ed977567 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -508,6 +508,10 @@ msgstr "" "Tentative d'allocation à la pile quand la Machine Virtuelle n'est pas en " "exécution." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN n'est pas utilisé avec un mot de passe" @@ -1260,6 +1264,10 @@ msgstr "Authentification insuffisante" msgid "Insufficient encryption" msgstr "Chiffrement insuffisant" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Erreur de définition interne" diff --git a/locale/hi.po b/locale/hi.po index 2fb00e2272..4ffcfe51ba 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -493,6 +493,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1217,6 +1221,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index a8786c7e32..b4f8a1c19c 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -505,6 +505,10 @@ msgstr "Provo ad allocare %d blocchi" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1241,6 +1245,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" diff --git a/locale/ja.po b/locale/ja.po index cfe5556941..a51b48f55d 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -498,6 +498,10 @@ msgstr "%d個のブロックの確保を試みました" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1228,6 +1232,10 @@ msgstr "認証が不十分" msgid "Insufficient encryption" msgstr "暗号化が不十分" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "内部定義エラー" diff --git a/locale/ko.po b/locale/ko.po index b46d9f5d11..b3dbf6c3e4 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -494,6 +494,10 @@ msgstr "" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1220,6 +1224,10 @@ msgstr "" msgid "Insufficient encryption" msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" diff --git a/locale/nl.po b/locale/nl.po index ec26087cd6..344b214289 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -496,6 +496,10 @@ msgstr "Poging om %d blokken toe te wijzen" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1229,6 +1233,10 @@ msgstr "Onvoldoende authenticatie" msgid "Insufficient encryption" msgstr "Onvoldoende encryptie" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Interne define fout" diff --git a/locale/pl.po b/locale/pl.po index 9a0f6614b8..268e12f340 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -498,6 +498,10 @@ msgstr "Próba przydzielenia %d bloków" msgid "Attempted heap allocation when VM not running." msgstr "" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -1228,6 +1232,10 @@ msgstr "Niewystarczające uwierzytelnienie" msgid "Insufficient encryption" msgstr "Niewystarczające szyfrowanie" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index 49f333678d..53c3ae381e 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -507,6 +507,10 @@ msgid "Attempted heap allocation when VM not running." msgstr "" "Tentativa de alocação das pilhas quando o VM não estiver em funcionamento." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "O AuthMode.OPEN não é usado com senha" @@ -1251,6 +1255,10 @@ msgstr "Autenticação insuficiente" msgid "Insufficient encryption" msgstr "Criptografia insuficiente" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Erro interno de definição" diff --git a/locale/sv.po b/locale/sv.po index 15cb50e88d..612121de2d 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -501,6 +501,10 @@ msgstr "Försök att tilldela %d block" msgid "Attempted heap allocation when VM not running." msgstr "Försök till heap-allokering när den virtuella maskinen inte är igång." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN används inte med lösenord" @@ -1236,6 +1240,10 @@ msgstr "Otillräcklig autentisering" msgid "Insufficient encryption" msgstr "Otillräcklig kryptering" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Internt define-fel" diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 8ff9e807ca..a172375454 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -503,6 +503,10 @@ msgstr "cháng shì fēn pèi %d kuài" msgid "Attempted heap allocation when VM not running." msgstr "dāng VM bú yùn xíng shí, cháng shì duī fēn pèi." +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN wèi shǐ yòng mì mǎ" @@ -1239,6 +1243,10 @@ msgstr "Rènzhèng bùzú" msgid "Insufficient encryption" msgstr "Jiāmì bùzú" +#: ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" msgstr "Nèibù dìngyì cuòwù" From 083960ce907b00d63f1c0aa7099d52e097f3b10a Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 11 Aug 2021 11:53:26 -0700 Subject: [PATCH 54/63] Fix SAMD51 builds and Prox Trinkey Adds CIRCUITPY_BUSIO_UART to disable UART by raising ValueError that no pins work. --- .../mpconfigboard.h | 1 + .../mpconfigboard.mk | 1 + ports/atmel-samd/supervisor/port.c | 2 ++ py/circuitpy_mpconfig.mk | 6 ++++++ shared-bindings/busio/SPI.c | 2 +- shared-bindings/busio/UART.c | 19 +++++++++++++++++++ 6 files changed, 30 insertions(+), 1 deletion(-) diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h index c792b01272..878b25f2f8 100644 --- a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.h @@ -2,6 +2,7 @@ #define MICROPY_HW_MCU_NAME "samd21e18" #define MICROPY_HW_NEOPIXEL (&pin_PA15) +#define MICROPY_HW_NEOPIXEL_COUNT (2) #define IGNORE_PIN_PA01 1 #define IGNORE_PIN_PA02 1 diff --git a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk index cf9afb3d21..1e1284ecb0 100644 --- a/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/adafruit_proxlight_trinkey_m0/mpconfigboard.mk @@ -14,6 +14,7 @@ CIRCUITPY_FULL_BUILD = 0 CIRCUITPY_ANALOGIO = 0 CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_BUSIO_SPI = 0 +CIRCUITPY_BUSIO_UART = 0 CIRCUITPY_PULSEIO = 0 CIRCUITPY_PWMIO = 0 CIRCUITPY_ROTARYIO = 0 diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 73303a8218..9ad54e5604 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -594,10 +594,12 @@ void port_interrupt_after_ticks(uint32_t ticks) { #endif uint32_t target = current_ticks + (ticks << 4); + #ifdef SAMD21 // Try and avoid a bus stall when writing COMP by checking for an obvious // existing sync. while (RTC->MODE0.STATUS.bit.SYNCBUSY == 1) { } + #endif // Writing the COMP register can take up to 180us to synchronize. During // this time, the bus will stall and no interrupts will be serviced. RTC->MODE0.COMP[0].reg = target; diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 45bc2e8fed..fd15be92b0 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -121,9 +121,15 @@ CFLAGS += -DCIRCUITPY_BUILTINS_POW3=$(CIRCUITPY_BUILTINS_POW3) CIRCUITPY_BUSIO ?= 1 CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO) +# These two flags pretend to implement their class but raise a ValueError due to +# unsupported pins. This should be used sparingly on boards that don't break out +# generic IO but need parts of busio. CIRCUITPY_BUSIO_SPI ?= 1 CFLAGS += -DCIRCUITPY_BUSIO_SPI=$(CIRCUITPY_BUSIO_SPI) +CIRCUITPY_BUSIO_UART ?= 1 +CFLAGS += -DCIRCUITPY_BUSIO_UART=$(CIRCUITPY_BUSIO_UART) + CIRCUITPY_CAMERA ?= 0 CFLAGS += -DCIRCUITPY_CAMERA=$(CIRCUITPY_CAMERA) diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index 31f3a9021e..a611d8e1d5 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -104,7 +104,7 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, con common_hal_busio_spi_construct(self, clock, mosi, miso); return MP_OBJ_FROM_PTR(self); #else - mp_raise_NotImplementedError(NULL); + mp_raise_ValueError(translate("Invalid pins")); #endif // CIRCUITPY_BUSIO_SPI } diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index bd97910192..efb0643d0b 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -72,13 +72,16 @@ typedef struct { extern const busio_uart_parity_obj_t busio_uart_parity_even_obj; extern const busio_uart_parity_obj_t busio_uart_parity_odd_obj; +#if CIRCUITPY_BUSIO_UART STATIC void validate_timeout(mp_float_t timeout) { if (timeout < (mp_float_t)0.0f || timeout > (mp_float_t)100.0f) { mp_raise_ValueError(translate("timeout must be 0.0-100.0 seconds")); } } +#endif // CIRCUITPY_BUSIO_UART STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + #if CIRCUITPY_BUSIO_UART // Always initially allocate the UART object within the long-lived heap. // This is needed to avoid crashes with certain UART implementations which // cannot accomodate being moved after creation. (See @@ -141,8 +144,12 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co args[ARG_baudrate].u_int, bits, parity, stop, timeout, args[ARG_receiver_buffer_size].u_int, NULL, false); return (mp_obj_t)self; + #else + mp_raise_ValueError(translate("Invalid pins")); + #endif // CIRCUITPY_BUSIO_UART } +#if CIRCUITPY_BUSIO_UART // Helper to ensure we have the native super class instead of a subclass. busio_uart_obj_t *native_uart(mp_obj_t uart_obj) { @@ -358,6 +365,7 @@ STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) { return mp_const_none; } STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer); +#endif // CIRCUITPY_BUSIO_UART //| class Parity: //| """Enum-like class to define the parity used to verify correct data transfer.""" @@ -400,6 +408,7 @@ const mp_obj_type_t busio_uart_parity_type = { }; STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = { + #if CIRCUITPY_BUSIO_UART { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&busio_uart_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_uart_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, @@ -417,12 +426,14 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) }, { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) }, { MP_ROM_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&busio_uart_timeout_obj) }, + #endif // CIRCUITPY_BUSIO_UART // Nested Enum-like Classes. { MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&busio_uart_parity_type) }, }; STATIC MP_DEFINE_CONST_DICT(busio_uart_locals_dict, busio_uart_locals_dict_table); +#if CIRCUITPY_BUSIO_UART STATIC const mp_stream_p_t uart_stream_p = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream) .read = busio_uart_read, @@ -445,3 +456,11 @@ const mp_obj_type_t busio_uart_type = { .protocol = &uart_stream_p, ), }; +#else +const mp_obj_type_t busio_uart_type = { + { &mp_type_type }, + .name = MP_QSTR_UART, + .make_new = busio_uart_make_new, + .locals_dict = (mp_obj_dict_t *)&busio_uart_locals_dict, +}; +#endif // CIRCUITPY_BUSIO_UART From 4be64cd8a9cf98e367f269057d9bdefc41aa5302 Mon Sep 17 00:00:00 2001 From: Bruce Segal Date: Wed, 11 Aug 2021 13:11:17 -0700 Subject: [PATCH 55/63] Initial MorphESP-240 support --- .../boards/morpheans_morphesp-240/board.c | 227 ++++++++++++++++++ .../morpheans_morphesp-240/mpconfigboard.h | 44 ++++ .../morpheans_morphesp-240/mpconfigboard.mk | 17 ++ .../boards/morpheans_morphesp-240/pins.c | 58 +++++ .../boards/morpheans_morphesp-240/sdkconfig | 6 + 5 files changed, 352 insertions(+) create mode 100644 ports/esp32s2/boards/morpheans_morphesp-240/board.c create mode 100644 ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.h create mode 100644 ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.mk create mode 100644 ports/esp32s2/boards/morpheans_morphesp-240/pins.c create mode 100644 ports/esp32s2/boards/morpheans_morphesp-240/sdkconfig diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/board.c b/ports/esp32s2/boards/morpheans_morphesp-240/board.c new file mode 100644 index 0000000000..3dcf6d2465 --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/board.c @@ -0,0 +1,227 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#define DELAY 0x80 + +// From Arduino-ST7789 library https://github.com/ananevilya/Arduino-ST7789-Library/blob/master/Arduino_ST7789.cpp +#define ST7789_TFTWIDTH 240 +#define ST7789_TFTHEIGHT 240 + +#define ST7789_240x240_XSTART 0 +#define ST7789_240x240_YSTART 0 + +#define ST7789_NOP 0x00 +#define ST7789_SWRESET 0x01 +#define ST7789_RDDID 0x04 +#define ST7789_RDDST 0x09 + +#define ST7789_SLPIN 0x10 +#define ST7789_SLPOUT 0x11 +#define ST7789_PTLON 0x12 +#define ST7789_NORON 0x13 + +#define ST7789_INVOFF 0x20 +#define ST7789_INVON 0x21 +#define ST7789_DISPOFF 0x28 +#define ST7789_DISPON 0x29 +#define ST7789_CASET 0x2A +#define ST7789_RASET 0x2B +#define ST7789_RAMWR 0x2C +#define ST7789_RAMRD 0x2E + +#define ST7789_PTLAR 0x30 +#define ST7789_COLMOD 0x3A +#define ST7789_MADCTL 0x36 +#define ST7789_VSCSAD 0x37 +#define ST7789_PORCTRL 0xB2 +#define ST7789_GCTRL 0xB7 +#define ST7789_VCOMS 0xBB +#define ST7789_LCMCTRL 0xC0 +#define ST7789_IDSET 0xC1 +#define ST7789_VDVVRHEN 0xC2 +#define ST7789_VRHS 0xC3 +#define ST7789_VDVS 0xC4 +#define ST7789_VCMOFSET 0xC5 +#define ST7789_FRCTRL2 0xC6 +#define ST7789_CABCCTRL 0xC7 +#define ST7789_REGSEL1 0xC8 +#define ST7789_REGSEL2 0xCA +#define ST7789_PWMFRSEL 0xCC +#define ST7789_PWCTRL1 0xD0 +#define ST7789_VAPVANEN 0xD2 +#define ST7789_PVGAMCTRL 0xE0 +#define ST7789_NVGAMCTRL 0xE1 + +#define ST7789_MADCTL_MY 0x80 +#define ST7789_MADCTL_MX 0x40 +#define ST7789_MADCTL_MV 0x20 +#define ST7789_MADCTL_ML 0x10 +#define ST7789_MADCTL_RGB 0x00 + +#define ST7789_RDID1 0xDA +#define ST7789_RDID2 0xDB +#define ST7789_RDID3 0xDC +#define ST7789_RDID4 0xDD + +#define DISPLAY_MADCTL (ST7789_MADCTL_RGB) +#define DISPLAY_VSCSAD 0 + +// The init_sequence is bitpacked to minimize the ram impact. Every command begins with a +// command byte followed by a byte to determine the parameter count and delay. When the top bit +// of the second byte is 1 (0x80), a delay will occur after the command parameters are sent. +// The remaining 7 bits are the parameter count excluding any delay byte. The bytes following +// are the parameters. When the delay bit is set, a single byte after the parameters specifies +// the delay duration in milliseconds. The value 0xff will lead to an extra long 500 ms delay +// instead of 255 ms.uint8_t display_init_sequence[] = { +// display init sequence according to LilyGO example app + +uint8_t display_init_sequence[] = { + // From Lilygo example + // sw reset + 0x01, 0 | DELAY, 150, + // sleep out + 0x11, 0 | DELAY, 120, + // normal display mode on + 0x13, 0, + // display and color format settings + 0x36, 1, DISPLAY_MADCTL, + 0xB6, 2, 0x0A, 0x82, + 0x3A, 1 | DELAY, 0x55, 10, + // ST7789V frame rate setting + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + // voltages: VGH / VGL + 0xB7, 1, 0x35, + // ST7789V power setting + 0xBB, 1, 0x28, + 0xC0, 1, 0x0C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x10, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + // ST7789V gamma setting + 0xE0, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17, + 0xE1, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E, + 0x21, 0, + // display on + 0x21, 0 | DELAY, 10, // _INVON + 0x29, 0 | DELAY, 120 +}; + + +void board_init(void) { + // USB + common_hal_never_reset_pin(&pin_GPIO19); + common_hal_never_reset_pin(&pin_GPIO20); + + // Debug UART + #ifdef DEBUG + common_hal_never_reset_pin(&pin_GPIO6); + common_hal_never_reset_pin(&pin_GPIO7); + #endif /* DEBUG */ + + // Display + + busio_spi_obj_t *spi = &displays[0].fourwire_bus.inline_bus; + + common_hal_busio_spi_construct( + spi, + &pin_GPIO12, // CLK + &pin_GPIO11, // MOSI + NULL // MISO not connected + ); + + common_hal_busio_spi_never_reset(spi); + + displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; + bus->base.type = &displayio_fourwire_type; + + common_hal_displayio_fourwire_construct( + bus, + spi, + &pin_GPIO14, // DC + &pin_GPIO10, // CS + &pin_GPIO9, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + + // workaround as board_init() is called before reset_port() in main.c + pwmout_reset(); + + displayio_display_obj_t *display = &displays[0].display; + display->base.type = &displayio_display_type; + common_hal_displayio_display_construct( + display, + bus, + 240, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 80, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + 0x37, // set vertical scroll command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // There is no backlight pin, defined for now. + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness (ignored) + true, // auto_brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + false, // backlight_on_high + false // SH1107_addressing + ); +} + +bool board_requests_safe_mode(void) { + return false; +} + +void reset_board(void) { + +} + +void board_deinit(void) { + common_hal_displayio_release_displays(); +} diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.h b/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.h new file mode 100644 index 0000000000..6a18f996bb --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "MORPHEANS MorphESP-240" +#define MICROPY_HW_MCU_NAME "ESP32S2" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO16) +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define BOARD_USER_SAFE_MODE_ACTION translate("pressing boot button at start up.\n") + +#define AUTORESET_DELAY_MS 500 + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO7) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO6) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO12) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO13) diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.mk b/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.mk new file mode 100644 index 0000000000..aee744ca1a --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x303a +USB_PID = 0x80B7 +USB_PRODUCT = "MORPHESP-240" +USB_MANUFACTURER = "MORPHEANS" + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = MPZ + +# The default queue depth of 16 overflows on release builds, +# so increase it to 32. +CFLAGS += -DCFG_TUD_TASK_QUEUE_SZ=32 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_MODULE = wroom diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/pins.c b/ports/esp32s2/boards/morpheans_morphesp-240/pins.c new file mode 100644 index 0000000000..a41da9e996 --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/pins.c @@ -0,0 +1,58 @@ +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +STATIC const mp_rom_map_elem_t board_global_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + + // Serial UART on breakout board + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO18) }, + + // I2C on breakout board. + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO7) }, + + // WS2812B RGB LED + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO16) }, + + // SPI on breakout board + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO13) }, + + // 1.3" 240x240 LCD ST7789 + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D_C), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/sdkconfig b/ports/esp32s2/boards/morpheans_morphesp-240/sdkconfig new file mode 100644 index 0000000000..36ada0b0c7 --- /dev/null +++ b/ports/esp32s2/boards/morpheans_morphesp-240/sdkconfig @@ -0,0 +1,6 @@ +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="MORPHESP-240" +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# end of LWIP \ No newline at end of file From f35afa8239ebd6b5da7f0d2d3f63b08fb2e2c089 Mon Sep 17 00:00:00 2001 From: Bruce Segal Date: Wed, 11 Aug 2021 13:43:08 -0700 Subject: [PATCH 56/63] Formatting and build.yml --- .github/workflows/build.yml | 1 + ports/esp32s2/boards/morpheans_morphesp-240/pins.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6d567ca9e2..fc96bc8995 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -516,6 +516,7 @@ jobs: - "gravitech_cucumber_rs" - "lilygo_ttgo_t8_s2_st7789" - "microdev_micro_s2" + - "morpheans_morphesp-240" - "muselab_nanoesp32_s2_wroom" - "muselab_nanoesp32_s2_wrover" - "targett_module_clip_wroom" diff --git a/ports/esp32s2/boards/morpheans_morphesp-240/pins.c b/ports/esp32s2/boards/morpheans_morphesp-240/pins.c index a41da9e996..f311daeaa2 100644 --- a/ports/esp32s2/boards/morpheans_morphesp-240/pins.c +++ b/ports/esp32s2/boards/morpheans_morphesp-240/pins.c @@ -34,7 +34,7 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO18) }, - // I2C on breakout board. + // I2C on breakout board. { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO7) }, From fb6b4385801fc05ac993c2fc4866a0f16bdfc4f5 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Wed, 11 Aug 2021 14:47:35 -0700 Subject: [PATCH 57/63] Make `getpass` and `traceback` full build only This leaves much more space on SAMD21 builds that aren't "full builds". These are new APIs that we don't need to add to old boards. Also, tweak two Arduino boards to save space on them. --- .../boards/arduino_mkr1300/mpconfigboard.h | 13 +++++++++++++ .../boards/arduino_nano_33_iot/mpconfigboard.h | 8 ++++++++ py/circuitpy_mpconfig.mk | 4 ++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h index f0748f35de..6a3f7a9687 100644 --- a/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h +++ b/ports/atmel-samd/boards/arduino_mkr1300/mpconfigboard.h @@ -16,3 +16,16 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 +// USD ID +#define IGNORE_PIN_PA18 1 + +// Hooked to the external crystal +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 + +// SWD only +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 + +// Not connected +#define IGNORE_PIN_PA28 1 diff --git a/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.h b/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.h index 62883ad4a5..6be4f5606a 100644 --- a/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.h +++ b/ports/atmel-samd/boards/arduino_nano_33_iot/mpconfigboard.h @@ -16,3 +16,11 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 + +// Not connected +#define IGNORE_PIN_PA00 1 +#define IGNORE_PIN_PA01 1 + +// SWD only +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index e22cccda43..be68904d18 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -190,7 +190,7 @@ CFLAGS += -DCIRCUITPY_FREQUENCYIO=$(CIRCUITPY_FREQUENCYIO) CIRCUITPY_GAMEPADSHIFT ?= 0 CFLAGS += -DCIRCUITPY_GAMEPADSHIFT=$(CIRCUITPY_GAMEPADSHIFT) -CIRCUITPY_GETPASS ?= 1 +CIRCUITPY_GETPASS ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_GETPASS=$(CIRCUITPY_GETPASS) CIRCUITPY_GNSS ?= 0 @@ -336,7 +336,7 @@ CFLAGS += -DCIRCUITPY_TOUCHIO_USE_NATIVE=$(CIRCUITPY_TOUCHIO_USE_NATIVE) CIRCUITPY_TOUCHIO ?= 1 CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO) -CIRCUITPY_TRACEBACK ?= 1 +CIRCUITPY_TRACEBACK ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_TRACEBACK=$(CIRCUITPY_TRACEBACK) # For debugging. From 47c8ff05707fb23814a44101d77df2f9cc2c737b Mon Sep 17 00:00:00 2001 From: ZodiusInfuser Date: Wed, 11 Aug 2021 23:34:20 +0100 Subject: [PATCH 58/63] Removed unnecessary defines --- .../pimoroni_interstate75/mpconfigboard.h | 31 ------------------- .../pimoroni_plasma2040/mpconfigboard.h | 29 ----------------- 2 files changed, 60 deletions(-) diff --git a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h index 1ce8e1e7e1..052c47fa68 100644 --- a/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_interstate75/mpconfigboard.h @@ -1,41 +1,10 @@ #define MICROPY_HW_BOARD_NAME "Pimoroni Interstate 75" #define MICROPY_HW_MCU_NAME "rp2040" -#define MICROPY_HW_R0 (&pin_GPIO0) -#define MICROPY_HW_G0 (&pin_GPIO1) -#define MICROPY_HW_B0 (&pin_GPIO2) -#define MICROPY_HW_R1 (&pin_GPIO3) -#define MICROPY_HW_G1 (&pin_GPIO4) -#define MICROPY_HW_B1 (&pin_GPIO5) - -#define MICROPY_HW_ROW_A (&pin_GPIO6) -#define MICROPY_HW_ROW_B (&pin_GPIO7) -#define MICROPY_HW_ROW_C (&pin_GPIO8) -#define MICROPY_HW_ROW_D (&pin_GPIO9) -#define MICROPY_HW_ROW_E (&pin_GPIO10) - -#define MICROPY_HW_CLK (&pin_GPIO11) -#define MICROPY_HW_LAT (&pin_GPIO12) -#define MICROPY_HW_OE (&pin_GPIO13) - -#define MICROPY_HW_SW_A (&pin_GPIO14) - #define CIRCUITPY_RGB_STATUS_INVERTED_PWM #define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) #define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) #define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) -#define MICROPY_HW_I2C_INT (&pin_GPIO19) - #define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) - -#define MICROPY_HW_USER_SW (&pin_GPIO23) - -#define MICROPY_HW_CURRENT_SENSE (&pin_GPIO29) - -// These pins are unconnected -#define IGNORE_PIN_GPIO15 1 -#define IGNORE_PIN_GPIO22 1 -#define IGNORE_PIN_GPIO24 1 -#define IGNORE_PIN_GPIO25 1 diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h index 6d1e137906..b8e48a26a2 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_plasma2040/mpconfigboard.h @@ -1,39 +1,10 @@ #define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2040" #define MICROPY_HW_MCU_NAME "rp2040" -#define MICROPY_HW_SW_A (&pin_GPIO12) -#define MICROPY_HW_SW_B (&pin_GPIO13) - -#define MICROPY_HW_CLK (&pin_GPIO14) -#define MICROPY_HW_DATA (&pin_GPIO15) - #define CIRCUITPY_RGB_STATUS_INVERTED_PWM #define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) #define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) #define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) -#define MICROPY_HW_I2C_INT (&pin_GPIO19) - #define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) - -#define MICROPY_HW_USER_SW (&pin_GPIO23) - -#define MICROPY_HW_CURRENT_SENSE (&pin_GPIO29) - -// These pins are unconnected -#define IGNORE_PIN_GPIO0 1 -#define IGNORE_PIN_GPIO1 1 -#define IGNORE_PIN_GPIO2 1 -#define IGNORE_PIN_GPIO3 1 -#define IGNORE_PIN_GPIO4 1 -#define IGNORE_PIN_GPIO5 1 -#define IGNORE_PIN_GPIO6 1 -#define IGNORE_PIN_GPIO7 1 -#define IGNORE_PIN_GPIO8 1 -#define IGNORE_PIN_GPIO9 1 -#define IGNORE_PIN_GPIO10 1 -#define IGNORE_PIN_GPIO11 1 -#define IGNORE_PIN_GPIO22 1 -#define IGNORE_PIN_GPIO24 1 -#define IGNORE_PIN_GPIO25 1 From 05205259c655a99bf3082848a044377cd0abd013 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 11 Aug 2021 21:52:20 -0400 Subject: [PATCH 59/63] update tools/adabot submodule --- requirements-dev.txt | 1 + tools/adabot | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 6db56d8940..c3b33f8713 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -7,6 +7,7 @@ jinja2 typer requests +requests-cache sh click setuptools diff --git a/tools/adabot b/tools/adabot index 393c275671..f879b24c5f 160000 --- a/tools/adabot +++ b/tools/adabot @@ -1 +1 @@ -Subproject commit 393c2756714b5cccf028a82c23b873d36b2d9e8b +Subproject commit f879b24c5fcf759be3ecbd2ef6c5302b2acc8d28 From a48aa979740a925bc3bec5ed81736b160a154c80 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 12 Aug 2021 07:47:34 -0400 Subject: [PATCH 60/63] riscv buidl: pip install -r requirements-dev.txt --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d078ad3f5f..abe8627489 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -462,7 +462,7 @@ jobs: - name: Install deps run: | sudo apt-get install -y gettext - pip install requests sh click setuptools awscli + pip install -r requirements-dev.txt wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz sudo tar -C /usr --strip-components=1 -xaf riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6.tar.gz - name: Versions From 670d295db53e69828ee1d7598333c5b6b185765a Mon Sep 17 00:00:00 2001 From: James Carr Date: Thu, 12 Aug 2021 14:05:17 +0100 Subject: [PATCH 61/63] Update the __init__ documentation for EPaperDisplay. The unknown parameter `single_byte_bounds` was removed. The missing parameters `set_current_column_command` and `set_current_row_command` were added. --- shared-bindings/displayio/EPaperDisplay.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c index e80b243223..0f62ae63b4 100644 --- a/shared-bindings/displayio/EPaperDisplay.c +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -54,7 +54,9 @@ //| width: int, height: int, ram_width: int, ram_height: int, //| colstart: int = 0, rowstart: int = 0, rotation: int = 0, //| set_column_window_command: Optional[int] = None, -//| set_row_window_command: Optional[int] = None, single_byte_bounds: bool = False, +//| set_row_window_command: Optional[int] = None, +//| set_current_column_command: Optional[int] = None, +//| set_current_row_command: Optional[int] = None, //| write_black_ram_command: int, black_bits_inverted: bool = False, //| write_color_ram_command: Optional[int] = None, //| color_bits_inverted: bool = False, highlight_color: int = 0x000000, From e8df829714199435b886af1d4580a94a7337c4a4 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 12 Aug 2021 11:59:58 -0500 Subject: [PATCH 62/63] Displayio: change refresh minimum_frames_per_second default to 0 Closes: #5133 --- shared-bindings/displayio/Display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index e12e398802..3509c7626a 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -230,7 +230,7 @@ STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) } MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show); -//| def refresh(self, *, target_frames_per_second: Optional[int] = None, minimum_frames_per_second: int = 1) -> bool: +//| def refresh(self, *, target_frames_per_second: Optional[int] = None, minimum_frames_per_second: int = 0) -> bool: //| """When auto refresh is off, waits for the target frame rate and then refreshes the display, //| returning True. If the call has taken too long since the last refresh call for the given //| target frame rate, then the refresh returns False immediately without updating the screen to @@ -254,7 +254,7 @@ STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; static const mp_arg_t allowed_args[] = { { MP_QSTR_target_frames_per_second, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; From a89f1c806fef876267f774565a5c46c9655a7ae5 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Thu, 12 Aug 2021 12:50:38 -0500 Subject: [PATCH 63/63] Update Display.c --- shared-bindings/displayio/Display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 3509c7626a..f5df146455 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -237,7 +237,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show //| hopefully help getting caught up. //| //| If the time since the last successful refresh is below the minimum frame rate, then an -//| exception will be raised. Set ``minimum_frames_per_second`` to 0 to disable. +//| exception will be raised. The default ``minimum_frames_per_second`` of 0 disables this behavior. //| //| When auto refresh is off, ``display.refresh()`` or ``display.refresh(target_frames_per_second=None)`` //| will update the display immediately.