summaryrefslogtreecommitdiff
path: root/shared-bindings
diff options
context:
space:
mode:
authorsommersoft <sommersoft@gmail.com>2019-07-31 16:44:43 -0500
committersommersoft <sommersoft@gmail.com>2019-07-31 16:44:43 -0500
commit9939d0c4f49db084f52a12b6ea5f6ce97b614146 (patch)
tree6c338f9e01c581793255757b4483d3d88824095f /shared-bindings
parenta498bcd94d7f869e2cb2e992babacb981de688c0 (diff)
parent366fdcce18e148a6828b7a7074e1e4198fca3595 (diff)
Merge branch 'master' of https://github.com/adafruit/circuitpython into mixer_voice
Diffstat (limited to 'shared-bindings')
-rw-r--r--shared-bindings/_pew/PewPew.c24
-rw-r--r--shared-bindings/_pixelbuf/PixelBuf.c42
-rw-r--r--shared-bindings/_pixelbuf/__init__.c38
-rw-r--r--shared-bindings/_stage/__init__.c30
-rw-r--r--shared-bindings/analogio/AnalogIn.c9
-rw-r--r--shared-bindings/analogio/AnalogOut.c4
-rw-r--r--shared-bindings/audiobusio/I2SOut.c17
-rw-r--r--shared-bindings/audiobusio/PDMIn.c11
-rw-r--r--shared-bindings/audiocore/Mixer.c (renamed from shared-bindings/audioio/Mixer.c)64
-rw-r--r--shared-bindings/audiocore/Mixer.h (renamed from shared-bindings/audioio/Mixer.h)4
-rw-r--r--shared-bindings/audiocore/RawSample.c (renamed from shared-bindings/audioio/RawSample.c)12
-rw-r--r--shared-bindings/audiocore/RawSample.h (renamed from shared-bindings/audioio/RawSample.h)3
-rw-r--r--shared-bindings/audiocore/WaveFile.c (renamed from shared-bindings/audioio/WaveFile.c)20
-rw-r--r--shared-bindings/audiocore/WaveFile.h (renamed from shared-bindings/audioio/WaveFile.h)5
-rw-r--r--shared-bindings/audiocore/__init__.c69
-rw-r--r--shared-bindings/audiocore/__init__.h (renamed from shared-bindings/bleio/AdvertisementData.h)10
-rw-r--r--shared-bindings/audioio/AudioOut.c19
-rw-r--r--shared-bindings/audioio/AudioOut.h2
-rw-r--r--shared-bindings/audioio/__init__.c12
-rw-r--r--shared-bindings/bitbangio/I2C.c35
-rw-r--r--shared-bindings/bitbangio/OneWire.c12
-rw-r--r--shared-bindings/bitbangio/SPI.c40
-rw-r--r--shared-bindings/bleio/Adapter.c1
-rw-r--r--shared-bindings/bleio/Adapter.h1
-rw-r--r--shared-bindings/bleio/Address.c195
-rw-r--r--shared-bindings/bleio/Address.h14
-rw-r--r--shared-bindings/bleio/AddressType.c99
-rw-r--r--shared-bindings/bleio/AdvertisementData.c90
-rw-r--r--shared-bindings/bleio/Broadcaster.c132
-rw-r--r--shared-bindings/bleio/Central.c199
-rw-r--r--shared-bindings/bleio/Central.h (renamed from shared-bindings/bleio/Device.h)24
-rw-r--r--shared-bindings/bleio/Characteristic.c92
-rw-r--r--shared-bindings/bleio/Characteristic.h10
-rw-r--r--shared-bindings/bleio/CharacteristicBuffer.c30
-rw-r--r--shared-bindings/bleio/CharacteristicBuffer.h2
-rw-r--r--shared-bindings/bleio/Descriptor.c99
-rw-r--r--shared-bindings/bleio/Descriptor.h19
-rw-r--r--shared-bindings/bleio/Device.c363
-rw-r--r--shared-bindings/bleio/Peripheral.c117
-rw-r--r--shared-bindings/bleio/Peripheral.h9
-rw-r--r--shared-bindings/bleio/ScanEntry.c252
-rw-r--r--shared-bindings/bleio/ScanEntry.h6
-rw-r--r--shared-bindings/bleio/Scanner.c151
-rw-r--r--shared-bindings/bleio/Scanner.h7
-rw-r--r--shared-bindings/bleio/Service.c75
-rw-r--r--shared-bindings/bleio/Service.h9
-rw-r--r--shared-bindings/bleio/UUID.c34
-rw-r--r--shared-bindings/bleio/UUID.h1
-rw-r--r--shared-bindings/bleio/__init__.c32
-rw-r--r--shared-bindings/bleio/__init__.h3
-rw-r--r--shared-bindings/board/__init__.c77
-rw-r--r--shared-bindings/board/__init__.h12
-rw-r--r--shared-bindings/busio/I2C.c40
-rw-r--r--shared-bindings/busio/I2C.h3
-rw-r--r--shared-bindings/busio/OneWire.c12
-rw-r--r--shared-bindings/busio/SPI.c47
-rw-r--r--shared-bindings/busio/SPI.h6
-rw-r--r--shared-bindings/busio/UART.c26
-rw-r--r--shared-bindings/busio/UART.h2
-rw-r--r--shared-bindings/busio/__init__.c1
-rw-r--r--shared-bindings/digitalio/DigitalInOut.c40
-rw-r--r--shared-bindings/digitalio/DigitalInOut.h2
-rw-r--r--shared-bindings/digitalio/Direction.c2
-rw-r--r--shared-bindings/digitalio/DriveMode.c2
-rw-r--r--shared-bindings/digitalio/Pull.c2
-rw-r--r--shared-bindings/displayio/Bitmap.c16
-rw-r--r--shared-bindings/displayio/ColorConverter.c8
-rw-r--r--shared-bindings/displayio/ColorConverter.h4
-rw-r--r--shared-bindings/displayio/Display.c128
-rw-r--r--shared-bindings/displayio/Display.h16
-rw-r--r--shared-bindings/displayio/FourWire.c15
-rw-r--r--shared-bindings/displayio/FourWire.h3
-rw-r--r--shared-bindings/displayio/Group.c61
-rw-r--r--shared-bindings/displayio/Group.h4
-rw-r--r--shared-bindings/displayio/I2CDisplay.c138
-rw-r--r--shared-bindings/displayio/I2CDisplay.h (renamed from shared-bindings/bleio/AddressType.h)34
-rw-r--r--shared-bindings/displayio/Palette.c38
-rw-r--r--shared-bindings/displayio/Palette.h2
-rw-r--r--shared-bindings/displayio/ParallelBus.c14
-rw-r--r--shared-bindings/displayio/TileGrid.c255
-rw-r--r--shared-bindings/displayio/TileGrid.h25
-rw-r--r--shared-bindings/displayio/__init__.c16
-rw-r--r--shared-bindings/fontio/BuiltinFont.c (renamed from shared-bindings/displayio/BuiltinFont.c)48
-rw-r--r--shared-bindings/fontio/BuiltinFont.h (renamed from shared-bindings/displayio/BuiltinFont.h)16
-rw-r--r--shared-bindings/fontio/Glyph.c (renamed from shared-bindings/displayio/Glyph.c)6
-rw-r--r--shared-bindings/fontio/Glyph.h (renamed from shared-bindings/displayio/Glyph.h)8
-rw-r--r--shared-bindings/fontio/__init__.c65
-rw-r--r--shared-bindings/fontio/__init__.h31
-rw-r--r--shared-bindings/frequencyio/FrequencyIn.c18
-rw-r--r--shared-bindings/gamepad/GamePad.c43
-rw-r--r--shared-bindings/gamepad/GamePad.h5
-rw-r--r--shared-bindings/gamepad/__init__.c4
-rw-r--r--shared-bindings/gamepad/__init__.h31
-rw-r--r--shared-bindings/gamepadshift/GamePadShift.c123
-rw-r--r--shared-bindings/gamepadshift/GamePadShift.h42
-rw-r--r--shared-bindings/gamepadshift/__init__.c54
-rw-r--r--shared-bindings/gamepadshift/__init__.h (renamed from shared-bindings/bleio/Broadcaster.h)15
-rw-r--r--shared-bindings/help.c2
-rw-r--r--shared-bindings/i2cslave/I2CSlave.c4
-rw-r--r--shared-bindings/index.rst60
-rw-r--r--shared-bindings/microcontroller/Pin.c2
-rw-r--r--shared-bindings/microcontroller/RunMode.c14
-rw-r--r--shared-bindings/microcontroller/__init__.c16
-rw-r--r--shared-bindings/neopixel_write/__init__.c4
-rw-r--r--shared-bindings/network/__init__.c2
-rw-r--r--shared-bindings/nvm/ByteArray.c3
-rw-r--r--shared-bindings/ps2io/Ps2.c243
-rw-r--r--shared-bindings/ps2io/Ps2.h45
-rw-r--r--shared-bindings/ps2io/__init__.c73
-rw-r--r--shared-bindings/ps2io/__init__.h35
-rw-r--r--shared-bindings/pulseio/PWMOut.c18
-rw-r--r--shared-bindings/pulseio/PulseIn.c24
-rw-r--r--shared-bindings/pulseio/PulseOut.c4
-rw-r--r--shared-bindings/pulseio/__init__.c4
-rw-r--r--shared-bindings/rotaryio/IncrementalEncoder.c10
-rw-r--r--shared-bindings/rtc/RTC.c16
-rw-r--r--shared-bindings/socket/__init__.c56
-rw-r--r--shared-bindings/storage/__init__.c6
-rw-r--r--shared-bindings/struct/__init__.c8
-rw-r--r--shared-bindings/support_matrix.rst16
-rw-r--r--shared-bindings/terminalio/Terminal.c8
-rw-r--r--shared-bindings/terminalio/Terminal.h2
-rw-r--r--shared-bindings/time/__init__.c33
-rw-r--r--shared-bindings/touchio/TouchIn.c14
-rw-r--r--shared-bindings/uheap/__init__.c2
-rw-r--r--shared-bindings/ustack/__init__.c6
-rw-r--r--shared-bindings/util.c8
-rw-r--r--shared-bindings/util.h2
-rw-r--r--shared-bindings/wiznet/wiznet5k.c55
129 files changed, 3012 insertions, 1891 deletions
diff --git a/shared-bindings/_pew/PewPew.c b/shared-bindings/_pew/PewPew.c
index 50647488c..3ff208761 100644
--- a/shared-bindings/_pew/PewPew.c
+++ b/shared-bindings/_pew/PewPew.c
@@ -88,35 +88,38 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args,
mp_obj_get_array(args[ARG_cols].u_obj, &cols_size, &cols);
if (bufinfo.len != rows_size * cols_size) {
- mp_raise_ValueError(translate(""));
+ mp_raise_ValueError(translate("Incorrect buffer size"));
}
for (size_t i = 0; i < rows_size; ++i) {
if (!MP_OBJ_IS_TYPE(rows[i], &digitalio_digitalinout_type)) {
- mp_raise_TypeError(translate(""));
+ mp_raise_TypeError(translate("Row entry must be digitalio.DigitalInOut"));
}
digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(rows[i]);
- raise_error_if_deinited(
- common_hal_digitalio_digitalinout_deinited(pin));
+ if (common_hal_digitalio_digitalinout_deinited(pin)) {
+ raise_deinited_error();
+ }
}
for (size_t i = 0; i < cols_size; ++i) {
if (!MP_OBJ_IS_TYPE(cols[i], &digitalio_digitalinout_type)) {
- mp_raise_TypeError(translate(""));
+ mp_raise_TypeError(translate("Column entry must be digitalio.DigitalInOut"));
}
digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(cols[i]);
- raise_error_if_deinited(
- common_hal_digitalio_digitalinout_deinited(pin));
+ if (common_hal_digitalio_digitalinout_deinited(pin)) {
+ raise_deinited_error();
+ }
}
if (!MP_OBJ_IS_TYPE(args[ARG_buttons].u_obj,
&digitalio_digitalinout_type)) {
- mp_raise_TypeError(translate(""));
+ mp_raise_TypeError(translate("buttons must be digitalio.DigitalInOut"));
}
digitalio_digitalinout_obj_t *buttons = MP_OBJ_TO_PTR(
args[ARG_buttons].u_obj);
- raise_error_if_deinited(
- common_hal_digitalio_digitalinout_deinited(buttons));
+ if (common_hal_digitalio_digitalinout_deinited(buttons)) {
+ raise_deinited_error();
+ }
pew_obj_t *pew = MP_STATE_VM(pew_singleton);
if (!pew) {
@@ -148,4 +151,3 @@ const mp_obj_type_t pewpew_type = {
.make_new = pewpew_make_new,
.locals_dict = (mp_obj_dict_t*)&pewpew_locals_dict,
};
-
diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c
index 7c2766aa3..420720e62 100644
--- a/shared-bindings/_pixelbuf/PixelBuf.c
+++ b/shared-bindings/_pixelbuf/PixelBuf.c
@@ -51,7 +51,7 @@ extern const int32_t colorwheel(float pos);
//|
//| :class:`~_pixelbuf.PixelBuf` implements an RGB[W] bytearray abstraction.
//|
-//| .. class:: PixelBuf(size, buf, byteorder=BGR, bpp=3)
+//| .. class:: PixelBuf(size, buf, byteorder=BGR, brightness=0, rawbuf=None, offset=0, dotstar=False, auto_write=False, write_function=None, write_args=None)
//|
//| Create a PixelBuf object of the specified size, byteorder, and bits per pixel.
//|
@@ -66,14 +66,14 @@ extern const int32_t colorwheel(float pos);
//|
//| :param ~int size: Number of pixelsx
//| :param ~bytearray buf: Bytearray to store pixel data in
-//| :param ~_pixelbuf.ByteOrder byteorder: Byte order constant from `_pixelbuf` (also sets the bpp)
+//| :param ~_pixelbuf.ByteOrder byteorder: Byte order constant from `_pixelbuf`
//| :param ~float brightness: Brightness (0 to 1.0, default 1.0)
//| :param ~bytearray rawbuf: Bytearray to store raw pixel colors in
//| :param ~int offset: Offset from start of buffer (default 0)
//| :param ~bool dotstar: Dotstar mode (default False)
//| :param ~bool auto_write: Whether to automatically write pixels (Default False)
//| :param ~callable write_function: (optional) Callable to use to send pixels
-//| :param ~list write_args: (optional) Tuple or list of args to pass to ``write_function``. The
+//| :param ~list write_args: (optional) Tuple or list of args to pass to ``write_function``. The
//| PixelBuf instance is appended after these args.
//|
STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -95,7 +95,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
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_subclass_fast(args[ARG_byteorder].u_obj, &pixelbuf_byteorder_type))
+ if (mp_obj_is_subclass_fast(args[ARG_byteorder].u_obj, &pixelbuf_byteorder_type))
mp_raise_TypeError_varg(translate("byteorder is not an instance of ByteOrder (got a %s)"), mp_obj_get_type_str(args[ARG_byteorder].u_obj));
pixelbuf_byteorder_obj_t *byteorder = (args[ARG_byteorder].u_obj == mp_const_none) ? MP_OBJ_FROM_PTR(&byteorder_BGR) : args[ARG_byteorder].u_obj;
@@ -122,7 +122,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
if (!MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_list) &&
!MP_OBJ_IS_TYPE(args[ARG_write_args].u_obj, &mp_type_tuple) &&
- args[ARG_write_args].u_obj != mp_const_none)
+ args[ARG_write_args].u_obj != mp_const_none)
{
mp_raise_ValueError(translate("write_args must be a list, tuple, or None"));
}
@@ -186,8 +186,8 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
else if (self->brightness > 1)
self->brightness = 1;
}
-
- if (self->dotstar_mode) {
+
+ if (self->dotstar_mode) {
// Initialize the buffer with the dotstar start bytes.
// Header and end must be setup by caller
for (uint i = 0; i < self->pixels * 4; i += 4) {
@@ -197,7 +197,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a
}
}
}
-
+
return MP_OBJ_FROM_PTR(self);
}
@@ -227,7 +227,7 @@ const mp_obj_property_t pixelbuf_pixelbuf_bpp_obj = {
//| setting this value causes a recomputation of the values in buf.
//| If only a buf was provided, then the brightness only applies to
//| future pixel changes.
-//| In DotStar mode
+//| In DotStar mode
//|
STATIC mp_obj_t pixelbuf_pixelbuf_obj_get_brightness(mp_obj_t self_in) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type));
@@ -266,7 +266,7 @@ void pixelbuf_recalculate_brightness(pixelbuf_pixelbuf_obj_t *self) {
// Compensate for shifted buffer (bpp=3 dotstar)
for (uint i = 0; i < self->bytes; i++) {
// Don't adjust per-pixel luminance bytes in dotstar mode
- if (!self->dotstar_mode || (i % 4 != 0))
+ if (!self->dotstar_mode || (i % 4 != 0))
buf[i] = rawbuf[i] * self->brightness;
}
}
@@ -367,11 +367,13 @@ void call_write_function(pixelbuf_pixelbuf_obj_t *self) {
}
}
-
-
-//| .. method:: []
+//| .. method:: __getitem__(index)
+//|
+//| Returns the pixel value at the given index.
//|
-//| Get or set pixels. Supports individual pixels and slices.
+//| .. method:: __setitem__(index, value)
+//|
+//| Sets the pixel value at the given index.
//|
STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
mp_check_self(MP_OBJ_IS_TYPE(self_in, &pixelbuf_pixelbuf_type));
@@ -380,7 +382,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
// delete item
// slice deletion
return MP_OBJ_NULL; // op not supported
- }
+ }
pixelbuf_pixelbuf_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (0) {
@@ -390,7 +392,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
if (!mp_seq_get_fast_slice_indexes(self->bytes, index_in, &slice))
mp_raise_NotImplementedError(translate("Only slices with step=1 (aka None) are supported"));
- if ((slice.stop * self->pixel_step) > self->bytes)
+ if ((slice.stop * self->pixel_step) > self->bytes)
mp_raise_IndexError(translate("Range out of bounds"));
if (value == MP_OBJ_SENTINEL) { // Get
@@ -422,8 +424,8 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
for (size_t i = slice.start; i < slice.stop; i++) {
mp_obj_t *item = src_objs[i-slice.start];
if (MP_OBJ_IS_TYPE(value, &mp_type_list) || MP_OBJ_IS_TYPE(value, &mp_type_tuple) || MP_OBJ_IS_INT(value)) {
- pixelbuf_set_pixel(self->buf + (i * self->pixel_step),
- self->two_buffers ? self->rawbuf + (i * self->pixel_step) : NULL,
+ pixelbuf_set_pixel(self->buf + (i * self->pixel_step),
+ self->two_buffers ? self->rawbuf + (i * self->pixel_step) : NULL,
self->brightness, item, &self->byteorder, self->dotstar_mode);
}
}
@@ -438,14 +440,14 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp
} else { // Single index rather than slice.
size_t index = mp_get_index(self->base.type, self->pixels, index_in, false);
size_t offset = (index * self->pixel_step);
- if (offset > self->bytes)
+ if (offset > self->bytes)
mp_raise_IndexError(translate("Pixel beyond bounds of buffer"));
if (value == MP_OBJ_SENTINEL) { // Get
uint8_t *pixelstart = (uint8_t *)(self->two_buffers ? self->rawbuf : self->buf) + offset;
return pixelbuf_get_pixel(pixelstart, &self->byteorder, self->dotstar_mode);
} else { // Store
- pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL,
+ pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL,
self->brightness, value, &self->byteorder, self->dotstar_mode);
if (self->auto_write)
call_write_function(self);
diff --git a/shared-bindings/_pixelbuf/__init__.c b/shared-bindings/_pixelbuf/__init__.c
index 31defc7fb..48b9f1cef 100644
--- a/shared-bindings/_pixelbuf/__init__.c
+++ b/shared-bindings/_pixelbuf/__init__.c
@@ -53,7 +53,7 @@
//|
//| PixelBuf
-//| .. class:: ByteOrder
+//| .. class:: ByteOrder()
//|
//| Classes representing byteorders for circuitpython
@@ -169,34 +169,34 @@ const int32_t colorwheel(float pos) {
/// RGB
-//| .. class:: RGB
+//| .. data:: RGB
//|
//| * **order** Red, Green, Blue
//| * **bpp** 3
PIXELBUF_BYTEORDER(RGB, 3, 0, 1, 2, 3, false, false)
-//| .. class:: RBG
+//| .. data:: RBG
//|
//| * **order** Red, Blue, Green
//| * **bpp** 3
PIXELBUF_BYTEORDER(RBG, 3, 0, 2, 1, 3, false, false)
-//| .. class:: GRB
+//| .. data:: GRB
//|
//| * **order** Green, Red, Blue
//| * **bpp** 3
//|
//| Commonly used by NeoPixel.
PIXELBUF_BYTEORDER(GRB, 3, 1, 0, 2, 3, false, false)
-//| .. class:: GBR
+//| .. data:: GBR
//|
//| * **order** Green, Blue, Red
//| * **bpp** 3
PIXELBUF_BYTEORDER(GBR, 3, 1, 2, 0, 3, false, false)
-//| .. class:: BRG
+//| .. data:: BRG
//|
//| * **order** Blue, Red, Green
//| * **bpp** 3
PIXELBUF_BYTEORDER(BRG, 3, 2, 0, 1, 3, false, false)
-//| .. class:: BGR
+//| .. data:: BGR
//|
//| * **order** Blue, Green, Red
//| * **bpp** 3
@@ -205,19 +205,19 @@ PIXELBUF_BYTEORDER(BRG, 3, 2, 0, 1, 3, false, false)
PIXELBUF_BYTEORDER(BGR, 3, 2, 1, 0, 3, false, false)
// RGBW
-//| .. class:: RGBW
+//| .. data:: RGBW
//|
//| * **order** Red, Green, Blue, White
//| * **bpp** 4
//| * **has_white** True
PIXELBUF_BYTEORDER(RGBW, 4, 0, 1, 2, 3, true, false)
-//| .. class:: RBGW
+//| .. data:: RBGW
//|
//| * **order** Red, Blue, Green, White
//| * **bpp** 4
//| * **has_white** True
PIXELBUF_BYTEORDER(RBGW, 4, 0, 2, 1, 3, true, false)
-//| .. class:: GRBW
+//| .. data:: GRBW
//|
//| * **order** Green, Red, Blue, White
//| * **bpp** 4
@@ -225,19 +225,19 @@ PIXELBUF_BYTEORDER(RBGW, 4, 0, 2, 1, 3, true, false)
//|
//| Commonly used by RGBW NeoPixels.
PIXELBUF_BYTEORDER(GRBW, 4, 1, 0, 2, 3, true, false)
-//| .. class:: GBRW
+//| .. data:: GBRW
//|
//| * **order** Green, Blue, Red, White
//| * **bpp** 4
//| * **has_white** True
PIXELBUF_BYTEORDER(GBRW, 4, 1, 2, 0, 3, true, false)
-//| .. class:: BRGW
+//| .. data:: BRGW
//|
//| * **order** Blue, Red, Green, White
//| * **bpp** 4
//| * **has_white** True
PIXELBUF_BYTEORDER(BRGW, 4, 2, 0, 1, 3, true, false)
-//| .. class:: BGRW
+//| .. data:: BGRW
//|
//| * **order** Blue, Green, Red, White
//| * **bpp** 4
@@ -248,37 +248,37 @@ PIXELBUF_BYTEORDER(BGRW, 4, 2, 1, 0, 3, true, false)
// Luminosity chosen because the luminosity of a Dotstar at full bright
// burns the eyes like looking at the Sun.
// https://www.thesaurus.com/browse/luminosity?s=t
-//| .. class:: LRGB
+//| .. data:: LRGB
//|
//| * **order** *Luminosity*, Red, Green, Blue
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LRGB, 4, 1, 2, 3, 0, false, true)
-//| .. class:: LRBG
+//| .. data:: LRBG
//|
//| * **order** *Luminosity*, Red, Blue, Green
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LRBG, 4, 1, 3, 2, 0, false, true)
-//| .. class:: LGRB
+//| .. data:: LGRB
//|
//| * **order** *Luminosity*, Green, Red, Blue
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LGRB, 4, 2, 1, 3, 0, false, true)
-//| .. class:: LGBR
+//| .. data:: LGBR
//|
//| * **order** *Luminosity*, Green, Blue, Red
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LGBR, 4, 2, 3, 1, 0, false, true)
-//| .. class:: LBRG
+//| .. data:: LBRG
//|
//| * **order** *Luminosity*, Blue, Red, Green
//| * **bpp** 4
//| * **has_luminosity** True
PIXELBUF_BYTEORDER(LBRG, 4, 3, 1, 2, 0, false, true)
-//| .. class:: LBGR
+//| .. data:: LBGR
//|
//| * **order** *Luminosity*, Blue, Green, Red
//| * **bpp** 4
diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c
index 24a359664..9f3f89462 100644
--- a/shared-bindings/_stage/__init__.c
+++ b/shared-bindings/_stage/__init__.c
@@ -28,6 +28,7 @@
#include "py/mperrno.h"
#include "py/runtime.h"
#include "shared-bindings/busio/SPI.h"
+#include "shared-bindings/displayio/Display.h"
#include "shared-module/_stage/__init__.h"
#include "Layer.h"
#include "Text.h"
@@ -49,7 +50,7 @@
//| Layer
//| Text
//|
-//| .. function:: render(x0, y0, x1, y1, layers, buffer, spi)
+//| .. function:: render(x0, y0, x1, y1, layers, buffer, display)
//|
//| Render and send to the display a fragment of the screen.
//|
@@ -59,11 +60,8 @@
//| :param int y1: Bottom edge of the fragment.
//| :param list layers: A list of the :py:class:`~_stage.Layer` objects.
//| :param bytearray buffer: A buffer to use for rendering.
-//| :param ~busio.SPI spi: The SPI bus to use.
+//| :param ~displayio.Display display: The display to use.
//|
-//| Note that this function only sends the raw pixel data. Setting up
-//| the display for receiving it and handling the chip-select and
-//| data-command pins has to be done outside of it.
//| There are also no sanity checks, outside of the basic overflow
//| checking. The caller is responsible for making the passed parameters
//| valid.
@@ -85,12 +83,26 @@ STATIC mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) {
uint16_t *buffer = bufinfo.buf;
size_t buffer_size = bufinfo.len / 2; // 16-bit indexing
- busio_spi_obj_t *spi = MP_OBJ_TO_PTR(args[6]);
+ mp_obj_t native_display = mp_instance_cast_to_native_base(args[6],
+ &displayio_display_type);
+ if (!MP_OBJ_IS_TYPE(native_display, &displayio_display_type)) {
+ mp_raise_TypeError(translate("argument num/types mismatch"));
+ }
+ displayio_display_obj_t *display = MP_OBJ_TO_PTR(native_display);
- if (!render_stage(x0, y0, x1, y1, layers, layers_size,
- buffer, buffer_size, spi)) {
- mp_raise_OSError(MP_EIO);
+ while (!displayio_display_begin_transaction(display)) {
+#ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP ;
+#endif
}
+ displayio_area_t area;
+ area.x1 = x0;
+ area.y1 = y0;
+ area.x2 = x1;
+ area.y2 = y1;
+ displayio_display_set_region_to_update(display, &area);
+ render_stage(x0, y0, x1, y1, layers, layers_size, buffer, buffer_size, display);
+ displayio_display_end_transaction(display);
return mp_const_none;
}
diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c
index 116f82a03..a8bbbf59a 100644
--- a/shared-bindings/analogio/AnalogIn.c
+++ b/shared-bindings/analogio/AnalogIn.c
@@ -86,6 +86,11 @@ STATIC mp_obj_t analogio_analogin_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_deinit_obj, analogio_analogin_deinit);
+STATIC void check_for_deinit(analogio_analogin_obj_t *self) {
+ if (common_hal_analogio_analogin_deinited(self)) {
+ raise_deinited_error();
+ }
+}
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -113,7 +118,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogin___exit___obj, 4, 4,
//|
STATIC mp_obj_t analogio_analogin_obj_get_value(mp_obj_t self_in) {
analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_analogio_analogin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_analogio_analogin_get_value(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_value_obj, analogio_analogin_obj_get_value);
@@ -132,7 +137,7 @@ const mp_obj_property_t analogio_analogin_value_obj = {
//|
STATIC mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) {
analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_analogio_analogin_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_float(common_hal_analogio_analogin_get_reference_voltage(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_reference_voltage_obj,
diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c
index dcbd7ecfb..0816da465 100644
--- a/shared-bindings/analogio/AnalogOut.c
+++ b/shared-bindings/analogio/AnalogOut.c
@@ -112,7 +112,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogout___exit___obj, 4, 4
//| resolution, the value is 16-bit.
STATIC mp_obj_t analogio_analogout_obj_set_value(mp_obj_t self_in, mp_obj_t value) {
analogio_analogout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_analogio_analogout_deinited(self));
+ if (common_hal_analogio_analogout_deinited(self)) {
+ raise_deinited_error();
+ }
uint32_t v = mp_obj_get_int(value);
if (v >= (1 << 16)) {
mp_raise_ValueError(translate("AnalogOut is only 16 bits. Value must be less than 65536."));
diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c
index 48424d073..980f11392 100644
--- a/shared-bindings/audiobusio/I2SOut.c
+++ b/shared-bindings/audiobusio/I2SOut.c
@@ -134,6 +134,11 @@ STATIC mp_obj_t audiobusio_i2sout_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_deinit_obj, audiobusio_i2sout_deinit);
+STATIC void check_for_deinit(audiobusio_i2sout_obj_t *self) {
+ if (common_hal_audiobusio_i2sout_deinited(self)) {
+ raise_deinited_error();
+ }
+}
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -169,7 +174,7 @@ STATIC mp_obj_t audiobusio_i2sout_obj_play(size_t n_args, const mp_obj_t *pos_ar
{ MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
};
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -186,7 +191,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiobusio_i2sout_play_obj, 1, audiobusio_i2sout_obj_
//|
STATIC mp_obj_t audiobusio_i2sout_obj_stop(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
common_hal_audiobusio_i2sout_stop(self);
return mp_const_none;
}
@@ -198,7 +203,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_stop_obj, audiobusio_i2sout_obj_stop
//|
STATIC mp_obj_t audiobusio_i2sout_obj_get_playing(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audiobusio_i2sout_get_playing(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_get_playing_obj, audiobusio_i2sout_obj_get_playing);
@@ -216,7 +221,7 @@ const mp_obj_property_t audiobusio_i2sout_playing_obj = {
//|
STATIC mp_obj_t audiobusio_i2sout_obj_pause(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
if (!common_hal_audiobusio_i2sout_get_playing(self)) {
mp_raise_RuntimeError(translate("Not playing"));
@@ -232,7 +237,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_pause_obj, audiobusio_i2sout_obj_pau
//|
STATIC mp_obj_t audiobusio_i2sout_obj_resume(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
if (common_hal_audiobusio_i2sout_get_paused(self)) {
common_hal_audiobusio_i2sout_resume(self);
@@ -248,7 +253,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_resume_obj, audiobusio_i2sout_obj_re
//|
STATIC mp_obj_t audiobusio_i2sout_obj_get_paused(mp_obj_t self_in) {
audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_i2sout_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audiobusio_i2sout_get_paused(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_get_paused_obj, audiobusio_i2sout_obj_get_paused);
diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c
index 5dca3fa59..0c92c2478 100644
--- a/shared-bindings/audiobusio/PDMIn.c
+++ b/shared-bindings/audiobusio/PDMIn.c
@@ -43,7 +43,7 @@
//|
//| PDMIn can be used to record an input audio signal on a given set of pins.
//|
-//| .. class:: PDMIn(clock_pin, data_pin, \*, sample_rate=16000, bit_depth=8, mono=True, oversample=64, startup_delay=0.11)
+//| .. class:: PDMIn(clock_pin, data_pin, *, sample_rate=16000, bit_depth=8, mono=True, oversample=64, startup_delay=0.11)
//|
//| Create a PDMIn object associated with the given pins. This allows you to
//| record audio signals from the given pins. Individual ports may put further
@@ -156,6 +156,11 @@ STATIC mp_obj_t audiobusio_pdmin_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_pdmin_deinit_obj, audiobusio_pdmin_deinit);
+STATIC void check_for_deinit(audiobusio_pdmin_obj_t *self) {
+ if (common_hal_audiobusio_pdmin_deinited(self)) {
+ raise_deinited_error();
+ }
+}
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -188,7 +193,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_pdmin___exit___obj, 4, 4,
//|
STATIC mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) {
audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_obj);
- raise_error_if_deinited(common_hal_audiobusio_pdmin_deinited(self));
+ check_for_deinit(self);
if (!MP_OBJ_IS_SMALL_INT(destination_length) || MP_OBJ_SMALL_INT_VALUE(destination_length) < 0) {
mp_raise_TypeError(translate("destination_length must be an int >= 0"));
}
@@ -223,7 +228,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(audiobusio_pdmin_record_obj, audiobusio_pdmin_obj_reco
//|
STATIC mp_obj_t audiobusio_pdmin_obj_get_sample_rate(mp_obj_t self_in) {
audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audiobusio_pdmin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audiobusio_pdmin_get_sample_rate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_pdmin_get_sample_rate_obj, audiobusio_pdmin_obj_get_sample_rate);
diff --git a/shared-bindings/audioio/Mixer.c b/shared-bindings/audiocore/Mixer.c
index 5f224ad4a..ee4d8548c 100644
--- a/shared-bindings/audioio/Mixer.c
+++ b/shared-bindings/audiocore/Mixer.c
@@ -23,9 +23,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#include "shared-bindings/audioio/Mixer.h"
-#include "shared-module/audioio/MixerVoice.h"
-#include "shared-bindings/audioio/MixerVoice.h"
+#include "shared-bindings/audiocore/Mixer.h"
#include <stdint.h>
@@ -34,7 +32,7 @@
#include "py/objproperty.h"
#include "py/runtime.h"
#include "shared-bindings/microcontroller/Pin.h"
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-bindings/audiocore/RawSample.h"
#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
@@ -129,6 +127,12 @@ STATIC mp_obj_t audioio_mixer_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_deinit_obj, audioio_mixer_deinit);
+STATIC void check_for_deinit(audioio_mixer_obj_t *self) {
+ if (common_hal_audioio_mixer_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -147,13 +151,61 @@ STATIC mp_obj_t audioio_mixer_obj___exit__(size_t n_args, const mp_obj_t *args)
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_mixer___exit___obj, 4, 4, audioio_mixer_obj___exit__);
+
+//| .. method:: play(sample, *, voice=0, loop=False)
+//|
+//| Plays the sample once when loop=False and continuously when loop=True.
+//| Does not block. Use `playing` to block.
+//|
+//| Sample must be an `audioio.WaveFile`, `audioio.Mixer` or `audioio.RawSample`.
+//|
+//| The sample must match the Mixer's encoding settings given in the constructor.
+//|
+STATIC mp_obj_t audioio_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_sample, ARG_voice, ARG_loop };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ { MP_QSTR_voice, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
+ { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
+ };
+ audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ check_for_deinit(self);
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_obj_t sample = args[ARG_sample].u_obj;
+ common_hal_audioio_mixer_play(self, sample, args[ARG_voice].u_int, args[ARG_loop].u_bool);
+
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_play_obj, 1, audioio_mixer_obj_play);
+
+//| .. method:: stop_voice(voice=0)
+//|
+//| Stops playback of the sample on the given voice.
+//|
+STATIC mp_obj_t audioio_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_voice };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_voice, MP_ARG_INT, {.u_int = 0} },
+ };
+ audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ check_for_deinit(self);
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ common_hal_audioio_mixer_stop_voice(self, args[ARG_voice].u_int);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_KW(audioio_mixer_stop_voice_obj, 1, audioio_mixer_obj_stop_voice);
+
//| .. attribute:: playing
//|
//| True when any voice is being output. (read-only)
//|
STATIC mp_obj_t audioio_mixer_obj_get_playing(mp_obj_t self_in) {
audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_mixer_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audioio_mixer_get_playing(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_playing_obj, audioio_mixer_obj_get_playing);
@@ -171,7 +223,7 @@ const mp_obj_property_t audioio_mixer_playing_obj = {
//|
STATIC mp_obj_t audioio_mixer_obj_get_sample_rate(mp_obj_t self_in) {
audioio_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_mixer_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_mixer_get_sample_rate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_mixer_get_sample_rate_obj, audioio_mixer_obj_get_sample_rate);
diff --git a/shared-bindings/audioio/Mixer.h b/shared-bindings/audiocore/Mixer.h
index 2e5adddf7..87d681ce6 100644
--- a/shared-bindings/audioio/Mixer.h
+++ b/shared-bindings/audiocore/Mixer.h
@@ -28,8 +28,8 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_MIXER_H
#include "common-hal/microcontroller/Pin.h"
-#include "shared-module/audioio/Mixer.h"
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-module/audiocore/Mixer.h"
+#include "shared-bindings/audiocore/RawSample.h"
extern const mp_obj_type_t audioio_mixer_type;
extern const mp_obj_type_t audioio_mixervoice_type;
diff --git a/shared-bindings/audioio/RawSample.c b/shared-bindings/audiocore/RawSample.c
index 7fc896449..912b48bfb 100644
--- a/shared-bindings/audioio/RawSample.c
+++ b/shared-bindings/audiocore/RawSample.c
@@ -31,8 +31,8 @@
#include "py/objproperty.h"
#include "py/runtime.h"
#include "shared-bindings/microcontroller/Pin.h"
-#include "shared-bindings/audioio/AudioOut.h"
#include "shared-bindings/util.h"
+#include "shared-bindings/audiocore/RawSample.h"
#include "supervisor/shared/translate.h"
//| .. currentmodule:: audioio
@@ -115,6 +115,12 @@ STATIC mp_obj_t audioio_rawsample_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_deinit_obj, audioio_rawsample_deinit);
+STATIC void check_for_deinit(audioio_rawsample_obj_t *self) {
+ if (common_hal_audioio_rawsample_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -142,14 +148,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_rawsample___exit___obj, 4, 4,
//|
STATIC mp_obj_t audioio_rawsample_obj_get_sample_rate(mp_obj_t self_in) {
audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_rawsample_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_rawsample_get_sample_rate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_get_sample_rate_obj, audioio_rawsample_obj_get_sample_rate);
STATIC mp_obj_t audioio_rawsample_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) {
audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_rawsample_deinited(self));
+ check_for_deinit(self);
common_hal_audioio_rawsample_set_sample_rate(self, mp_obj_get_int(sample_rate));
return mp_const_none;
}
diff --git a/shared-bindings/audioio/RawSample.h b/shared-bindings/audiocore/RawSample.h
index 0d764b77c..b02778cad 100644
--- a/shared-bindings/audioio/RawSample.h
+++ b/shared-bindings/audiocore/RawSample.h
@@ -27,9 +27,8 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_RAWSAMPLE_H
-#include "common-hal/audioio/AudioOut.h"
#include "common-hal/microcontroller/Pin.h"
-#include "shared-module/audioio/RawSample.h"
+#include "shared-module/audiocore/RawSample.h"
extern const mp_obj_type_t audioio_rawsample_type;
diff --git a/shared-bindings/audioio/WaveFile.c b/shared-bindings/audiocore/WaveFile.c
index cddeef769..4c1993b7c 100644
--- a/shared-bindings/audioio/WaveFile.c
+++ b/shared-bindings/audiocore/WaveFile.c
@@ -29,7 +29,7 @@
#include "lib/utils/context_manager_helpers.h"
#include "py/objproperty.h"
#include "py/runtime.h"
-#include "shared-bindings/audioio/WaveFile.h"
+#include "shared-bindings/audiocore/WaveFile.h"
#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
@@ -41,11 +41,11 @@
//| A .wav file prepped for audio playback. Only mono and stereo files are supported. Samples must
//| be 8 bit unsigned or 16 bit signed.
//|
-//| .. class:: WaveFile(filename)
+//| .. class:: WaveFile(file)
//|
//| Load a .wav file for playback with `audioio.AudioOut` or `audiobusio.I2SOut`.
//|
-//| :param bytes-like file: Already opened wave file
+//| :param typing.BinaryIO file: Already opened wave file
//|
//| Playing a wave file from flash::
//|
@@ -92,6 +92,12 @@ STATIC mp_obj_t audioio_wavefile_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_deinit_obj, audioio_wavefile_deinit);
+STATIC void check_for_deinit(audioio_wavefile_obj_t *self) {
+ if (common_hal_audioio_wavefile_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -118,14 +124,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_wavefile___exit___obj, 4, 4,
//|
STATIC mp_obj_t audioio_wavefile_obj_get_sample_rate(mp_obj_t self_in) {
audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_sample_rate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_sample_rate_obj, audioio_wavefile_obj_get_sample_rate);
STATIC mp_obj_t audioio_wavefile_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) {
audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self));
+ check_for_deinit(self);
common_hal_audioio_wavefile_set_sample_rate(self, mp_obj_get_int(sample_rate));
return mp_const_none;
}
@@ -144,7 +150,7 @@ const mp_obj_property_t audioio_wavefile_sample_rate_obj = {
//|
STATIC mp_obj_t audioio_wavefile_obj_get_bits_per_sample(mp_obj_t self_in) {
audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_bits_per_sample(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_bits_per_sample_obj, audioio_wavefile_obj_get_bits_per_sample);
@@ -162,7 +168,7 @@ const mp_obj_property_t audioio_wavefile_bits_per_sample_obj = {
//|
STATIC mp_obj_t audioio_wavefile_obj_get_channel_count(mp_obj_t self_in) {
audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_wavefile_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_channel_count(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_channel_count_obj, audioio_wavefile_obj_get_channel_count);
diff --git a/shared-bindings/audioio/WaveFile.h b/shared-bindings/audiocore/WaveFile.h
index 62a4200dc..d2572318b 100644
--- a/shared-bindings/audioio/WaveFile.h
+++ b/shared-bindings/audiocore/WaveFile.h
@@ -27,10 +27,11 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOIO_WAVEFILE_H
-#include "common-hal/audioio/AudioOut.h"
-#include "common-hal/microcontroller/Pin.h"
+#include "py/obj.h"
#include "extmod/vfs_fat.h"
+#include "shared-module/audiocore/WaveFile.h"
+
extern const mp_obj_type_t audioio_wavefile_type;
void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t* self,
diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c
new file mode 100644
index 000000000..c64759d4f
--- /dev/null
+++ b/shared-bindings/audiocore/__init__.c
@@ -0,0 +1,69 @@
+/*
+ * 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 <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/audiocore/__init__.h"
+#include "shared-bindings/audiocore/Mixer.h"
+#include "shared-bindings/audiocore/RawSample.h"
+#include "shared-bindings/audiocore/WaveFile.h"
+
+//| :mod:`audiocore` --- Support for audio samples and mixer
+//| ========================================================
+//|
+//| .. module:: audiocore
+//| :synopsis: Support for audio samples and mixer
+//| :platform: SAMD21
+//|
+//| The `audiocore` module contains core classes for audio IO
+//|
+//| Libraries
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| Mixer
+//| RawSample
+//| WaveFile
+//|
+
+STATIC const mp_rom_map_elem_t audiocore_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiocore) },
+ { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) },
+ { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) },
+ { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(audiocore_module_globals, audiocore_module_globals_table);
+
+const mp_obj_module_t audiocore_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&audiocore_module_globals,
+};
diff --git a/shared-bindings/bleio/AdvertisementData.h b/shared-bindings/audiocore/__init__.h
index 05b5a2c8d..02437cd13 100644
--- a/shared-bindings/bleio/AdvertisementData.h
+++ b/shared-bindings/audiocore/__init__.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
+ * 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
@@ -24,11 +24,11 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOCORE___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOCORE___INIT___H
#include "py/obj.h"
-extern const mp_obj_type_t bleio_advertisementdata_type;
+// Nothing now.
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_AUDIOCORE___INIT___H
diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c
index 9cb98d1f8..79df66f7d 100644
--- a/shared-bindings/audioio/AudioOut.c
+++ b/shared-bindings/audioio/AudioOut.c
@@ -32,7 +32,7 @@
#include "py/runtime.h"
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/audioio/AudioOut.h"
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-bindings/audiocore/RawSample.h"
#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
@@ -133,6 +133,11 @@ STATIC mp_obj_t audioio_audioout_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_deinit_obj, audioio_audioout_deinit);
+STATIC void check_for_deinit(audioio_audioout_obj_t *self) {
+ if (common_hal_audioio_audioout_deinited(self)) {
+ raise_deinited_error();
+ }
+}
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -170,7 +175,7 @@ STATIC mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_arg
{ MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
};
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -187,7 +192,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audioio_audioout_play_obj, 1, audioio_audioout_obj_pl
//|
STATIC mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
common_hal_audioio_audioout_stop(self);
return mp_const_none;
}
@@ -199,7 +204,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_stop_obj, audioio_audioout_obj_stop);
//|
STATIC mp_obj_t audioio_audioout_obj_get_playing(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audioio_audioout_get_playing(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_playing_obj, audioio_audioout_obj_get_playing);
@@ -217,7 +222,7 @@ const mp_obj_property_t audioio_audioout_playing_obj = {
//|
STATIC mp_obj_t audioio_audioout_obj_pause(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
if (!common_hal_audioio_audioout_get_playing(self)) {
mp_raise_RuntimeError(translate("Not playing"));
@@ -233,7 +238,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_pause_obj, audioio_audioout_obj_pause
//|
STATIC mp_obj_t audioio_audioout_obj_resume(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
if (common_hal_audioio_audioout_get_paused(self)) {
common_hal_audioio_audioout_resume(self);
@@ -249,7 +254,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_resume_obj, audioio_audioout_obj_resu
//|
STATIC mp_obj_t audioio_audioout_obj_get_paused(mp_obj_t self_in) {
audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_audioio_audioout_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_audioio_audioout_get_paused(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_get_paused_obj, audioio_audioout_obj_get_paused);
diff --git a/shared-bindings/audioio/AudioOut.h b/shared-bindings/audioio/AudioOut.h
index d09a5c9ca..1076ac5cc 100644
--- a/shared-bindings/audioio/AudioOut.h
+++ b/shared-bindings/audioio/AudioOut.h
@@ -29,7 +29,7 @@
#include "common-hal/audioio/AudioOut.h"
#include "common-hal/microcontroller/Pin.h"
-#include "shared-bindings/audioio/RawSample.h"
+#include "shared-bindings/audiocore/RawSample.h"
extern const mp_obj_type_t audioio_audioout_type;
diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c
index 4786b6425..3fecf2708 100644
--- a/shared-bindings/audioio/__init__.c
+++ b/shared-bindings/audioio/__init__.c
@@ -32,9 +32,6 @@
#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/audioio/__init__.h"
#include "shared-bindings/audioio/AudioOut.h"
-#include "shared-bindings/audioio/Mixer.h"
-#include "shared-bindings/audioio/RawSample.h"
-#include "shared-bindings/audioio/WaveFile.h"
//| :mod:`audioio` --- Support for audio input and output
//| ======================================================
@@ -51,22 +48,19 @@
//| :maxdepth: 3
//|
//| AudioOut
-//| Mixer
-//| RawSample
-//| WaveFile
//|
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
//| :ref:`lifetime-and-contextmanagers` for more info.
//|
+//| Since CircuitPython 5, `Mixer`, `RawSample` and `WaveFile` are moved
+//| to :mod:`audiocore`.
+//|
STATIC const mp_rom_map_elem_t audioio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audioio) },
{ MP_ROM_QSTR(MP_QSTR_AudioOut), MP_ROM_PTR(&audioio_audioout_type) },
- { MP_ROM_QSTR(MP_QSTR_Mixer), MP_ROM_PTR(&audioio_mixer_type) },
- { MP_ROM_QSTR(MP_QSTR_RawSample), MP_ROM_PTR(&audioio_rawsample_type) },
- { MP_ROM_QSTR(MP_QSTR_WaveFile), MP_ROM_PTR(&audioio_wavefile_type) },
};
STATIC MP_DEFINE_CONST_DICT(audioio_module_globals, audioio_module_globals_table);
diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c
index 374268e3d..0a3b03f51 100644
--- a/shared-bindings/bitbangio/I2C.c
+++ b/shared-bindings/bitbangio/I2C.c
@@ -42,7 +42,7 @@
//| :class:`I2C` --- Two wire serial protocol
//| ------------------------------------------
//|
-//| .. class:: I2C(scl, sda, \*, frequency=400000)
+//| .. class:: I2C(scl, sda, *, frequency=400000, timeout)
//|
//| I2C is a two-wire protocol for communicating between devices. At the
//| physical level it consists of 2 wires: SCL and SDA, the clock and data
@@ -69,13 +69,12 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args,
const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj);
bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
self->base.type = &bitbangio_i2c_type;
shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int);
return (mp_obj_t)self;
}
-//| .. method:: I2C.deinit()
+//| .. method:: deinit()
//|
//| Releases control of the underlying hardware so other classes can use it.
//|
@@ -86,13 +85,19 @@ STATIC mp_obj_t bitbangio_i2c_obj_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_deinit_obj, bitbangio_i2c_obj_deinit);
-//| .. method:: I2C.__enter__()
+STATIC void check_for_deinit(bitbangio_i2c_obj_t *self) {
+ if (shared_module_bitbangio_i2c_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: __enter__()
//|
//| No-op used in Context Managers.
//|
// Provided by context manager helper.
-//| .. method:: I2C.__exit__()
+//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware on context exit. See
//| :ref:`lifetime-and-contextmanagers` for more info.
@@ -110,7 +115,7 @@ static void check_lock(bitbangio_i2c_obj_t *self) {
}
}
-//| .. method:: I2C.scan()
+//| .. method:: scan()
//|
//| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of
//| those that respond. A device responds if it pulls the SDA line low after
@@ -118,7 +123,7 @@ static void check_lock(bitbangio_i2c_obj_t *self) {
//|
STATIC mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) {
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_obj_t list = mp_obj_new_list(0, NULL);
// 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
@@ -132,30 +137,30 @@ STATIC mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_scan_obj, bitbangio_i2c_scan);
-//| .. method:: I2C.try_lock()
+//| .. method:: try_lock()
//|
//| Attempts to grab the I2C lock. Returns True on success.
//|
STATIC mp_obj_t bitbangio_i2c_obj_try_lock(mp_obj_t self_in) {
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(shared_module_bitbangio_i2c_try_lock(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_try_lock_obj, bitbangio_i2c_obj_try_lock);
-//| .. method:: I2C.unlock()
+//| .. method:: unlock()
//|
//| Releases the I2C lock.
//|
STATIC mp_obj_t bitbangio_i2c_obj_unlock(mp_obj_t self_in) {
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
shared_module_bitbangio_i2c_unlock(self);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock);
-//| .. method:: I2C.readfrom_into(address, buffer, \*, start=0, end=len(buffer))
+//| .. method:: readfrom_into(address, buffer, *, start=0, end=None)
//|
//| Read into ``buffer`` from the slave specified by ``address``.
//| The number of bytes read will be the length of ``buffer``.
@@ -179,7 +184,7 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
check_lock(self);
@@ -203,7 +208,7 @@ STATIC mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a
}
MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 3, bitbangio_i2c_readfrom_into);
-//| .. method:: I2C.writeto(address, buffer, \*, start=0, end=len(buffer), stop=True)
+//| .. method:: writeto(address, buffer, *, start=0, end=None, stop=True)
//|
//| Write the bytes from ``buffer`` to the slave specified by ``address``.
//| Transmits a stop bit if ``stop`` is set.
@@ -232,7 +237,7 @@ STATIC mp_obj_t bitbangio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, m
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
};
bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(shared_module_bitbangio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
diff --git a/shared-bindings/bitbangio/OneWire.c b/shared-bindings/bitbangio/OneWire.c
index a3c53d2a5..73bedcd8d 100644
--- a/shared-bindings/bitbangio/OneWire.c
+++ b/shared-bindings/bitbangio/OneWire.c
@@ -91,6 +91,12 @@ STATIC mp_obj_t bitbangio_onewire_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_deinit_obj, bitbangio_onewire_deinit);
+STATIC void check_for_deinit(bitbangio_onewire_obj_t *self) {
+ if (shared_module_bitbangio_onewire_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -115,7 +121,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_onewire___exit___obj, 4, 4,
//|
STATIC mp_obj_t bitbangio_onewire_obj_reset(mp_obj_t self_in) {
bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(shared_module_bitbangio_onewire_reset(self));
}
@@ -130,7 +136,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_reset_obj, bitbangio_onewire_obj_res
//|
STATIC mp_obj_t bitbangio_onewire_obj_read_bit(mp_obj_t self_in) {
bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(shared_module_bitbangio_onewire_read_bit(self));
}
@@ -142,7 +148,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_onewire_read_bit_obj, bitbangio_onewire_obj_
//|
STATIC mp_obj_t bitbangio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) {
bitbangio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_onewire_deinited(self));
+ check_for_deinit(self);
shared_module_bitbangio_onewire_write_bit(self, mp_obj_is_true(bool_obj));
return mp_const_none;
diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c
index 974ec99e2..88bd3d6cb 100644
--- a/shared-bindings/bitbangio/SPI.c
+++ b/shared-bindings/bitbangio/SPI.c
@@ -84,7 +84,7 @@ STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args,
return (mp_obj_t)self;
}
-//| .. method:: SPI.deinit()
+//| .. method:: deinit()
//|
//| Turn off the SPI bus.
//|
@@ -95,13 +95,19 @@ STATIC mp_obj_t bitbangio_spi_obj_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_deinit_obj, bitbangio_spi_obj_deinit);
-//| .. method:: SPI.__enter__()
+STATIC void check_for_deinit(bitbangio_spi_obj_t *self) {
+ if (shared_module_bitbangio_spi_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
//|
// Provided by context manager helper.
-//| .. method:: SPI.__exit__()
+//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
@@ -120,7 +126,7 @@ static void check_lock(bitbangio_spi_obj_t *self) {
}
}
-//| .. method:: SPI.configure(\*, baudrate=100000, polarity=0, phase=0, bits=8)
+//| .. method:: configure(*, baudrate=100000, polarity=0, phase=0, bits=8)
//|
//| Configures the SPI bus. Only valid when locked.
//|
@@ -139,7 +145,7 @@ STATIC mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args,
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
};
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -162,7 +168,7 @@ STATIC mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args,
}
MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configure);
-//| .. method:: SPI.try_lock()
+//| .. method:: try_lock()
//|
//| Attempts to grab the SPI lock. Returns True on success.
//|
@@ -171,24 +177,24 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configu
//|
STATIC mp_obj_t bitbangio_spi_obj_try_lock(mp_obj_t self_in) {
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(shared_module_bitbangio_spi_try_lock(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_try_lock_obj, bitbangio_spi_obj_try_lock);
-//| .. method:: SPI.unlock()
+//| .. method:: unlock()
//|
//| Releases the SPI lock.
//|
STATIC mp_obj_t bitbangio_spi_obj_unlock(mp_obj_t self_in) {
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
shared_module_bitbangio_spi_unlock(self);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock);
-//| .. method:: SPI.write(buf)
+//| .. method:: write(buf)
//|
//| Write the data contained in ``buf``. Requires the SPI being locked.
//| If the buffer is empty, nothing happens.
@@ -196,7 +202,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock);
// TODO(tannewt): Add support for start and end kwargs.
STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) {
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
mp_buffer_info_t src;
mp_get_buffer_raise(wr_buf, &src, MP_BUFFER_READ);
if (src.len == 0) {
@@ -212,7 +218,7 @@ STATIC mp_obj_t bitbangio_spi_write(mp_obj_t self_in, mp_obj_t wr_buf) {
MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write);
-//| .. method:: SPI.readinto(buf)
+//| .. method:: readinto(buf)
//|
//| Read into the buffer specified by ``buf`` while writing zeroes.
//| Requires the SPI being locked.
@@ -221,7 +227,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_spi_write_obj, bitbangio_spi_write);
// TODO(tannewt): Add support for start and end kwargs.
STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) {
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(args[0]);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
if (bufinfo.len == 0) {
@@ -236,7 +242,7 @@ STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_readinto_obj, 2, 2, bitbangio_spi_readinto);
-//| .. method:: SPI.write_readinto(buffer_out, buffer_in, \*, out_start=0, out_end=len(buffer_out), in_start=0, in_end=len(buffer_in))
+//| .. method:: write_readinto(buffer_out, buffer_in, *, out_start=0, out_end=None, in_start=0, in_end=None)
//|
//| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``.
//| The lengths of the slices defined by ``buffer_out[out_start:out_end]`` and ``buffer_in[in_start:in_end]``
@@ -246,9 +252,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_readinto_obj, 2, 2, bitbangio_
//| :param bytearray buffer_out: Write out the data in this buffer
//| :param bytearray buffer_in: Read data into this buffer
//| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]``
-//| :param int out_end: End of the slice; this index is not included
+//| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)``
//| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]``
-//| :param int in_end: End of the slice; this index is not included
+//| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)``
//|
STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end };
@@ -261,7 +267,7 @@ STATIC mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_
{ MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(shared_module_bitbangio_spi_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
diff --git a/shared-bindings/bleio/Adapter.c b/shared-bindings/bleio/Adapter.c
index d9449d3ab..7b8df5103 100644
--- a/shared-bindings/bleio/Adapter.c
+++ b/shared-bindings/bleio/Adapter.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/shared-bindings/bleio/Adapter.h b/shared-bindings/bleio/Adapter.h
index fe3886e59..de9d1d6db 100644
--- a/shared-bindings/bleio/Adapter.h
+++ b/shared-bindings/bleio/Adapter.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c
index b7c76b7b2..37f01042c 100644
--- a/shared-bindings/bleio/Address.c
+++ b/shared-bindings/bleio/Address.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -33,13 +34,6 @@
#include "shared-bindings/bleio/Address.h"
#include "shared-module/bleio/Address.h"
-#define ADDRESS_BYTE_LEN 12
-
-STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) {
- return unichar_xdigit_value(nibble1) | (unichar_xdigit_value(nibble2) << 4);
-}
-
-
//| .. currentmodule:: bleio
//|
//| :class:`Address` -- BLE address
@@ -48,31 +42,20 @@ STATIC uint8_t xdigit_8b_value(byte nibble1, byte nibble2) {
//| Encapsulates the address of a BLE device.
//|
-//| .. class:: Address(address)
+//| .. class:: Address(address, address_type)
//|
//| Create a new Address object encapsulating the address value.
//| The value itself can be one of:
//|
-//| - a `str` value in the format of 'XXXXXXXXXXXX' or 'XX:XX:XX:XX:XX:XX' (12 hex digits)
-//| - a `bytes` or `bytearray` containing 6 bytes
-//| - another Address object
-//|
-//| :param address: The address to encapsulate
-//|
-
-//| .. attribute:: type
-//|
-//| The address type. One of:
-//|
-//| - `bleio.AddressType.PUBLIC`
-//| - `bleio.AddressType.RANDOM_STATIC`
-//| - `bleio.AddressType.RANDOM_PRIVATE_RESOLVABLE`
-//| - `bleio.AddressType.RANDOM_PRIVATE_NON_RESOLVABLE`
+//| :param buf address: The address value to encapsulate. A buffer object (bytearray, bytes) of 6 bytes.
+//| :param int address_type: one of the integer values: `PUBLIC`, `RANDOM_STATIC`,
+//| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`.
//|
STATIC mp_obj_t bleio_address_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_address };
+ enum { ARG_address, ARG_address_type };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_address, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ { MP_QSTR_address_type, MP_ARG_INT, {.u_int = BLEIO_ADDRESS_TYPE_PUBLIC } },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -80,83 +63,52 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args,
bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t);
self->base.type = &bleio_address_type;
- self->type = ADDRESS_PUBLIC;
const mp_obj_t address = args[ARG_address].u_obj;
+ mp_buffer_info_t buf_info;
+ mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ);
+ if (buf_info.len != NUM_BLEIO_ADDRESS_BYTES) {
+ mp_raise_ValueError_varg(translate("Address must be %d bytes long"), NUM_BLEIO_ADDRESS_BYTES);
+ }
- if (MP_OBJ_IS_STR(address)) {
- GET_STR_DATA_LEN(address, str, str_len);
-
- size_t value_index = 0;
- int str_index = str_len;
- bool error = false;
-
- // Loop until fewer than two characters left.
- while (str_index >= 1 && value_index < sizeof(self->value)) {
- if (str[str_index] == ':') {
- // Skip colon separators.
- str_index--;
- continue;
- }
-
- if (!unichar_isxdigit(str[str_index]) ||
- !unichar_isxdigit(str[str_index-1])) {
- error = true;
- break;
- }
-
- self->value[value_index] = xdigit_8b_value(str[str_index],
- str[str_index-1]);
- value_index += 1;
- str_index -= 2;
- }
- // Check for correct number of hex digits and no parsing errors.
- if (error || value_index != ADDRESS_BYTE_LEN || str_index != -1) {
- mp_raise_ValueError_varg(translate("Address is not %d bytes long or is in wrong format"),
- ADDRESS_BYTE_LEN);
- }
- } else if (MP_OBJ_IS_TYPE(address, &mp_type_bytearray) || MP_OBJ_IS_TYPE(address, &mp_type_bytes)) {
- mp_buffer_info_t buf_info;
- mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ);
- if (buf_info.len != BLEIO_ADDRESS_BYTES) {
- mp_raise_ValueError_varg(translate("Address must be %d bytes long"), BLEIO_ADDRESS_BYTES);
- }
-
- for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) {
- self->value[BLEIO_ADDRESS_BYTES - b - 1] = ((uint8_t*)buf_info.buf)[b];
- }
- } else if (MP_OBJ_IS_TYPE(address, &bleio_address_type)) {
- // deep copy
- bleio_address_obj_t *other = MP_OBJ_TO_PTR(address);
- self->type = other->type;
- memcpy(self->value, other->value, BLEIO_ADDRESS_BYTES);
+ const mp_int_t address_type = args[ARG_address_type].u_int;
+ if (address_type < BLEIO_ADDRESS_TYPE_MIN || address_type > BLEIO_ADDRESS_TYPE_MAX) {
+ mp_raise_ValueError(translate("Address type out of range"));
}
+ common_hal_bleio_address_construct(self, buf_info.buf, address_type);
+
return MP_OBJ_FROM_PTR(self);
}
-STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+//| .. attribute:: address_bytes
+//|
+//| The bytes that make up the device address (read-only)
+//|
+STATIC mp_obj_t bleio_address_get_address_bytes(mp_obj_t self_in) {
bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_printf(print, "Address('%02x:%02x:%02x:%02x:%02x:%02x')",
- self->value[5], self->value[4], self->value[3],
- self->value[2], self->value[1], self->value[0]);
+ return common_hal_bleio_address_get_address_bytes(self);
}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_address_bytes_obj, bleio_address_get_address_bytes);
+
+const mp_obj_property_t bleio_address_address_bytes_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&bleio_address_get_address_bytes_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+//| .. attribute:: type
+//|
+//| The address type (read-only).
+//| One of the integer values: `PUBLIC`, `RANDOM_STATIC`,
+//| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`.
+//|
STATIC mp_obj_t bleio_address_get_type(mp_obj_t self_in) {
bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
- if (self->type == ADDRESS_PUBLIC) {
- return (mp_obj_t)&bleio_addresstype_public_obj;
- } else if (self->type == ADDRESS_RANDOM_STATIC) {
- return (mp_obj_t)&bleio_addresstype_random_static_obj;
- } else if (self->type == ADDRESS_RANDOM_PRIVATE_RESOLVABLE) {
- return (mp_obj_t)&bleio_addresstype_random_private_resolvable_obj;
- } else if (self->type == ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE) {
- return (mp_obj_t)&bleio_addresstype_random_private_non_resolvable_obj;
- }
-
- return mp_const_none;
+ return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_address_get_type(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_type_obj, bleio_address_get_type);
@@ -167,8 +119,74 @@ const mp_obj_property_t bleio_address_type_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+//| .. method:: __eq__(other)
+//|
+//| Two Address objects are equal if their addresses and address types are equal.
+//|
+STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
+ switch (op) {
+ // Two Addresses are equal if their address bytes and address_type are equal
+ case MP_BINARY_OP_EQUAL:
+ if (MP_OBJ_IS_TYPE(rhs_in, &bleio_address_type)) {
+ bleio_address_obj_t *lhs = MP_OBJ_TO_PTR(lhs_in);
+ bleio_address_obj_t *rhs = MP_OBJ_TO_PTR(rhs_in);
+ return mp_obj_new_bool(
+ mp_obj_equal(common_hal_bleio_address_get_address_bytes(lhs),
+ common_hal_bleio_address_get_address_bytes(rhs)) &&
+ common_hal_bleio_address_get_type(lhs) ==
+ common_hal_bleio_address_get_type(rhs));
+
+ } else {
+ return mp_const_false;
+ }
+
+ default:
+ return MP_OBJ_NULL; // op not supported
+ }
+}
+
+STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ if (kind == PRINT_STR) {
+ mp_buffer_info_t buf_info;
+ mp_obj_t address_bytes = common_hal_bleio_address_get_address_bytes(self);
+ mp_get_buffer_raise(address_bytes, &buf_info, MP_BUFFER_READ);
+
+ const uint8_t *buf = (uint8_t *) buf_info.buf;
+ mp_printf(print,
+ "%02x:%02x:%02x:%02x:%02x:%02x",
+ buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
+ } else {
+ mp_printf(print, "<Address>");
+ }
+}
+
+//| .. data:: PUBLIC
+//|
+//| A publicly known address, with a company ID (high 24 bits)and company-assigned part (low 24 bits).
+//|
+//| .. data:: RANDOM_STATIC
+//|
+//| A randomly generated address that does not change often. It may never change or may change after
+//| a power cycle.
+//|
+//| .. data:: RANDOM_PRIVATE_RESOLVABLE
+//|
+//| An address that is usable when the peer knows the other device's secret Identity Resolving Key (IRK).
+//|
+//| .. data:: RANDOM_PRIVATE_NON_RESOLVABLE
+//|
+//| A randomly generated address that changes on every connection.
+//|
STATIC const mp_rom_map_elem_t bleio_address_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_address_bytes), MP_ROM_PTR(&bleio_address_address_bytes_obj) },
{ MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) },
+ // These match the BLE_GAP_ADDR_TYPES values used by the nRF library.
+ { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_OBJ_NEW_SMALL_INT(0) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_OBJ_NEW_SMALL_INT(1) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(2) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(3) },
+
};
STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict_table);
@@ -176,7 +194,8 @@ STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict
const mp_obj_type_t bleio_address_type = {
{ &mp_type_type },
.name = MP_QSTR_Address,
- .print = bleio_address_print,
.make_new = bleio_address_make_new,
+ .print = bleio_address_print,
+ .binary_op = bleio_address_binary_op,
.locals_dict = (mp_obj_dict_t*)&bleio_address_locals_dict
};
diff --git a/shared-bindings/bleio/Address.h b/shared-bindings/bleio/Address.h
index 9c9e20968..5e02ee210 100644
--- a/shared-bindings/bleio/Address.h
+++ b/shared-bindings/bleio/Address.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -28,7 +29,20 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H
#include "py/objtype.h"
+#include "shared-module/bleio/Address.h"
+
+#define BLEIO_ADDRESS_TYPE_PUBLIC (0)
+#define BLEIO_ADDRESS_TYPE_RANDOM_STATIC (1)
+#define BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_RESOLVABLE (2)
+#define BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE (3)
+
+#define BLEIO_ADDRESS_TYPE_MIN BLEIO_ADDRESS_TYPE_PUBLIC
+#define BLEIO_ADDRESS_TYPE_MAX BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE
extern const mp_obj_type_t bleio_address_type;
+extern void common_hal_bleio_address_construct(bleio_address_obj_t *self, uint8_t *bytes, uint8_t address_type);
+extern mp_obj_t common_hal_bleio_address_get_address_bytes(bleio_address_obj_t *self);
+extern uint8_t common_hal_bleio_address_get_type(bleio_address_obj_t *self);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H
diff --git a/shared-bindings/bleio/AddressType.c b/shared-bindings/bleio/AddressType.c
deleted file mode 100644
index cf2151c94..000000000
--- a/shared-bindings/bleio/AddressType.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * This file is part of the Micro Python project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Artur Pacholec
- *
- * 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/bleio/AddressType.h"
-
-//| .. currentmodule:: bleio
-//|
-//| :class:`AddressType` -- defines the type of a BLE address
-//| =============================================================
-//|
-//| .. class:: bleio.AddressType
-//|
-//| Enum-like class to define the type of a BLE address, see also `bleio.Address`.
-//|
-//| .. data:: PUBLIC
-//|
-//| The address is public
-//|
-//| .. data:: RANDOM_STATIC
-//|
-//| The address is random static
-//|
-//| .. data:: RANDOM_PRIVATE_RESOLVABLE
-//|
-//| The address is random private resolvable
-//|
-//| .. data:: RANDOM_PRIVATE_NON_RESOLVABLE
-//|
-//| The address is private non-resolvable
-//|
-const mp_obj_type_t bleio_addresstype_type;
-
-const bleio_addresstype_obj_t bleio_addresstype_public_obj = {
- { &bleio_addresstype_type },
-};
-
-const bleio_addresstype_obj_t bleio_addresstype_random_static_obj = {
- { &bleio_addresstype_type },
-};
-
-const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj = {
- { &bleio_addresstype_type },
-};
-
-const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj = {
- { &bleio_addresstype_type },
-};
-
-STATIC const mp_rom_map_elem_t bleio_addresstype_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_ROM_PTR(&bleio_addresstype_public_obj) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_ROM_PTR(&bleio_addresstype_random_static_obj) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj) },
-};
-STATIC MP_DEFINE_CONST_DICT(bleio_addresstype_locals_dict, bleio_addresstype_locals_dict_table);
-
-STATIC void bleio_addresstype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- qstr type = MP_QSTR_PUBLIC;
-
- if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_static_obj)) {
- type = MP_QSTR_RANDOM_STATIC;
- } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj)) {
- type = MP_QSTR_RANDOM_PRIVATE_RESOLVABLE;
- } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj)) {
- type = MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE;
- }
-
- mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_AddressType, type);
-}
-
-const mp_obj_type_t bleio_addresstype_type = {
- { &mp_type_type },
- .name = MP_QSTR_AddressType,
- .print = bleio_addresstype_print,
- .locals_dict = (mp_obj_t)&bleio_addresstype_locals_dict,
-};
diff --git a/shared-bindings/bleio/AdvertisementData.c b/shared-bindings/bleio/AdvertisementData.c
deleted file mode 100644
index 9cfdd74e9..000000000
--- a/shared-bindings/bleio/AdvertisementData.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Artur Pacholec
- *
- * 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/obj.h"
-#include "shared-module/bleio/AdvertisementData.h"
-
-//| .. currentmodule:: bleio
-//|
-//| :class:`AdvertisementData` -- data used during BLE advertising
-//| ==============================================================
-//|
-//| Represents the data to be broadcast during BLE advertising.
-//|
-
-STATIC const mp_rom_map_elem_t bleio_advertisementdata_locals_dict_table[] = {
- // Static variables
- { MP_ROM_QSTR(MP_QSTR_FLAGS), MP_ROM_INT(AdFlags) },
- { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf16BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf16BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf32BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf32BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf128BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf128BitServiceClassUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_SHORTENED_LOCAL_NAME), MP_ROM_INT(AdShortenedLocalName) },
- { MP_ROM_QSTR(MP_QSTR_COMPLETE_LOCAL_NAME), MP_ROM_INT(AdCompleteLocalName) },
- { MP_ROM_QSTR(MP_QSTR_TX_POWER_LEVEL), MP_ROM_INT(AdTxPowerLevel) },
- { MP_ROM_QSTR(MP_QSTR_CLASS_OF_DEVICE), MP_ROM_INT(AdClassOfDevice) },
- { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C), MP_ROM_INT(AdSimplePairingHashC) },
- { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R), MP_ROM_INT(AdSimplePairingRandomizerR) },
- { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_TK_VALUE), MP_ROM_INT(AdSecurityManagerTKValue) },
- { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_OOB_FLAGS), MP_ROM_INT(AdSecurityManagerOOBFlags) },
- { MP_ROM_QSTR(MP_QSTR_SLAVE_CONNECTION_INTERVAL_RANGE), MP_ROM_INT(AdSlaveConnectionIntervalRange) },
- { MP_ROM_QSTR(MP_QSTR_LIST_OF_16BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf16BitServiceSolicitationUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_LIST_OF_128BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf128BitServiceSolicitationUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA), MP_ROM_INT(AdServiceData) },
- { MP_ROM_QSTR(MP_QSTR_PUBLIC_TARGET_ADDRESS), MP_ROM_INT(AdPublicTargetAddress) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_TARGET_ADDRESS), MP_ROM_INT(AdRandomTargetAddress) },
- { MP_ROM_QSTR(MP_QSTR_APPEARANCE), MP_ROM_INT(AdAppearance) },
- { MP_ROM_QSTR(MP_QSTR_ADVERTISING_INTERNAL), MP_ROM_INT(AdAdvertisingInterval) },
- { MP_ROM_QSTR(MP_QSTR_LE_BLUETOOTH_DEVICE_ADDRESS), MP_ROM_INT(AdLEBluetoothDeviceAddress) },
- { MP_ROM_QSTR(MP_QSTR_LE_ROLE), MP_ROM_INT(AdLERole) },
- { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C256), MP_ROM_INT(AdSimplePairingHashC256) },
- { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R256), MP_ROM_INT(AdSimplePairingRandomizerR256) },
- { MP_ROM_QSTR(MP_QSTR_LIST_OF_32BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf32BitServiceSolicitationUUIDs) },
- { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_32BIT_UUID), MP_ROM_INT(AdServiceData32BitUUID) },
- { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_128BIT_UUID), MP_ROM_INT(AdServiceData128BitUUID) },
- { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE), MP_ROM_INT(AdLESecureConnectionsConfirmationValue) },
- { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_RANDOM_VALUE), MP_ROM_INT(AdLESecureConnectionsRandomValue) },
- { MP_ROM_QSTR(MP_QSTR_URI), MP_ROM_INT(AdURI) },
- { MP_ROM_QSTR(MP_QSTR_INDOOR_POSITIONING), MP_ROM_INT(AdIndoorPositioning) },
- { MP_ROM_QSTR(MP_QSTR_TRANSPORT_DISCOVERY_DATA), MP_ROM_INT(AdTransportDiscoveryData) },
- { MP_ROM_QSTR(MP_QSTR_LE_SUPPORTED_FEATURES), MP_ROM_INT(AdLESupportedFeatures) },
- { MP_ROM_QSTR(MP_QSTR_CHANNEL_MAP_UPDATE_INDICATION), MP_ROM_INT(AdChannelMapUpdateIndication) },
- { MP_ROM_QSTR(MP_QSTR_PB_ADV), MP_ROM_INT(AdPBADV) },
- { MP_ROM_QSTR(MP_QSTR_MESH_MESSAGE), MP_ROM_INT(AdMeshMessage) },
- { MP_ROM_QSTR(MP_QSTR_MESH_BEACON), MP_ROM_INT(AdMeshBeacon) },
- { MP_ROM_QSTR(MP_QSTR_3D_INFORMATION_DATA), MP_ROM_INT(Ad3DInformationData) },
- { MP_ROM_QSTR(MP_QSTR_MANUFACTURER_SPECIFIC_DATA), MP_ROM_INT(AdManufacturerSpecificData) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_advertisementdata_locals_dict, bleio_advertisementdata_locals_dict_table);
-
-const mp_obj_type_t bleio_advertisementdata_type = {
- { &mp_type_type },
- .name = MP_QSTR_AdvertisementData,
- .locals_dict = (mp_obj_dict_t*)&bleio_advertisementdata_locals_dict
-};
diff --git a/shared-bindings/bleio/Broadcaster.c b/shared-bindings/bleio/Broadcaster.c
deleted file mode 100644
index 209e66490..000000000
--- a/shared-bindings/bleio/Broadcaster.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Dan Halbert 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 "ble_drv.h"
-#include "py/runtime.h"
-
-#include "shared-bindings/bleio/Broadcaster.h"
-
-//| .. currentmodule:: bleio
-//|
-//| :class:`Broadcaster` -- Broadcast advertising packets.
-//| =========================================================
-//|
-//| Implement a BLE broadcaster which sends data in advertising packets and does not connect.
-//| Used for beacons and other one-way data transmission.
-//|
-//| Usage::
-//|
-//| import bleio
-//| import time
-//|
-//| # Broadcast once a second.
-//| broadcaster = bleio.Broadcaster(interval=1)
-//| data = 0
-//| # Broadcast a byte of data that's incremented once a minute
-//| while True:
-//| # data is an entire advertising data packet, starting with flags.
-//| broadcaster.start_advertising(data)
-//| time.sleep(60)
-//| data += 1
-//|
-//| .. class:: Broadcaster(interval=1)
-//|
-//| Create a new Broadcaster object.
-
-//| :param float interval: how often to broadcast
-//|
-
-STATIC mp_obj_t bleio_broadcaster_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_interval };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_interval, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} },
- };
-
- 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_float_t interval = mp_obj_get_float(args[ARG_interval].u_obj);
-
- bleio_broadcaster_obj_t *self = m_new_obj(bleio_broadcaster_obj_t);
- self->base.type = &bleio_broadcaster_type;
- // Do port-specific initialization. interval will be validated.
- common_hal_bleio_broadcaster_construct(self, interval);
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-//| .. method:: start_advertising(data)
-//|
-//| Start advertising using the given data packet.
-//|
-//| :param buf data: advertising data packet, starting with advertising data flags (0x01)
-//|
-STATIC mp_obj_t bleio_broadcaster_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- bleio_broadcaster_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
-
- enum { ARG_data };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
-
- common_hal_bleio_broadcaster_start_advertising(self, &bufinfo);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_broadcaster_start_advertising_obj, 0, bleio_broadcaster_start_advertising);
-
-//| .. method:: stop_advertising()
-//|
-//| Stop sending advertising packets.
-STATIC mp_obj_t bleio_broadcaster_stop_advertising(mp_obj_t self_in) {
- bleio_broadcaster_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_broadcaster_stop_advertising(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_broadcaster_stop_advertising_obj, bleio_broadcaster_stop_advertising);
-
-STATIC const mp_rom_map_elem_t bleio_broadcaster_locals_dict_table[] = {
- // Methods
- { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_broadcaster_start_advertising_obj) },
- { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_broadcaster_stop_advertising_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_broadcaster_locals_dict, bleio_broadcaster_locals_dict_table);
-
-const mp_obj_type_t bleio_broadcaster_type = {
- { &mp_type_type },
- .name = MP_QSTR_Broadcaster,
- .make_new = bleio_broadcaster_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_broadcaster_locals_dict
-};
diff --git a/shared-bindings/bleio/Central.c b/shared-bindings/bleio/Central.c
new file mode 100644
index 000000000..fc00bce5c
--- /dev/null
+++ b/shared-bindings/bleio/Central.c
@@ -0,0 +1,199 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * 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 <string.h>
+#include <stdio.h>
+
+#include "ble_drv.h"
+#include "py/objarray.h"
+#include "py/objproperty.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Adapter.h"
+#include "shared-bindings/bleio/Address.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Central.h"
+#include "shared-bindings/bleio/Service.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`Central` -- A BLE central device
+//| =========================================================
+//|
+//| Implement a BLE central, which runs locally. Can connect to a given address.
+//|
+//| Usage::
+//|
+//| import bleio
+//|
+//| scanner = bleio.Scanner()
+//| entries = scanner.scan(2.5)
+//|
+//| my_entry = None
+//| for entry in entries:
+//| if entry.name is not None and entry.name == 'MyPeripheral':
+//| my_entry = entry
+//| break
+//|
+//| central = bleio.Central(my_entry.address)
+//| central.connect(10.0) # timeout after 10 seconds
+//|
+
+//| .. class:: Central()
+//|
+//| Create a new Central object.
+//|
+STATIC mp_obj_t bleio_central_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, 0, false);
+
+ bleio_central_obj_t *self = m_new_obj(bleio_central_obj_t);
+ self->base.type = &bleio_central_type;
+
+ common_hal_bleio_central_construct(self);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| .. method:: connect(address, timeout, *, service_uuids=None)
+//| Attempts a connection to the remote peripheral. If the connection is successful,
+//| Do BLE discovery for the listed services, to find their handles and characteristics.
+//| The attribute `remote_services` will contain a list of all discovered services.
+//|
+//| :param bleio.Address address: The address of the peripheral to connect to
+//| :param float/int timeout: Try to connect for timeout seconds.
+//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services
+//| provided by the peripheral that you want to use.
+//| The peripheral may provide more services, but services not listed are ignored.
+//| If a service in service_uuids is not found during discovery, it will not
+//| appear in `remote_services`.
+//|
+//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow.
+//|
+//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you
+//| you must have already created a :py:class:~`UUID` object for that UUID in order for the
+//| service or characteristic to be discovered. (This restriction may be lifted in the future.)
+//|
+STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_address, ARG_timeout, ARG_service_uuids_whitelist };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_service_uuids_whitelist, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ if (!MP_OBJ_IS_TYPE(args[ARG_address].u_obj, &bleio_address_type)) {
+ mp_raise_ValueError(translate("Expected an Address"));
+ }
+
+ bleio_address_obj_t *address = MP_OBJ_TO_PTR(args[ARG_address].u_obj);
+ mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
+
+ // common_hal_bleio_central_connect() will validate that services is an iterable or None.
+ common_hal_bleio_central_connect(self, address, timeout, args[ARG_service_uuids_whitelist].u_obj);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_connect_obj, 3, bleio_central_connect);
+
+
+//| .. method:: disconnect()
+//|
+//| Disconnects from the remote peripheral.
+//|
+STATIC mp_obj_t bleio_central_disconnect(mp_obj_t self_in) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_central_disconnect(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_disconnect_obj, bleio_central_disconnect);
+
+//| .. attribute:: connected
+//|
+//| True if connected to a remove peripheral.
+//|
+STATIC mp_obj_t bleio_central_get_connected(mp_obj_t self_in) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_central_get_connected(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_connected_obj, bleio_central_get_connected);
+
+const mp_obj_property_t bleio_central_connected_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_central_get_connected_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+
+//| .. attribute:: remote_services (read-only)
+//|
+//| A tuple of services provided by the remote peripheral.
+//| If the Central is not connected, an empty tuple will be returned.
+//|
+STATIC mp_obj_t bleio_central_get_remote_services(mp_obj_t self_in) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ // Return list as a tuple so user won't be able to change it.
+ mp_obj_list_t *service_list = common_hal_bleio_central_get_remote_services(self);
+ return mp_obj_new_tuple(service_list->len, service_list->items);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_remote_services_obj, bleio_central_get_remote_services);
+
+const mp_obj_property_t bleio_central_remote_services_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_central_get_remote_services_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_central_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) },
+
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_central_connected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remote_services), MP_ROM_PTR(&bleio_central_remote_services_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_central_locals_dict, bleio_central_locals_dict_table);
+
+const mp_obj_type_t bleio_central_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Central,
+ .make_new = bleio_central_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_central_locals_dict
+};
diff --git a/shared-bindings/bleio/Device.h b/shared-bindings/bleio/Central.h
index aebf1d639..0e84037f9 100644
--- a/shared-bindings/bleio/Device.h
+++ b/shared-bindings/bleio/Central.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,19 +25,18 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
-#include "shared-module/bleio/AdvertisementData.h"
-#include "shared-module/bleio/Device.h"
-#include "shared-module/bleio/Service.h"
+#include "common-hal/bleio/Central.h"
+#include "common-hal/bleio/Service.h"
-extern const mp_obj_type_t bleio_device_type;
+extern const mp_obj_type_t bleio_central_type;
-extern void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service);
-extern void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data);
-extern void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device);
-extern void common_hal_bleio_device_connect(bleio_device_obj_t *device);
-extern void common_hal_bleio_device_disconnect(bleio_device_obj_t *device);
+extern void common_hal_bleio_central_construct(bleio_central_obj_t *self);
+extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, mp_obj_t service_uuids);
+extern void common_hal_bleio_central_disconnect(bleio_central_obj_t *self);
+extern bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self);
+extern mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self);
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c
index ae83de864..3bf0476ab 100644
--- a/shared-bindings/bleio/Characteristic.c
+++ b/shared-bindings/bleio/Characteristic.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -68,15 +69,15 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t
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 mp_obj_t uuid = args[ARG_uuid].u_obj;
+ const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
- if (!MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) {
+ if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
mp_raise_ValueError(translate("Expected a UUID"));
}
+ bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t);
self->base.type = &bleio_characteristic_type;
- self->uuid = MP_OBJ_TO_PTR(uuid);
bleio_characteristic_properties_t properties;
@@ -87,7 +88,8 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t
properties.write = args[ARG_write].u_bool;
properties.write_no_response = args[ARG_write_no_response].u_bool;
- common_hal_bleio_characteristic_construct(self, uuid, properties);
+ // Initialize, with an empty descriptor list.
+ common_hal_bleio_characteristic_construct(self, uuid, properties, mp_obj_new_list(0, NULL));
return MP_OBJ_FROM_PTR(self);
}
@@ -99,7 +101,7 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t
STATIC mp_obj_t bleio_characteristic_get_broadcast(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.broadcast);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).broadcast);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_broadcast);
@@ -117,7 +119,7 @@ const mp_obj_property_t bleio_characteristic_broadcast_obj = {
STATIC mp_obj_t bleio_characteristic_get_indicate(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.indicate);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).indicate);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_indicate_obj, bleio_characteristic_get_indicate);
@@ -136,7 +138,7 @@ const mp_obj_property_t bleio_characteristic_indicate_obj = {
STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.notify);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).notify);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_notify_obj, bleio_characteristic_get_notify);
@@ -154,7 +156,7 @@ const mp_obj_property_t bleio_characteristic_notify_obj = {
STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.read);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).read);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_read_obj, bleio_characteristic_get_read);
@@ -172,7 +174,7 @@ const mp_obj_property_t bleio_characteristic_read_obj = {
STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.write);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_obj, bleio_characteristic_get_write);
@@ -190,7 +192,7 @@ const mp_obj_property_t bleio_characteristic_write_obj = {
STATIC mp_obj_t bleio_characteristic_get_write_no_response(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(self->props.write_no_response);
+ return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write_no_response);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_no_response_obj, bleio_characteristic_get_write_no_response);
@@ -204,11 +206,13 @@ const mp_obj_property_t bleio_characteristic_write_no_response_obj = {
//| .. attribute:: uuid
//|
//| The UUID of this characteristic. (read-only)
+//| Will be ``None`` if the 128-bit UUID for this characteristic is not known.
//|
STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return MP_OBJ_FROM_PTR(self->uuid);
+ bleio_uuid_obj_t *uuid = common_hal_bleio_characteristic_get_uuid(self);
+ return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_uuid_obj, bleio_characteristic_get_uuid);
@@ -228,9 +232,7 @@ const mp_obj_property_t bleio_characteristic_uuid_obj = {
STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- common_hal_bleio_characteristic_get_value(self);
-
- return self->value_data;
+ return common_hal_bleio_characteristic_get_value(self);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_value_obj, bleio_characteristic_get_value);
@@ -253,22 +255,80 @@ const mp_obj_property_t bleio_characteristic_value_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: descriptors
+//|
+//| A tuple of `bleio.Descriptor` that describe this characteristic. (read-only)
+//|
+STATIC mp_obj_t bleio_characteristic_get_descriptors(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ // Return list as a tuple so user won't be able to change it.
+ mp_obj_list_t *char_list = common_hal_bleio_characteristic_get_descriptor_list(self);
+ return mp_obj_new_tuple(char_list->len, char_list->items);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_descriptors_obj, bleio_characteristic_get_descriptors);
+
+const mp_obj_property_t bleio_characteristic_descriptors_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_descriptors_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+//| .. method:: set_cccd(*, notify=False, indicate=False)
+//|
+//| Set the remote characteristic's CCCD to enable or disable notification and indication.
+//|
+//| :param bool notify: True if Characteristic should receive notifications of remote writes
+//| :param float indicate: True if Characteristic should receive indications of remote writes
+//|
+STATIC mp_obj_t bleio_characteristic_set_cccd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_notify, ARG_indicate };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_notify, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_indicate, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ common_hal_bleio_characteristic_set_cccd(self, args[ARG_notify].u_bool, args[ARG_indicate].u_bool);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_set_cccd_obj, 1, bleio_characteristic_set_cccd);
+
+
STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_broadcast), MP_ROM_PTR(&bleio_characteristic_broadcast_obj) },
+ { MP_ROM_QSTR(MP_QSTR_descriptors), MP_ROM_PTR(&bleio_characteristic_descriptors_obj) },
{ MP_ROM_QSTR(MP_QSTR_indicate), MP_ROM_PTR(&bleio_characteristic_indicate_obj) },
{ MP_ROM_QSTR(MP_QSTR_notify), MP_ROM_PTR(&bleio_characteristic_notify_obj) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&bleio_characteristic_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) },
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_characteristic_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_write_no_response), MP_ROM_PTR(&bleio_characteristic_write_no_response_obj) },
};
-
STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characteristic_locals_dict_table);
+STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ if (self->uuid) {
+ mp_printf(print, "Characteristic(");
+ bleio_uuid_print(print, MP_OBJ_FROM_PTR(self->uuid), kind);
+ mp_printf(print, ")");
+ } else {
+ mp_printf(print, "<Characteristic with Unregistered UUID>");
+ }
+}
+
const mp_obj_type_t bleio_characteristic_type = {
{ &mp_type_type },
.name = MP_QSTR_Characteristic,
.make_new = bleio_characteristic_make_new,
+ .print = bleio_characteristic_print,
.locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict
};
diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h
index 206cbcd40..d450c42b4 100644
--- a/shared-bindings/bleio/Characteristic.h
+++ b/shared-bindings/bleio/Characteristic.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,12 +28,17 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
+#include "shared-module/bleio/Characteristic.h"
#include "common-hal/bleio/Characteristic.h"
extern const mp_obj_type_t bleio_characteristic_type;
-extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props);
-extern void common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self);
+extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, mp_obj_list_t *descriptor_list);
+extern mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self);
extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
+extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self);
+extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self);
+extern mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self);
+extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
diff --git a/shared-bindings/bleio/CharacteristicBuffer.c b/shared-bindings/bleio/CharacteristicBuffer.c
index 66d164954..26f9e012b 100644
--- a/shared-bindings/bleio/CharacteristicBuffer.c
+++ b/shared-bindings/bleio/CharacteristicBuffer.c
@@ -47,12 +47,15 @@ STATIC void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self
//|
//| Accumulates a Characteristic's incoming values in a FIFO buffer.
//|
-//| .. class:: CharacteristicBuffer(Characteristic, *, timeout=1, buffer_size=64)
+//| .. class:: CharacteristicBuffer(characteristic, *, timeout=1, buffer_size=64)
//|
-//| Create a new Characteristic object identified by the specified UUID.
+//| Monitor the given Characteristic. Each time a new value is written to the Characteristic
+//| add the newly-written bytes to a FIFO buffer.
//|
-//| :param bleio.Characteristic characteristic: The characteristic to monitor
-//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters.//|
+//| :param bleio.Characteristic characteristic: The Characteristic to monitor.
+//| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic
+//| in a remote Service that a Central has connected to.
+//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters.
//| :param int buffer_size: Size of ring buffer that stores incoming data coming from client.
//| Must be >= 1.
//|
@@ -85,13 +88,18 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type,
bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t);
self->base.type = &bleio_characteristic_buffer_type;
- self->characteristic = MP_OBJ_TO_PTR(characteristic);
- common_hal_bleio_characteristic_buffer_construct(self, self->characteristic, timeout, buffer_size);
+ common_hal_bleio_characteristic_buffer_construct(self, MP_OBJ_TO_PTR(characteristic), timeout, buffer_size);
return MP_OBJ_FROM_PTR(self);
}
+STATIC void check_for_deinit(bleio_characteristic_buffer_obj_t *self) {
+ if (common_hal_bleio_characteristic_buffer_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
// These are standard stream methods. Code is in py/stream.c.
//
//| .. method:: read(nbytes=None)
@@ -122,7 +130,7 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type,
// These three methods are used by the shared stream methods.
STATIC mp_uint_t bleio_characteristic_buffer_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self));
+ check_for_deinit(self);
raise_error_if_not_connected(self);
byte *buf = buf_in;
@@ -141,10 +149,10 @@ STATIC mp_uint_t bleio_characteristic_buffer_write(mp_obj_t self_in, const void
STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self));
+ check_for_deinit(self);
raise_error_if_not_connected(self);
if (!common_hal_bleio_characteristic_buffer_connected(self)) {
- mp_raise_ValueError(translate("Not connected."));
+ mp_raise_ValueError(translate("Not connected"));
}
mp_uint_t ret;
if (request == MP_IOCTL_POLL) {
@@ -170,7 +178,7 @@ STATIC mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r
//|
STATIC mp_obj_t bleio_characteristic_buffer_obj_get_in_waiting(mp_obj_t self_in) {
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_buffer_rx_characters_available(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_get_in_waiting_obj, bleio_characteristic_buffer_obj_get_in_waiting);
@@ -188,7 +196,7 @@ const mp_obj_property_t bleio_characteristic_buffer_in_waiting_obj = {
//|
STATIC mp_obj_t bleio_characteristic_buffer_obj_reset_input_buffer(mp_obj_t self_in) {
bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_bleio_characteristic_buffer_deinited(self));
+ check_for_deinit(self);
common_hal_bleio_characteristic_buffer_clear_rx_buffer(self);
return mp_const_none;
}
diff --git a/shared-bindings/bleio/CharacteristicBuffer.h b/shared-bindings/bleio/CharacteristicBuffer.h
index f25017c19..b45835ff3 100644
--- a/shared-bindings/bleio/CharacteristicBuffer.h
+++ b/shared-bindings/bleio/CharacteristicBuffer.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2019 Dan Halbert 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
diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c
index b32f4f08e..f2e5aa01d 100644
--- a/shared-bindings/bleio/Descriptor.c
+++ b/shared-bindings/bleio/Descriptor.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -30,27 +31,6 @@
#include "shared-bindings/bleio/Descriptor.h"
#include "shared-bindings/bleio/UUID.h"
-enum {
- DescriptorUuidCharacteristicExtendedProperties = 0x2900,
- DescriptorUuidCharacteristicUserDescription = 0x2901,
- DescriptorUuidClientCharacteristicConfiguration = 0x2902,
- DescriptorUuidServerCharacteristicConfiguration = 0x2903,
- DescriptorUuidCharacteristicPresentationFormat = 0x2904,
- DescriptorUuidCharacteristicAggregateFormat = 0x2905,
- DescriptorUuidValidRange = 0x2906,
- DescriptorUuidExternalReportReference = 0x2907,
- DescriptorUuidReportReference = 0x2908,
- DescriptorUuidNumberOfDigitals = 0x2909,
- DescriptorUuidValueTriggerSetting = 0x290A,
- DescriptorUuidEnvironmentalSensingConfiguration = 0x290B,
- DescriptorUuidEnvironmentalSensingMeasurement = 0x290C,
- DescriptorUuidEnvironmentalSensingTriggerSetting = 0x290D,
- DescriptorUuidTimeTriggerSetting = 0x290E,
-};
-
-// Work-in-progress: orphaned for now.
-//| :orphan:
-//|
//| .. currentmodule:: bleio
//|
//| :class:`Descriptor` -- BLE descriptor
@@ -113,7 +93,9 @@ const mp_obj_property_t bleio_descriptor_handle_obj = {
STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) {
bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return common_hal_bleio_descriptor_get_uuid(self);
+
+ bleio_uuid_obj_t *uuid = common_hal_bleio_descriptor_get_uuid(self);
+ return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_uuid_obj, bleio_descriptor_get_uuid);
@@ -130,28 +112,69 @@ STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) },
// Static variables
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_EXTENDED_PROPERTIES), MP_ROM_INT(DescriptorUuidCharacteristicExtendedProperties) },
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION), MP_ROM_INT(DescriptorUuidCharacteristicUserDescription) },
- { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidClientCharacteristicConfiguration) },
- { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidServerCharacteristicConfiguration) },
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicPresentationFormat) },
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicAggregateFormat) },
- { MP_ROM_QSTR(MP_QSTR_VALID_RANGE), MP_ROM_INT(DescriptorUuidValidRange) },
- { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidExternalReportReference) },
- { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidReportReference) },
- { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS), MP_ROM_INT(DescriptorUuidNumberOfDigitals) },
- { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidValueTriggerSetting) },
- { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION), MP_ROM_INT(DescriptorUuidEnvironmentalSensingConfiguration) },
- { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ), MP_ROM_INT(DescriptorUuidEnvironmentalSensingMeasurement) },
- { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidEnvironmentalSensingTriggerSetting) },
- { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidTimeTriggerSetting) }
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_EXTENDED_PROPERTIES),
+ MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES) },
+
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION),
+ MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION) },
+
+ { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION),
+ MP_ROM_INT(DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION) },
+
+ { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION),
+ MP_ROM_INT(DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION) },
+
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT),
+ MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT) },
+
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT),
+ MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT) },
+
+ { MP_ROM_QSTR(MP_QSTR_VALID_RANGE),
+ MP_ROM_INT(DESCRIPTOR_UUID_VALID_RANGE) },
+
+ { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE),
+ MP_ROM_INT(DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE) },
+
+ { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE),
+ MP_ROM_INT(DESCRIPTOR_UUID_REPORT_REFERENCE) },
+
+ { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS),
+ MP_ROM_INT(DESCRIPTOR_UUID_NUMBER_OF_DIGITALS) },
+
+ { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING),
+ MP_ROM_INT(DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING) },
+
+ { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION),
+ MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION) },
+
+ { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ),
+ MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT) },
+
+ { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING),
+ MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING) },
+
+ { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING),
+ MP_ROM_INT(DESCRIPTOR_UUID_TIME_TRIGGER_SETTING) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_locals_dict_table);
+STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ if (self->uuid) {
+ mp_printf(print, "Descriptor(");
+ bleio_uuid_print(print, MP_OBJ_FROM_PTR(self->uuid), kind);
+ mp_printf(print, ")");
+ } else {
+ mp_printf(print, "<Descriptor with Unregistered UUID>");
+ }
+}
+
const mp_obj_type_t bleio_descriptor_type = {
{ &mp_type_type },
.name = MP_QSTR_Descriptor,
.make_new = bleio_descriptor_make_new,
+ .print = bleio_descriptor_print,
.locals_dict = (mp_obj_dict_t*)&bleio_descriptor_locals_dict
};
diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h
index f47378ee1..fd11ea08c 100644
--- a/shared-bindings/bleio/Descriptor.h
+++ b/shared-bindings/bleio/Descriptor.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -30,6 +31,24 @@
#include "common-hal/bleio/Descriptor.h"
#include "common-hal/bleio/UUID.h"
+enum {
+ DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES = 0x2900,
+ DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION = 0x2901,
+ DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION = 0x2902,
+ DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION = 0x2903,
+ DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT = 0x2904,
+ DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT = 0x2905,
+ DESCRIPTOR_UUID_VALID_RANGE = 0x2906,
+ DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE = 0x2907,
+ DESCRIPTOR_UUID_REPORT_REFERENCE = 0x2908,
+ DESCRIPTOR_UUID_NUMBER_OF_DIGITALS = 0x2909,
+ DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING = 0x290A,
+ DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION = 0x290B,
+ DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT = 0x290C,
+ DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING = 0x290D,
+ DESCRIPTOR_UUID_TIME_TRIGGER_SETTING = 0x290E,
+};
+
extern const mp_obj_type_t bleio_descriptor_type;
extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid);
diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c
deleted file mode 100644
index 80595ef33..000000000
--- a/shared-bindings/bleio/Device.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 Glenn Ruben Bakke
- * Copyright (c) 2018 Artur Pacholec
- *
- * 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 <string.h>
-#include <stdio.h>
-
-#include "ble_drv.h"
-#include "py/objarray.h"
-#include "py/objproperty.h"
-#include "py/objstr.h"
-#include "py/runtime.h"
-#include "shared-bindings/bleio/Adapter.h"
-#include "shared-bindings/bleio/AddressType.h"
-#include "shared-bindings/bleio/Characteristic.h"
-#include "shared-bindings/bleio/Device.h"
-#include "shared-bindings/bleio/Service.h"
-#include "shared-bindings/bleio/UUID.h"
-#include "shared-module/bleio/AdvertisementData.h"
-#include "shared-module/bleio/Device.h"
-#include "shared-module/bleio/ScanEntry.h"
-
-// Work-in-progress: orphaned for now.
-//| :orphan:
-//|
-//| .. currentmodule:: bleio
-//|
-//| :class:`Device` -- BLE device
-//| =========================================================
-//|
-//| **IGNORE ``Device`` and all its documentation.
-//| It is being replaced by `Peripheral` and other classes.**
-//|
-//| Provides access a to BLE device, either in a Peripheral or Central role.
-//| When a device is created without any parameter passed to the constructor,
-//| it will be set to the Peripheral role. If a address is passed, the device
-//| will be a Central. For a Peripheral you can set the `name`, add services
-//| via `add_service` and then start and stop advertising via `bleio.Device.start_advertising`
-//| and `bleio.Device.stop_advertising`. For the Central, you can `bleio.Device.connect` and `bleio.Device.disconnect`
-//| to the device, once a connection is established, the device's services can
-//| be accessed using `bleio.Device.services`.
-//|
-//| Usage::
-//|
-//| import bleio
-//|
-//| # Peripheral
-//| periph = bleio.Device()
-//|
-//| serv = bleio.Service(bleio.UUID(0x180f))
-//| p.add_service(serv)
-//|
-//| chara = bleio.Characteristic(bleio.UUID(0x2919))
-//| chara.read = True
-//| chara.notify = True
-//| serv.add_characteristic(chara)
-//|
-//| periph.start_advertising()
-//|
-//| # Central
-//| scanner = bleio.Scanner()
-//| entries = scanner.scan(2500)
-//|
-//| my_entry = None
-//| for entry in entries:
-//| if entry.name is not None and entry.name == 'MyDevice':
-//| my_entry = entry
-//| break
-//|
-//| central = bleio.Device(my_entry.address)
-//| central.connect()
-//|
-
-//| .. class:: Device(address=None, scan_entry=None)
-//|
-//| Create a new Device object. If the `address` or :py:data:`scan_entry` parameters are not `None`,
-//| the role is set to Central, otherwise it's set to Peripheral.
-//|
-//| :param bleio.Address address: The address of the device to connect to
-//| :param bleio.ScanEntry scan_entry: The scan entry returned from `bleio.Scanner`
-//|
-
-//| .. attribute:: name
-//|
-//| For the Peripheral role, this property can be used to read and write the device's name.
-//| For the Central role, this property will equal the name of the remote device, if one was
-//| advertised by the device. In the Central role this property is read-only.
-//|
-
-//| .. attribute:: services
-//|
-//| A `list` of `bleio.Service` that are offered by this device. (read-only)
-//| For a Peripheral device, this list will contain services added using `add_service`,
-//| for a Central, this list will be empty until a connection is established, at which point
-//| it will be filled with the remote device's services.
-//|
-
-//| .. method:: add_service(service)
-//|
-//| Appends the :py:data:`service` to the list of this devices's services.
-//| This method can only be called for Peripheral devices.
-//|
-//| :param bleio.Service service: the service to append
-//|
-
-//| .. method:: connect()
-//|
-//| Attempts a connection to the remote device. If the connection is successful,
-//| the device's services are available via `services`.
-//| This method can only be called for Central devices.
-//|
-
-//| .. method:: disconnect()
-//|
-//| Disconnects from the remote device.
-//| This method can only be called for Central devices.
-//|
-
-//| .. method:: start_advertising(connectable=True)
-//|
-//| Starts advertising the device. The device's name and
-//| services are put into the advertisement packets.
-//| If :py:data:`connectable` is `True` then other devices are allowed to conncet to this device.
-//| This method can only be called for Peripheral devices.
-//|
-
-//| .. method:: stop_advertising()
-//|
-//| Disconnects from the remote device.
-//| This method can only be called for Peripheral devices.
-//|
-
-// TODO: Add unique MAC address part to name
-static const char default_name[] = "CIRCUITPY";
-
-STATIC void bleio_device_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- mp_printf(print, "Device(role: %s)", self->is_peripheral ? "Peripheral" : "Central");
-}
-
-STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
- mp_arg_check_num(n_args, n_kw, 0, 1, true);
- bleio_device_obj_t *self = m_new_obj(bleio_device_obj_t);
- self->base.type = &bleio_device_type;
- self->service_list = mp_obj_new_list(0, NULL);
- self->notif_handler = mp_const_none;
- self->conn_handler = mp_const_none;
- self->conn_handle = 0xFFFF;
- self->is_peripheral = true;
-
- mp_map_t kw_args;
- mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
-
- enum { ARG_address, ARG_scan_entry };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_address, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_scan_entry, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.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 mp_obj_t address_obj = args[ARG_address].u_obj;
- const mp_obj_t scan_entry_obj = args[ARG_scan_entry].u_obj;
-
- if (address_obj != mp_const_none) {
- bleio_address_obj_t *address = MP_OBJ_TO_PTR(address_obj);
-
- self->is_peripheral = false;
- self->address.type = address->type;
- memcpy(self->address.value, address->value, BLEIO_ADDRESS_BYTES);
- } else if (scan_entry_obj != mp_const_none) {
- bleio_scanentry_obj_t *scan_entry = MP_OBJ_TO_PTR(scan_entry_obj);
-
- self->is_peripheral = false;
- self->address.type = scan_entry->address.type;
- memcpy(self->address.value, scan_entry->address.value, BLEIO_ADDRESS_BYTES);
- } else {
- self->name = mp_obj_new_str(default_name, strlen(default_name));
- common_hal_bleio_adapter_get_address(&self->address);
- }
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-STATIC mp_obj_t bleio_device_add_service(mp_obj_t self_in, mp_obj_t service_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
- bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_in);
-
- if (!self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't add services in Central mode")));
- }
-
- service->device = self;
-
- mp_obj_list_append(self->service_list, service);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_add_service_obj, bleio_device_add_service);
-
-STATIC mp_obj_t bleio_device_connect(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't connect in Peripheral mode")));
- }
-
- common_hal_bleio_device_connect(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_connect_obj, bleio_device_connect);
-
-STATIC mp_obj_t bleio_device_disconnect(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_device_disconnect(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_disconnect_obj, bleio_device_disconnect);
-
-STATIC mp_obj_t bleio_device_get_name(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return self->name;
-}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_name_obj, bleio_device_get_name);
-
-static mp_obj_t bleio_device_set_name(mp_obj_t self_in, mp_obj_t value) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (!self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't change the name in Central mode")));
- }
-
- self->name = value;
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_set_name_obj, bleio_device_set_name);
-
-const mp_obj_property_t bleio_device_name_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_device_get_name_obj,
- (mp_obj_t)&bleio_device_set_name_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t bleio_device_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
-
- if (!self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't advertise in Central mode")));
- }
-
- enum { ARG_connectable, ARG_data };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
- { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- mp_buffer_info_t bufinfo = { 0 };
- if (args[ARG_data].u_obj != mp_const_none) {
- mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
- }
-
- const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list);
- for (size_t i = 0; i < service_list->len; ++i) {
- bleio_service_obj_t *service = service_list->items[i];
- if (service->handle == 0xFFFF) {
- common_hal_bleio_device_add_service(self, service);
- }
- }
-
- common_hal_bleio_device_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_device_start_advertising_obj, 0, bleio_device_start_advertising);
-
-STATIC mp_obj_t bleio_device_stop_advertising(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- if (!self->is_peripheral) {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
- translate("Can't advertise in Central mode")));
- }
-
- common_hal_bleio_device_stop_advertising(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_stop_advertising_obj, bleio_device_stop_advertising);
-
-STATIC mp_obj_t bleio_device_get_services(mp_obj_t self_in) {
- bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return self->service_list;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_services_obj, bleio_device_get_services);
-
-const mp_obj_property_t bleio_device_services_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_device_get_services_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC const mp_rom_map_elem_t bleio_device_locals_dict_table[] = {
- // Methods
- { MP_ROM_QSTR(MP_QSTR_add_service), MP_ROM_PTR(&bleio_device_add_service_obj) },
- { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_device_connect_obj) },
- { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_device_disconnect_obj) },
- { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_device_start_advertising_obj) },
- { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_device_stop_advertising_obj) },
-
- // Properties
- { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_device_name_obj) },
- { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_device_services_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_device_locals_dict, bleio_device_locals_dict_table);
-
-const mp_obj_type_t bleio_device_type = {
- { &mp_type_type },
- .name = MP_QSTR_Device,
- .print = bleio_device_print,
- .make_new = bleio_device_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_device_locals_dict
-};
diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c
index 340485f35..570896d27 100644
--- a/shared-bindings/bleio/Peripheral.c
+++ b/shared-bindings/bleio/Peripheral.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -35,19 +36,22 @@
#include "py/runtime.h"
#include "shared-bindings/bleio/Adapter.h"
-#include "shared-bindings/bleio/AddressType.h"
#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/Peripheral.h"
#include "shared-bindings/bleio/Service.h"
#include "shared-bindings/bleio/UUID.h"
-#include "shared-module/bleio/AdvertisementData.h"
#include "shared-module/bleio/ScanEntry.h"
#include "common-hal/bleio/Peripheral.h"
-// TODO: Add unique MAC address part to name
static const char default_name[] = "CIRCUITPY";
+#define ADV_INTERVAL_DEFAULT (1.0f)
+#define ADV_INTERVAL_MIN (0.0020f)
+#define ADV_INTERVAL_MIN_STRING "0.0020"
+#define ADV_INTERVAL_MAX (10.24f)
+#define ADV_INTERVAL_MAX_STRING "10.24"
+
//| .. currentmodule:: bleio
//|
//| :class:`Peripheral` -- A BLE peripheral device
@@ -59,6 +63,7 @@ static const char default_name[] = "CIRCUITPY";
//| Usage::
//|
//| import bleio
+//| from adafruit_ble.advertising import ServerAdvertisement
//|
//| # Create a Characteristic.
//| chara = bleio.Characteristic(bleio.UUID(0x2919), read=True, notify=True)
@@ -67,26 +72,28 @@ static const char default_name[] = "CIRCUITPY";
//| serv = bleio.Service(bleio.UUID(0x180f), [chara])
//|
//| # Create a peripheral and start it up.
-//| periph = bleio.Peripheral([service])
-//| periph.start_advertising()
+//| periph = bleio.Peripheral([serv])
+//| adv = ServerAdvertisement(periph)
+//| periph.start_advertising(adv.advertising_data_bytes, adv.scan_response_bytes)
//|
//| while not periph.connected:
//| # Wait for connection.
//| pass
//|
-//| .. class:: Peripheral(services, *, name='CIRCUITPY')
+//| .. class:: Peripheral(services=(), \*, name='CIRCUITPY')
//|
//| Create a new Peripheral object.
-
-//| :param iterable services: the Service objects representing services available from this peripheral.
-//| :param str name: The name used when advertising this peripheral
//|
-
+//| :param iterable services: the Service objects representing services available from this peripheral, if any.
+//| A non-connectable peripheral will have no services.
+//| :param str name: The name used when advertising this peripheral. Use ``None`` when a name is not needed,
+//| such as when the peripheral is a beacon
+//|
STATIC mp_obj_t bleio_peripheral_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_services, ARG_name };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_services, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_name, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
+ { MP_QSTR_services, MP_ARG_OBJ, {.u_obj = mp_const_empty_tuple} },
+ { MP_QSTR_name, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -95,32 +102,33 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar
// If services is not an iterable, an exception will be thrown.
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(args[ARG_services].u_obj, &iter_buf);
- mp_obj_t service;
bleio_peripheral_obj_t *self = m_new_obj(bleio_peripheral_obj_t);
self->base.type = &bleio_peripheral_type;
- self->service_list = mp_obj_new_list(0, NULL);
- self->notif_handler = mp_const_none;
+
+ // Copy the services list and validate its items.
+ mp_obj_t service_list_obj = mp_obj_new_list(0, NULL);
+ mp_obj_list_t *service_list = MP_OBJ_FROM_PTR(service_list_obj);
+
+ mp_obj_t service;
while ((service = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
if (!MP_OBJ_IS_TYPE(service, &bleio_service_type)) {
- mp_raise_ValueError(translate("services includes an object that is not a Service"));
+ mp_raise_ValueError(translate("non-Service found in services"));
}
- bleio_service_obj_t *service_ptr = MP_OBJ_TO_PTR(service);
- service_ptr->device = MP_OBJ_FROM_PTR(self);
- mp_obj_list_append(self->service_list, service);
+ mp_obj_list_append(service_list, service);
}
const mp_obj_t name = args[ARG_name].u_obj;
- if (name == mp_const_none) {
- self->name = mp_obj_new_str(default_name, strlen(default_name));
+ mp_obj_t name_str;
+ if (name == MP_OBJ_NULL || name == mp_const_none) {
+ name_str = mp_obj_new_str(default_name, strlen(default_name));
} else if (MP_OBJ_IS_STR(name)) {
- self->name = name;
+ name_str = name;
} else {
mp_raise_ValueError(translate("name must be a string"));
}
- // Do port-specific initialization.
- common_hal_bleio_peripheral_construct(self);
+ common_hal_bleio_peripheral_construct(self, service_list, name_str);
return MP_OBJ_FROM_PTR(self);
}
@@ -132,7 +140,6 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar
STATIC mp_obj_t bleio_peripheral_get_connected(mp_obj_t self_in) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
- // Return list as a tuple so user won't be able to change it.
return mp_obj_new_bool(common_hal_bleio_peripheral_get_connected(self));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_connected_obj, bleio_peripheral_get_connected);
@@ -151,7 +158,7 @@ const mp_obj_property_t bleio_peripheral_connected_obj = {
STATIC mp_obj_t bleio_peripheral_get_services(mp_obj_t self_in) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
// Return list as a tuple so user won't be able to change it.
- mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list);
+ mp_obj_list_t *service_list = common_hal_bleio_peripheral_get_service_list(self);
return mp_obj_new_tuple(service_list->len, service_list->items);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_services_obj, bleio_peripheral_get_services);
@@ -170,7 +177,7 @@ const mp_obj_property_t bleio_peripheral_services_obj = {
STATIC mp_obj_t bleio_peripheral_get_name(mp_obj_t self_in) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return self->name;
+ return common_hal_bleio_peripheral_get_name(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_name_obj, bleio_peripheral_get_name);
@@ -181,37 +188,55 @@ const mp_obj_property_t bleio_peripheral_name_obj = {
(mp_obj_t)&mp_const_none_obj },
};
-//| .. method:: start_advertising(*, connectable=True, data=None)
+//| .. method:: start_advertising(data, *, scan_response=None, connectable=True, interval=1)
//|
//| Starts advertising the peripheral. The peripheral's name and
//| services are included in the advertisement packets.
//|
+//| :param buf data: advertising data packet bytes
+//| :param buf scan_response: scan response data packet bytes. ``None`` if no scan response is needed.
//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral.
-//| :param buf data: If `None`, advertise the services passed to this Peripheral when it was created.
-//| If not `None`, then send the bytes in ``data`` as the advertising packet.
+//| :param float interval: advertising interval, in seconds
//|
STATIC mp_obj_t bleio_peripheral_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- enum { ARG_connectable, ARG_data };
+ enum { ARG_data, ARG_scan_response, ARG_connectable, ARG_interval };
static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_scan_response, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
- { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- mp_buffer_info_t bufinfo = { 0 };
- if (args[ARG_data].u_obj != mp_const_none) {
- mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
+ mp_buffer_info_t data_bufinfo;
+ mp_get_buffer_raise(args[ARG_data].u_obj, &data_bufinfo, MP_BUFFER_READ);
+
+ // Pass an empty buffer if scan_response not provided.
+ mp_buffer_info_t scan_response_bufinfo = { 0 };
+ if (args[ARG_scan_response].u_obj != mp_const_none) {
+ mp_get_buffer_raise(args[ARG_scan_response].u_obj, &scan_response_bufinfo, MP_BUFFER_READ);
}
- common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo);
+ if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
+ args[ARG_interval].u_obj = mp_obj_new_float(1.0F);
+ }
+
+ const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
+ if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) {
+ mp_raise_ValueError_varg(translate("interval must be in range %s-%s"),
+ ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING);
+ }
+
+ common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool, interval,
+ &data_bufinfo, &scan_response_bufinfo);
return mp_const_none;
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_start_advertising_obj, 0, bleio_peripheral_start_advertising);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_start_advertising_obj, 2, bleio_peripheral_start_advertising);
//| .. method:: stop_advertising()
//|
@@ -225,10 +250,26 @@ STATIC mp_obj_t bleio_peripheral_stop_advertising(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_stop_advertising_obj, bleio_peripheral_stop_advertising);
+//| .. method:: disconnect()
+//|
+//| Disconnects from the remote central.
+//| Normally the central initiates a disconnection. Use this only
+//| if necessary for your application.
+//|
+STATIC mp_obj_t bleio_peripheral_disconnect(mp_obj_t self_in) {
+ bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_peripheral_disconnect(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_disconnect_obj, bleio_peripheral_disconnect);
+
STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = {
// Methods
{ MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_peripheral_disconnect_obj) },
// Properties
{ MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) },
diff --git a/shared-bindings/bleio/Peripheral.h b/shared-bindings/bleio/Peripheral.h
index 02a5c1ef8..846250a5f 100644
--- a/shared-bindings/bleio/Peripheral.h
+++ b/shared-bindings/bleio/Peripheral.h
@@ -3,8 +3,8 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2018 Dan Halbert 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
@@ -32,9 +32,12 @@
extern const mp_obj_type_t bleio_peripheral_type;
-extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self);
+extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *service_list, mp_obj_t name);
+extern mp_obj_list_t *common_hal_bleio_peripheral_get_service_list(bleio_peripheral_obj_t *self);
extern bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self);
-extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, mp_buffer_info_t *raw_data);
+extern mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self);
+extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, float interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
extern void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *device);
+extern void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *device);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c
index e6b955078..6eb02c716 100644
--- a/shared-bindings/bleio/ScanEntry.c
+++ b/shared-bindings/bleio/ScanEntry.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
* Copyright (c) 2017 Glenn Ruben Bakke
*
@@ -27,278 +28,78 @@
#include <string.h>
-#include "py/objarray.h"
#include "py/objproperty.h"
-#include "py/objstr.h"
-#include "py/objtuple.h"
#include "shared-bindings/bleio/Address.h"
#include "shared-bindings/bleio/ScanEntry.h"
#include "shared-bindings/bleio/UUID.h"
-#include "shared-module/bleio/AdvertisementData.h"
#include "shared-module/bleio/ScanEntry.h"
-// Work-in-progress: orphaned for now.
-//| :orphan:
-//|
//| .. currentmodule:: bleio
//|
//| :class:`ScanEntry` -- BLE scan response entry
//| =========================================================
//|
//| Encapsulates information about a device that was received as a
-//| response to a BLE scan request.
+//| response to a BLE scan request. This object may only be created
+//| by a `bleio.Scanner`: it has no user-visible constructor.
//|
//| .. attribute:: address
//|
-//| The address of the device. (read-only)
-//| This attribute is of type `bleio.Address`.
-//|
-
-//| .. attribute:: manufacturer_specific_data
-//|
-//| The manufacturer-specific data present in the advertisement packet. (read-only)
-//|
-
-//| .. attribute:: name
-//|
-//| The name of the device. (read-only)
-//| This attribute might be `None` if the data was missing from the advertisement packet.
-//|
-
-//| .. attribute:: raw_data
-//|
-//| All the advertisement data present in the packet. (read-only)
+//| The address of the device (read-only), of type `bleio.Address`.
//|
-
-//| .. attribute:: rssi
-//|
-//| The signal strength of the device at the time of the scan. (read-only)
-//|
-
-//| .. attribute:: service_uuids
-//|
-//| The address of the device. (read-only)
-//| This attribute is a list of `bleio.UUID`.
-//| This attribute might be empty or incomplete, depending on the advertisement packet.
-//| Currently only 16-bit UUIDS are listed.
-//|
-
-//| .. attribute:: tx_power_level
-//|
-//| The transmit power level of the device. (read-only)
-//| This attribute might be `None` if the data was missing from the advertisement packet.
-//|
-static uint8_t find_data_item(mp_obj_array_t *data_in, uint8_t type, uint8_t **data_out) {
- uint16_t i = 0;
- while (i < data_in->len) {
- const uint8_t item_len = ((uint8_t*)data_in->items)[i];
- const uint8_t item_type = ((uint8_t*)data_in->items)[i + 1];
- if (item_type != type) {
- i += (item_len + 1);
- continue;
- }
-
- *data_out = &((uint8_t*)data_in->items)[i + 2];
-
- return item_len;
- }
-
- return 0;
-}
-
-STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in);
-
-STATIC void bleio_scanentry_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- bleio_scanentry_obj_t *self = (bleio_scanentry_obj_t *)self_in;
- mp_printf(print, "ScanEntry(address: %02x:%02x:%02x:%02x:%02x:%02x",
- self->address.value[5], self->address.value[4], self->address.value[3],
- self->address.value[1], self->address.value[1], self->address.value[0]);
-
- const mp_obj_t name_obj = scanentry_get_name(self_in);
- if (name_obj != mp_const_none) {
- mp_obj_str_t *str = MP_OBJ_TO_PTR(name_obj);
- mp_printf(print, " name: %s", str->data);
- }
-
- mp_print_str(print, ")");
-}
-
STATIC mp_obj_t bleio_scanentry_get_address(mp_obj_t self_in) {
bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, (mp_obj_t)&mp_const_none_obj);
- bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj);
-
- address->type = self->address.type;
- memcpy(address->value, self->address.value, BLEIO_ADDRESS_BYTES);
-
- return obj;
+ return common_hal_bleio_scanentry_get_address(self);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_address_obj, bleio_scanentry_get_address);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_address_obj, bleio_scanentry_get_address);
const mp_obj_property_t bleio_scanentry_address_obj = {
.base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bluepy_scanentry_get_address_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t scanentry_get_manufacturer_specific_data(mp_obj_t self_in) {
- bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
- uint8_t *manuf_data;
-
- const uint8_t manuf_data_len = find_data_item(data, AdManufacturerSpecificData, &manuf_data);
- if (manuf_data_len == 0) {
- return mp_const_none;
- }
-
- return mp_obj_new_bytearray_by_ref(manuf_data_len, manuf_data);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_manufacturer_specific_data_obj, scanentry_get_manufacturer_specific_data);
-
-const mp_obj_property_t bleio_scanentry_manufacturer_specific_data_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&scanentry_get_manufacturer_specific_data_obj,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_address_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
-STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in) {
- bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
- uint8_t *name;
-
- // Try for Complete but settle for Shortened
- uint8_t name_len = find_data_item(data, AdCompleteLocalName, &name);
- if (name_len == 0) {
- name_len = find_data_item(data, AdShortenedLocalName, &name);
- }
-
- if (name_len == 0) {
- return mp_const_none;
- }
-
- return mp_obj_new_str((const char*)name, name_len - 1);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_name_obj, scanentry_get_name);
-
-const mp_obj_property_t bleio_scanentry_name_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bluepy_scanentry_get_name_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t scanentry_get_raw_data(mp_obj_t self_in) {
+//| .. attribute:: advertisement_bytes
+//|
+//| All the advertisement data present in the packet, returned as a ``bytes`` object. (read-only)
+//|
+STATIC mp_obj_t scanentry_get_advertisement_bytes(mp_obj_t self_in) {
bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- mp_obj_t entries = mp_obj_new_list(0, NULL);
-
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
-
- uint16_t i = 0;
- while (i < data->len) {
- mp_obj_tuple_t *entry = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
-
- const uint8_t item_len = ((uint8_t*)data->items)[i];
- const uint8_t item_type = ((uint8_t*)data->items)[i + 1];
-
- entry->items[0] = MP_OBJ_NEW_SMALL_INT(item_type);
- entry->items[1] = mp_obj_new_bytearray(item_len - 1, &((uint8_t*)data->items)[i + 2]);
- mp_obj_list_append(entries, MP_OBJ_FROM_PTR(entry));
-
- i += (item_len + 1);
- }
-
- return entries;
+ return common_hal_bleio_scanentry_get_advertisement_bytes(self);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_raw_data_obj, scanentry_get_raw_data);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_advertisement_bytes_obj, scanentry_get_advertisement_bytes);
-const mp_obj_property_t bleio_scanentry_raw_data_obj = {
+const mp_obj_property_t bleio_scanentry_advertisement_bytes_obj = {
.base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_scanentry_get_raw_data_obj,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_advertisement_bytes_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: rssi
+//|
+//| The signal strength of the device at the time of the scan, in integer dBm. (read-only)
+//|
STATIC mp_obj_t scanentry_get_rssi(mp_obj_t self_in) {
bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_int(self->rssi);
+ return mp_obj_new_int(common_hal_bleio_scanentry_get_rssi(self));
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_rssi_obj, scanentry_get_rssi);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_rssi_obj, scanentry_get_rssi);
const mp_obj_property_t bleio_scanentry_rssi_obj = {
.base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bluepy_scanentry_get_rssi_obj,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_rssi_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
-STATIC mp_obj_t scanentry_get_service_uuids(mp_obj_t self_in) {
- bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
- uint8_t *uuids;
-
- // Try for Complete but settle for Incomplete
- uint8_t uuids_len = find_data_item(data, AdCompleteListOf16BitServiceClassUUIDs, &uuids);
- if (uuids_len == 0) {
- uuids_len = find_data_item(data, AdIncompleteListOf16BitServiceClassUUIDs, &uuids);
- }
-
- mp_obj_t entries = mp_obj_new_list(0, NULL);
- for (size_t i = 0; i < uuids_len / sizeof(uint16_t); ++i) {
- const mp_obj_t uuid_int = mp_obj_new_int(uuids[sizeof(uint16_t) * i] | (uuids[sizeof(uint16_t) * i + 1] << 8));
- const mp_obj_t uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, &uuid_int, NULL);
-
- mp_obj_list_append(entries, uuid_obj);
- }
-
- // TODO: 32-bit UUIDs
- // TODO: 128-bit UUIDs
-
- return entries;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_service_uuids_obj, scanentry_get_service_uuids);
-
-const mp_obj_property_t bleio_scanentry_service_uuids_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&scanentry_get_service_uuids_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t scanentry_get_tx_power_level(mp_obj_t self_in) {
- bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
- uint8_t *tx_power;
-
- const uint8_t tx_power_len = find_data_item(data, AdTxPowerLevel, &tx_power);
- if (tx_power_len == 0) {
- return mp_const_none;
- }
-
- return mp_obj_new_int((int8_t)(*tx_power));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_tx_power_level_obj, scanentry_get_tx_power_level);
-
-const mp_obj_property_t bleio_scanentry_tx_power_level_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&scanentry_get_tx_power_level_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
STATIC const mp_rom_map_elem_t bleio_scanentry_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) },
- { MP_ROM_QSTR(MP_QSTR_manufacturer_specific_data), MP_ROM_PTR(&bleio_scanentry_manufacturer_specific_data_obj) },
- { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_scanentry_name_obj) },
- { MP_ROM_QSTR(MP_QSTR_raw_data), MP_ROM_PTR(&bleio_scanentry_raw_data_obj) },
- { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) },
- { MP_ROM_QSTR(MP_QSTR_service_uuids), MP_ROM_PTR(&bleio_scanentry_service_uuids_obj) },
- { MP_ROM_QSTR(MP_QSTR_tx_power_level), MP_ROM_PTR(&bleio_scanentry_tx_power_level_obj) },
+ { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) },
+ { MP_ROM_QSTR(MP_QSTR_advertisement_bytes), MP_ROM_PTR(&bleio_scanentry_advertisement_bytes_obj) },
+ { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_dict_table);
@@ -306,6 +107,5 @@ STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_
const mp_obj_type_t bleio_scanentry_type = {
{ &mp_type_type },
.name = MP_QSTR_ScanEntry,
- .print = bleio_scanentry_print,
.locals_dict = (mp_obj_dict_t*)&bleio_scanentry_locals_dict
};
diff --git a/shared-bindings/bleio/ScanEntry.h b/shared-bindings/bleio/ScanEntry.h
index 2b44ba3f4..77e93175f 100644
--- a/shared-bindings/bleio/ScanEntry.h
+++ b/shared-bindings/bleio/ScanEntry.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
* Copyright (c) 2017 Glenn Ruben Bakke
*
@@ -29,7 +30,12 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
#include "py/obj.h"
+#include "shared-module/bleio/ScanEntry.h"
extern const mp_obj_type_t bleio_scanentry_type;
+mp_obj_t common_hal_bleio_scanentry_get_address(bleio_scanentry_obj_t *self);
+mp_obj_t common_hal_bleio_scanentry_get_advertisement_bytes(bleio_scanentry_obj_t *self);
+mp_int_t common_hal_bleio_scanentry_get_rssi(bleio_scanentry_obj_t *self);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
diff --git a/shared-bindings/bleio/Scanner.c b/shared-bindings/bleio/Scanner.c
index f5424f706..269c42591 100644
--- a/shared-bindings/bleio/Scanner.c
+++ b/shared-bindings/bleio/Scanner.c
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -29,132 +30,93 @@
#include "shared-bindings/bleio/ScanEntry.h"
#include "shared-bindings/bleio/Scanner.h"
-#define DEFAULT_INTERVAL 100
-#define DEFAULT_WINDOW 100
+#define INTERVAL_DEFAULT (0.1f)
+#define INTERVAL_MIN (0.0025f)
+#define INTERVAL_MIN_STRING "0.0025"
+#define INTERVAL_MAX (40.959375f)
+#define INTERVAL_MAX_STRING "40.959375"
+#define WINDOW_DEFAULT (0.1f)
-// Work-in-progress: orphaned for now.
-//| :orphan:
-//|
//| .. currentmodule:: bleio
//|
//| :class:`Scanner` -- scan for nearby BLE devices
//| =========================================================
//|
-//| Allows scanning for nearby BLE devices.
+//| Scan for nearby BLE devices.
//|
//| Usage::
//|
//| import bleio
//| scanner = bleio.Scanner()
-//| entries = scanner.scan(2500)
-//| print(entries)
+//| entries = scanner.scan(2.5) # Scan for 2.5 seconds
//|
//| .. class:: Scanner()
//|
//| Create a new Scanner object.
//|
-
-//| .. attribute:: interval
-//|
-//| The interval (in ms) between the start of two consecutive scan windows.
-//| Allowed values are between 10ms and 10.24 sec.
-//|
-
-//| .. attribute:: window
-//|
-//| The duration (in ms) in which a single BLE channel is scanned.
-//| Allowed values are between 10ms and 10.24 sec.
-//|
-
-//| .. method:: scan(timeout)
-//|
-//| Performs a BLE scan.
-//|
-//| :param int timeout: the scan timeout in ms
-//| :returns: advertising packets found
-//| :rtype: list of :py:class:`bleio.ScanEntry`
-//|
-STATIC void bleio_scanner_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- mp_printf(print, "Scanner(interval: %d window: %d)", self->interval, self->window);
-}
-
STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) {
mp_arg_check_num(n_args, kw_args, 0, 0, false);
bleio_scanner_obj_t *self = m_new_obj(bleio_scanner_obj_t);
self->base.type = type;
- self->interval = DEFAULT_INTERVAL;
- self->window = DEFAULT_WINDOW;
+ common_hal_bleio_scanner_construct(self);
return MP_OBJ_FROM_PTR(self);
}
-STATIC mp_obj_t bleio_scanner_get_interval(mp_obj_t self_in) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_int(self->interval);
-}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_interval_obj, bleio_scanner_get_interval);
-
-static mp_obj_t bleio_scanner_set_interval(mp_obj_t self_in, mp_obj_t value) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- self->interval = mp_obj_get_int(value);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_interval_obj, bleio_scanner_set_interval);
-
-const mp_obj_property_t bleio_scanner_interval_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_scanner_get_interval_obj,
- (mp_obj_t)&bleio_scanner_set_interval_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-STATIC mp_obj_t scanner_scan(mp_obj_t self_in, mp_obj_t timeout_in) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
- const mp_int_t timeout = mp_obj_get_int(timeout_in);
-
- self->adv_reports = mp_obj_new_list(0, NULL);
-
- common_hal_bleio_scanner_scan(self, timeout);
-
- return self->adv_reports;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_scan_obj, scanner_scan);
-
-STATIC mp_obj_t bleio_scanner_get_window(mp_obj_t self_in) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_int(self->window);
-}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_window_obj, bleio_scanner_get_window);
-
-static mp_obj_t bleio_scanner_set_window(mp_obj_t self_in, mp_obj_t value) {
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- self->window = mp_obj_get_int(value);
-
- return mp_const_none;
+//| .. method:: scan(timeout, \*, interval=0.1, window=0.1)
+//|
+//| Performs a BLE scan.
+//|
+//| :param float timeout: the scan timeout in seconds
+//| :param float interval: the interval (in seconds) between the start of two consecutive scan windows
+//| Must be in the range 0.0025 - 40.959375 seconds.
+//| :param float window: the duration (in seconds) to scan a single BLE channel.
+//| window must be <= interval.
+//| :returns: an iterable of `ScanEntry` objects
+//| :rtype: iterable
+//|
+STATIC mp_obj_t bleio_scanner_scan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_timeout, ARG_interval, ARG_window };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ };
+
+ bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ const mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
+
+ if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
+ args[ARG_interval].u_obj = mp_obj_new_float(INTERVAL_DEFAULT);
+ }
+
+ if (args[ARG_window].u_obj == MP_OBJ_NULL) {
+ args[ARG_window].u_obj = mp_obj_new_float(WINDOW_DEFAULT);
+ }
+
+ const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
+ if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
+ mp_raise_ValueError_varg(translate("interval must be in range %s-%s"), INTERVAL_MIN_STRING, INTERVAL_MAX_STRING);
+ }
+
+ const mp_float_t window = mp_obj_float_get(args[ARG_window].u_obj);
+ if (window > interval) {
+ mp_raise_ValueError(translate("window must be <= interval"));
+ }
+
+ return common_hal_bleio_scanner_scan(self, timeout, interval, window);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_window_obj, bleio_scanner_set_window);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_scanner_scan_obj, 2, bleio_scanner_scan);
-const mp_obj_property_t bleio_scanner_window_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_scanner_get_window_obj,
- (mp_obj_t)&bleio_scanner_set_window_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
STATIC const mp_rom_map_elem_t bleio_scanner_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_interval), MP_ROM_PTR(&bleio_scanner_interval_obj) },
{ MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bleio_scanner_scan_obj) },
- { MP_ROM_QSTR(MP_QSTR_window), MP_ROM_PTR(&bleio_scanner_window_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict_table);
@@ -162,7 +124,6 @@ STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict
const mp_obj_type_t bleio_scanner_type = {
{ &mp_type_type },
.name = MP_QSTR_Scanner,
- .print = bleio_scanner_print,
.make_new = bleio_scanner_make_new,
.locals_dict = (mp_obj_dict_t*)&bleio_scanner_locals_dict
};
diff --git a/shared-bindings/bleio/Scanner.h b/shared-bindings/bleio/Scanner.h
index 9bd071747..3a0ce7eae 100644
--- a/shared-bindings/bleio/Scanner.h
+++ b/shared-bindings/bleio/Scanner.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -29,11 +29,12 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
#include "py/objtype.h"
-#include "shared-module/bleio/Scanner.h"
+#include "common-hal/bleio/Scanner.h"
extern const mp_obj_type_t bleio_scanner_type;
-extern void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout);
+extern void common_hal_bleio_scanner_construct(bleio_scanner_obj_t *self);
+extern mp_obj_t common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_float_t timeout, mp_float_t interval, mp_float_t window);
extern void common_hal_bleio_scanner_stop(bleio_scanner_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c
index c3be26260..db0606991 100644
--- a/shared-bindings/bleio/Service.c
+++ b/shared-bindings/bleio/Service.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -60,53 +61,53 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
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 mp_obj_t uuid = args[ARG_uuid].u_obj;
+ const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
- if (!MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) {
+ if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
mp_raise_ValueError(translate("Expected a UUID"));
}
bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t);
- self->char_list = mp_obj_new_list(0, NULL);
self->base.type = &bleio_service_type;
- self->device = mp_const_none;
- self->handle = 0xFFFF;
- self->is_secondary = args[ARG_secondary].u_bool;
- self->uuid = MP_OBJ_TO_PTR(uuid);
+
+ const bool is_secondary = args[ARG_secondary].u_bool;
+ bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
// If characteristics is not an iterable, an exception will be thrown.
mp_obj_iter_buf_t iter_buf;
mp_obj_t iterable = mp_getiter(args[ARG_characteristics].u_obj, &iter_buf);
- mp_obj_t characteristic;
+ mp_obj_t characteristic_obj;
- while ((characteristic = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
- if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) {
+ // Copy the characteristics list and validate its items.
+ mp_obj_t char_list_obj = mp_obj_new_list(0, NULL);
+ mp_obj_list_t *char_list = MP_OBJ_TO_PTR(char_list_obj);
+
+ while ((characteristic_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
+ if (!MP_OBJ_IS_TYPE(characteristic_obj, &bleio_characteristic_type)) {
mp_raise_ValueError(translate("characteristics includes an object that is not a Characteristic"));
}
- bleio_characteristic_obj_t *characteristic_ptr = MP_OBJ_TO_PTR(characteristic);
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_obj);
if (common_hal_bleio_uuid_get_uuid128_reference(uuid) !=
- common_hal_bleio_uuid_get_uuid128_reference(characteristic_ptr->uuid)) {
+ common_hal_bleio_uuid_get_uuid128_reference(characteristic->uuid)) {
// The descriptor base UUID doesn't match the characteristic base UUID.
mp_raise_ValueError(translate("Characteristic UUID doesn't match Service UUID"));
}
- characteristic_ptr->service = self;
- mp_obj_list_append(self->char_list, characteristic);
+ mp_obj_list_append(char_list_obj, characteristic_obj);
}
- // Do port-specific initialization.
- common_hal_bleio_service_construct(self);
+ common_hal_bleio_service_construct(self, uuid, char_list, is_secondary);
return MP_OBJ_FROM_PTR(self);
}
//| .. attribute:: characteristics
//|
-//| A `list` of `bleio.Characteristic` that are offered by this service. (read-only)
+//| A tuple of `bleio.Characteristic` that are offered by this service. (read-only)
//|
STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) {
bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
// Return list as a tuple so user won't be able to change it.
- mp_obj_list_t *char_list = MP_OBJ_TO_PTR(self->char_list);
+ mp_obj_list_t *char_list = common_hal_bleio_service_get_characteristic_list(self);
return mp_obj_new_tuple(char_list->len, char_list->items);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_characteristics_obj, bleio_service_get_characteristics);
@@ -118,14 +119,34 @@ const mp_obj_property_t bleio_service_characteristics_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: secondary
+//|
+//| True if this is a secondary service. (read-only)
+//|
+STATIC mp_obj_t bleio_service_get_secondary(mp_obj_t self_in) {
+ bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_service_get_is_secondary(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_secondary_obj, bleio_service_get_secondary);
+
+const mp_obj_property_t bleio_service_secondary_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_service_get_secondary_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
//| .. attribute:: uuid
//|
//| The UUID of this service. (read-only)
+//| Will be ``None`` if the 128-bit UUID for this service is not known.
//|
STATIC mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) {
bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return MP_OBJ_FROM_PTR(self->uuid);
+ bleio_uuid_obj_t *uuid = common_hal_bleio_service_get_uuid(self);
+ return uuid ? MP_OBJ_FROM_PTR(uuid) : mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_uuid_obj, bleio_service_get_uuid);
@@ -138,14 +159,26 @@ const mp_obj_property_t bleio_service_uuid_obj = {
STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) },
+ { MP_ROM_QSTR(MP_QSTR_secondary), MP_ROM_PTR(&bleio_service_secondary_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) },
};
-
STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table);
+STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ if (self->uuid) {
+ mp_printf(print, "Service(");
+ bleio_uuid_print(print, MP_OBJ_FROM_PTR(self->uuid), kind);
+ mp_printf(print, ")");
+ } else {
+ mp_printf(print, "<Service with unregistered UUID>");
+ }
+}
+
const mp_obj_type_t bleio_service_type = {
{ &mp_type_type },
.name = MP_QSTR_Service,
.make_new = bleio_service_make_new,
+ .print = bleio_service_print,
.locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict
};
diff --git a/shared-bindings/bleio/Service.h b/shared-bindings/bleio/Service.h
index 389db3b2e..f646c81a9 100644
--- a/shared-bindings/bleio/Service.h
+++ b/shared-bindings/bleio/Service.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,12 +28,14 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
-#include "shared-module/bleio/Characteristic.h"
-#include "shared-module/bleio/Service.h"
+#include "common-hal/bleio/Service.h"
const mp_obj_type_t bleio_service_type;
-extern void common_hal_bleio_service_construct(bleio_service_obj_t *self);
+extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, mp_obj_list_t *characteristic_list, bool is_secondary);
+extern bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self);
+extern mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self);
+extern bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self);
extern void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c
index c6ad9e626..dca7ea010 100644
--- a/shared-bindings/bleio/UUID.c
+++ b/shared-bindings/bleio/UUID.c
@@ -3,9 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -47,9 +47,14 @@
//| The value can be one of:
//|
//| - an `int` value in range 0 to 0xFFFF (Bluetooth SIG 16-bit UUID)
-//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID)
+//| - a buffer object (bytearray, bytes) of 16 bytes in little-endian order (128-bit UUID)
+//| - a string of hex digits of the form 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
+//|
+//| Creating a 128-bit UUID registers the UUID with the onboard BLE software, and provides a
+//| temporary 16-bit UUID that can be used in place of the full 128-bit UUID.
//|
-//| :param int/buffer value: The uuid value to encapsulate
+//| :param value: The uuid value to encapsulate
+//| :type value: int or typing.ByteString
//|
STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mp_arg_check_num(n_args, kw_args, 1, 1, false);
@@ -63,7 +68,7 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, co
if (MP_OBJ_IS_INT(value)) {
mp_int_t uuid16 = mp_obj_get_int(value);
if (uuid16 < 0 || uuid16 > 0xffff) {
- mp_raise_ValueError(translate("UUID integer value not in range 0 to 0xffff"));
+ mp_raise_ValueError(translate("UUID integer value must be 0-0xffff"));
}
// NULL means no 128-bit value.
@@ -124,6 +129,8 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, co
//|
//| The 16-bit part of the UUID. (read-only)
//|
+//| :type: int
+//|
STATIC mp_obj_t bleio_uuid_get_uuid16(mp_obj_t self_in) {
bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_uuid16(self));
@@ -140,9 +147,11 @@ const mp_obj_property_t bleio_uuid_uuid16_obj = {
//| .. attribute:: uuid128
//|
-//| The 128-bit value of the UUID, returned as bytes.
+//| The 128-bit value of the UUID
//| Raises AttributeError if this is a 16-bit UUID. (read-only)
//|
+//| :type: bytes
+//|
STATIC mp_obj_t bleio_uuid_get_uuid128(mp_obj_t self_in) {
bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -164,9 +173,10 @@ const mp_obj_property_t bleio_uuid_uuid128_obj = {
//| .. attribute:: size
//|
-//| Returns 128 if this UUID represents a 128-bit vendor-specific UUID.
-//| Returns 16 if this UUID represents a 16-bit Bluetooth SIG assigned UUID. (read-only)
-//| 32-bit UUIDs are not currently supported.
+//| 128 if this UUID represents a 128-bit vendor-specific UUID. 16 if this UUID represents a
+//| 16-bit Bluetooth SIG assigned UUID. (read-only) 32-bit UUIDs are not currently supported.
+//|
+//| :type: int
//|
STATIC mp_obj_t bleio_uuid_get_size(mp_obj_t self_in) {
bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -213,6 +223,12 @@ STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
}
}
+//|
+
+//| .. method:: __eq__(other)
+//|
+//| Two UUID objects are equal if their values match and they are both 128-bit or both 16-bit.
+//|
STATIC mp_obj_t bleio_uuid_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
switch (op) {
// Two UUID's are equal if their uuid16 values and uuid128 references match.
diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/bleio/UUID.h
index aef2c1e29..caf039aec 100644
--- a/shared-bindings/bleio/UUID.h
+++ b/shared-bindings/bleio/UUID.h
@@ -3,6 +3,7 @@
*
* The MIT License (MIT)
*
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c
index 7348655ac..ba3bae6c7 100644
--- a/shared-bindings/bleio/__init__.c
+++ b/shared-bindings/bleio/__init__.c
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -27,12 +28,10 @@
#include "shared-bindings/bleio/__init__.h"
#include "shared-bindings/bleio/Address.h"
-#include "shared-bindings/bleio/AddressType.h"
-#include "shared-bindings/bleio/AdvertisementData.h"
-#include "shared-bindings/bleio/Broadcaster.h"
+#include "shared-bindings/bleio/Central.h"
#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/CharacteristicBuffer.h"
-#include "shared-bindings/bleio/Descriptor.h"
+// #include "shared-bindings/bleio/Descriptor.h"
#include "shared-bindings/bleio/Peripheral.h"
#include "shared-bindings/bleio/ScanEntry.h"
#include "shared-bindings/bleio/Scanner.h"
@@ -54,18 +53,14 @@
//| :maxdepth: 3
//|
//| Address
-//| AddressType
-//| AdvertisementData
//| Adapter
-//| Broadcaster
+//| Central
//| Characteristic
//| CharacteristicBuffer
-// Work-in-progress classes are omitted, and marked as :orphan: in their files.
-// Descriptor
-// Device
+//| Descriptor
//| Peripheral
-// ScanEntry
-// Scanner
+//| ScanEntry
+//| Scanner
//| Service
//| UUID
//|
@@ -79,23 +74,18 @@
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) },
{ MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) },
- { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) },
- { MP_ROM_QSTR(MP_QSTR_Broadcaster), MP_ROM_PTR(&bleio_broadcaster_type) },
+ { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&bleio_central_type) },
{ MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
{ MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) },
// { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },
{ MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&bleio_peripheral_type) },
-// Hide work-in-progress.
-// { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
-// { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) },
+ { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
+ { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) },
{ MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) },
{ MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) },
// Properties
{ MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) },
-
- // Enum-like Classes.
- { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table);
diff --git a/shared-bindings/bleio/__init__.h b/shared-bindings/bleio/__init__.h
index 1f4e0a66f..4aa6dd45b 100644
--- a/shared-bindings/bleio/__init__.h
+++ b/shared-bindings/bleio/__init__.h
@@ -3,8 +3,9 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c
index 06c2f218f..47e2d64bc 100644
--- a/shared-bindings/board/__init__.c
+++ b/shared-bindings/board/__init__.c
@@ -25,6 +25,7 @@
*/
#include "py/obj.h"
+#include "py/runtime.h"
#include "shared-bindings/board/__init__.h"
@@ -33,10 +34,84 @@
//|
//| .. module:: board
//| :synopsis: Board specific pin names
-//| :platform: SAMD21
//|
//| Common container for board base pin names. These will vary from board to
//| board so don't expect portability when using this module.
+//|
+//| .. warning:: The board module varies by board. The APIs documented here may or may not be
+//| available on a specific board.
+
+//| .. function:: I2C()
+//|
+//| Returns the `busio.I2C` object for the board designated SDA and SCL pins. It is a singleton.
+//|
+
+#if BOARD_I2C
+mp_obj_t board_i2c(void) {
+ mp_obj_t singleton = common_hal_board_get_i2c();
+ if (singleton != NULL) {
+ return singleton;
+ }
+ assert_pin_free(DEFAULT_I2C_BUS_SDA);
+ assert_pin_free(DEFAULT_I2C_BUS_SCL);
+ return common_hal_board_create_i2c();
+}
+#else
+mp_obj_t board_i2c(void) {
+ mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_I2C);
+ return NULL;
+}
+#endif
+MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c);
+
+
+//| .. function:: SPI()
+//|
+//| Returns the `busio.SPI` object for the board designated SCK, MOSI and MISO pins. It is a
+//| singleton.
+//|
+#if BOARD_SPI
+mp_obj_t board_spi(void) {
+ mp_obj_t singleton = common_hal_board_get_spi();
+ if (singleton != NULL) {
+ return singleton;
+ }
+ assert_pin_free(DEFAULT_SPI_BUS_SCK);
+ assert_pin_free(DEFAULT_SPI_BUS_MOSI);
+ assert_pin_free(DEFAULT_SPI_BUS_MISO);
+ return common_hal_board_create_spi();
+}
+#else
+mp_obj_t board_spi(void) {
+ mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_SPI);
+ return NULL;
+}
+#endif
+MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi);
+
+//| .. function:: UART()
+//|
+//| Returns the `busio.UART` object for the board designated TX and RX pins. It is a singleton.
+//|
+#if BOARD_UART
+mp_obj_t board_uart(void) {
+ mp_obj_t singleton = common_hal_board_get_uart();
+ if (singleton != NULL) {
+ return singleton;
+ }
+
+ assert_pin_free(DEFAULT_UART_BUS_RX);
+ assert_pin_free(DEFAULT_UART_BUS_TX);
+
+ return common_hal_board_create_uart();
+}
+#else
+mp_obj_t board_uart(void) {
+ mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_SPI);
+ return NULL;
+}
+#endif
+MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart);
const mp_obj_module_t board_module = {
.base = { &mp_type_module },
diff --git a/shared-bindings/board/__init__.h b/shared-bindings/board/__init__.h
index 2730e5f51..a9b652ba8 100644
--- a/shared-bindings/board/__init__.h
+++ b/shared-bindings/board/__init__.h
@@ -33,4 +33,16 @@
extern const mp_obj_dict_t board_module_globals;
+mp_obj_t common_hal_board_get_i2c(void);
+mp_obj_t common_hal_board_create_i2c(void);
+MP_DECLARE_CONST_FUN_OBJ_0(board_i2c_obj);
+
+mp_obj_t common_hal_board_get_spi(void);
+mp_obj_t common_hal_board_create_spi(void);
+MP_DECLARE_CONST_FUN_OBJ_0(board_spi_obj);
+
+mp_obj_t common_hal_board_get_uart(void);
+mp_obj_t common_hal_board_create_uart(void);
+MP_DECLARE_CONST_FUN_OBJ_0(board_uart_obj);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BOARD___INIT___H
diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c
index e792d2575..0e639f0b5 100644
--- a/shared-bindings/busio/I2C.c
+++ b/shared-bindings/busio/I2C.c
@@ -41,7 +41,7 @@
//| :class:`I2C` --- Two wire serial protocol
//| ------------------------------------------
//|
-//| .. class:: I2C(scl, sda, \*, frequency=400000)
+//| .. class:: I2C(scl, sda, *, frequency=400000, timeout=255)
//|
//| I2C is a two-wire protocol for communicating between devices. At the
//| physical level it consists of 2 wires: SCL and SDA, the clock and data
@@ -82,7 +82,7 @@ STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, con
return (mp_obj_t)self;
}
-//| .. method:: I2C.deinit()
+//| .. method:: deinit()
//|
//| Releases control of the underlying hardware so other classes can use it.
//|
@@ -93,13 +93,19 @@ STATIC mp_obj_t busio_i2c_obj_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_deinit_obj, busio_i2c_obj_deinit);
-//| .. method:: I2C.__enter__()
+STATIC void check_for_deinit(busio_i2c_obj_t *self) {
+ if (common_hal_busio_i2c_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: __enter__()
//|
//| No-op used in Context Managers.
//|
// Provided by context manager helper.
-//| .. method:: I2C.__exit__()
+//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware on context exit. See
//| :ref:`lifetime-and-contextmanagers` for more info.
@@ -114,11 +120,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_i2c___exit___obj, 4, 4, busio_i
static void check_lock(busio_i2c_obj_t *self) {
asm("");
if (!common_hal_busio_i2c_has_lock(self)) {
- mp_raise_RuntimeError(translate("Function requires lock."));
+ mp_raise_RuntimeError(translate("Function requires lock"));
}
}
-//| .. method:: I2C.scan()
+//| .. method:: scan()
//|
//| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a
//| list of those that respond.
@@ -128,7 +134,7 @@ static void check_lock(busio_i2c_obj_t *self) {
//|
STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) {
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_obj_t list = mp_obj_new_list(0, NULL);
// 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
@@ -142,7 +148,7 @@ STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan);
-//| .. method:: I2C.try_lock()
+//| .. method:: try_lock()
//|
//| Attempts to grab the I2C lock. Returns True on success.
//|
@@ -151,24 +157,24 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan);
//|
STATIC mp_obj_t busio_i2c_obj_try_lock(mp_obj_t self_in) {
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_busio_i2c_try_lock(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_try_lock_obj, busio_i2c_obj_try_lock);
-//| .. method:: I2C.unlock()
+//| .. method:: unlock()
//|
//| Releases the I2C lock.
//|
STATIC mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) {
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
common_hal_busio_i2c_unlock(self);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock);
-//| .. method:: I2C.readfrom_into(address, buffer, \*, start=0, end=len(buffer))
+//| .. method:: readfrom_into(address, buffer, *, start=0, end=None)
//|
//| Read into ``buffer`` from the slave specified by ``address``.
//| The number of bytes read will be the length of ``buffer``.
@@ -181,7 +187,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock);
//| :param int address: 7-bit device address
//| :param bytearray buffer: buffer to write into
//| :param int start: Index to start writing at
-//| :param int end: Index to write up to but not include
+//| :param int end: Index to write up to but not include. Defaults to ``len(buffer)``
//|
STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_address, ARG_buffer, ARG_start, ARG_end };
@@ -192,7 +198,7 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args,
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -216,7 +222,7 @@ STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args,
}
MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_into);
-//| .. method:: I2C.writeto(address, buffer, \*, start=0, end=len(buffer), stop=True)
+//| .. method:: writeto(address, buffer, *, start=0, end=None, stop=True)
//|
//| Write the bytes from ``buffer`` to the slave specified by ``address``.
//| Transmits a stop bit if ``stop`` is set.
@@ -231,7 +237,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_in
//| :param int address: 7-bit device address
//| :param bytearray buffer: buffer containing the bytes to write
//| :param int start: Index to start writing from
-//| :param int end: Index to read up to but not include
+//| :param int end: Index to read up to but not include. Defaults to ``len(buffer)``
//| :param bool stop: If true, output an I2C stop condition after the
//| buffer is written
//|
@@ -245,7 +251,7 @@ STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
};
busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_i2c_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h
index 739732e97..a2d5dbf50 100644
--- a/shared-bindings/busio/I2C.h
+++ b/shared-bindings/busio/I2C.h
@@ -69,4 +69,7 @@ extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addres
extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address,
uint8_t * data, size_t len);
+// This is used by the supervisor to claim I2C devices indefinitely.
+extern void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_H
diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/busio/OneWire.c
index ceba4f8ee..aca2a3ef2 100644
--- a/shared-bindings/busio/OneWire.c
+++ b/shared-bindings/busio/OneWire.c
@@ -91,6 +91,12 @@ STATIC mp_obj_t busio_onewire_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_deinit_obj, busio_onewire_deinit);
+STATIC void check_for_deinit(busio_onewire_obj_t *self) {
+ if (common_hal_busio_onewire_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -118,7 +124,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_onewire___exit___obj, 4, 4, bus
//|
STATIC mp_obj_t busio_onewire_obj_reset(mp_obj_t self_in) {
busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_onewire_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_busio_onewire_reset(self));
}
@@ -133,7 +139,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_reset_obj, busio_onewire_obj_reset);
//|
STATIC mp_obj_t busio_onewire_obj_read_bit(mp_obj_t self_in) {
busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_onewire_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_busio_onewire_read_bit(self));
}
@@ -145,7 +151,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_read_bit_obj, busio_onewire_obj_read_bit
//|
STATIC mp_obj_t busio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) {
busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_onewire_deinited(self));
+ check_for_deinit(self);
common_hal_busio_onewire_write_bit(self, mp_obj_is_true(bool_obj));
return mp_const_none;
diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c
index f690eea18..a7d7d515c 100644
--- a/shared-bindings/busio/SPI.c
+++ b/shared-bindings/busio/SPI.c
@@ -95,7 +95,7 @@ STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, con
return (mp_obj_t)self;
}
-//| .. method:: SPI.deinit()
+//| .. method:: deinit()
//|
//| Turn off the SPI bus.
//|
@@ -106,13 +106,13 @@ STATIC mp_obj_t busio_spi_obj_deinit(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_deinit_obj, busio_spi_obj_deinit);
-//| .. method:: SPI.__enter__()
+//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
//|
// Provided by context manager helper.
-//| .. method:: SPI.__exit__()
+//| .. method:: __exit__()
//|
//| Automatically deinitializes the hardware when exiting a context. See
//| :ref:`lifetime-and-contextmanagers` for more info.
@@ -124,14 +124,20 @@ STATIC mp_obj_t busio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_spi_obj___exit___obj, 4, 4, busio_spi_obj___exit__);
-static void check_lock(busio_spi_obj_t *self) {
+STATIC void check_lock(busio_spi_obj_t *self) {
asm("");
if (!common_hal_busio_spi_has_lock(self)) {
mp_raise_RuntimeError(translate("Function requires lock"));
}
}
-//| .. method:: SPI.configure(\*, baudrate=100000, polarity=0, phase=0, bits=8)
+STATIC void check_for_deinit(busio_spi_obj_t *self) {
+ if (common_hal_busio_spi_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: configure(*, baudrate=100000, polarity=0, phase=0, bits=8)
//|
//| Configures the SPI bus. The SPI object must be locked.
//|
@@ -162,7 +168,7 @@ STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
};
busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -188,7 +194,7 @@ STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_
}
MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure);
-//| .. method:: SPI.try_lock()
+//| .. method:: try_lock()
//|
//| Attempts to grab the SPI lock. Returns True on success.
//|
@@ -197,31 +203,30 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure);
//|
STATIC mp_obj_t busio_spi_obj_try_lock(mp_obj_t self_in) {
busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
return mp_obj_new_bool(common_hal_busio_spi_try_lock(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_try_lock_obj, busio_spi_obj_try_lock);
-//| .. method:: SPI.unlock()
+//| .. method:: unlock()
//|
//| Releases the SPI lock.
//|
STATIC mp_obj_t busio_spi_obj_unlock(mp_obj_t self_in) {
busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
common_hal_busio_spi_unlock(self);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock);
-//| .. method:: SPI.write(buffer, \*, start=0, end=len(buffer))
+//| .. method:: write(buffer, *, start=0, end=None)
//|
//| Write the data contained in ``buffer``. The SPI object must be locked.
//| If the buffer is empty, nothing happens.
//|
//| :param bytearray buffer: Write out the data in this buffer
//| :param int start: Start of the slice of ``buffer`` to write out: ``buffer[start:end]``
-//| :param int end: End of the slice; this index is not included
+//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``
//|
STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer, ARG_start, ARG_end };
@@ -231,7 +236,7 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_
{ MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -255,7 +260,7 @@ STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_
MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write);
-//| .. method:: SPI.readinto(buffer, \*, start=0, end=len(buffer), write_value=0)
+//| .. method:: readinto(buffer, *, start=0, end=None, write_value=0)
//|
//| Read into ``buffer`` while writing ``write_value`` for each byte read.
//| The SPI object must be locked.
@@ -263,7 +268,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write);
//|
//| :param bytearray buffer: Read data into this buffer
//| :param int start: Start of the slice of ``buffer`` to read into: ``buffer[start:end]``
-//| :param int end: End of the slice; this index is not included
+//| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)``
//| :param int write_value: Value to write while reading. (Usually ignored.)
//|
STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -275,7 +280,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m
{ MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
};
busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -298,7 +303,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m
}
MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 2, busio_spi_readinto);
-//| .. method:: SPI.write_readinto(buffer_out, buffer_in, \*, out_start=0, out_end=len(buffer_out), in_start=0, in_end=len(buffer_in))
+//| .. method:: write_readinto(buffer_out, buffer_in, *, out_start=0, out_end=None, in_start=0, in_end=None)
//|
//| Write out the data in ``buffer_out`` while simultaneously reading data into ``buffer_in``.
//| The SPI object must be locked.
@@ -309,9 +314,9 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 2, busio_spi_readinto);
//| :param bytearray buffer_out: Write out the data in this buffer
//| :param bytearray buffer_in: Read data into this buffer
//| :param int out_start: Start of the slice of buffer_out to write out: ``buffer_out[out_start:out_end]``
-//| :param int out_end: End of the slice; this index is not included
+//| :param int out_end: End of the slice; this index is not included. Defaults to ``len(buffer_out)``
//| :param int in_start: Start of the slice of ``buffer_in`` to read into: ``buffer_in[in_start:in_end]``
-//| :param int in_end: End of the slice; this index is not included
+//| :param int in_end: End of the slice; this index is not included. Defaults to ``len(buffer_in)``
//|
STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end };
@@ -324,7 +329,7 @@ STATIC mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args
{ MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} },
};
busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
check_lock(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -367,7 +372,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_readinto_obj, 2, busio_spi_write_read
//|
STATIC mp_obj_t busio_spi_obj_get_frequency(mp_obj_t self_in) {
busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_spi_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_busio_spi_get_frequency(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_get_frequency_obj, busio_spi_obj_get_frequency);
diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h
index 2d12b8b76..b7b0715d1 100644
--- a/shared-bindings/busio/SPI.h
+++ b/shared-bindings/busio/SPI.h
@@ -61,6 +61,12 @@ extern bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_o
// Return actual SPI bus frequency.
uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self);
+// Return SPI bus phase.
+uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t* self);
+
+// Return SPI bus polarity.
+uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t* self);
+
// This is used by the supervisor to claim SPI devices indefinitely.
extern void common_hal_busio_spi_never_reset(busio_spi_obj_t *self);
diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c
index b40f3fa03..c7eef8c43 100644
--- a/shared-bindings/busio/UART.c
+++ b/shared-bindings/busio/UART.c
@@ -46,7 +46,7 @@
//| =================================================
//|
//|
-//| .. class:: UART(tx, rx, \*, baudrate=9600, bits=8, parity=None, stop=1, timeout=1, receiver_buffer_size=64)
+//| .. class:: UART(tx, rx, *, baudrate=9600, bits=8, parity=None, stop=1, timeout=1, receiver_buffer_size=64)
//|
//| A common bidirectional serial protocol that uses an an agreed upon speed
//| rather than a shared clock line.
@@ -57,7 +57,7 @@
//| :param int bits: the number of bits per byte, 7, 8 or 9.
//| :param Parity parity: the parity used for error checking.
//| :param int stop: the number of stop bits, 1 or 2.
-//| :param int timeout: the timeout in seconds to wait for the first character and between subsequent characters. Raises ``ValueError`` if timeout >100 seconds.
+//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters. Raises ``ValueError`` if timeout >100 seconds.
//| :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.)
//|
//| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds.
@@ -137,6 +137,12 @@ STATIC mp_obj_t busio_uart_obj_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_deinit_obj, busio_uart_obj_deinit);
+STATIC void check_for_deinit(busio_uart_obj_t *self) {
+ if (common_hal_busio_uart_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -196,7 +202,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_
// These three methods are used by the shared stream methods.
STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
byte *buf = buf_in;
// make sure we want at least 1 char
@@ -209,7 +215,7 @@ STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size,
STATIC mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
const byte *buf = buf_in;
return common_hal_busio_uart_write(self, buf, size, errcode);
@@ -217,7 +223,7 @@ STATIC mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_
STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
mp_uint_t ret;
if (request == MP_IOCTL_POLL) {
mp_uint_t flags = arg;
@@ -241,14 +247,14 @@ STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t
//|
STATIC mp_obj_t busio_uart_obj_get_baudrate(mp_obj_t self_in) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_get_baudrate(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_baudrate_obj, busio_uart_obj_get_baudrate);
STATIC mp_obj_t busio_uart_obj_set_baudrate(mp_obj_t self_in, mp_obj_t baudrate) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
common_hal_busio_uart_set_baudrate(self, mp_obj_get_int(baudrate));
return mp_const_none;
}
@@ -268,7 +274,7 @@ const mp_obj_property_t busio_uart_baudrate_obj = {
//|
STATIC mp_obj_t busio_uart_obj_get_in_waiting(mp_obj_t self_in) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_rx_characters_available(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_in_waiting_obj, busio_uart_obj_get_in_waiting);
@@ -286,13 +292,13 @@ const mp_obj_property_t busio_uart_in_waiting_obj = {
//|
STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) {
busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_busio_uart_deinited(self));
+ check_for_deinit(self);
common_hal_busio_uart_clear_rx_buffer(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer);
-//| .. class:: busio.UART.Parity
+//| .. class:: busio.UART.Parity()
//|
//| Enum-like class to define the parity used to verify correct data transfer.
//|
diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h
index e171f8bb4..776a996be 100644
--- a/shared-bindings/busio/UART.h
+++ b/shared-bindings/busio/UART.h
@@ -42,7 +42,7 @@ typedef enum {
extern void common_hal_busio_uart_construct(busio_uart_obj_t *self,
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
- uint8_t receiver_buffer_size);
+ uint16_t receiver_buffer_size);
extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self);
extern bool common_hal_busio_uart_deinited(busio_uart_obj_t *self);
diff --git a/shared-bindings/busio/__init__.c b/shared-bindings/busio/__init__.c
index 958ee062a..ff2933dc6 100644
--- a/shared-bindings/busio/__init__.c
+++ b/shared-bindings/busio/__init__.c
@@ -35,7 +35,6 @@
#include "shared-bindings/busio/OneWire.h"
#include "shared-bindings/busio/SPI.h"
#include "shared-bindings/busio/UART.h"
-#include "shared-bindings/busio/__init__.h"
#include "py/runtime.h"
diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c
index 2fcbefe11..16472c12c 100644
--- a/shared-bindings/digitalio/DigitalInOut.c
+++ b/shared-bindings/digitalio/DigitalInOut.c
@@ -49,8 +49,8 @@
//| =========================================================
//|
//| A DigitalInOut is used to digitally control I/O pins. For analog control of
-//| a pin, see the :py:class:`~digitalio.AnalogIn` and
-//| :py:class:`~digitalio.AnalogOut` classes.
+//| a pin, see the :py:class:`analogio.AnalogIn` and
+//| :py:class:`analogio.AnalogOut` classes.
//|
//| .. class:: DigitalInOut(pin)
@@ -105,6 +105,12 @@ STATIC mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(digitalio_digitalinout_obj___exit___obj, 4, 4, digitalio_digitalinout_obj___exit__);
+STATIC void check_for_deinit(digitalio_digitalinout_obj_t *self) {
+ if (common_hal_digitalio_digitalinout_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//|
//| .. method:: switch_to_output(value=False, drive_mode=digitalio.DriveMode.PUSH_PULL)
//|
@@ -121,7 +127,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_output(size_t n_args, const mp_
{ MP_QSTR_drive_mode, MP_ARG_OBJ, {.u_rom_obj = &digitalio_drive_mode_push_pull_obj} },
};
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -158,7 +164,7 @@ STATIC mp_obj_t digitalio_digitalinout_switch_to_input(size_t n_args, const mp_o
{ MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
};
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -191,7 +197,7 @@ extern const digitalio_digitalio_direction_obj_t digitalio_digitalio_direction_o
STATIC mp_obj_t digitalio_digitalinout_obj_get_direction(mp_obj_t self_in) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
digitalio_direction_t direction = common_hal_digitalio_digitalinout_get_direction(self);
if (direction == DIRECTION_INPUT) {
return (mp_obj_t)&digitalio_direction_input_obj;
@@ -202,7 +208,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_direction_obj, digitalio_di
STATIC mp_obj_t digitalio_digitalinout_obj_set_direction(mp_obj_t self_in, mp_obj_t value) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (value == &digitalio_direction_input_obj) {
common_hal_digitalio_digitalinout_switch_to_input(self, PULL_NONE);
} else if (value == &digitalio_direction_output_obj) {
@@ -227,7 +233,7 @@ const mp_obj_property_t digitalio_digitalio_direction_obj = {
//|
STATIC mp_obj_t digitalio_digitalinout_obj_get_value(mp_obj_t self_in) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
bool value = common_hal_digitalio_digitalinout_get_value(self);
return mp_obj_new_bool(value);
}
@@ -235,7 +241,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_value_obj, digitalio_digita
STATIC mp_obj_t digitalio_digitalinout_obj_set_value(mp_obj_t self_in, mp_obj_t value) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) {
mp_raise_AttributeError(translate("Cannot set value when direction is input."));
return mp_const_none;
@@ -261,7 +267,7 @@ const mp_obj_property_t digitalio_digitalinout_value_obj = {
//|
STATIC mp_obj_t digitalio_digitalinout_obj_get_drive_mode(mp_obj_t self_in) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) {
mp_raise_AttributeError(translate("Drive mode not used when direction is input."));
return mp_const_none;
@@ -276,7 +282,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_drive_mode_obj, digitalio_d
STATIC mp_obj_t digitalio_digitalinout_obj_set_drive_mode(mp_obj_t self_in, mp_obj_t drive_mode) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_INPUT) {
mp_raise_AttributeError(translate("Drive mode not used when direction is input."));
return mp_const_none;
@@ -309,7 +315,7 @@ const mp_obj_property_t digitalio_digitalio_drive_mode_obj = {
//|
STATIC mp_obj_t digitalio_digitalinout_obj_get_pull(mp_obj_t self_in) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) {
mp_raise_AttributeError(translate("Pull not used when direction is output."));
return mp_const_none;
@@ -326,7 +332,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_pull_obj, digitalio_digital
STATIC mp_obj_t digitalio_digitalinout_obj_set_pull(mp_obj_t self_in, mp_obj_t pull_obj) {
digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_digitalio_digitalinout_deinited(self));
+ check_for_deinit(self);
if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUTPUT) {
mp_raise_AttributeError(translate("Pull not used when direction is output."));
return mp_const_none;
@@ -374,3 +380,13 @@ const mp_obj_type_t digitalio_digitalinout_type = {
.make_new = digitalio_digitalinout_make_new,
.locals_dict = (mp_obj_t)&digitalio_digitalinout_locals_dict,
};
+
+// Helper for validating digitalio.DigitalInOut arguments
+digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj) {
+ if (!MP_OBJ_IS_TYPE(obj, &digitalio_digitalinout_type)) {
+ mp_raise_TypeError(translate("argument num/types mismatch"));
+ }
+ digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(obj);
+ check_for_deinit(pin);
+ return pin;
+}
diff --git a/shared-bindings/digitalio/DigitalInOut.h b/shared-bindings/digitalio/DigitalInOut.h
index 2aaa31b7f..eee0d5801 100644
--- a/shared-bindings/digitalio/DigitalInOut.h
+++ b/shared-bindings/digitalio/DigitalInOut.h
@@ -52,5 +52,7 @@ void common_hal_digitalio_digitalinout_set_drive_mode(digitalio_digitalinout_obj
digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(digitalio_digitalinout_obj_t* self);
void common_hal_digitalio_digitalinout_set_pull(digitalio_digitalinout_obj_t* self, digitalio_pull_t pull);
digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(digitalio_digitalinout_obj_t* self);
+void common_hal_digitalio_digitalinout_never_reset(digitalio_digitalinout_obj_t *self);
+digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIGITALINOUT_H
diff --git a/shared-bindings/digitalio/Direction.c b/shared-bindings/digitalio/Direction.c
index a3433d4b0..c8188fc89 100644
--- a/shared-bindings/digitalio/Direction.c
+++ b/shared-bindings/digitalio/Direction.c
@@ -43,7 +43,7 @@
//| :class:`Direction` -- defines the direction of a digital pin
//| =============================================================
//|
-//| .. class:: digitalio.DigitalInOut.Direction
+//| .. class:: Direction
//|
//| Enum-like class to define which direction the digital values are
//| going.
diff --git a/shared-bindings/digitalio/DriveMode.c b/shared-bindings/digitalio/DriveMode.c
index 477cd904c..51e1e2ee5 100644
--- a/shared-bindings/digitalio/DriveMode.c
+++ b/shared-bindings/digitalio/DriveMode.c
@@ -31,7 +31,7 @@
//| :class:`DriveMode` -- defines the drive mode of a digital pin
//| =============================================================
//|
-//| .. class:: digitalio.DriveMode
+//| .. class:: DriveMode
//|
//| Enum-like class to define the drive mode used when outputting
//| digital values.
diff --git a/shared-bindings/digitalio/Pull.c b/shared-bindings/digitalio/Pull.c
index 8d03f6c05..813268db7 100644
--- a/shared-bindings/digitalio/Pull.c
+++ b/shared-bindings/digitalio/Pull.c
@@ -31,7 +31,7 @@
//| :class:`Pull` -- defines the pull of a digital input pin
//| =============================================================
//|
-//| .. class:: digitalio.Pull
+//| .. class:: Pull
//|
//| Enum-like class to define the pull value, if any, used while reading
//| digital values in.
diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c
index 3612b8d63..91c17f2d1 100644
--- a/shared-bindings/displayio/Bitmap.c
+++ b/shared-bindings/displayio/Bitmap.c
@@ -58,14 +58,22 @@ STATIC mp_obj_t displayio_bitmap_make_new(const mp_obj_type_t *type, size_t n_ar
uint32_t width = mp_obj_get_int(pos_args[0]);
uint32_t height = mp_obj_get_int(pos_args[1]);
uint32_t value_count = mp_obj_get_int(pos_args[2]);
- uint32_t power_of_two = 1;
- while (value_count > (1U << power_of_two)) {
- power_of_two <<= 1;
+ uint32_t bits = 1;
+
+ if (value_count == 0) {
+ mp_raise_ValueError(translate("value_count must be > 0"));
+ }
+ while ((value_count - 1) >> bits) {
+ if (bits < 8) {
+ bits <<= 1;
+ } else {
+ bits += 8;
+ }
}
displayio_bitmap_t *self = m_new_obj(displayio_bitmap_t);
self->base.type = &displayio_bitmap_type;
- common_hal_displayio_bitmap_construct(self, width, height, power_of_two);
+ common_hal_displayio_bitmap_construct(self, width, height, bits);
return MP_OBJ_FROM_PTR(self);
}
diff --git a/shared-bindings/displayio/ColorConverter.c b/shared-bindings/displayio/ColorConverter.c
index 561883810..d9524870d 100644
--- a/shared-bindings/displayio/ColorConverter.c
+++ b/shared-bindings/displayio/ColorConverter.c
@@ -62,6 +62,8 @@ STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, siz
//| .. method:: convert(color)
//|
+//| Converts the given RGB888 color to RGB565
+//|
STATIC mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t color_obj) {
displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in);
@@ -69,8 +71,10 @@ STATIC mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t
if (!mp_obj_get_int_maybe(color_obj, &color)) {
mp_raise_ValueError(translate("color should be an int"));
}
- uint16_t output_color;
- common_hal_displayio_colorconverter_convert(self, color, &output_color);
+ _displayio_colorspace_t colorspace;
+ colorspace.depth = 16;
+ uint32_t output_color;
+ common_hal_displayio_colorconverter_convert(self, &colorspace, color, &output_color);
return MP_OBJ_NEW_SMALL_INT(output_color);
}
MP_DEFINE_CONST_FUN_OBJ_2(displayio_colorconverter_convert_obj, displayio_colorconverter_obj_convert);
diff --git a/shared-bindings/displayio/ColorConverter.h b/shared-bindings/displayio/ColorConverter.h
index 71be7f543..24895500e 100644
--- a/shared-bindings/displayio/ColorConverter.h
+++ b/shared-bindings/displayio/ColorConverter.h
@@ -29,9 +29,11 @@
#include "shared-module/displayio/ColorConverter.h"
+#include "shared-module/displayio/Palette.h"
+
extern const mp_obj_type_t displayio_colorconverter_type;
void common_hal_displayio_colorconverter_construct(displayio_colorconverter_t* self);
-bool common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *colorconverter, uint32_t input_color, uint16_t* output_color);
+void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *colorconverter, const _displayio_colorspace_t* colorspace, uint32_t input_color, uint32_t* output_color);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_COLORCONVERTER_H
diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c
index 1f46330e8..9cb4d6e74 100644
--- a/shared-bindings/displayio/Display.c
+++ b/shared-bindings/displayio/Display.c
@@ -31,6 +31,7 @@
#include "lib/utils/context_manager_helpers.h"
#include "py/binary.h"
#include "py/objproperty.h"
+#include "py/objtype.h"
#include "py/runtime.h"
#include "shared-bindings/displayio/Group.h"
#include "shared-bindings/microcontroller/Pin.h"
@@ -50,7 +51,7 @@
//| Most people should not use this class directly. Use a specific display driver instead that will
//| contain the initialization sequence at minimum.
//|
-//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None)
+//| .. class:: Display(display_bus, init_sequence, *, width, height, colstart=0, rowstart=0, rotation=0, color_depth=16, grayscale=False, pixels_in_byte_share_row=True, bytes_per_cell=1, reverse_pixels_in_byte=False, set_column_command=0x2a, set_row_command=0x2b, write_ram_command=0x2c, set_vertical_scroll=0, backlight_pin=None, brightness_command=None, brightness=1.0, auto_brightness=False, single_byte_bounds=False, data_as_commands=False)
//|
//| Create a Display object on the given display bus (`displayio.FourWire` or `displayio.ParallelBus`).
//|
@@ -77,7 +78,8 @@
//| The initialization sequence should always leave the display memory access inline with the scan
//| of the display to minimize tearing artifacts.
//|
-//| :param displayio.FourWire or displayio.ParallelBus display_bus: The bus that the display is connected to
+//| :param display_bus: The bus that the display is connected to
+//| :type display_bus: displayio.FourWire or displayio.ParallelBus
//| :param buffer init_sequence: Byte-packed initialization sequence.
//| :param int width: Width in pixels
//| :param int height: Height in pixels
@@ -86,14 +88,23 @@
//| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270)
//| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays
//| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.)
+//| :param bool grayscale: True if the display only shows a single color.
+//| :param bool pixels_in_byte_share_row: True when pixels are less than a byte and a byte includes pixels from the same row of the display. When False, pixels share a column.
+//| :param int bytes_per_cell: Number of bytes per addressable memory location when color_depth < 8. When greater than one, bytes share a row or column according to pixels_in_byte_share_row.
+//| :param bool reverse_pixels_in_byte: Reverses the pixel order within each byte when color_depth < 8. Does not apply across multiple bytes even if there is more than one byte per cell (bytes_per_cell.)
//| :param int set_column_command: Command used to set the start and end columns to update
//| :param int set_row_command: Command used so set the start and end rows to update
-//| :param int write_ram_command: Command used to write pixels values into the update region
+//| :param int write_ram_command: Command used to write pixels values into the update region. Ignored if data_as_commands is set.
//| :param int set_vertical_scroll: Command used to set the first row to show
//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight
+//| :param int brightness_command: Command to set display brightness. Usually available in OLED controllers.
+//| :param bool brightness: Initial display brightness. This value is ignored if auto_brightness is True.
+//| :param bool auto_brightness: If True, brightness is controlled via an ambient light sensor or other mechanism.
+//| :param bool single_byte_bounds: Display column and row commands use single bytes
+//| :param bool data_as_commands: Treat all init and boundary data as SPI commands. Certain displays require this.
//|
STATIC mp_obj_t displayio_display_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_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin };
+ enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_auto_brightness, ARG_single_byte_bounds, ARG_data_as_commands };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ },
@@ -103,11 +114,20 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
{ MP_QSTR_rowstart, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
{ MP_QSTR_rotation, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
{ MP_QSTR_color_depth, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} },
+ { MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
+ { MP_QSTR_pixels_in_byte_share_row, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} },
+ { MP_QSTR_bytes_per_cell, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} },
+ { MP_QSTR_reverse_pixels_in_byte, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
{ MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} },
{ MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} },
{ MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} },
{ MP_QSTR_set_vertical_scroll, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x0} },
{ MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
+ { MP_QSTR_brightness_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_BRIGHTNESS_COMMAND} },
+ { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} },
+ { MP_QSTR_auto_brightness, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
+ { MP_QSTR_single_byte_bounds, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
+ { MP_QSTR_data_as_commands, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} },
};
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);
@@ -124,6 +144,9 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
backlight_pin = MP_OBJ_TO_PTR(backlight_pin_obj);
assert_pin_free(backlight_pin);
}
+
+ mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj);
+
mp_int_t rotation = args[ARG_rotation].u_int;
if (rotation % 90 != 0) {
mp_raise_ValueError(translate("Display rotation must be in 90 degree increments"));
@@ -141,33 +164,50 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a
mp_raise_RuntimeError(translate("Too many displays"));
}
self->base.type = &displayio_display_type;
- common_hal_displayio_display_construct(self,
- display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation,
- args[ARG_color_depth].u_int, args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int,
- args[ARG_write_ram_command].u_int,
- args[ARG_set_vertical_scroll].u_int,
- bufinfo.buf, bufinfo.len, MP_OBJ_TO_PTR(backlight_pin));
+ common_hal_displayio_display_construct(
+ self,
+ display_bus, args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation,
+ args[ARG_color_depth].u_int, args[ARG_grayscale].u_bool,
+ args[ARG_pixels_in_byte_share_row].u_bool, args[ARG_bytes_per_cell].u_bool, args[ARG_reverse_pixels_in_byte].u_bool,
+ args[ARG_set_column_command].u_int, args[ARG_set_row_command].u_int,
+ args[ARG_write_ram_command].u_int,
+ args[ARG_set_vertical_scroll].u_int,
+ bufinfo.buf, bufinfo.len,
+ MP_OBJ_TO_PTR(backlight_pin),
+ args[ARG_brightness_command].u_int,
+ brightness,
+ args[ARG_auto_brightness].u_bool,
+ args[ARG_single_byte_bounds].u_bool,
+ args[ARG_data_as_commands].u_bool
+ );
return self;
}
+// Helper to ensure we have the native super class instead of a subclass.
+static displayio_display_obj_t* native_display(mp_obj_t display_obj) {
+ mp_obj_t native_display = mp_instance_cast_to_native_base(display_obj, &displayio_display_type);
+ mp_obj_assert_native_inited(native_display);
+ return MP_OBJ_TO_PTR(native_display);
+}
+
//| .. method:: show(group)
//|
//| Switches to displaying the given group of layers. When group is None, the default
//| CircuitPython terminal will be shown.
//|
+//| :param Group group: The group to show.
STATIC mp_obj_t displayio_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) {
- displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_display_obj_t *self = native_display(self_in);
displayio_group_t* group = NULL;
if (group_in != mp_const_none) {
- mp_obj_t native_layer = mp_instance_cast_to_native_base(group_in, &displayio_group_type);
- if (native_layer == MP_OBJ_NULL) {
- mp_raise_ValueError(translate("Must be a Group subclass."));
- }
- group = MP_OBJ_TO_PTR(native_layer);
+ group = MP_OBJ_TO_PTR(native_group(group_in));
}
- common_hal_displayio_display_show(self, group);
+ bool ok = common_hal_displayio_display_show(self, group);
+ if (!ok) {
+ mp_raise_ValueError(translate("Group already used"));
+ }
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show);
@@ -177,7 +217,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_display_show_obj, displayio_display_obj_show
//| Queues up a display refresh that happens in the background.
//|
STATIC mp_obj_t displayio_display_obj_refresh_soon(mp_obj_t self_in) {
- displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_display_obj_t *self = native_display(self_in);
common_hal_displayio_display_refresh_soon(self);
return mp_const_none;
}
@@ -189,7 +229,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_refresh_soon_obj, displayio_display_
//| behind the rendered frames. In that case, this will return immediately with the wait count.
//|
STATIC mp_obj_t displayio_display_obj_wait_for_frame(mp_obj_t self_in) {
- displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_display_obj_t *self = native_display(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_wait_for_frame(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_display_obj_wait_for_frame);
@@ -197,11 +237,11 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_wait_for_frame_obj, displayio_displa
//| .. attribute:: brightness
//|
//| The brightness of the display as a float. 0.0 is off and 1.0 is full brightness. When
-//| `auto_brightness` is True this value will change automatically and setting it will have no
-//| effect. To control the brightness, auto_brightness must be false.
+//| `auto_brightness` is True, the value of `brightness` will change automatically.
+//| If `brightness` is set, `auto_brightness` will be disabled and will be set to False.
//|
STATIC mp_obj_t displayio_display_obj_get_brightness(mp_obj_t self_in) {
- displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_display_obj_t *self = native_display(self_in);
mp_float_t brightness = common_hal_displayio_display_get_brightness(self);
if (brightness < 0) {
mp_raise_RuntimeError(translate("Brightness not adjustable"));
@@ -210,9 +250,14 @@ STATIC mp_obj_t displayio_display_obj_get_brightness(mp_obj_t self_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_brightness_obj, displayio_display_obj_get_brightness);
-STATIC mp_obj_t displayio_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness) {
- displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
- bool ok = common_hal_displayio_display_set_brightness(self, mp_obj_get_float(brightness));
+STATIC mp_obj_t displayio_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness_obj) {
+ displayio_display_obj_t *self = native_display(self_in);
+ common_hal_displayio_display_set_auto_brightness(self, false);
+ mp_float_t brightness = mp_obj_get_float(brightness_obj);
+ if (brightness < 0 || brightness > 1.0) {
+ mp_raise_ValueError(translate("Brightness must be 0-1.0"));
+ }
+ bool ok = common_hal_displayio_display_set_brightness(self, brightness);
if (!ok) {
mp_raise_RuntimeError(translate("Brightness not adjustable"));
}
@@ -229,16 +274,19 @@ const mp_obj_property_t displayio_display_brightness_obj = {
//| .. attribute:: auto_brightness
//|
-//| True when the display brightness is auto adjusted.
+//| True when the display brightness is adjusted automatically, based on an ambient
+//| light sensor or other method. Note that some displays may have this set to True by default,
+//| but not actually implement automatic brightness adjustment. `auto_brightness` is set to False
+//| if `brightness` is set manually.
//|
STATIC mp_obj_t displayio_display_obj_get_auto_brightness(mp_obj_t self_in) {
- displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_display_obj_t *self = native_display(self_in);
return mp_obj_new_bool(common_hal_displayio_display_get_auto_brightness(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_auto_brightness_obj, displayio_display_obj_get_auto_brightness);
STATIC mp_obj_t displayio_display_obj_set_auto_brightness(mp_obj_t self_in, mp_obj_t auto_brightness) {
- displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_display_obj_t *self = native_display(self_in);
common_hal_displayio_display_set_auto_brightness(self, mp_obj_is_true(auto_brightness));
@@ -259,7 +307,7 @@ const mp_obj_property_t displayio_display_auto_brightness_obj = {
//|
//|
STATIC mp_obj_t displayio_display_obj_get_width(mp_obj_t self_in) {
- displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_display_obj_t *self = native_display(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_get_width(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_width_obj, displayio_display_obj_get_width);
@@ -277,7 +325,7 @@ const mp_obj_property_t displayio_display_width_obj = {
//|
//|
STATIC mp_obj_t displayio_display_obj_get_height(mp_obj_t self_in) {
- displayio_display_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_display_obj_t *self = native_display(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_display_get_height(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_height_obj, displayio_display_obj_get_height);
@@ -289,6 +337,25 @@ const mp_obj_property_t displayio_display_height_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+//| .. attribute:: bus
+//|
+//| The bus being used by the display
+//|
+//|
+STATIC mp_obj_t displayio_display_obj_get_bus(mp_obj_t self_in) {
+ displayio_display_obj_t *self = native_display(self_in);
+ return self->bus;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(displayio_display_get_bus_obj, displayio_display_obj_get_bus);
+
+const mp_obj_property_t displayio_display_bus_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&displayio_display_get_bus_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+
STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&displayio_display_show_obj) },
{ MP_ROM_QSTR(MP_QSTR_refresh_soon), MP_ROM_PTR(&displayio_display_refresh_soon_obj) },
@@ -299,6 +366,7 @@ STATIC const mp_rom_map_elem_t displayio_display_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&displayio_display_width_obj) },
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_display_height_obj) },
+ { MP_ROM_QSTR(MP_QSTR_bus), MP_ROM_PTR(&displayio_display_bus_obj) },
};
STATIC MP_DEFINE_CONST_DICT(displayio_display_locals_dict, displayio_display_locals_dict_table);
diff --git a/shared-bindings/displayio/Display.h b/shared-bindings/displayio/Display.h
index 7d6444a2d..a8938bbcd 100644
--- a/shared-bindings/displayio/Display.h
+++ b/shared-bindings/displayio/Display.h
@@ -36,27 +36,33 @@ extern const mp_obj_type_t displayio_display_type;
#define DELAY 0x80
+#define NO_BRIGHTNESS_COMMAND 0x100
+
void common_hal_displayio_display_construct(displayio_display_obj_t* self,
mp_obj_t bus, uint16_t width, uint16_t height,
- int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth,
+ int16_t colstart, int16_t rowstart, uint16_t rotation, uint16_t color_depth, bool grayscale,
+ bool pixels_in_byte_share_row, uint8_t bytes_per_cell, bool reverse_pixels_in_byte,
uint8_t set_column_command, uint8_t set_row_command, uint8_t write_ram_command, uint8_t set_vertical_scroll,
- uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin);
+ uint8_t* init_sequence, uint16_t init_sequence_len, const mcu_pin_obj_t* backlight_pin, uint16_t brightness_command,
+ mp_float_t brightness, bool auto_brightness,
+ bool single_byte_bounds, bool data_as_commands);
int32_t common_hal_displayio_display_wait_for_frame(displayio_display_obj_t* self);
-void common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group);
+bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group);
void common_hal_displayio_display_refresh_soon(displayio_display_obj_t* self);
bool displayio_display_begin_transaction(displayio_display_obj_t* self);
void displayio_display_end_transaction(displayio_display_obj_t* self);
-void displayio_display_set_region_to_update(displayio_display_obj_t* self, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
+// The second point of the region is exclusive.
+void displayio_display_set_region_to_update(displayio_display_obj_t* self, displayio_area_t* area);
bool displayio_display_frame_queued(displayio_display_obj_t* self);
bool displayio_display_refresh_queued(displayio_display_obj_t* self);
void displayio_display_finish_refresh(displayio_display_obj_t* self);
-void displayio_display_send_pixels(displayio_display_obj_t* self, uint32_t* pixels, uint32_t length);
+void displayio_display_send_pixels(displayio_display_obj_t* self, uint8_t* pixels, uint32_t length);
bool common_hal_displayio_display_get_auto_brightness(displayio_display_obj_t* self);
void common_hal_displayio_display_set_auto_brightness(displayio_display_obj_t* self, bool auto_brightness);
diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c
index 70cd42747..af64a2028 100644
--- a/shared-bindings/displayio/FourWire.c
+++ b/shared-bindings/displayio/FourWire.c
@@ -46,22 +46,29 @@
//| Manage updating a display over SPI four wire protocol in the background while Python code runs.
//| It doesn't handle display initialization.
//|
-//| .. class:: FourWire(spi_bus, *, command, chip_select, reset)
+//| .. class:: FourWire(spi_bus, *, command, chip_select, reset=None, baudrate=24000000)
//|
//| Create a FourWire object associated with the given pins.
//|
+//| The SPI bus and pins are then in use by the display until `displayio.release_displays()` is
+//| called even after a reload. (It does this so CircuitPython can use the display after your code
+//| is done.) So, the first time you initialize a display bus in code.py you should call
+//| :py:func`displayio.release_displays` first, otherwise it will error after the first code.py run.
+//|
//| :param busio.SPI spi_bus: The SPI bus that make up the clock and data lines
//| :param microcontroller.Pin command: Data or command pin
//| :param microcontroller.Pin chip_select: Chip select pin
-//| :param microcontroller.Pin reset: Reset pin
+//| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used
+//| :param int baudrate: Maximum baudrate in Hz for the display on the bus
//|
STATIC mp_obj_t displayio_fourwire_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_spi_bus, ARG_command, ARG_chip_select, ARG_reset };
+ enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset, ARG_baudrate };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_spi_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_command, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
{ MP_QSTR_chip_select, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
{ MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
+ { MP_QSTR_baudrate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 24000000} },
};
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);
@@ -92,7 +99,7 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_
}
common_hal_displayio_fourwire_construct(self,
- MP_OBJ_TO_PTR(spi), command, chip_select, reset);
+ MP_OBJ_TO_PTR(spi), command, chip_select, reset, args[ARG_baudrate].u_int);
return self;
}
diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h
index b8b00372c..5dbd60764 100644
--- a/shared-bindings/displayio/FourWire.h
+++ b/shared-bindings/displayio/FourWire.h
@@ -31,13 +31,12 @@
#include "common-hal/microcontroller/Pin.h"
#include "shared-module/displayio/Group.h"
-#include "supervisor/shared/board_busses.h"
extern const mp_obj_type_t displayio_fourwire_type;
void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
busio_spi_obj_t* spi, const mcu_pin_obj_t* command,
- const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset);
+ const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, uint32_t baudrate);
void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self);
diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c
index 7b79f3229..5a35424ce 100644
--- a/shared-bindings/displayio/Group.c
+++ b/shared-bindings/displayio/Group.c
@@ -31,6 +31,7 @@
#include "lib/utils/context_manager_helpers.h"
#include "py/binary.h"
#include "py/objproperty.h"
+#include "py/objtype.h"
#include "py/runtime.h"
#include "supervisor/shared/translate.h"
@@ -41,19 +42,23 @@
//|
//| Manage a group of sprites and groups and how they are inter-related.
//|
-//| .. class:: Group(*, max_size=4, scale=1)
+//| .. class:: Group(*, max_size=4, scale=1, x=0, y=0)
//|
//| Create a Group of a given size and scale. Scale is in one dimension. For example, scale=2
//| leads to a layer's pixel being 2x2 pixels when in the group.
//|
//| :param int max_size: The maximum group size.
//| :param int scale: Scale of layer pixels in one dimension.
+//| :param int x: Initial x position within the parent.
+//| :param int y: Initial y position within the parent.
//|
STATIC mp_obj_t displayio_group_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_max_size, ARG_scale };
+ enum { ARG_max_size, ARG_scale, ARG_x, ARG_y };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_max_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 4} },
{ MP_QSTR_scale, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} },
+ { 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);
@@ -70,14 +75,18 @@ STATIC mp_obj_t displayio_group_make_new(const mp_obj_type_t *type, size_t n_arg
displayio_group_t *self = m_new_obj(displayio_group_t);
self->base.type = &displayio_group_type;
- common_hal_displayio_group_construct(self, max_size, scale);
+ common_hal_displayio_group_construct(self, max_size, scale, args[ARG_x].u_int, args[ARG_y].u_int);
return MP_OBJ_FROM_PTR(self);
}
// Helper to ensure we have the native super class instead of a subclass.
-static displayio_group_t* native_group(mp_obj_t group_obj) {
+displayio_group_t* native_group(mp_obj_t group_obj) {
mp_obj_t native_group = mp_instance_cast_to_native_base(group_obj, &displayio_group_type);
+ if (native_group == MP_OBJ_NULL) {
+ mp_raise_ValueError_varg(translate("Must be a %q subclass."), MP_QSTR_Group);
+ }
+ mp_obj_assert_native_inited(native_group);
return MP_OBJ_TO_PTR(native_group);
}
@@ -168,7 +177,7 @@ const mp_obj_property_t displayio_group_y_obj = {
//| Append a layer to the group. It will be drawn above other layers.
//|
STATIC mp_obj_t displayio_group_obj_append(mp_obj_t self_in, mp_obj_t layer) {
- displayio_group_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_group_t *self = native_group(self_in);
common_hal_displayio_group_insert(self, common_hal_displayio_group_get_len(self), layer);
return mp_const_none;
}
@@ -179,13 +188,28 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_append_obj, displayio_group_obj_append
//| Insert a layer into the group.
//|
STATIC mp_obj_t displayio_group_obj_insert(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t layer) {
- displayio_group_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_group_t *self = native_group(self_in);
size_t index = mp_get_index(&displayio_group_type, common_hal_displayio_group_get_len(self), index_obj, false);
common_hal_displayio_group_insert(self, index, layer);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_3(displayio_group_insert_obj, displayio_group_obj_insert);
+
+//| .. method:: index(layer)
+//|
+//| Returns the index of the first copy of layer. Raises ValueError if not found.
+//|
+STATIC mp_obj_t displayio_group_obj_index(mp_obj_t self_in, mp_obj_t layer) {
+ displayio_group_t *self = native_group(self_in);
+ mp_int_t index = common_hal_displayio_group_index(self, layer);
+ if (index < 0) {
+ mp_raise_ValueError(translate("object not in sequence"));
+ }
+ return MP_OBJ_NEW_SMALL_INT(index);
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_index_obj, displayio_group_obj_index);
+
//| .. method:: pop(i=-1)
//|
//| Remove the ith item and return it.
@@ -198,7 +222,7 @@ STATIC mp_obj_t displayio_group_obj_pop(size_t n_args, const mp_obj_t *pos_args,
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- displayio_group_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ displayio_group_t *self = native_group(pos_args[0]);
size_t index = mp_get_index(&displayio_group_type,
common_hal_displayio_group_get_len(self),
@@ -208,12 +232,26 @@ 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);
+
+//| .. method:: remove(layer)
+//|
+//| Remove the first copy of layer. Raises ValueError if it is not present.
+//|
+STATIC mp_obj_t displayio_group_obj_remove(mp_obj_t self_in, mp_obj_t layer) {
+ mp_obj_t index = displayio_group_obj_index(self_in, layer);
+ displayio_group_t *self = native_group(self_in);
+
+ common_hal_displayio_group_pop(self, MP_OBJ_SMALL_INT_VALUE(index));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_remove_obj, displayio_group_obj_remove);
+
//| .. method:: __len__()
//|
//| Returns the number of layers in a Group
//|
STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
- displayio_group_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_group_t *self = native_group(self_in);
uint16_t len = common_hal_displayio_group_get_len(self);
switch (op) {
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0);
@@ -247,7 +285,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
//| del group[0]
//|
STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) {
- displayio_group_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_group_t *self = native_group(self_in);
if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) {
mp_raise_NotImplementedError(translate("Slices not supported"));
@@ -257,7 +295,7 @@ STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t valu
if (value == MP_OBJ_SENTINEL) {
// load
return common_hal_displayio_group_get(self, index);
- } else if (value == mp_const_none) {
+ } else if (value == MP_OBJ_NULL) {
common_hal_displayio_group_pop(self, index);
} else {
common_hal_displayio_group_set(self, index, value);
@@ -272,7 +310,9 @@ STATIC const mp_rom_map_elem_t displayio_group_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&displayio_group_y_obj) },
{ MP_ROM_QSTR(MP_QSTR_append), MP_ROM_PTR(&displayio_group_append_obj) },
{ MP_ROM_QSTR(MP_QSTR_insert), MP_ROM_PTR(&displayio_group_insert_obj) },
+ { MP_ROM_QSTR(MP_QSTR_index), MP_ROM_PTR(&displayio_group_index_obj) },
{ MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&displayio_group_pop_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&displayio_group_remove_obj) },
};
STATIC MP_DEFINE_CONST_DICT(displayio_group_locals_dict, displayio_group_locals_dict_table);
@@ -282,5 +322,6 @@ const mp_obj_type_t displayio_group_type = {
.make_new = displayio_group_make_new,
.subscr = group_subscr,
.unary_op = group_unary_op,
+ .getiter = mp_obj_new_generic_iterator,
.locals_dict = (mp_obj_dict_t*)&displayio_group_locals_dict,
};
diff --git a/shared-bindings/displayio/Group.h b/shared-bindings/displayio/Group.h
index d326dbf4d..dc9616f2e 100644
--- a/shared-bindings/displayio/Group.h
+++ b/shared-bindings/displayio/Group.h
@@ -31,8 +31,9 @@
extern const mp_obj_type_t displayio_group_type;
+displayio_group_t* native_group(mp_obj_t group_obj);
-void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale);
+void common_hal_displayio_group_construct(displayio_group_t* self, uint32_t max_size, uint32_t scale, mp_int_t x, mp_int_t y);
uint32_t common_hal_displayio_group_get_scale(displayio_group_t* self);
void common_hal_displayio_group_set_scale(displayio_group_t* self, uint32_t scale);
mp_int_t common_hal_displayio_group_get_x(displayio_group_t* self);
@@ -43,6 +44,7 @@ void common_hal_displayio_group_append(displayio_group_t* self, mp_obj_t layer);
void common_hal_displayio_group_insert(displayio_group_t* self, size_t index, mp_obj_t layer);
size_t common_hal_displayio_group_get_len(displayio_group_t* self);
mp_obj_t common_hal_displayio_group_pop(displayio_group_t* self, size_t index);
+mp_int_t common_hal_displayio_group_index(displayio_group_t* self, mp_obj_t layer);
mp_obj_t common_hal_displayio_group_get(displayio_group_t* self, size_t index);
void common_hal_displayio_group_set(displayio_group_t* self, size_t index, mp_obj_t layer);
diff --git a/shared-bindings/displayio/I2CDisplay.c b/shared-bindings/displayio/I2CDisplay.c
new file mode 100644
index 000000000..1f74e8c9e
--- /dev/null
+++ b/shared-bindings/displayio/I2CDisplay.c
@@ -0,0 +1,138 @@
+/*
+ * This file is part of the Micro Python 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.
+ */
+
+#include "shared-bindings/displayio/I2CDisplay.h"
+
+#include <stdint.h>
+#include <string.h>
+
+#include "lib/utils/context_manager_helpers.h"
+#include "py/binary.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/util.h"
+#include "shared-module/displayio/__init__.h"
+#include "supervisor/shared/translate.h"
+
+//| .. currentmodule:: displayio
+//|
+//| :class:`I2CDisplay` -- Manage updating a display over I2C
+//| ==========================================================================
+//|
+//| Manage updating a display over I2C in the background while Python code runs.
+//| It doesn't handle display initialization.
+//|
+//| .. class:: I2CDisplay(i2c_bus, *, device_address, reset=None)
+//|
+//| Create a I2CDisplay object associated with the given I2C bus and reset pin.
+//|
+//| The I2C bus and pins are then in use by the display until `displayio.release_displays()` is
+//| called even after a reload. (It does this so CircuitPython can use the display after your code
+//| is done.) So, the first time you initialize a display bus in code.py you should call
+//| :py:func`displayio.release_displays` first, otherwise it will error after the first code.py run.
+//|
+//| :param busio.I2C i2c_bus: The I2C bus that make up the clock and data lines
+//| :param int device_address: The I2C address of the device
+//| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used
+//|
+STATIC mp_obj_t displayio_i2cdisplay_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_i2c_bus, ARG_device_address, ARG_reset };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_i2c_bus, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_device_address, MP_ARG_INT | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
+ { MP_QSTR_reset, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.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);
+
+ mp_obj_t reset = args[ARG_reset].u_obj;
+ if (reset != mp_const_none) {
+ assert_pin_free(reset);
+ } else {
+ reset = NULL;
+ }
+
+ displayio_i2cdisplay_obj_t* self = NULL;
+ mp_obj_t i2c = args[ARG_i2c_bus].u_obj;
+ for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
+ if (displays[i].i2cdisplay_bus.base.type == NULL ||
+ displays[i].i2cdisplay_bus.base.type == &mp_type_NoneType) {
+ self = &displays[i].i2cdisplay_bus;
+ self->base.type = &displayio_i2cdisplay_type;
+ break;
+ }
+ }
+ if (self == NULL) {
+ mp_raise_RuntimeError(translate("Too many display busses"));
+ }
+
+ common_hal_displayio_i2cdisplay_construct(self,
+ MP_OBJ_TO_PTR(i2c), args[ARG_device_address].u_int, reset);
+ return self;
+}
+
+//| .. method:: send(command, data)
+//|
+//| Sends the given command value followed by the full set of data. Display state, such as
+//| vertical scroll, set via ``send`` may or may not be reset once the code is done.
+//|
+STATIC mp_obj_t displayio_i2cdisplay_obj_send(mp_obj_t self, mp_obj_t command_obj, mp_obj_t data_obj) {
+ mp_int_t command_int = MP_OBJ_SMALL_INT_VALUE(command_obj);
+ if (!MP_OBJ_IS_SMALL_INT(command_obj) || command_int > 255 || command_int < 0) {
+ mp_raise_ValueError(translate("Command must be 0-255"));
+ }
+ uint8_t command = command_int;
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ);
+
+ // Wait for display bus to be available.
+ while (!common_hal_displayio_i2cdisplay_begin_transaction(self)) {
+#ifdef MICROPY_VM_HOOK_LOOP
+ MICROPY_VM_HOOK_LOOP ;
+#endif
+ }
+ uint8_t full_command[bufinfo.len + 1];
+ full_command[0] = command;
+ memcpy(full_command + 1, ((uint8_t*) bufinfo.buf), bufinfo.len);
+ common_hal_displayio_i2cdisplay_send(self, true, full_command, bufinfo.len + 1);
+ common_hal_displayio_i2cdisplay_end_transaction(self);
+
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_3(displayio_i2cdisplay_send_obj, displayio_i2cdisplay_obj_send);
+
+STATIC const mp_rom_map_elem_t displayio_i2cdisplay_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&displayio_i2cdisplay_send_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(displayio_i2cdisplay_locals_dict, displayio_i2cdisplay_locals_dict_table);
+
+const mp_obj_type_t displayio_i2cdisplay_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_I2CDisplay,
+ .make_new = displayio_i2cdisplay_make_new,
+ .locals_dict = (mp_obj_dict_t*)&displayio_i2cdisplay_locals_dict,
+};
diff --git a/shared-bindings/bleio/AddressType.h b/shared-bindings/displayio/I2CDisplay.h
index e69caffab..cc4162800 100644
--- a/shared-bindings/bleio/AddressType.h
+++ b/shared-bindings/displayio/I2CDisplay.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017, 2018 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
@@ -24,27 +24,23 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H
-#include "py/obj.h"
+#include "shared-module/displayio/I2CDisplay.h"
+#include "common-hal/microcontroller/Pin.h"
-typedef enum {
- ADDRESS_PUBLIC,
- ADDRESS_RANDOM_STATIC,
- ADDRESS_RANDOM_PRIVATE_RESOLVABLE,
- ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE
-} bleio_address_type_t;
+extern const mp_obj_type_t displayio_i2cdisplay_type;
-extern const mp_obj_type_t bleio_addresstype_type;
+void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self,
+ busio_i2c_obj_t* i2c, uint16_t device_address, const mcu_pin_obj_t* reset);
-typedef struct {
- mp_obj_base_t base;
-} bleio_addresstype_obj_t;
+void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self);
-extern const bleio_addresstype_obj_t bleio_addresstype_public_obj;
-extern const bleio_addresstype_obj_t bleio_addresstype_random_static_obj;
-extern const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj;
-extern const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj;
+bool common_hal_displayio_i2cdisplay_begin_transaction(mp_obj_t self);
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H
+void common_hal_displayio_i2cdisplay_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length);
+
+void common_hal_displayio_i2cdisplay_end_transaction(mp_obj_t self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYBUSIO_I2CDISPLAY_H
diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c
index 799d42bef..dda58e3c5 100644
--- a/shared-bindings/displayio/Palette.c
+++ b/shared-bindings/displayio/Palette.c
@@ -67,6 +67,34 @@ STATIC mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_a
return MP_OBJ_FROM_PTR(self);
}
+//| .. method:: __len__()
+//|
+//| Returns the number of colors in a Palette
+//|
+STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
+ displayio_palette_t *self = MP_OBJ_TO_PTR(self_in);
+ switch (op) {
+ case MP_UNARY_OP_BOOL: return mp_const_true;
+ case MP_UNARY_OP_LEN:
+ return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_palette_get_len(self));
+ default: return MP_OBJ_NULL; // op not supported
+ }
+}
+
+//| .. method:: __setitem__(index, value)
+//|
+//| Sets the pixel color at the given index. The index should be an integer in the range 0 to color_count-1.
+//|
+//| The value argument represents a color, and can be from 0x000000 to 0xFFFFFF (to represent an RGB value).
+//| Value can be an int, bytes (3 bytes (RGB) or 4 bytes (RGB + pad byte)), or bytearray.
+//|
+//| This allows you to::
+//|
+//| palette[0] = 0xFFFFFF # set using an integer
+//| palette[1] = b'\xff\xff\x00' # set using 3 bytes
+//| palette[2] = b'\xff\xff\x00\x00' # set using 4 bytes
+//| palette[3] = bytearray(b'\x00\x00\xFF') # set using a bytearay of 3 or 4 bytes
+//|
STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) {
if (value == MP_OBJ_NULL) {
// delete item
@@ -76,12 +104,12 @@ STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t val
if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) {
return MP_OBJ_NULL;
}
- // index read is not supported
- if (value == MP_OBJ_SENTINEL) {
- return MP_OBJ_NULL;
- }
displayio_palette_t *self = MP_OBJ_TO_PTR(self_in);
size_t index = mp_get_index(&displayio_palette_type, self->color_count, index_in, false);
+ // index read
+ if (value == MP_OBJ_SENTINEL) {
+ return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_palette_get_color(self, index));
+ }
uint32_t color;
mp_int_t int_value;
@@ -147,5 +175,7 @@ const mp_obj_type_t displayio_palette_type = {
.name = MP_QSTR_Palette,
.make_new = displayio_palette_make_new,
.subscr = palette_subscr,
+ .unary_op = group_unary_op,
+ .getiter = mp_obj_new_generic_iterator,
.locals_dict = (mp_obj_dict_t*)&displayio_palette_locals_dict,
};
diff --git a/shared-bindings/displayio/Palette.h b/shared-bindings/displayio/Palette.h
index 767fc7b63..8c9fe11e3 100644
--- a/shared-bindings/displayio/Palette.h
+++ b/shared-bindings/displayio/Palette.h
@@ -33,6 +33,8 @@ extern const mp_obj_type_t displayio_palette_type;
void common_hal_displayio_palette_construct(displayio_palette_t* self, uint16_t color_count);
void common_hal_displayio_palette_set_color(displayio_palette_t* self, uint32_t palette_index, uint32_t color);
+uint32_t common_hal_displayio_palette_get_color(displayio_palette_t* self, uint32_t palette_index);
+uint32_t common_hal_displayio_palette_get_len(displayio_palette_t* self);
void common_hal_displayio_palette_make_opaque(displayio_palette_t* self, uint32_t palette_index);
void common_hal_displayio_palette_make_transparent(displayio_palette_t* self, uint32_t palette_index);
diff --git a/shared-bindings/displayio/ParallelBus.c b/shared-bindings/displayio/ParallelBus.c
index 6a499ed06..00a96d230 100644
--- a/shared-bindings/displayio/ParallelBus.c
+++ b/shared-bindings/displayio/ParallelBus.c
@@ -39,18 +39,24 @@
//| .. currentmodule:: displayio
//|
-//| :class:`ParallelBus` -- Manage updating a display over SPI four wire protocol
+//| :class:`ParallelBus` -- Manage updating a display over 8-bit parallel bus
//| ==============================================================================
//|
-//| Manage updating a display over SPI four wire protocol in the background while Python code runs.
-//| It doesn't handle display initialization.
+//| Manage updating a display over 8-bit parallel bus in the background while Python code runs. This
+//| protocol may be refered to as 8080-I Series Parallel Interface in datasheets. It doesn't handle
+//| display initialization.
//|
//| .. class:: ParallelBus(*, data0, command, chip_select, write, read, reset)
//|
//| Create a ParallelBus object associated with the given pins. The bus is inferred from data0
//| by implying the next 7 additional pins on a given GPIO port.
//|
-//| :param microcontroller.Pin: The first data pin. The rest are implied
+//| The parallel bus and pins are then in use by the display until `displayio.release_displays()`
+//| is called even after a reload. (It does this so CircuitPython can use the display after your
+//| code is done.) So, the first time you initialize a display bus in code.py you should call
+//| :py:func`displayio.release_displays` first, otherwise it will error after the first code.py run.
+//|
+//| :param microcontroller.Pin data0: The first data pin. The rest are implied
//| :param microcontroller.Pin command: Data or command pin
//| :param microcontroller.Pin chip_select: Chip select pin
//| :param microcontroller.Pin write: Write pin
diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c
index eeacd1918..6ba4914a0 100644
--- a/shared-bindings/displayio/TileGrid.c
+++ b/shared-bindings/displayio/TileGrid.c
@@ -31,6 +31,7 @@
#include "lib/utils/context_manager_helpers.h"
#include "py/binary.h"
#include "py/objproperty.h"
+#include "py/objtype.h"
#include "py/runtime.h"
#include "shared-bindings/displayio/Bitmap.h"
#include "shared-bindings/displayio/ColorConverter.h"
@@ -39,17 +40,6 @@
#include "shared-bindings/displayio/Shape.h"
#include "supervisor/shared/translate.h"
-static void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) {
- // TODO(tannewt): Support any value sequence such as bytearray or bytes.
- mp_obj_tuple_t *position = MP_OBJ_TO_PTR(position_obj);
- if (MP_OBJ_IS_TYPE(position_obj, &mp_type_tuple) && position->len == 2) {
- *x = mp_obj_get_int(position->items[0]);
- *y = mp_obj_get_int(position->items[1]);
- } else if (position != mp_const_none) {
- mp_raise_TypeError(translate("position must be 2-tuple"));
- }
-}
-
//| .. currentmodule:: displayio
//|
//| :class:`TileGrid` -- A grid of tiles sourced out of one bitmap
@@ -60,7 +50,7 @@ static void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) {
//|
//| A single tile grid is also known as a Sprite.
//|
-//| .. class:: TileGrid(bitmap, *, pixel_shader, position, width=1, height=1, tile_width=None, tile_height=None, default_tile=0)
+//| .. class:: TileGrid(bitmap, *, pixel_shader, width=1, height=1, tile_width=None, tile_height=None, default_tile=0, x=0, y=0)
//|
//| Create a TileGrid object. The bitmap is source for 2d pixels. The pixel_shader is used to
//| convert the value and its location to a display native pixel color. This may be a simple color
@@ -70,24 +60,26 @@ static void unpack_position(mp_obj_t position_obj, int16_t* x, int16_t* y) {
//|
//| :param displayio.Bitmap bitmap: The bitmap storing one or more tiles.
//| :param displayio.Palette pixel_shader: The pixel shader that produces colors from values
-//| :param tuple position: Upper left corner of the grid
//| :param int width: Width of the grid in tiles.
//| :param int height: Height of the grid in tiles.
//| :param int tile_width: Width of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions.
//| :param int tile_height: Height of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions.
-//| :param in default_tile: Default tile index to show.
+//| :param int default_tile: Default tile index to show.
+//| :param int x: Initial x position of the left edge within the parent.
+//| :param int y: Initial y position of the top edge within the parent.
//|
STATIC mp_obj_t displayio_tilegrid_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_bitmap, ARG_pixel_shader, ARG_position, ARG_width, ARG_height, ARG_tile_width, ARG_tile_height, ARG_default_tile };
+ enum { ARG_bitmap, ARG_pixel_shader, ARG_width, ARG_height, ARG_tile_width, ARG_tile_height, ARG_default_tile, ARG_x, ARG_y };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
- { MP_QSTR_position, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED },
{ MP_QSTR_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} },
{ MP_QSTR_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} },
{ MP_QSTR_tile_width, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
{ MP_QSTR_tile_height, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
{ MP_QSTR_default_tile, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} },
+ { 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);
@@ -112,7 +104,12 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_
bitmap_width = bmp->width;
bitmap_height = bmp->height;
} else {
- mp_raise_TypeError(translate("unsupported bitmap type"));
+ mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_bitmap);
+ }
+ mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj;
+ 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);
}
uint16_t tile_width = args[ARG_tile_width].u_int;
if (tile_width == 0) {
@@ -129,54 +126,150 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_
mp_raise_ValueError(translate("Tile height must exactly divide bitmap height"));
}
- int16_t x = 0;
- int16_t y = 0;
- mp_obj_t position_obj = args[ARG_position].u_obj;
- unpack_position(position_obj, &x, &y);
+ int16_t x = args[ARG_x].u_int;
+ int16_t y = args[ARG_y].u_int;
displayio_tilegrid_t *self = m_new_obj(displayio_tilegrid_t);
self->base.type = &displayio_tilegrid_type;
common_hal_displayio_tilegrid_construct(self, native, bitmap_width / tile_width,
- args[ARG_pixel_shader].u_obj, args[ARG_width].u_int, args[ARG_height].u_int,
+ pixel_shader, args[ARG_width].u_int, args[ARG_height].u_int,
tile_width, tile_height, x, y, args[ARG_default_tile].u_int);
return MP_OBJ_FROM_PTR(self);
}
-//| .. attribute:: position
+// Helper to ensure we have the native super class instead of a subclass.
+static displayio_tilegrid_t* native_tilegrid(mp_obj_t tilegrid_obj) {
+ mp_obj_t native_tilegrid = mp_instance_cast_to_native_base(tilegrid_obj, &displayio_tilegrid_type);
+ mp_obj_assert_native_inited(native_tilegrid);
+ return MP_OBJ_TO_PTR(native_tilegrid);
+}
+
+//| .. attribute:: x
//|
-//| The position of the top-left corner of the tilegrid.
+//| X position of the left edge in the parent.
//|
-STATIC mp_obj_t displayio_tilegrid_obj_get_position(mp_obj_t self_in) {
- displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in);
- int16_t x;
- int16_t y;
- common_hal_displayio_tilegrid_get_position(self, &x, &y);
+STATIC mp_obj_t displayio_tilegrid_obj_get_x(mp_obj_t self_in) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+ return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_x(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_x_obj, displayio_tilegrid_obj_get_x);
- mp_obj_t coords[2];
- coords[0] = mp_obj_new_int(x);
- coords[1] = mp_obj_new_int(y);
+STATIC mp_obj_t displayio_tilegrid_obj_set_x(mp_obj_t self_in, mp_obj_t x_obj) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
- return mp_obj_new_tuple(2, coords);
+ mp_int_t x = mp_obj_get_int(x_obj);
+ common_hal_displayio_tilegrid_set_x(self, x);
+ return mp_const_none;
}
-MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_position_obj, displayio_tilegrid_obj_get_position);
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_x_obj, displayio_tilegrid_obj_set_x);
-STATIC mp_obj_t displayio_tilegrid_obj_set_position(mp_obj_t self_in, mp_obj_t value) {
- displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in);
+const mp_obj_property_t displayio_tilegrid_x_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&displayio_tilegrid_get_x_obj,
+ (mp_obj_t)&displayio_tilegrid_set_x_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
- int16_t x = 0;
- int16_t y = 0;
- unpack_position(value, &x, &y);
+//| .. attribute:: y
+//|
+//| Y position of the top edge in the parent.
+//|
+STATIC mp_obj_t displayio_tilegrid_obj_get_y(mp_obj_t self_in) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+ return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_y(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_y_obj, displayio_tilegrid_obj_get_y);
- common_hal_displayio_tilegrid_set_position(self, x, y);
+STATIC mp_obj_t displayio_tilegrid_obj_set_y(mp_obj_t self_in, mp_obj_t y_obj) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+ mp_int_t y = mp_obj_get_int(y_obj);
+ common_hal_displayio_tilegrid_set_y(self, y);
return mp_const_none;
}
-MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_position_obj, displayio_tilegrid_obj_set_position);
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_y_obj, displayio_tilegrid_obj_set_y);
-const mp_obj_property_t displayio_tilegrid_position_obj = {
+const mp_obj_property_t displayio_tilegrid_y_obj = {
.base.type = &mp_type_property,
- .proxy = {(mp_obj_t)&displayio_tilegrid_get_position_obj,
- (mp_obj_t)&displayio_tilegrid_set_position_obj,
+ .proxy = {(mp_obj_t)&displayio_tilegrid_get_y_obj,
+ (mp_obj_t)&displayio_tilegrid_set_y_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+//| .. attribute:: flip_x
+//|
+//| If true, the left edge rendered will be the right edge of the right-most tile.
+//|
+STATIC mp_obj_t displayio_tilegrid_obj_get_flip_x(mp_obj_t self_in) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+ return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_x(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_flip_x_obj, displayio_tilegrid_obj_get_flip_x);
+
+STATIC mp_obj_t displayio_tilegrid_obj_set_flip_x(mp_obj_t self_in, mp_obj_t flip_x_obj) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+
+ common_hal_displayio_tilegrid_set_flip_x(self, mp_obj_is_true(flip_x_obj));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_flip_x_obj, displayio_tilegrid_obj_set_flip_x);
+
+const mp_obj_property_t displayio_tilegrid_flip_x_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&displayio_tilegrid_get_flip_x_obj,
+ (mp_obj_t)&displayio_tilegrid_set_flip_x_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+//| .. attribute:: flip_y
+//|
+//| If true, the top edge rendered will be the bottom edge of the bottom-most tile.
+//|
+STATIC mp_obj_t displayio_tilegrid_obj_get_flip_y(mp_obj_t self_in) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+ return mp_obj_new_bool(common_hal_displayio_tilegrid_get_flip_y(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_flip_y_obj, displayio_tilegrid_obj_get_flip_y);
+
+STATIC mp_obj_t displayio_tilegrid_obj_set_flip_y(mp_obj_t self_in, mp_obj_t flip_y_obj) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+
+ common_hal_displayio_tilegrid_set_flip_y(self, mp_obj_is_true(flip_y_obj));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_flip_y_obj, displayio_tilegrid_obj_set_flip_y);
+
+const mp_obj_property_t displayio_tilegrid_flip_y_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&displayio_tilegrid_get_flip_y_obj,
+ (mp_obj_t)&displayio_tilegrid_set_flip_y_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+
+//| .. attribute:: transpose_xy
+//|
+//| If true, the TileGrid's axis will be swapped. When combined with mirroring, any 90 degree
+//| rotation can be achieved along with the corresponding mirrored version.
+//|
+STATIC mp_obj_t displayio_tilegrid_obj_get_transpose_xy(mp_obj_t self_in) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+ return mp_obj_new_bool(common_hal_displayio_tilegrid_get_transpose_xy(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_transpose_xy_obj, displayio_tilegrid_obj_get_transpose_xy);
+
+STATIC mp_obj_t displayio_tilegrid_obj_set_transpose_xy(mp_obj_t self_in, mp_obj_t transpose_xy_obj) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+
+ common_hal_displayio_tilegrid_set_transpose_xy(self, mp_obj_is_true(transpose_xy_obj));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_set_transpose_xy_obj, displayio_tilegrid_obj_set_transpose_xy);
+
+const mp_obj_property_t displayio_tilegrid_transpose_xy_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&displayio_tilegrid_get_transpose_xy_obj,
+ (mp_obj_t)&displayio_tilegrid_set_transpose_xy_obj,
(mp_obj_t)&mp_const_none_obj},
};
@@ -185,13 +278,13 @@ const mp_obj_property_t displayio_tilegrid_position_obj = {
//| The pixel shader of the tilegrid.
//|
STATIC mp_obj_t displayio_tilegrid_obj_get_pixel_shader(mp_obj_t self_in) {
- displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
return common_hal_displayio_tilegrid_get_pixel_shader(self);
}
MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_pixel_shader_obj, displayio_tilegrid_obj_get_pixel_shader);
STATIC mp_obj_t displayio_tilegrid_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) {
- displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in);
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
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"));
}
@@ -209,9 +302,76 @@ const mp_obj_property_t displayio_tilegrid_pixel_shader_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+//| .. method:: __getitem__(index)
+//|
+//| Returns the tile index at the given index. The index can either be an x,y tuple or an int equal
+//| to ``y * width + x``.
+//|
+//| This allows you to::
+//|
+//| print(grid[0])
+//|
+//| .. method:: __setitem__(index, tile_index)
+//|
+//| Sets the tile index at the given index. The index can either be an x,y tuple or an int equal
+//| to ``y * width + x``.
+//|
+//| This allows you to::
+//|
+//| grid[0] = 10
+//|
+//| or::
+//|
+//| grid[0,0] = 10
+//|
+STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) {
+ displayio_tilegrid_t *self = native_tilegrid(self_in);
+
+
+ if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) {
+ mp_raise_NotImplementedError(translate("Slices not supported"));
+ } else {
+ uint16_t x = 0;
+ uint16_t y = 0;
+ if (MP_OBJ_IS_SMALL_INT(index_obj)) {
+ mp_int_t i = MP_OBJ_SMALL_INT_VALUE(index_obj);
+ uint16_t width = common_hal_displayio_tilegrid_get_width(self);
+ x = i % width;
+ y = i / width;
+ } else {
+ mp_obj_t* items;
+ mp_obj_get_array_fixed_n(index_obj, 2, &items);
+ x = mp_obj_get_int(items[0]);
+ y = mp_obj_get_int(items[1]);
+ }
+ if (x >= common_hal_displayio_tilegrid_get_width(self) ||
+ y >= common_hal_displayio_tilegrid_get_height(self)) {
+ mp_raise_IndexError(translate("tile index out of bounds"));
+ }
+
+ if (value_obj == MP_OBJ_SENTINEL) {
+ // load
+ return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_tilegrid_get_tile(self, x, y));
+ } else if (value_obj == mp_const_none) {
+ return MP_OBJ_NULL; // op not supported
+ } else {
+ mp_int_t value = mp_obj_get_int(value_obj);
+ if (value < 0 || value > 255) {
+ mp_raise_ValueError(translate("Tile indices must be 0 - 255"));
+ }
+ common_hal_displayio_tilegrid_set_tile(self, x, y, value);
+ }
+ }
+ return mp_const_none;
+}
+
STATIC const mp_rom_map_elem_t displayio_tilegrid_locals_dict_table[] = {
// Properties
- { MP_ROM_QSTR(MP_QSTR_position), MP_ROM_PTR(&displayio_tilegrid_position_obj) },
+ { MP_ROM_QSTR(MP_QSTR_x), MP_ROM_PTR(&displayio_tilegrid_x_obj) },
+ { MP_ROM_QSTR(MP_QSTR_y), MP_ROM_PTR(&displayio_tilegrid_y_obj) },
+ { MP_ROM_QSTR(MP_QSTR_flip_x), MP_ROM_PTR(&displayio_tilegrid_flip_x_obj) },
+ { MP_ROM_QSTR(MP_QSTR_flip_y), MP_ROM_PTR(&displayio_tilegrid_flip_y_obj) },
+ { MP_ROM_QSTR(MP_QSTR_transpose_xy), MP_ROM_PTR(&displayio_tilegrid_transpose_xy_obj) },
{ MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&displayio_tilegrid_pixel_shader_obj) },
};
STATIC MP_DEFINE_CONST_DICT(displayio_tilegrid_locals_dict, displayio_tilegrid_locals_dict_table);
@@ -220,5 +380,6 @@ const mp_obj_type_t displayio_tilegrid_type = {
{ &mp_type_type },
.name = MP_QSTR_TileGrid,
.make_new = displayio_tilegrid_make_new,
+ .subscr = tilegrid_subscr,
.locals_dict = (mp_obj_dict_t*)&displayio_tilegrid_locals_dict,
};
diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h
index 2260db413..1f9995a94 100644
--- a/shared-bindings/displayio/TileGrid.h
+++ b/shared-bindings/displayio/TileGrid.h
@@ -35,13 +35,28 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_
uint16_t bitmap_width_in_tiles, mp_obj_t pixel_shader, uint16_t width, uint16_t height,
uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile);
-void common_hal_displayio_tilegrid_get_position(displayio_tilegrid_t *self, int16_t* x, int16_t* y);
-void common_hal_displayio_tilegrid_set_position(displayio_tilegrid_t *self, int16_t x, int16_t y);
-
+mp_int_t common_hal_displayio_tilegrid_get_x(displayio_tilegrid_t *self);
+void common_hal_displayio_tilegrid_set_x(displayio_tilegrid_t *self, mp_int_t x);
+mp_int_t common_hal_displayio_tilegrid_get_y(displayio_tilegrid_t *self);
+void common_hal_displayio_tilegrid_set_y(displayio_tilegrid_t *self, mp_int_t y);
mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *self);
void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader);
-void common_hal_displayio_textgrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index);
-void common_hal_displayio_textgrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
+
+bool common_hal_displayio_tilegrid_get_flip_x(displayio_tilegrid_t *self);
+void common_hal_displayio_tilegrid_set_flip_x(displayio_tilegrid_t *self, bool flip_x);
+bool common_hal_displayio_tilegrid_get_flip_y(displayio_tilegrid_t *self);
+void common_hal_displayio_tilegrid_set_flip_y(displayio_tilegrid_t *self, bool flip_y);
+bool common_hal_displayio_tilegrid_get_transpose_xy(displayio_tilegrid_t *self);
+void common_hal_displayio_tilegrid_set_transpose_xy(displayio_tilegrid_t *self, bool transpose_xy);
+
+uint16_t common_hal_displayio_tilegrid_get_width(displayio_tilegrid_t *self);
+uint16_t common_hal_displayio_tilegrid_get_height(displayio_tilegrid_t *self);
+
+uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
+void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index);
+
+// Private API for scrolling the TileGrid.
+void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_TILEGRID_H
diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c
index 1ee755014..fd3dc4233 100644
--- a/shared-bindings/displayio/__init__.c
+++ b/shared-bindings/displayio/__init__.c
@@ -31,12 +31,11 @@
#include "shared-bindings/displayio/__init__.h"
#include "shared-bindings/displayio/Bitmap.h"
-#include "shared-bindings/displayio/BuiltinFont.h"
#include "shared-bindings/displayio/ColorConverter.h"
#include "shared-bindings/displayio/Display.h"
#include "shared-bindings/displayio/FourWire.h"
-#include "shared-bindings/displayio/Glyph.h"
#include "shared-bindings/displayio/Group.h"
+#include "shared-bindings/displayio/I2CDisplay.h"
#include "shared-bindings/displayio/OnDiskBitmap.h"
#include "shared-bindings/displayio/Palette.h"
#include "shared-bindings/displayio/ParallelBus.h"
@@ -59,28 +58,28 @@
//| :maxdepth: 3
//|
//| Bitmap
-//| BuiltinFont
//| ColorConverter
//| Display
//| FourWire
-//| Glyph
//| Group
+//| I2CDisplay
//| OnDiskBitmap
//| Palette
//| ParallelBus
//| Shape
//| TileGrid
//|
-//| All libraries change hardware state but are never deinit
-//|
-//| .. method:: release_displays()
+//| .. function:: release_displays()
//|
//| Releases any actively used displays so their busses and pins can be used again. This will also
//| release the builtin display on boards that have one. You will need to reinitialize it yourself
//| afterwards.
//|
+//| Use this once in your code.py if you initialize a display. Place it right before the
+//| initialization so the display is active as long as possible.
+//|
STATIC mp_obj_t displayio_release_displays(void) {
common_hal_displayio_release_displays();
return mp_const_none;
@@ -90,10 +89,8 @@ MP_DEFINE_CONST_FUN_OBJ_0(displayio_release_displays_obj, displayio_release_disp
STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) },
{ MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) },
- { MP_ROM_QSTR(MP_QSTR_BuiltinFont), MP_ROM_PTR(&displayio_builtinfont_type) },
{ MP_ROM_QSTR(MP_QSTR_ColorConverter), MP_ROM_PTR(&displayio_colorconverter_type) },
{ MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&displayio_display_type) },
- { MP_ROM_QSTR(MP_QSTR_Glyph), MP_ROM_PTR(&displayio_glyph_type) },
{ MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) },
{ MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) },
{ MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) },
@@ -101,6 +98,7 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_TileGrid), MP_ROM_PTR(&displayio_tilegrid_type) },
{ MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) },
+ { MP_ROM_QSTR(MP_QSTR_I2CDisplay), MP_ROM_PTR(&displayio_i2cdisplay_type) },
{ MP_ROM_QSTR(MP_QSTR_ParallelBus), MP_ROM_PTR(&displayio_parallelbus_type) },
{ MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) },
diff --git a/shared-bindings/displayio/BuiltinFont.c b/shared-bindings/fontio/BuiltinFont.c
index 55d38458e..74bc4d29e 100644
--- a/shared-bindings/displayio/BuiltinFont.c
+++ b/shared-bindings/fontio/BuiltinFont.c
@@ -24,7 +24,7 @@
* THE SOFTWARE.
*/
-#include "shared-bindings/displayio/BuiltinFont.h"
+#include "shared-bindings/fontio/BuiltinFont.h"
#include <stdint.h>
@@ -36,7 +36,7 @@
#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
-//| .. currentmodule:: displayio
+//| .. currentmodule:: fontio
//|
//| :class:`BuiltinFont` -- A font built into CircuitPython
//| =========================================================================================
@@ -56,15 +56,15 @@
//| `get_glyph` in most cases. This is useful for use with `displayio.TileGrid` and
//| `terminalio.Terminal`.
//|
-STATIC mp_obj_t displayio_builtinfont_obj_get_bitmap(mp_obj_t self_in) {
- displayio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in);
- return common_hal_displayio_builtinfont_get_bitmap(self);
+STATIC mp_obj_t fontio_builtinfont_obj_get_bitmap(mp_obj_t self_in) {
+ fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in);
+ return common_hal_fontio_builtinfont_get_bitmap(self);
}
-MP_DEFINE_CONST_FUN_OBJ_1(displayio_builtinfont_get_bitmap_obj, displayio_builtinfont_obj_get_bitmap);
+MP_DEFINE_CONST_FUN_OBJ_1(fontio_builtinfont_get_bitmap_obj, fontio_builtinfont_obj_get_bitmap);
-const mp_obj_property_t displayio_builtinfont_bitmap_obj = {
+const mp_obj_property_t fontio_builtinfont_bitmap_obj = {
.base.type = &mp_type_property,
- .proxy = {(mp_obj_t)&displayio_builtinfont_get_bitmap_obj,
+ .proxy = {(mp_obj_t)&fontio_builtinfont_get_bitmap_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj},
};
@@ -73,38 +73,38 @@ const mp_obj_property_t displayio_builtinfont_bitmap_obj = {
//|
//| Returns the maximum bounds of all glyphs in the font in a tuple of two values: width, height.
//|
-STATIC mp_obj_t displayio_builtinfont_obj_get_bounding_box(mp_obj_t self_in) {
- displayio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_obj_t fontio_builtinfont_obj_get_bounding_box(mp_obj_t self_in) {
+ fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in);
- return common_hal_displayio_builtinfont_get_bounding_box(self);
+ return common_hal_fontio_builtinfont_get_bounding_box(self);
}
-MP_DEFINE_CONST_FUN_OBJ_1(displayio_builtinfont_get_bounding_box_obj, displayio_builtinfont_obj_get_bounding_box);
+MP_DEFINE_CONST_FUN_OBJ_1(fontio_builtinfont_get_bounding_box_obj, fontio_builtinfont_obj_get_bounding_box);
//| .. method:: get_glyph(codepoint)
//|
-//| Returns a `displayio.Glyph` for the given codepoint or None if no glyph is available.
+//| Returns a `fontio.Glyph` for the given codepoint or None if no glyph is available.
//|
-STATIC mp_obj_t displayio_builtinfont_obj_get_glyph(mp_obj_t self_in, mp_obj_t codepoint_obj) {
- displayio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in);
+STATIC mp_obj_t fontio_builtinfont_obj_get_glyph(mp_obj_t self_in, mp_obj_t codepoint_obj) {
+ fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in);
mp_int_t codepoint;
if (!mp_obj_get_int_maybe(codepoint_obj, &codepoint)) {
mp_raise_ValueError_varg(translate("%q should be an int"), MP_QSTR_codepoint);
}
- return common_hal_displayio_builtinfont_get_glyph(self, codepoint);
+ return common_hal_fontio_builtinfont_get_glyph(self, codepoint);
}
-MP_DEFINE_CONST_FUN_OBJ_2(displayio_builtinfont_get_glyph_obj, displayio_builtinfont_obj_get_glyph);
+MP_DEFINE_CONST_FUN_OBJ_2(fontio_builtinfont_get_glyph_obj, fontio_builtinfont_obj_get_glyph);
-STATIC const mp_rom_map_elem_t displayio_builtinfont_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_bitmap), MP_ROM_PTR(&displayio_builtinfont_bitmap_obj) },
- { MP_ROM_QSTR(MP_QSTR_get_bounding_box), MP_ROM_PTR(&displayio_builtinfont_get_bounding_box_obj) },
- { MP_ROM_QSTR(MP_QSTR_get_glyph), MP_ROM_PTR(&displayio_builtinfont_get_glyph_obj) },
+STATIC const mp_rom_map_elem_t fontio_builtinfont_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_bitmap), MP_ROM_PTR(&fontio_builtinfont_bitmap_obj) },
+ { MP_ROM_QSTR(MP_QSTR_get_bounding_box), MP_ROM_PTR(&fontio_builtinfont_get_bounding_box_obj) },
+ { MP_ROM_QSTR(MP_QSTR_get_glyph), MP_ROM_PTR(&fontio_builtinfont_get_glyph_obj) },
};
-STATIC MP_DEFINE_CONST_DICT(displayio_builtinfont_locals_dict, displayio_builtinfont_locals_dict_table);
+STATIC MP_DEFINE_CONST_DICT(fontio_builtinfont_locals_dict, fontio_builtinfont_locals_dict_table);
-const mp_obj_type_t displayio_builtinfont_type = {
+const mp_obj_type_t fontio_builtinfont_type = {
{ &mp_type_type },
.name = MP_QSTR_BuiltinFont,
- .locals_dict = (mp_obj_dict_t*)&displayio_builtinfont_locals_dict,
+ .locals_dict = (mp_obj_dict_t*)&fontio_builtinfont_locals_dict,
};
diff --git a/shared-bindings/displayio/BuiltinFont.h b/shared-bindings/fontio/BuiltinFont.h
index 766013158..e87445e6b 100644
--- a/shared-bindings/displayio/BuiltinFont.h
+++ b/shared-bindings/fontio/BuiltinFont.h
@@ -24,15 +24,15 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_BUILTINFONT_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_BUILTINFONT_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_BUILTINFONT_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_BUILTINFONT_H
-#include "shared-module/displayio/BuiltinFont.h"
+#include "shared-module/fontio/BuiltinFont.h"
-extern const mp_obj_type_t displayio_builtinfont_type;
+extern const mp_obj_type_t fontio_builtinfont_type;
-mp_obj_t common_hal_displayio_builtinfont_get_bitmap(const displayio_builtinfont_t *self);
-mp_obj_t common_hal_displayio_builtinfont_get_bounding_box(const displayio_builtinfont_t *self);
-mp_obj_t common_hal_displayio_builtinfont_get_glyph(const displayio_builtinfont_t *self, mp_uint_t codepoint);
+mp_obj_t common_hal_fontio_builtinfont_get_bitmap(const fontio_builtinfont_t *self);
+mp_obj_t common_hal_fontio_builtinfont_get_bounding_box(const fontio_builtinfont_t *self);
+mp_obj_t common_hal_fontio_builtinfont_get_glyph(const fontio_builtinfont_t *self, mp_uint_t codepoint);
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_BUILTINFONT_H
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_BUILTINFONT_H
diff --git a/shared-bindings/displayio/Glyph.c b/shared-bindings/fontio/Glyph.c
index 1a4a75522..a23284152 100644
--- a/shared-bindings/displayio/Glyph.c
+++ b/shared-bindings/fontio/Glyph.c
@@ -24,11 +24,11 @@
* THE SOFTWARE.
*/
-#include "shared-bindings/displayio/Glyph.h"
+#include "shared-bindings/fontio/Glyph.h"
#include <stdint.h>
-//| .. currentmodule:: displayio
+//| .. currentmodule:: fontio
//|
//| :class:`Glyph` -- Storage of glyph info
//| ==========================================================================
@@ -46,7 +46,7 @@
//| :param int shift_x: the x difference to the next glyph
//| :param int shift_y: the y difference to the next glyph
//|
-const mp_obj_namedtuple_type_t displayio_glyph_type = {
+const mp_obj_namedtuple_type_t fontio_glyph_type = {
.base = {
.base = {
.type = &mp_type_type
diff --git a/shared-bindings/displayio/Glyph.h b/shared-bindings/fontio/Glyph.h
index d26a4b9e4..c58d812dd 100644
--- a/shared-bindings/displayio/Glyph.h
+++ b/shared-bindings/fontio/Glyph.h
@@ -24,11 +24,11 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_GLYPH_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_GLYPH_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_GLYPH_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_GLYPH_H
#include "py/objnamedtuple.h"
-extern const mp_obj_namedtuple_type_t displayio_glyph_type;
+extern const mp_obj_namedtuple_type_t fontio_glyph_type;
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO_GLYPH_H
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO_GLYPH_H
diff --git a/shared-bindings/fontio/__init__.c b/shared-bindings/fontio/__init__.c
new file mode 100644
index 000000000..cd0f5ab0f
--- /dev/null
+++ b/shared-bindings/fontio/__init__.c
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#include <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/fontio/__init__.h"
+#include "shared-bindings/fontio/BuiltinFont.h"
+#include "shared-bindings/fontio/Glyph.h"
+
+//| :mod:`fontio` --- Core font related data structures
+//| =========================================================================
+//|
+//| .. module:: fontio
+//| :synopsis: Core font related data structures
+//| :platform: SAMD21, SAMD51, nRF52
+//|
+//| The `fontio` module contains classes to store font related information.
+//|
+//| Libraries
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| BuiltinFont
+//| Glyph
+//|
+
+STATIC const mp_rom_map_elem_t fontio_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_fontio) },
+ { MP_ROM_QSTR(MP_QSTR_BuiltinFont), MP_ROM_PTR(&fontio_builtinfont_type) },
+ { MP_ROM_QSTR(MP_QSTR_Glyph), MP_ROM_PTR(&fontio_glyph_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(fontio_module_globals, fontio_module_globals_table);
+
+const mp_obj_module_t fontio_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&fontio_module_globals,
+};
diff --git a/shared-bindings/fontio/__init__.h b/shared-bindings/fontio/__init__.h
new file mode 100644
index 000000000..209919777
--- /dev/null
+++ b/shared-bindings/fontio/__init__.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 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.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO___INIT___H
+
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_FONTIO___INIT___H
diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c
index 908cb307d..e2b924c07 100644
--- a/shared-bindings/frequencyio/FrequencyIn.c
+++ b/shared-bindings/frequencyio/FrequencyIn.c
@@ -109,6 +109,12 @@ STATIC mp_obj_t frequencyio_frequencyin_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_deinit_obj, frequencyio_frequencyin_deinit);
+STATIC void check_for_deinit(frequencyio_frequencyin_obj_t *self) {
+ if (common_hal_frequencyio_frequencyin_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -133,7 +139,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(frequencyio_frequencyin___exit___obj,
//|
STATIC mp_obj_t frequencyio_frequencyin_obj_pause(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
common_hal_frequencyio_frequencyin_pause(self);
return mp_const_none;
@@ -146,7 +152,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_pause_obj, frequencyio_frequen
//|
STATIC mp_obj_t frequencyio_frequencyin_obj_resume(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
common_hal_frequencyio_frequencyin_resume(self);
return mp_const_none;
@@ -160,7 +166,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_resume_obj, frequencyio_freque
STATIC mp_obj_t frequencyio_frequencyin_obj_clear(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
common_hal_frequencyio_frequencyin_clear(self);
return mp_const_none;
@@ -178,7 +184,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_clear_obj, frequencyio_frequen
//|
STATIC mp_obj_t frequencyio_frequencyin_obj_get_capture_period(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_frequencyio_frequencyin_get_capture_period(self));
}
@@ -186,7 +192,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequency_get_capture_period_obj, frequenc
STATIC mp_obj_t frequencyio_frequencyin_obj_set_capture_period(mp_obj_t self_in, mp_obj_t capture_period) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
common_hal_frequencyio_frequencyin_set_capture_period(self, mp_obj_get_int(capture_period));
return mp_const_none;
@@ -206,7 +212,7 @@ const mp_obj_property_t frequencyio_frequencyin_capture_period_obj = {
//|
STATIC mp_obj_t frequencyio_frequencyin_obj_get_value(mp_obj_t self_in) {
frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_frequencyio_frequencyin_deinited(self));
+ check_for_deinit(self);
//return MP_OBJ_NEW_SMALL_INT(common_hal_frequencyio_frequencyin_get_item(self));
return mp_obj_new_int_from_float(common_hal_frequencyio_frequencyin_get_item(self));
diff --git a/shared-bindings/gamepad/GamePad.c b/shared-bindings/gamepad/GamePad.c
index 4458c972f..d3c29019a 100644
--- a/shared-bindings/gamepad/GamePad.c
+++ b/shared-bindings/gamepad/GamePad.c
@@ -23,17 +23,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
+#include "shared-bindings/gamepad/GamePad.h"
+
#include "py/obj.h"
#include "py/runtime.h"
#include "py/mphal.h"
#include "py/gc.h"
#include "py/mpstate.h"
-#include "shared-module/gamepad/__init__.h"
-#include "shared-module/gamepad/GamePad.h"
+#include "shared-bindings/gamepad/__init__.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
-#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
-#include "GamePad.h"
//| .. currentmodule:: gamepad
@@ -78,7 +77,8 @@
//| Initializes button scanning routines.
//|
//| The ``b1``-``b8`` parameters are ``DigitalInOut`` objects, which
-//| immediately get switched to input with a pull-up, and then scanned
+//| immediately get switched to input with a pull-up, (unless they already
+//| were set to pull-down, in which case they remain so), and then scanned
//| regularly for button presses. The order is the same as the order of
//| bits returned by the ``get_pressed`` function. You can re-initialize
//| it with different keys, then the new object will replace the previous
@@ -96,27 +96,24 @@
//|
STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args,
const mp_obj_t *args, mp_map_t *kw_args) {
- if (n_args > 8) {
- mp_raise_TypeError(translate("too many arguments"));
+ if (n_args > 8 || n_args == 0) {
+ mp_raise_TypeError(translate("argument num/types mismatch"));
}
for (size_t i = 0; i < n_args; ++i) {
- if (!MP_OBJ_IS_TYPE(args[i], &digitalio_digitalinout_type)) {
- mp_raise_TypeError(translate("expected a DigitalInOut"));
- }
- digitalio_digitalinout_obj_t *pin = MP_OBJ_TO_PTR(args[i]);
- raise_error_if_deinited(
- common_hal_digitalio_digitalinout_deinited(pin));
+ assert_digitalinout(args[i]);
}
- if (!MP_STATE_VM(gamepad_singleton)) {
- gamepad_obj_t* gamepad_singleton = m_new_obj(gamepad_obj_t);
+ gamepad_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton);
+ if (!gamepad_singleton ||
+ !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(gamepad_singleton), &gamepad_type)) {
+ gamepad_singleton = m_new_obj(gamepad_obj_t);
gamepad_singleton->base.type = &gamepad_type;
- MP_STATE_VM(gamepad_singleton) = gc_make_long_lived(gamepad_singleton);
+ gamepad_singleton = gc_make_long_lived(gamepad_singleton);
+ MP_STATE_VM(gamepad_singleton) = gamepad_singleton;
}
- gamepad_init(n_args, args);
- return MP_OBJ_FROM_PTR(MP_STATE_VM(gamepad_singleton));
+ common_hal_gamepad_gamepad_init(gamepad_singleton, args, n_args);
+ return MP_OBJ_FROM_PTR(gamepad_singleton);
}
-
//| .. method:: get_pressed()
//|
//| Get the status of buttons pressed since the last call and clear it.
@@ -129,9 +126,9 @@ STATIC mp_obj_t gamepad_make_new(const mp_obj_type_t *type, size_t n_args,
//|
STATIC mp_obj_t gamepad_get_pressed(mp_obj_t self_in) {
gamepad_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton);
- mp_obj_t gamepad = MP_OBJ_NEW_SMALL_INT(gamepad_singleton->pressed);
- gamepad_singleton->pressed = 0;
- return gamepad;
+ mp_obj_t pressed = MP_OBJ_NEW_SMALL_INT(gamepad_singleton->pressed);
+ gamepad_singleton->pressed = gamepad_singleton->last;
+ return pressed;
}
MP_DEFINE_CONST_FUN_OBJ_1(gamepad_get_pressed_obj, gamepad_get_pressed);
@@ -141,7 +138,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(gamepad_get_pressed_obj, gamepad_get_pressed);
//| Disable button scanning.
//|
STATIC mp_obj_t gamepad_deinit(mp_obj_t self_in) {
- gamepad_reset();
+ common_hal_gamepad_gamepad_deinit(self_in);
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(gamepad_deinit_obj, gamepad_deinit);
diff --git a/shared-bindings/gamepad/GamePad.h b/shared-bindings/gamepad/GamePad.h
index 172c95ace..3bbad4c97 100644
--- a/shared-bindings/gamepad/GamePad.h
+++ b/shared-bindings/gamepad/GamePad.h
@@ -28,6 +28,11 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD_GAMEPAD_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD_GAMEPAD_H
+#include "shared-module/gamepad/GamePad.h"
+
extern const mp_obj_type_t gamepad_type;
+void common_hal_gamepad_gamepad_init(gamepad_obj_t *gamepad, const mp_obj_t pins[], size_t n_pins);
+void common_hal_gamepad_gamepad_deinit(gamepad_obj_t *gamepad);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD_GAMEPAD_H
diff --git a/shared-bindings/gamepad/__init__.c b/shared-bindings/gamepad/__init__.c
index 0c99d0d52..cea0b4ee9 100644
--- a/shared-bindings/gamepad/__init__.c
+++ b/shared-bindings/gamepad/__init__.c
@@ -26,8 +26,8 @@
#include "py/obj.h"
#include "py/runtime.h"
#include "py/mphal.h"
-#include "GamePad.h"
-
+#include "shared-bindings/gamepad/GamePad.h"
+#include "shared-bindings/util.h"
//| :mod:`gamepad` --- Button handling
//| ==================================
diff --git a/shared-bindings/gamepad/__init__.h b/shared-bindings/gamepad/__init__.h
new file mode 100644
index 000000000..2ae5efb3a
--- /dev/null
+++ b/shared-bindings/gamepad/__init__.h
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Radomir Dopieralski 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.
+ */
+
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD___INIT___H
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPAD___INIT___H
diff --git a/shared-bindings/gamepadshift/GamePadShift.c b/shared-bindings/gamepadshift/GamePadShift.c
new file mode 100644
index 000000000..91203ad20
--- /dev/null
+++ b/shared-bindings/gamepadshift/GamePadShift.c
@@ -0,0 +1,123 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Radomir Dopieralski 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 "py/obj.h"
+#include "py/runtime.h"
+#include "py/mphal.h"
+#include "py/gc.h"
+#include "py/mpstate.h"
+#include "shared-bindings/gamepadshift/GamePadShift.h"
+#include "shared-bindings/gamepadshift/__init__.h"
+#include "supervisor/shared/translate.h"
+
+//| .. currentmodule:: gamepadshift
+//|
+//| :class:`GamePadShift` -- Scan buttons for presses through a shift register
+//| ===========================================================================
+//|
+//| .. class:: GamePadShift(clock, data, latch)
+//|
+//| Initializes button scanning routines.
+//|
+//| The ``clock``, ``data`` and ``latch`` parameters are ``DigitalInOut``
+//| objects connected to the shift register controlling the buttons.
+//|
+//| They button presses are accumulated, until the ``get_pressed`` method
+//| is called, at which point the button state is cleared, and the new
+//| button presses start to be recorded.
+//|
+//| Only one gamepad (`gamepad.GamePad` or `gamepadshift.GamePadShift`)
+//| may be used at a time.
+//|
+STATIC mp_obj_t gamepadshift_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_clock, ARG_data, ARG_latch };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ},
+ { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_latch, MP_ARG_REQUIRED | MP_ARG_OBJ},
+ };
+ 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);
+
+ digitalio_digitalinout_obj_t *clock_pin = assert_digitalinout(args[ARG_clock].u_obj);
+ digitalio_digitalinout_obj_t *data_pin = assert_digitalinout(args[ARG_data].u_obj);
+ digitalio_digitalinout_obj_t *latch_pin = assert_digitalinout(args[ARG_latch].u_obj);
+
+ gamepadshift_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton);
+ if (!gamepad_singleton ||
+ !MP_OBJ_IS_TYPE(MP_OBJ_FROM_PTR(gamepad_singleton),
+ &gamepadshift_type)) {
+ gamepad_singleton = m_new_obj(gamepadshift_obj_t);
+ gamepad_singleton->base.type = &gamepadshift_type;
+ gamepad_singleton = gc_make_long_lived(gamepad_singleton);
+ MP_STATE_VM(gamepad_singleton) = gamepad_singleton;
+ }
+ common_hal_gamepadshift_gamepadshift_init(gamepad_singleton, clock_pin, data_pin, latch_pin);
+ return MP_OBJ_FROM_PTR(gamepad_singleton);
+}
+
+//| .. method:: get_pressed()
+//|
+//| Get the status of buttons pressed since the last call and clear it.
+//|
+//| Returns an 8-bit number, with bits that correspond to buttons,
+//| which have been pressed (or held down) since the last call to this
+//| function set to 1, and the remaining bits set to 0. Then it clears
+//| the button state, so that new button presses (or buttons that are
+//| held down) can be recorded for the next call.
+//|
+STATIC mp_obj_t gamepadshift_get_pressed(mp_obj_t self_in) {
+ gamepadshift_obj_t* gamepad_singleton = MP_STATE_VM(gamepad_singleton);
+ mp_obj_t pressed = MP_OBJ_NEW_SMALL_INT(gamepad_singleton->pressed);
+ gamepad_singleton->pressed = gamepad_singleton->last;
+ return pressed;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(gamepadshift_get_pressed_obj, gamepadshift_get_pressed);
+
+//| .. method:: deinit()
+//|
+//| Disable button scanning.
+//|
+STATIC mp_obj_t gamepadshift_deinit(mp_obj_t self_in) {
+ common_hal_gamepadshift_gamepadshift_deinit(self_in);
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(gamepadshift_deinit_obj, gamepadshift_deinit);
+
+
+STATIC const mp_rom_map_elem_t gamepadshift_locals_dict_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR_get_pressed), MP_ROM_PTR(&gamepadshift_get_pressed_obj)},
+ { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gamepadshift_deinit_obj)},
+};
+STATIC MP_DEFINE_CONST_DICT(gamepadshift_locals_dict, gamepadshift_locals_dict_table);
+const mp_obj_type_t gamepadshift_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_GamePadShift,
+ .make_new = gamepadshift_make_new,
+ .locals_dict = (mp_obj_dict_t*)&gamepadshift_locals_dict,
+};
diff --git a/shared-bindings/gamepadshift/GamePadShift.h b/shared-bindings/gamepadshift/GamePadShift.h
new file mode 100644
index 000000000..3e8ea9693
--- /dev/null
+++ b/shared-bindings/gamepadshift/GamePadShift.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Radomir Dopieralski 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.
+ */
+
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT_GAMEPADSHIFT_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT_GAMEPADSHIFT_H
+
+#include "shared-module/gamepadshift/GamePadShift.h"
+
+extern const mp_obj_type_t gamepadshift_type;
+
+void common_hal_gamepadshift_gamepadshift_init(gamepadshift_obj_t *gamepadshift,
+ digitalio_digitalinout_obj_t *clock_pin,
+ digitalio_digitalinout_obj_t *data_pin,
+ digitalio_digitalinout_obj_t *latch_pin);
+
+void common_hal_gamepadshift_gamepadshift_deinit(gamepadshift_obj_t *gamepadshift);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT_GAMEPADSHIFT_H
diff --git a/shared-bindings/gamepadshift/__init__.c b/shared-bindings/gamepadshift/__init__.c
new file mode 100644
index 000000000..2d3667726
--- /dev/null
+++ b/shared-bindings/gamepadshift/__init__.c
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Radomir Dopieralski 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 "py/obj.h"
+#include "py/runtime.h"
+#include "py/mphal.h"
+#include "shared-bindings/gamepadshift/GamePadShift.h"
+#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/util.h"
+
+//| :mod:`gamepadshift` --- Tracks button presses read through a shift register
+//| ===========================================================================
+//|
+//| .. module:: gamepadshift
+//| :synopsis: Tracks button presses read through a shift register
+//| :platform: SAMD21, SAMD51
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| GamePadShift
+//|
+STATIC const mp_rom_map_elem_t gamepadshift_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gamepadshift) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_GamePadShift), MP_ROM_PTR(&gamepadshift_type)},
+};
+STATIC MP_DEFINE_CONST_DICT(gamepadshift_module_globals, gamepadshift_module_globals_table);
+
+const mp_obj_module_t gamepadshift_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&gamepadshift_module_globals,
+};
diff --git a/shared-bindings/bleio/Broadcaster.h b/shared-bindings/gamepadshift/__init__.h
index 8aa125af9..4b4be756a 100644
--- a/shared-bindings/bleio/Broadcaster.h
+++ b/shared-bindings/gamepadshift/__init__.h
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Radomir Dopieralski 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
@@ -24,15 +24,8 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H
-#include "common-hal/bleio/Broadcaster.h"
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT___INIT___H
-extern const mp_obj_type_t bleio_broadcaster_type;
-
-extern void common_hal_bleio_broadcaster_construct(bleio_broadcaster_obj_t *self, mp_float_t interval);
-extern void common_hal_bleio_broadcaster_start_advertising(bleio_broadcaster_obj_t *self, mp_buffer_info_t *data);
-extern void common_hal_bleio_broadcaster_stop_advertising(bleio_broadcaster_obj_t *self);
-
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_BROADCASTER_H
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_GAMEPADSHIFT___INIT___H
diff --git a/shared-bindings/help.c b/shared-bindings/help.c
index e0770ff3c..4e7c3a78b 100644
--- a/shared-bindings/help.c
+++ b/shared-bindings/help.c
@@ -27,7 +27,7 @@
//| :func:`help` - Built-in method to provide helpful information
//| ==============================================================
//|
-//| .. method:: help(object=None)
+//| .. function:: help(object=None)
//|
//| Prints a help method about the given object. When ``object`` is none,
//| prints general port information.
diff --git a/shared-bindings/i2cslave/I2CSlave.c b/shared-bindings/i2cslave/I2CSlave.c
index 090a53581..2598accbb 100644
--- a/shared-bindings/i2cslave/I2CSlave.c
+++ b/shared-bindings/i2cslave/I2CSlave.c
@@ -150,7 +150,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cslave_i2c_slave___exit___obj, 4, 4
STATIC mp_obj_t i2cslave_i2c_slave_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mp_check_self(MP_OBJ_IS_TYPE(pos_args[0], &i2cslave_i2c_slave_type));
i2cslave_i2c_slave_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_i2cslave_i2c_slave_deinited(self));
+ if(common_hal_i2cslave_i2c_slave_deinited(self)) {
+ raise_deinited_error();
+ }
enum { ARG_timeout };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} },
diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst
index 4f2e28702..cbffdb614 100644
--- a/shared-bindings/index.rst
+++ b/shared-bindings/index.rst
@@ -1,11 +1,11 @@
Core Modules
========================================
-These core modules are intended on being consistent across ports. Currently
-they are only implemented in the SAMD21 and ESP8266 ports. A module may not exist
-in a port if no underlying hardware support is present or if flash space is
-limited. For example, a microcontroller without analog features will not have
-`analogio`.
+These core modules are intended on being consistent across ports and boards.
+A module may not exist on a port/board if no underlying hardware support is
+present or if flash space is limited. For example, a microcontroller without
+analog features will not have `analogio`. See the `support_matrix` page for
+a list of modules supported on each board.
Modules
---------
@@ -14,54 +14,6 @@ Modules
:glob:
:maxdepth: 3
+ support_matrix
*/__init__
help
-
-.. _module-support-matrix:
-
-Support Matrix
----------------
-NOTE 1: **All Supported** means the following ports are supported: SAMD21, SAMD21 Express,
-SAMD51, SAMD51 Express, and ESP8266.
-
-NOTE 2: **SAMD** and/or **SAMD Express** without additional numbers, means both SAMD21 & SAMD51 versions
-are supported.
-
-NOTE 3: The `pIRkey SAMD21 board <https://www.adafruit.com/product/3364>`_ is specialized and may not
-have modules as listed below.
-
-================= ==============================
-Module Supported Ports
-================= ==============================
-`analogio` **All Supported**
-`audiobusio` **SAMD/SAMD Express**
-`audioio` **SAMD Express**
-`binascii` **ESP8266**
-`bitbangio` **SAMD Express, ESP8266**
-`board` **All Supported**
-`bleio` **nRF**
-`busio` **All Supported**
-`digitalio` **All Supported**
-`frequencyio` **SAMD51**
-`gamepad` **SAMD Express, nRF**
-`hashlib` **ESP8266**
-`i2cslave` **SAMD Express**
-`math` **All Supported**
-`microcontroller` **All Supported**
-`multiterminal` **ESP8266**
-`neopixel_write` **All Supported**
-`nvm` **SAMD Express**
-`os` **All Supported**
-`pulseio` **SAMD/SAMD Express**
-`random` **All Supported**
-`rotaryio` **SAMD51, SAMD Express**
-`storage` **All Supported**
-`struct` **All Supported**
-`supervisor` **SAMD/SAMD Express**
-`time` **All Supported**
-`touchio` **SAMD/SAMD Express**
-`uheap` **Debug (All)**
-`usb_hid` **SAMD/SAMD Express**
-`_pixelbuf` **SAMD Express**
-`_stage` **SAMD/SAMD Express**
-================= ==============================
diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c
index e79663107..3635f0afb 100644
--- a/shared-bindings/microcontroller/Pin.c
+++ b/shared-bindings/microcontroller/Pin.c
@@ -40,7 +40,7 @@
//|
//| Identifies an IO pin on the microcontroller.
//|
-//| .. class:: Pin
+//| .. class:: Pin()
//|
//| Identifies an IO pin on the microcontroller. They are fixed by the
//| hardware so they cannot be constructed on demand. Instead, use
diff --git a/shared-bindings/microcontroller/RunMode.c b/shared-bindings/microcontroller/RunMode.c
index 7c3f84fca..913242ad2 100644
--- a/shared-bindings/microcontroller/RunMode.c
+++ b/shared-bindings/microcontroller/RunMode.c
@@ -31,24 +31,30 @@
//| :class:`RunMode` -- run state of the microcontroller
//| =============================================================
//|
-//| .. class:: microcontroller.RunMode
+//| .. class:: RunMode()
//|
//| Enum-like class to define the run mode of the microcontroller and
//| CircuitPython.
//|
-//| .. data:: NORMAL
+//| .. attribute:: NORMAL
//|
//| Run CircuitPython as normal.
//|
-//| .. data:: SAFE_MODE
+//| :type microcontroller.RunMode:
+//|
+//| .. attribute:: SAFE_MODE
//|
//| Run CircuitPython in safe mode. User code will not be run and the
//| file system will be writeable over USB.
//|
-//| .. data:: BOOTLOADER
+//| :type microcontroller.RunMode:
+//|
+//| .. attribute:: BOOTLOADER
//|
//| Run the bootloader.
//|
+//| :type microcontroller.RunMode:
+//|
const mp_obj_type_t mcu_runmode_type;
const mcu_runmode_obj_t mcu_runmode_normal_obj = {
diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c
index da8d0bd94..090c4564d 100644
--- a/shared-bindings/microcontroller/__init__.c
+++ b/shared-bindings/microcontroller/__init__.c
@@ -62,14 +62,14 @@
//| RunMode
//|
-//| .. attribute:: cpu
+//| .. data:: cpu
//|
//| CPU information and control, such as ``cpu.temperature`` and ``cpu.frequency``
//| (clock frequency).
//| This object is the sole instance of `microcontroller.Processor`.
//|
-//| .. method:: delay_us(delay)
+//| .. function:: delay_us(delay)
//|
//| Dedicated delay method used for very short delays. **Do not** do long delays
//| because this stops all other functions from completing. Think of this as an empty
@@ -87,7 +87,7 @@ STATIC mp_obj_t mcu_delay_us(mp_obj_t delay_obj) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mcu_delay_us_obj, mcu_delay_us);
-//| .. method:: disable_interrupts()
+//| .. function:: disable_interrupts()
//|
//| Disable all interrupts. Be very careful, this can stall everything.
//|
@@ -97,7 +97,7 @@ STATIC mp_obj_t mcu_disable_interrupts(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_disable_interrupts_obj, mcu_disable_interrupts);
-//| .. method:: enable_interrupts()
+//| .. function:: enable_interrupts()
//|
//| Enable the interrupts that were enabled at the last disable.
//|
@@ -107,7 +107,7 @@ STATIC mp_obj_t mcu_enable_interrupts(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_enable_interrupts_obj, mcu_enable_interrupts);
-//| .. method:: on_next_reset(run_mode)
+//| .. function:: on_next_reset(run_mode)
//|
//| Configure the run mode used the next time the microcontroller is reset but
//| not powered down.
@@ -132,7 +132,7 @@ STATIC mp_obj_t mcu_on_next_reset(mp_obj_t run_mode_obj) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mcu_on_next_reset_obj, mcu_on_next_reset);
-//| .. method:: reset()
+//| .. function:: reset()
//|
//| Reset the microcontroller. After reset, the microcontroller will enter the
//| run mode last set by `on_next_reset`.
@@ -148,11 +148,13 @@ STATIC mp_obj_t mcu_reset(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mcu_reset_obj, mcu_reset);
-//| .. attribute:: nvm
+//| .. data:: nvm
//|
//| Available non-volatile memory.
//| This object is the sole instance of `nvm.ByteArray` when available or ``None`` otherwise.
//|
+//| :type: nvm.ByteArray or None
+//|
//| :mod:`microcontroller.pin` --- Microcontroller pin names
//| --------------------------------------------------------
diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c
index 05d6fd97a..1ee66337b 100644
--- a/shared-bindings/neopixel_write/__init__.c
+++ b/shared-bindings/neopixel_write/__init__.c
@@ -55,11 +55,11 @@
//| pixel_off = bytearray([0, 0, 0])
//| neopixel_write.neopixel_write(pin, pixel_off)
//|
-//| .. method:: neopixel_write.neopixel_write(digitalinout, buf)
+//| .. function:: neopixel_write(digitalinout, buf)
//|
//| Write buf out on the given DigitalInOut.
//|
-//| :param ~digitalio.DigitalInOut gpio: the DigitalInOut to output with
+//| :param ~digitalio.DigitalInOut digitalinout: the DigitalInOut to output with
//| :param bytearray buf: The bytes to clock out. No assumption is made about color order
//|
STATIC mp_obj_t neopixel_write_neopixel_write_(mp_obj_t digitalinout_obj, mp_obj_t buf) {
diff --git a/shared-bindings/network/__init__.c b/shared-bindings/network/__init__.c
index 1067ea549..01763a73c 100644
--- a/shared-bindings/network/__init__.c
+++ b/shared-bindings/network/__init__.c
@@ -49,7 +49,7 @@
//| It is used by the 'socket' module to look up a suitable
//| NIC when a socket is created.
//|
-//| .. function:: route
+//| .. function:: route()
//|
//| Returns a list of all configured NICs.
//|
diff --git a/shared-bindings/nvm/ByteArray.c b/shared-bindings/nvm/ByteArray.c
index 22cd838b1..31bedeacc 100644
--- a/shared-bindings/nvm/ByteArray.c
+++ b/shared-bindings/nvm/ByteArray.c
@@ -124,7 +124,8 @@ STATIC mp_obj_t nvm_bytearray_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj
#endif
} else {
// Single index rather than slice.
- size_t index = mp_get_index(self->base.type, self->len, index_in, false);
+ size_t index = mp_get_index(self->base.type, common_hal_nvm_bytearray_get_length(self),
+ index_in, false);
if (value == MP_OBJ_SENTINEL) {
// load
uint8_t value_out;
diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c
new file mode 100644
index 000000000..fb5c24b85
--- /dev/null
+++ b/shared-bindings/ps2io/Ps2.c
@@ -0,0 +1,243 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * 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 <stdint.h>
+
+#include "lib/utils/context_manager_helpers.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "py/runtime0.h"
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/ps2io/Ps2.h"
+#include "shared-bindings/util.h"
+#include "supervisor/shared/translate.h"
+
+//| .. currentmodule:: ps2io
+//|
+//| :class:`Ps2` -- Communicate with a PS/2 keyboard or mouse
+//| =========================================================
+//|
+//| Ps2 implements the PS/2 keyboard/mouse serial protocol, used in
+//| legacy devices. It is similar to UART but there are only two
+//| lines (Data and Clock). PS/2 devices are 5V, so bidirectional
+//| level converters must be used to connect the I/O lines to pins
+//| of 3.3V boards.
+//|
+//| .. class:: Ps2(data_pin, clock_pin)
+//|
+//| Create a Ps2 object associated with the given pins.
+//|
+//| :param ~microcontroller.Pin data_pin: Pin tied to data wire.
+//| :param ~microcontroller.Pin clock_pin: Pin tied to clock wire.
+//| This pin must support interrupts.
+//|
+//| Read one byte from PS/2 keyboard and turn on Scroll Lock LED::
+//|
+//| import ps2io
+//| import board
+//|
+//| kbd = ps2io.Ps2(board.D10, board.D11)
+//|
+//| while len(kbd) == 0:
+//| pass
+//|
+//| print(kbd.popleft())
+//| print(kbd.sendcmd(0xed))
+//| print(kbd.sendcmd(0x01))
+//|
+STATIC mp_obj_t ps2io_ps2_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_datapin, ARG_clkpin };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_datapin, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_clkpin, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ };
+ 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);
+ assert_pin(args[ARG_clkpin].u_obj, false);
+ assert_pin(args[ARG_datapin].u_obj, false);
+ const mcu_pin_obj_t* clkpin = MP_OBJ_TO_PTR(args[ARG_clkpin].u_obj);
+ assert_pin_free(clkpin);
+ const mcu_pin_obj_t* datapin = MP_OBJ_TO_PTR(args[ARG_datapin].u_obj);
+ assert_pin_free(datapin);
+
+ ps2io_ps2_obj_t *self = m_new_obj(ps2io_ps2_obj_t);
+ self->base.type = &ps2io_ps2_type;
+
+ common_hal_ps2io_ps2_construct(self, datapin, clkpin);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+//| .. method:: deinit()
+//|
+//| Deinitialises the Ps2 and releases any hardware resources for reuse.
+//|
+STATIC mp_obj_t ps2io_ps2_deinit(mp_obj_t self_in) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ common_hal_ps2io_ps2_deinit(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_deinit_obj, ps2io_ps2_deinit);
+
+STATIC void check_for_deinit(ps2io_ps2_obj_t *self) {
+ if (common_hal_ps2io_ps2_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: __enter__()
+//|
+//| No-op used by Context Managers.
+//|
+// Provided by context manager helper.
+
+//| .. method:: __exit__()
+//|
+//| Automatically deinitializes the hardware when exiting a context. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+STATIC mp_obj_t ps2io_ps2_obj___exit__(size_t n_args, const mp_obj_t *args) {
+ (void)n_args;
+ common_hal_ps2io_ps2_deinit(args[0]);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ps2io_ps2___exit___obj, 4, 4, ps2io_ps2_obj___exit__);
+
+//| .. method:: popleft()
+//|
+//| Removes and returns the oldest received byte. When buffer
+//| is empty, raises an IndexError exception.
+//|
+STATIC mp_obj_t ps2io_ps2_obj_popleft(mp_obj_t self_in) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+
+ int b = common_hal_ps2io_ps2_popleft(self);
+ if (b < 0) {
+ mp_raise_IndexError(translate("Pop from an empty Ps2 buffer"));
+ }
+ return MP_OBJ_NEW_SMALL_INT(b);
+}
+MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_popleft_obj, ps2io_ps2_obj_popleft);
+
+//| .. method:: sendcmd(byte)
+//|
+//| Sends a command byte to PS/2. Returns the response byte, typically
+//| the general ack value (0xFA). Some commands return additional data
+//| which is available through :py:func:`popleft()`.
+//|
+//| Raises a RuntimeError in case of failure. The root cause can be found
+//| by calling :py:func:`clear_errors()`. It is advisable to call
+//| :py:func:`clear_errors()` before :py:func:`sendcmd()` to flush any
+//| previous errors.
+//|
+//| :param int byte: byte value of the command
+//|
+STATIC mp_obj_t ps2io_ps2_obj_sendcmd(mp_obj_t self_in, mp_obj_t ob) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ mp_int_t cmd = mp_obj_get_int(ob) & 0xff;
+ int resp = common_hal_ps2io_ps2_sendcmd(self, cmd);
+ if (resp < 0) {
+ mp_raise_RuntimeError(translate("Failed sending command."));
+ }
+ return MP_OBJ_NEW_SMALL_INT(resp);
+}
+MP_DEFINE_CONST_FUN_OBJ_2(ps2io_ps2_sendcmd_obj, ps2io_ps2_obj_sendcmd);
+
+//| .. method:: clear_errors()
+//|
+//| Returns and clears a bitmap with latest recorded communication errors.
+//|
+//| Reception errors (arise asynchronously, as data is received):
+//|
+//| 0x01: start bit not 0
+//|
+//| 0x02: timeout
+//|
+//| 0x04: parity bit error
+//|
+//| 0x08: stop bit not 1
+//|
+//| 0x10: buffer overflow, newest data discarded
+//|
+//| Transmission errors (can only arise in the course of sendcmd()):
+//|
+//| 0x100: clock pin didn't go to LO in time
+//|
+//| 0x200: clock pin didn't go to HI in time
+//|
+//| 0x400: data pin didn't ACK
+//|
+//| 0x800: clock pin didn't ACK
+//|
+//| 0x1000: device didn't respond to RTS
+//|
+//| 0x2000: device didn't send a response byte in time
+//|
+STATIC mp_obj_t ps2io_ps2_obj_clear_errors(mp_obj_t self_in) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+
+ return MP_OBJ_NEW_SMALL_INT(common_hal_ps2io_ps2_clear_errors(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_clear_errors_obj, ps2io_ps2_obj_clear_errors);
+
+//| .. method:: __len__()
+//|
+//| Returns the number of received bytes in buffer, available
+//| to :py:func:`popleft()`.
+//|
+STATIC mp_obj_t ps2_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
+ ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+ uint16_t len = common_hal_ps2io_ps2_get_len(self);
+ switch (op) {
+ case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0);
+ case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len);
+ default: return MP_OBJ_NULL; // op not supported
+ }
+}
+
+STATIC const mp_rom_map_elem_t ps2io_ps2_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&ps2io_ps2_deinit_obj) },
+ { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
+ { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&ps2io_ps2___exit___obj) },
+ { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&ps2io_ps2_popleft_obj) },
+ { MP_ROM_QSTR(MP_QSTR_sendcmd), MP_ROM_PTR(&ps2io_ps2_sendcmd_obj) },
+ { MP_ROM_QSTR(MP_QSTR_clear_errors), MP_ROM_PTR(&ps2io_ps2_clear_errors_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(ps2io_ps2_locals_dict, ps2io_ps2_locals_dict_table);
+
+const mp_obj_type_t ps2io_ps2_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Ps2,
+ .make_new = ps2io_ps2_make_new,
+ .unary_op = ps2_unary_op,
+ .locals_dict = (mp_obj_dict_t*)&ps2io_ps2_locals_dict,
+};
diff --git a/shared-bindings/ps2io/Ps2.h b/shared-bindings/ps2io/Ps2.h
new file mode 100644
index 000000000..523869d55
--- /dev/null
+++ b/shared-bindings/ps2io/Ps2.h
@@ -0,0 +1,45 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * 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_BINDINGS_PS2IO_PS2_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H
+
+#include "common-hal/microcontroller/Pin.h"
+#include "common-hal/ps2io/Ps2.h"
+
+extern const mp_obj_type_t ps2io_ps2_type;
+
+extern void common_hal_ps2io_ps2_construct(ps2io_ps2_obj_t* self,
+ const mcu_pin_obj_t* data_pin, const mcu_pin_obj_t* clk_pin);
+extern void common_hal_ps2io_ps2_deinit(ps2io_ps2_obj_t* self);
+extern bool common_hal_ps2io_ps2_deinited(ps2io_ps2_obj_t* self);
+extern uint16_t common_hal_ps2io_ps2_get_len(ps2io_ps2_obj_t* self);
+extern int16_t common_hal_ps2io_ps2_popleft(ps2io_ps2_obj_t* self);
+extern int16_t common_hal_ps2io_ps2_sendcmd(ps2io_ps2_obj_t* self, uint8_t b);
+extern uint16_t common_hal_ps2io_ps2_clear_errors(ps2io_ps2_obj_t* self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO_PS2_H
diff --git a/shared-bindings/ps2io/__init__.c b/shared-bindings/ps2io/__init__.c
new file mode 100644
index 000000000..ec7c43e51
--- /dev/null
+++ b/shared-bindings/ps2io/__init__.c
@@ -0,0 +1,73 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * 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 <stdint.h>
+
+#include "py/obj.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/microcontroller/Pin.h"
+#include "shared-bindings/ps2io/Ps2.h"
+
+//| :mod:`ps2io` --- Support for PS/2 protocol
+//| =====================================================
+//|
+//| .. module:: ps2io
+//| :synopsis: Support for PS/2 based devices
+//| :platform: SAMD21
+//|
+//| The `ps2io` module contains classes to provide PS/2 communication.
+//|
+//| Libraries
+//|
+//| .. toctree::
+//| :maxdepth: 3
+//|
+//| Ps2
+//|
+
+//| .. warning:: This module is not available in some SAMD21 builds. See the
+//| :ref:`module-support-matrix` for more info.
+//|
+
+//| All classes change hardware state and should be deinitialized when they
+//| are no longer needed if the program continues after use. To do so, either
+//| call :py:meth:`!deinit` or use a context manager. See
+//| :ref:`lifetime-and-contextmanagers` for more info.
+//|
+
+STATIC const mp_rom_map_elem_t ps2io_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ps2io) },
+ { MP_ROM_QSTR(MP_QSTR_Ps2), MP_ROM_PTR(&ps2io_ps2_type) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(ps2io_module_globals, ps2io_module_globals_table);
+
+const mp_obj_module_t ps2io_module = {
+ .base = { &mp_type_module },
+ .globals = (mp_obj_dict_t*)&ps2io_module_globals,
+};
diff --git a/shared-bindings/ps2io/__init__.h b/shared-bindings/ps2io/__init__.h
new file mode 100644
index 000000000..1ff3d97b5
--- /dev/null
+++ b/shared-bindings/ps2io/__init__.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Scott Shawcroft
+ * Copyright (c) 2019 Elvis Pfutzenreuter <epxx@epxx.co>
+ *
+ * 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_BINDINGS_PS2IO___INIT___H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H
+
+#include "py/obj.h"
+
+// Nothing now.
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_PS2IO___INIT___H
diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c
index bba5fe883..40981e0a8 100644
--- a/shared-bindings/pulseio/PWMOut.c
+++ b/shared-bindings/pulseio/PWMOut.c
@@ -42,7 +42,7 @@
//|
//| PWMOut can be used to output a PWM signal on a given pin.
//|
-//| .. class:: PWMOut(pin, \*, duty_cycle=0, frequency=500, variable_frequency=False)
+//| .. class:: PWMOut(pin, *, duty_cycle=0, frequency=500, variable_frequency=False)
//|
//| Create a PWM object associated with the given pin. This allows you to
//| write PWM signals out on the given pin. Frequency is fixed after init
@@ -103,7 +103,7 @@ STATIC mp_obj_t pulseio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args
uint16_t duty_cycle = parsed_args[ARG_duty_cycle].u_int;
uint32_t frequency = parsed_args[ARG_frequency].u_int;
- bool variable_frequency = parsed_args[ARG_variable_frequency].u_int;
+ bool variable_frequency = parsed_args[ARG_variable_frequency].u_bool;
// create PWM object from the given pin
pulseio_pwmout_obj_t *self = m_new_obj(pulseio_pwmout_obj_t);
@@ -133,6 +133,12 @@ STATIC mp_obj_t pulseio_pwmout_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_deinit_obj, pulseio_pwmout_deinit);
+STATIC void check_for_deinit(pulseio_pwmout_obj_t *self) {
+ if (common_hal_pulseio_pwmout_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -158,14 +164,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pwmout___exit___obj, 4, 4, pu
//| be half high and then half low.
STATIC mp_obj_t pulseio_pwmout_obj_get_duty_cycle(mp_obj_t self_in) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_duty_cycle(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_duty_cycle_obj, pulseio_pwmout_obj_get_duty_cycle);
STATIC mp_obj_t pulseio_pwmout_obj_set_duty_cycle(mp_obj_t self_in, mp_obj_t duty_cycle) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self));
+ check_for_deinit(self);
mp_int_t duty = mp_obj_get_int(duty_cycle);
if (duty < 0 || duty > 0xffff) {
mp_raise_ValueError(translate("PWM duty_cycle must be between 0 and 65535 inclusive (16 bit resolution)"));
@@ -189,14 +195,14 @@ const mp_obj_property_t pulseio_pwmout_duty_cycle_obj = {
//|
STATIC mp_obj_t pulseio_pwmout_obj_get_frequency(mp_obj_t self_in) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_frequency(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_frequency_obj, pulseio_pwmout_obj_get_frequency);
STATIC mp_obj_t pulseio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t frequency) {
pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pwmout_deinited(self));
+ check_for_deinit(self);
if (!common_hal_pulseio_pwmout_get_variable_frequency(self)) {
mp_raise_AttributeError(translate(
"PWM frequency not writable when variable_frequency is False on "
diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c
index 426ac4384..8b69109f0 100644
--- a/shared-bindings/pulseio/PulseIn.c
+++ b/shared-bindings/pulseio/PulseIn.c
@@ -45,7 +45,7 @@
//| The pulsed signal consists of timed active and idle periods. Unlike PWM,
//| there is no set duration for active and idle pairs.
//|
-//| .. class:: PulseIn(pin, maxlen=2, \*, idle_state=False)
+//| .. class:: PulseIn(pin, maxlen=2, *, idle_state=False)
//|
//| Create a PulseIn object associated with the given pin. The object acts as
//| a read-only sequence of pulse lengths with a given max length. When it is
@@ -114,6 +114,12 @@ STATIC mp_obj_t pulseio_pulsein_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_deinit_obj, pulseio_pulsein_deinit);
+STATIC void check_for_deinit(pulseio_pulsein_obj_t *self) {
+ if (common_hal_pulseio_pulsein_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -138,7 +144,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulsein___exit___obj, 4, 4, p
//|
STATIC mp_obj_t pulseio_pulsein_obj_pause(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
common_hal_pulseio_pulsein_pause(self);
return mp_const_none;
@@ -162,7 +168,7 @@ STATIC mp_obj_t pulseio_pulsein_obj_resume(size_t n_args, const mp_obj_t *pos_ar
{ MP_QSTR_trigger_duration, MP_ARG_INT, {.u_int = 0} },
};
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
@@ -178,7 +184,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pulseio_pulsein_resume_obj, 1, pulseio_pulsein_obj_re
//|
STATIC mp_obj_t pulseio_pulsein_obj_clear(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
common_hal_pulseio_pulsein_clear(self);
return mp_const_none;
@@ -191,7 +197,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_clear_obj, pulseio_pulsein_obj_clear);
//|
STATIC mp_obj_t pulseio_pulsein_obj_popleft(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_popleft(self));
}
@@ -204,7 +210,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_popleft_obj, pulseio_pulsein_obj_pople
//|
STATIC mp_obj_t pulseio_pulsein_obj_get_maxlen(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_get_maxlen(self));
}
@@ -224,7 +230,7 @@ const mp_obj_property_t pulseio_pulsein_maxlen_obj = {
//|
STATIC mp_obj_t pulseio_pulsein_obj_get_paused(mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_pulseio_pulsein_get_paused(self));
}
@@ -248,7 +254,7 @@ const mp_obj_property_t pulseio_pulsein_paused_obj = {
//|
STATIC mp_obj_t pulsein_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
uint16_t len = common_hal_pulseio_pulsein_get_len(self);
switch (op) {
case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0);
@@ -272,7 +278,7 @@ STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t va
mp_raise_AttributeError(translate("Cannot delete values"));
} else {
pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+ check_for_deinit(self);
if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) {
mp_raise_NotImplementedError(translate("Slices not supported"));
diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c
index 493b7e2ff..172459e5d 100644
--- a/shared-bindings/pulseio/PulseOut.c
+++ b/shared-bindings/pulseio/PulseOut.c
@@ -127,7 +127,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulseout___exit___obj, 4, 4,
//|
STATIC mp_obj_t pulseio_pulseout_obj_send(mp_obj_t self_in, mp_obj_t pulses) {
pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_pulseio_pulseout_deinited(self));
+ if (common_hal_pulseio_pulseout_deinited(self)) {
+ raise_deinited_error();
+ }
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(pulses, &bufinfo, MP_BUFFER_READ);
diff --git a/shared-bindings/pulseio/__init__.c b/shared-bindings/pulseio/__init__.c
index 1114b604b..a3cec3dca 100644
--- a/shared-bindings/pulseio/__init__.c
+++ b/shared-bindings/pulseio/__init__.c
@@ -54,10 +54,6 @@
//| PWMOut
//|
-//| .. warning:: This module is not available in some SAMD21 builds. See the
-//| :ref:`module-support-matrix` for more info.
-//|
-
//| All classes change hardware state and should be deinitialized when they
//| are no longer needed if the program continues after use. To do so, either
//| call :py:meth:`!deinit` or use a context manager. See
diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c
index 5d2264ffc..f2f157847 100644
--- a/shared-bindings/rotaryio/IncrementalEncoder.c
+++ b/shared-bindings/rotaryio/IncrementalEncoder.c
@@ -100,6 +100,12 @@ STATIC mp_obj_t rotaryio_incrementalencoder_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_deinit_obj, rotaryio_incrementalencoder_deinit);
+STATIC void check_for_deinit(rotaryio_incrementalencoder_obj_t *self) {
+ if (common_hal_rotaryio_incrementalencoder_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -126,7 +132,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rotaryio_incrementalencoder___exit___
//|
STATIC mp_obj_t rotaryio_incrementalencoder_obj_get_position(mp_obj_t self_in) {
rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_rotaryio_incrementalencoder_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_int(common_hal_rotaryio_incrementalencoder_get_position(self));
}
@@ -134,7 +140,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(rotaryio_incrementalencoder_get_position_obj, rotaryio
STATIC mp_obj_t rotaryio_incrementalencoder_obj_set_position(mp_obj_t self_in, mp_obj_t new_position) {
rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_rotaryio_incrementalencoder_deinited(self));
+ check_for_deinit(self);
common_hal_rotaryio_incrementalencoder_set_position(self, mp_obj_get_int(new_position));
return mp_const_none;
diff --git a/shared-bindings/rtc/RTC.c b/shared-bindings/rtc/RTC.c
index 474d4a399..17dccdb03 100644
--- a/shared-bindings/rtc/RTC.c
+++ b/shared-bindings/rtc/RTC.c
@@ -36,22 +36,6 @@
#include "shared-bindings/time/__init__.h"
#include "supervisor/shared/translate.h"
-void MP_WEAK common_hal_rtc_get_time(timeutils_struct_time_t *tm) {
- mp_raise_NotImplementedError(translate("RTC is not supported on this board"));
-}
-
-void MP_WEAK common_hal_rtc_set_time(timeutils_struct_time_t *tm) {
- mp_raise_NotImplementedError(translate("RTC is not supported on this board"));
-}
-
-int MP_WEAK common_hal_rtc_get_calibration(void) {
- return 0;
-}
-
-void MP_WEAK common_hal_rtc_set_calibration(int calibration) {
- mp_raise_NotImplementedError(translate("RTC calibration is not supported on this board"));
-}
-
const rtc_rtc_obj_t rtc_rtc_obj = {{&rtc_rtc_type}};
//| .. currentmodule:: rtc
diff --git a/shared-bindings/socket/__init__.c b/shared-bindings/socket/__init__.c
index 29d47de56..6d04a9893 100644
--- a/shared-bindings/socket/__init__.c
+++ b/shared-bindings/socket/__init__.c
@@ -51,7 +51,7 @@ STATIC const mp_obj_type_t socket_type;
//| .. currentmodule:: socket
//|
-//| .. class:: socket(family, type, proto, ...)
+//| .. class:: socket(family, type, proto)
//|
//| Create a new socket
//|
@@ -240,6 +240,53 @@ STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send);
+
+// helper function for socket_recv and socket_recv_into to handle common operations of both
+STATIC mp_int_t _socket_recv_into(mod_network_socket_obj_t *sock, byte *buf, mp_int_t len) {
+ int _errno;
+ mp_int_t ret = sock->nic_type->recv(sock, buf, len, &_errno);
+ if (ret == -1) {
+ mp_raise_OSError(_errno);
+ }
+ return ret;
+}
+
+
+//| .. method:: recv_into(buffer[, bufsize])
+//|
+//| Reads some bytes from the connected remote address, writing
+//| into the provided buffer. If bufsize <= len(buffer) is given,
+//| a maximum of bufsize bytes will be read into the buffer. If no
+//| valid value is given for bufsize, the default is the length of
+//| the given buffer.
+//|
+//| Suits sockets of type SOCK_STREAM
+//| Returns an int of number of bytes read.
+//|
+//| :param bytearray buffer: buffer to receive into
+//| :param int bufsize: optionally, a maximum number of bytes to read.
+
+STATIC mp_obj_t socket_recv_into(size_t n_args, const mp_obj_t *args) {
+ mod_network_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]);
+ if (self->nic == MP_OBJ_NULL) {
+ // not connected
+ mp_raise_OSError(MP_ENOTCONN);
+ }
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE);
+ mp_int_t len = bufinfo.len;
+ if (n_args == 3) {
+ mp_int_t given_len = mp_obj_get_int(args[2]);
+ if (given_len < len) {
+ len = given_len;
+ }
+ }
+
+ mp_int_t ret = _socket_recv_into(self, (byte*)bufinfo.buf, len);
+ return mp_obj_new_int_from_uint(ret);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_recv_into_obj, 2, 3, socket_recv_into);
+
//| .. method:: recv(bufsize)
//|
//| Reads some bytes from the connected remote address.
@@ -257,11 +304,7 @@ STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
mp_int_t len = mp_obj_get_int(len_in);
vstr_t vstr;
vstr_init_len(&vstr, len);
- int _errno;
- mp_int_t ret = self->nic_type->recv(self, (byte*)vstr.buf, len, &_errno);
- if (ret == -1) {
- mp_raise_OSError(_errno);
- }
+ mp_int_t ret = _socket_recv_into(self, (byte*)vstr.buf, len);
if (ret == 0) {
return mp_const_empty_bytes;
}
@@ -436,6 +479,7 @@ STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&socket_recv_obj) },
{ MP_ROM_QSTR(MP_QSTR_sendto), MP_ROM_PTR(&socket_sendto_obj) },
{ MP_ROM_QSTR(MP_QSTR_recvfrom), MP_ROM_PTR(&socket_recvfrom_obj) },
+ { MP_ROM_QSTR(MP_QSTR_recv_into), MP_ROM_PTR(&socket_recv_into_obj) },
{ MP_ROM_QSTR(MP_QSTR_setsockopt), MP_ROM_PTR(&socket_setsockopt_obj) },
{ MP_ROM_QSTR(MP_QSTR_settimeout), MP_ROM_PTR(&socket_settimeout_obj) },
{ MP_ROM_QSTR(MP_QSTR_setblocking), MP_ROM_PTR(&socket_setblocking_obj) },
diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c
index 4db3a9fec..ba439b951 100644
--- a/shared-bindings/storage/__init__.c
+++ b/shared-bindings/storage/__init__.c
@@ -48,7 +48,7 @@
//| directly.
//|
-//| .. function:: mount(filesystem, mount_path, \*, readonly=False)
+//| .. function:: mount(filesystem, mount_path, *, readonly=False)
//|
//| Mounts the given filesystem object at the given path.
//|
@@ -183,7 +183,7 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = {
//| this property can only be set when the device is writable by the
//| microcontroller.
//|
- //| .. method:: mkfs
+ //| .. method:: mkfs()
//|
//| Format the block device, deleting any data that may have been there
//|
@@ -216,7 +216,7 @@ STATIC const mp_rom_map_elem_t storage_module_globals_table[] = {
//|
//| Don't call this directly, call `storage.mount`.
//|
- //| .. method:: umount
+ //| .. method:: umount()
//|
//| Don't call this directly, call `storage.umount`.
//|
diff --git a/shared-bindings/struct/__init__.c b/shared-bindings/struct/__init__.c
index 9240a15bb..ea14b3763 100644
--- a/shared-bindings/struct/__init__.c
+++ b/shared-bindings/struct/__init__.c
@@ -67,9 +67,9 @@ STATIC mp_obj_t struct_calcsize(mp_obj_t fmt_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize);
-//| .. function:: pack(fmt, v1, v2, ...)
+//| .. function:: pack(fmt, *values)
//|
-//| Pack the values v1, v2, ... according to the format string fmt.
+//| Pack the values according to the format string fmt.
//| The return value is a bytes object encoding the values.
//|
@@ -85,9 +85,9 @@ STATIC mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, struct_pack);
-//| .. function:: pack_into(fmt, buffer, offset, v1, v2, ...)
+//| .. function:: pack_into(fmt, buffer, offset, *values)
//|
-//| Pack the values v1, v2, ... according to the format string fmt into a buffer
+//| Pack the values according to the format string fmt into a buffer
//| starting at offset. offset may be negative to count from the end of buffer.
//|
diff --git a/shared-bindings/support_matrix.rst b/shared-bindings/support_matrix.rst
new file mode 100644
index 000000000..124f3a810
--- /dev/null
+++ b/shared-bindings/support_matrix.rst
@@ -0,0 +1,16 @@
+.. _module-support-matrix:
+
+Support Matrix
+===============
+
+The following table lists the available built-in modules for each CircuitPython
+capable board.
+
+.. csv-table::
+ :header-rows: 1
+ :widths: 7, 50
+
+ "Board", "Modules Available"
+ {% for key, value in support_matrix|dictsort -%}
+ "{{ key }}", "{{ '`' ~ value|join("`, `") ~ '`' }}"
+ {% endfor -%}
diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c
index e3822d858..cdde672d3 100644
--- a/shared-bindings/terminalio/Terminal.c
+++ b/shared-bindings/terminalio/Terminal.c
@@ -34,7 +34,7 @@
#include "py/objstr.h"
#include "py/runtime.h"
#include "py/stream.h"
-#include "shared-bindings/displayio/BuiltinFont.h"
+#include "shared-bindings/fontio/BuiltinFont.h"
#include "supervisor/shared/translate.h"
@@ -46,7 +46,7 @@
//| .. class:: Terminal(tilegrid, font)
//|
//| Terminal manages tile indices and cursor position based on VT100 commands. The font should be
-//| a `displayio.BuiltinFont` and the TileGrid's bitmap should match the font's bitmap.
+//| a `fontio.BuiltinFont` and the TileGrid's bitmap should match the font's bitmap.
//|
STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -64,8 +64,8 @@ STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n
}
mp_obj_t font = args[ARG_font].u_obj;
- if (!MP_OBJ_IS_TYPE(font, &displayio_builtinfont_type)) {
- mp_raise_TypeError_varg(translate("Expected a %q"), displayio_builtinfont_type.name);
+ if (!MP_OBJ_IS_TYPE(font, &fontio_builtinfont_type)) {
+ mp_raise_TypeError_varg(translate("Expected a %q"), fontio_builtinfont_type.name);
}
terminalio_terminal_obj_t *self = m_new_obj(terminalio_terminal_obj_t);
self->base.type = &terminalio_terminal_type;
diff --git a/shared-bindings/terminalio/Terminal.h b/shared-bindings/terminalio/Terminal.h
index a5dadac89..7ae0bf1b0 100644
--- a/shared-bindings/terminalio/Terminal.h
+++ b/shared-bindings/terminalio/Terminal.h
@@ -34,7 +34,7 @@
extern const mp_obj_type_t terminalio_terminal_type;
extern void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
- displayio_tilegrid_t* tilegrid, const displayio_builtinfont_t* font);
+ displayio_tilegrid_t* tilegrid, const fontio_builtinfont_t* font);
// Write characters. len is in characters NOT bytes!
extern size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self,
diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c
index 3babe2db4..70c01c2d8 100644
--- a/shared-bindings/time/__init__.c
+++ b/shared-bindings/time/__init__.c
@@ -47,7 +47,7 @@
//| written in MicroPython will work in CPython but not necessarily the other
//| way around.
//|
-//| .. method:: monotonic()
+//| .. function:: monotonic()
//|
//| Returns an always increasing value of time with an unknown reference
//| point. Only use it to compare against other values from `monotonic`.
@@ -62,7 +62,7 @@ STATIC mp_obj_t time_monotonic(void) {
}
MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_obj, time_monotonic);
-//| .. method:: sleep(seconds)
+//| .. function:: sleep(seconds)
//|
//| Sleep for a given number of seconds.
//|
@@ -95,19 +95,20 @@ mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp
return namedtuple_make_new(type, 9, tuple->items, NULL);
}
-//| .. class:: struct_time((tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst))
+//| .. class:: struct_time(time_tuple)
//|
//| Structure used to capture a date and time. Note that it takes a tuple!
//|
-//| :param int tm_year: the year, 2017 for example
-//| :param int tm_mon: the month, range [1, 12]
-//| :param int tm_mday: the day of the month, range [1, 31]
-//| :param int tm_hour: the hour, range [0, 23]
-//| :param int tm_min: the minute, range [0, 59]
-//| :param int tm_sec: the second, range [0, 61]
-//| :param int tm_wday: the day of the week, range [0, 6], Monday is 0
-//| :param int tm_yday: the day of the year, range [1, 366], -1 indicates not known
-//| :param int tm_isdst: 1 when in daylight savings, 0 when not, -1 if unknown.
+//| :param Tuple[tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst] time_tuple: Tuple of time info.
+//| * the year, 2017 for example
+//| * the month, range [1, 12]
+//| * the day of the month, range [1, 31]
+//| * the hour, range [0, 23]
+//| * the minute, range [0, 59]
+//| * the second, range [0, 61]
+//| * the day of the week, range [0, 6], Monday is 0
+//| * the day of the year, range [1, 366], -1 indicates not known
+//| * 1 when in daylight savings, 0 when not, -1 if unknown.
//|
const mp_obj_namedtuple_type_t struct_time_type_obj = {
.base = {
@@ -190,7 +191,7 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
mp_raise_RuntimeError(translate("RTC is not supported on this board"));
}
-//| .. method:: time()
+//| .. function:: time()
//|
//| Return the current time in seconds since since Jan 1, 1970.
//|
@@ -206,7 +207,7 @@ STATIC mp_obj_t time_time(void) {
}
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
-//| .. method:: monotonic_ns()
+//| .. function:: monotonic_ns()
//|
//| Return the time of the specified clock clk_id in nanoseconds.
//|
@@ -219,7 +220,7 @@ STATIC mp_obj_t time_monotonic_ns(void) {
}
MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_ns_obj, time_monotonic_ns);
-//| .. method:: localtime([secs])
+//| .. function:: localtime([secs])
//|
//| Convert a time expressed in seconds since Jan 1, 1970 to a struct_time in
//| local time. If secs is not provided or None, the current time as returned
@@ -245,7 +246,7 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
-//| .. method:: mktime(t)
+//| .. function:: mktime(t)
//|
//| This is the inverse function of localtime(). Its argument is the
//| struct_time or full 9-tuple (since the dst flag is needed; use -1 as the
diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c
index 3b26aca8c..78fceef41 100644
--- a/shared-bindings/touchio/TouchIn.c
+++ b/shared-bindings/touchio/TouchIn.c
@@ -88,6 +88,12 @@ STATIC mp_obj_t touchio_touchin_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_deinit_obj, touchio_touchin_deinit);
+STATIC void check_for_deinit(touchio_touchin_obj_t *self) {
+ if (common_hal_touchio_touchin_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
//| .. method:: __enter__()
//|
//| No-op used by Context Managers.
@@ -114,7 +120,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(touchio_touchin___exit___obj, 4, 4, t
//|
STATIC mp_obj_t touchio_touchin_obj_get_value(mp_obj_t self_in) {
touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_touchio_touchin_deinited(self));
+ check_for_deinit(self);
return mp_obj_new_bool(common_hal_touchio_touchin_get_value(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_value_obj, touchio_touchin_obj_get_value);
@@ -133,7 +139,7 @@ const mp_obj_property_t touchio_touchin_value_obj = {
//|
STATIC mp_obj_t touchio_touchin_obj_get_raw_value(mp_obj_t self_in) {
touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_touchio_touchin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_raw_value(self));
}
@@ -158,7 +164,7 @@ const mp_obj_property_t touchio_touchin_raw_value_obj = {
//|
STATIC mp_obj_t touchio_touchin_obj_get_threshold(mp_obj_t self_in) {
touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_touchio_touchin_deinited(self));
+ check_for_deinit(self);
return MP_OBJ_NEW_SMALL_INT(common_hal_touchio_touchin_get_threshold(self));
}
@@ -166,7 +172,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_threshold_obj, touchio_touchin_obj
STATIC mp_obj_t touchio_touchin_obj_set_threshold(mp_obj_t self_in, mp_obj_t threshold_obj) {
touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- raise_error_if_deinited(common_hal_touchio_touchin_deinited(self));
+ check_for_deinit(self);
uint32_t new_threshold = mp_obj_get_int(threshold_obj);
if (new_threshold < 0 || new_threshold > UINT16_MAX) {
// I would use MP_STRINGIFY(UINT16_MAX), but that prints "0xffff" instead of 65536.
diff --git a/shared-bindings/uheap/__init__.c b/shared-bindings/uheap/__init__.c
index df18237ac..0d699cd28 100644
--- a/shared-bindings/uheap/__init__.c
+++ b/shared-bindings/uheap/__init__.c
@@ -38,7 +38,7 @@
//| :synopsis: Heap size analysis
//|
-//| .. method:: info(object)
+//| .. function:: info(object)
//|
//| Prints memory debugging info for the given object and returns the
//| estimated size.
diff --git a/shared-bindings/ustack/__init__.c b/shared-bindings/ustack/__init__.c
index c4391c132..08b772e41 100644
--- a/shared-bindings/ustack/__init__.c
+++ b/shared-bindings/ustack/__init__.c
@@ -39,7 +39,7 @@
//|
#if MICROPY_MAX_STACK_USAGE
-//| .. method:: max_stack_usage()
+//| .. function:: max_stack_usage()
//|
//| Return the maximum excursion of the stack so far.
//|
@@ -50,7 +50,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(max_stack_usage_obj, max_stack_usage);
#endif // MICROPY_MAX_STACK_USAGE
-//| .. method:: stack_size()
+//| .. function:: stack_size()
//|
//| Return the size of the entire stack.
//| Same as in micropython.mem_info(), but returns a value instead
@@ -61,7 +61,7 @@ STATIC mp_obj_t stack_size(void) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(stack_size_obj, stack_size);
-//| .. method:: stack_usage()
+//| .. function:: stack_usage()
//|
//| Return how much stack is currently in use.
//| Same as micropython.stack_use(); duplicated here for convenience.
diff --git a/shared-bindings/util.c b/shared-bindings/util.c
index 80a0bdaeb..c1ca01e0a 100644
--- a/shared-bindings/util.c
+++ b/shared-bindings/util.c
@@ -32,11 +32,9 @@
#include "shared-bindings/util.h"
#include "supervisor/shared/translate.h"
-// Check if pin is None. If so, deinit() has already been called on the object, so complain.
-void raise_error_if_deinited(bool deinited) {
- if (deinited) {
- mp_raise_ValueError(translate("Object has been deinitialized and can no longer be used. Create a new object."));
- }
+// If so, deinit() has already been called on the object, so complain.
+void raise_deinited_error(void) {
+ mp_raise_ValueError(translate("Object has been deinitialized and can no longer be used. Create a new object."));
}
diff --git a/shared-bindings/util.h b/shared-bindings/util.h
index b26ed7e93..33454f10e 100644
--- a/shared-bindings/util.h
+++ b/shared-bindings/util.h
@@ -27,7 +27,7 @@
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H
#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H
-void raise_error_if_deinited(bool deinited);
+void raise_deinited_error(void);
#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_UTIL_H
diff --git a/shared-bindings/wiznet/wiznet5k.c b/shared-bindings/wiznet/wiznet5k.c
index 6d43e8992..ac89cc691 100644
--- a/shared-bindings/wiznet/wiznet5k.c
+++ b/shared-bindings/wiznet/wiznet5k.c
@@ -41,6 +41,7 @@
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/digitalio/DriveMode.h"
#include "shared-bindings/busio/SPI.h"
+#include "shared-bindings/microcontroller/Pin.h"
#include "shared-module/network/__init__.h"
#include "shared-module/wiznet/wiznet5k.h"
@@ -50,25 +51,44 @@
//| :class:`WIZNET5K` -- wrapper for Wiznet 5500 Ethernet interface
//| ===============================================================
//|
-//| .. class:: WIZNET5K(spi, cs, rst)
+//| .. class:: WIZNET5K(spi, cs, rst, dhcp=True)
//|
//| Create a new WIZNET5500 interface using the specified pins
//|
-//| :param spi: spi bus to use
-//| :param cs: pin to use for Chip Select
-//| :param rst: pin to sue for Reset
+//| :param ~busio.SPI spi: spi bus to use
+//| :param ~microcontroller.Pin cs: pin to use for Chip Select
+//| :param ~microcontroller.Pin rst: pin to use for Reset (optional)
+//| :param bool dhcp: boolean flag, whether to start DHCP automatically (optional, keyword only, default True)
+//|
+//| * The reset pin is optional: if supplied it is used to reset the
+//| wiznet board before initialization.
+//| * The SPI bus will be initialized appropriately by this library.
+//| * At present, the WIZNET5K object is a singleton, so only one WizNet
+//| interface is supported at a time.
//|
-STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
- // check arguments
- mp_arg_check_num(n_args, kw_args, 3, 3, false);
-
- return wiznet5k_create(args[0], args[1], args[2]);
+STATIC mp_obj_t wiznet5k_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_spi, ARG_cs, ARG_rst, ARG_dhcp };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_spi, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_cs, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_rst, MP_ARG_OBJ, { .u_obj = mp_const_none } },
+ { MP_QSTR_dhcp, MP_ARG_KW_ONLY | 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);
+ // TODO check type of ARG_spi?
+ assert_pin(args[ARG_cs].u_obj, false);
+ assert_pin(args[ARG_rst].u_obj, true); // may be NULL
+
+ mp_obj_t ret = wiznet5k_create(args[ARG_spi].u_obj, args[ARG_cs].u_obj, args[ARG_rst].u_obj);
+ if (args[ARG_dhcp].u_bool) wiznet5k_start_dhcp();
+ return ret;
}
//| .. attribute:: connected
//|
-//| is this device physically connected?
+//| (boolean, readonly) is this device physically connected?
//|
STATIC mp_obj_t wiznet5k_connected_get_value(mp_obj_t self_in) {
@@ -86,7 +106,9 @@ const mp_obj_property_t wiznet5k_connected_obj = {
//| .. attribute:: dhcp
//|
-//| is DHCP active on this device? (set to true to activate DHCP, false to turn it off)
+//| (boolean, readwrite) is DHCP active on this device?
+//|
+//| * set to True to activate DHCP, False to turn it off
//|
STATIC mp_obj_t wiznet5k_dhcp_get_value(mp_obj_t self_in) {
@@ -99,9 +121,11 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(wiznet5k_dhcp_get_value_obj, wiznet5k_dhcp_get_
STATIC mp_obj_t wiznet5k_dhcp_set_value(mp_obj_t self_in, mp_obj_t value) {
(void)self_in;
if (mp_obj_is_true(value)) {
- wiznet5k_start_dhcp();
+ int ret = wiznet5k_start_dhcp();
+ if (ret) mp_raise_OSError(ret);
} else {
- wiznet5k_stop_dhcp();
+ int ret = wiznet5k_stop_dhcp();
+ if (ret) mp_raise_OSError(ret);
}
return mp_const_none;
}
@@ -114,12 +138,13 @@ const mp_obj_property_t wiznet5k_dhcp_obj = {
(mp_obj_t)&mp_const_none_obj},
};
-//| .. method:: ifconfig(...)
+//| .. method:: ifconfig(params=None)
//|
//| Called without parameters, returns a tuple of
//| (ip_address, subnet_mask, gateway_address, dns_server)
//|
//| Or can be called with the same tuple to set those parameters.
+//| Setting ifconfig parameters turns DHCP off, if it was on.
//|
STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) {
@@ -136,6 +161,7 @@ STATIC mp_obj_t wiznet5k_ifconfig(size_t n_args, const mp_obj_t *args) {
return mp_obj_new_tuple(4, tuple);
} else {
// set
+ wiznet5k_stop_dhcp();
mp_obj_t *items;
mp_obj_get_array_fixed_n(args[1], 4, &items);
netutils_parse_ipv4_addr(items[0], netinfo.ip, NETUTILS_BIG);
@@ -178,6 +204,7 @@ const mod_network_nic_type_t mod_network_nic_type_wiznet5k = {
.settimeout = wiznet5k_socket_settimeout,
.ioctl = wiznet5k_socket_ioctl,
.timer_tick = wiznet5k_socket_timer_tick,
+ .deinit = wiznet5k_socket_deinit,
};
#endif // MICROPY_PY_WIZNET5K