summaryrefslogtreecommitdiff
path: root/shared-module
diff options
context:
space:
mode:
authorLimor "Ladyada" Fried <limor@ladyada.net>2020-01-23 12:32:19 -0500
committerGitHub <noreply@github.com>2020-01-23 12:32:19 -0500
commitfe70072d68f4b10b4193274d965cf830411cc7f6 (patch)
tree86bf30191dcbcd0605d0cc877a1bc978d0a9bc86 /shared-module
parent4675783545d782540d5e3d064dfe1a96b9e6c91e (diff)
parentb3c09e1bc06331a83c063ab66536c9aa729de210 (diff)
Merge branch 'master' into ndbit6
Diffstat (limited to 'shared-module')
-rw-r--r--shared-module/_pixelbuf/PixelBuf.c14
-rw-r--r--shared-module/_pixelbuf/PixelBuf.h8
-rw-r--r--shared-module/audiocore/RawSample.c6
-rw-r--r--shared-module/audiocore/__init__.c92
-rw-r--r--shared-module/audiocore/__init__.h24
-rw-r--r--shared-module/audiomixer/Mixer.c8
-rw-r--r--shared-module/audiomp3/MP3Decoder.c352
-rw-r--r--shared-module/audiomp3/MP3Decoder.h72
-rw-r--r--shared-module/audiomp3/__init__.c0
-rw-r--r--shared-module/audiomp3/__init__.h30
-rw-r--r--shared-module/board/__init__.c2
-rw-r--r--shared-module/displayio/Display.c30
-rw-r--r--shared-module/displayio/EPaperDisplay.c12
-rw-r--r--shared-module/displayio/FourWire.c17
-rw-r--r--shared-module/displayio/I2CDisplay.c5
-rw-r--r--shared-module/displayio/display_core.c14
-rw-r--r--shared-module/displayio/display_core.h2
-rw-r--r--shared-module/network/__init__.c4
-rw-r--r--shared-module/usb_hid/Device.c5
19 files changed, 581 insertions, 116 deletions
diff --git a/shared-module/_pixelbuf/PixelBuf.c b/shared-module/_pixelbuf/PixelBuf.c
index d32697239..020151bc3 100644
--- a/shared-module/_pixelbuf/PixelBuf.c
+++ b/shared-module/_pixelbuf/PixelBuf.c
@@ -31,7 +31,7 @@
#include "PixelBuf.h"
#include <string.h>
-void pixelbuf_set_pixel_int(uint8_t *buf, mp_int_t value, pixelbuf_byteorder_obj_t *byteorder) {
+void pixelbuf_set_pixel_int(uint8_t *buf, mp_int_t value, pixelbuf_byteorder_details_t *byteorder) {
buf[byteorder->byteorder.r] = value >> 16 & 0xff;
buf[byteorder->byteorder.g] = (value >> 8) & 0xff;
buf[byteorder->byteorder.b] = value & 0xff;
@@ -43,15 +43,15 @@ void pixelbuf_set_pixel_int(uint8_t *buf, mp_int_t value, pixelbuf_byteorder_obj
}
}
-void pixelbuf_set_pixel(uint8_t *buf, uint8_t *rawbuf, float brightness, mp_obj_t *item, pixelbuf_byteorder_obj_t *byteorder, bool dotstar) {
+void pixelbuf_set_pixel(uint8_t *buf, uint8_t *rawbuf, float brightness, mp_obj_t *item, pixelbuf_byteorder_details_t *byteorder, bool dotstar) {
if (MP_OBJ_IS_INT(item)) {
uint8_t *target = rawbuf ? rawbuf : buf;
pixelbuf_set_pixel_int(target, mp_obj_get_int_truncated(item), byteorder);
- if (dotstar) {
+ if (dotstar) {
buf[0] = DOTSTAR_LED_START_FULL_BRIGHT;
if (rawbuf)
rawbuf[0] = DOTSTAR_LED_START_FULL_BRIGHT;
- }
+ }
if (rawbuf) {
buf[byteorder->byteorder.r] = rawbuf[byteorder->byteorder.r] * brightness;
buf[byteorder->byteorder.g] = rawbuf[byteorder->byteorder.g] * brightness;
@@ -94,15 +94,15 @@ void pixelbuf_set_pixel(uint8_t *buf, uint8_t *rawbuf, float brightness, mp_obj_
}
}
-mp_obj_t *pixelbuf_get_pixel_array(uint8_t *buf, uint len, pixelbuf_byteorder_obj_t *byteorder, uint8_t step, bool dotstar) {
+mp_obj_t *pixelbuf_get_pixel_array(uint8_t *buf, uint len, pixelbuf_byteorder_details_t *byteorder, uint8_t step, mp_int_t slice_step, bool dotstar) {
mp_obj_t elems[len];
for (uint i = 0; i < len; i++) {
- elems[i] = pixelbuf_get_pixel(buf + (i * step), byteorder, dotstar);
+ elems[i] = pixelbuf_get_pixel(buf + ((i * slice_step) * step), byteorder, dotstar);
}
return mp_obj_new_tuple(len, elems);
}
-mp_obj_t *pixelbuf_get_pixel(uint8_t *buf, pixelbuf_byteorder_obj_t *byteorder, bool dotstar) {
+mp_obj_t *pixelbuf_get_pixel(uint8_t *buf, pixelbuf_byteorder_details_t *byteorder, bool dotstar) {
mp_obj_t elems[byteorder->bpp];
elems[0] = mp_obj_new_int(buf[byteorder->byteorder.r]);
diff --git a/shared-module/_pixelbuf/PixelBuf.h b/shared-module/_pixelbuf/PixelBuf.h
index 9e115fe0c..173ce61a8 100644
--- a/shared-module/_pixelbuf/PixelBuf.h
+++ b/shared-module/_pixelbuf/PixelBuf.h
@@ -42,9 +42,9 @@
#define DOTSTAR_GET_BRIGHTNESS(value) ((value & 0b00011111) / 31.0)
#define DOTSTAR_LED_START_FULL_BRIGHT 0xFF
-void pixelbuf_set_pixel(uint8_t *buf, uint8_t *rawbuf, float brightness, mp_obj_t *item, pixelbuf_byteorder_obj_t *byteorder, bool dotstar);
-mp_obj_t *pixelbuf_get_pixel(uint8_t *buf, pixelbuf_byteorder_obj_t *byteorder, bool dotstar);
-mp_obj_t *pixelbuf_get_pixel_array(uint8_t *buf, uint len, pixelbuf_byteorder_obj_t *byteorder, uint8_t step, bool dotstar);
-void pixelbuf_set_pixel_int(uint8_t *buf, mp_int_t value, pixelbuf_byteorder_obj_t *byteorder);
+void pixelbuf_set_pixel(uint8_t *buf, uint8_t *rawbuf, float brightness, mp_obj_t *item, pixelbuf_byteorder_details_t *byteorder, bool dotstar);
+mp_obj_t *pixelbuf_get_pixel(uint8_t *buf, pixelbuf_byteorder_details_t *byteorder, bool dotstar);
+mp_obj_t *pixelbuf_get_pixel_array(uint8_t *buf, uint len, pixelbuf_byteorder_details_t *byteorder, uint8_t step, mp_int_t slice_step, bool dotstar);
+void pixelbuf_set_pixel_int(uint8_t *buf, mp_int_t value, pixelbuf_byteorder_details_t *byteorder);
#endif
diff --git a/shared-module/audiocore/RawSample.c b/shared-module/audiocore/RawSample.c
index d6bf3a567..a69ddeb65 100644
--- a/shared-module/audiocore/RawSample.c
+++ b/shared-module/audiocore/RawSample.c
@@ -60,6 +60,12 @@ void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t* self,
uint32_t sample_rate) {
self->sample_rate = sample_rate;
}
+uint8_t common_hal_audioio_rawsample_get_bits_per_sample(audioio_rawsample_obj_t* self) {
+ return self->bits_per_sample;
+}
+uint8_t common_hal_audioio_rawsample_get_channel_count(audioio_rawsample_obj_t* self) {
+ return self->channel_count;
+}
void audioio_rawsample_reset_buffer(audioio_rawsample_obj_t* self,
bool single_channel,
diff --git a/shared-module/audiocore/__init__.c b/shared-module/audiocore/__init__.c
index f9762676f..ac9d41b60 100644
--- a/shared-module/audiocore/__init__.c
+++ b/shared-module/audiocore/__init__.c
@@ -36,103 +36,37 @@
#include "shared-module/audiomixer/Mixer.h"
uint32_t audiosample_sample_rate(mp_obj_t sample_obj) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return sample->sample_rate;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return file->sample_rate;
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
- return mixer->sample_rate;
- #endif
- }
- return 16000;
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ return proto->sample_rate(MP_OBJ_TO_PTR(sample_obj));
}
uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return sample->bits_per_sample;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return file->bits_per_sample;
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
- return mixer->bits_per_sample;
- #endif
- }
- return 8;
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ return proto->bits_per_sample(MP_OBJ_TO_PTR(sample_obj));
}
uint8_t audiosample_channel_count(mp_obj_t sample_obj) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return sample->channel_count;
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return file->channel_count;
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* mixer = MP_OBJ_TO_PTR(sample_obj);
- return mixer->channel_count;
- #endif
- }
- return 1;
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ return proto->channel_count(MP_OBJ_TO_PTR(sample_obj));
}
void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel, uint8_t audio_channel) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- audioio_rawsample_reset_buffer(sample, single_channel, audio_channel);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audioio_wavefile_reset_buffer(file, single_channel, audio_channel);
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audiomixer_mixer_reset_buffer(file, single_channel, audio_channel);
- #endif
- }
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ proto->reset_buffer(MP_OBJ_TO_PTR(sample_obj), single_channel, audio_channel);
}
audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj,
bool single_channel,
uint8_t channel,
uint8_t** buffer, uint32_t* buffer_length) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- return audioio_rawsample_get_buffer(sample, single_channel, channel, buffer, buffer_length);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return audioio_wavefile_get_buffer(file, single_channel, channel, buffer, buffer_length);
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- return audiomixer_mixer_get_buffer(file, single_channel, channel, buffer, buffer_length);
- #endif
- }
- return GET_BUFFER_DONE;
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ return proto->get_buffer(MP_OBJ_TO_PTR(sample_obj), single_channel, channel, buffer, buffer_length);
}
void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel,
bool* single_buffer, bool* samples_signed,
uint32_t* max_buffer_length, uint8_t* spacing) {
- if (MP_OBJ_IS_TYPE(sample_obj, &audioio_rawsample_type)) {
- audioio_rawsample_obj_t* sample = MP_OBJ_TO_PTR(sample_obj);
- audioio_rawsample_get_buffer_structure(sample, single_channel, single_buffer,
- samples_signed, max_buffer_length, spacing);
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audioio_wavefile_type)) {
- audioio_wavefile_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audioio_wavefile_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
- max_buffer_length, spacing);
- #if CIRCUITPY_AUDIOMIXER
- } else if (MP_OBJ_IS_TYPE(sample_obj, &audiomixer_mixer_type)) {
- audiomixer_mixer_obj_t* file = MP_OBJ_TO_PTR(sample_obj);
- audiomixer_mixer_get_buffer_structure(file, single_channel, single_buffer, samples_signed,
- max_buffer_length, spacing);
- #endif
- }
+ const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj);
+ proto->get_buffer_structure(MP_OBJ_TO_PTR(sample_obj), single_channel, single_buffer,
+ samples_signed, max_buffer_length, spacing);
}
diff --git a/shared-module/audiocore/__init__.h b/shared-module/audiocore/__init__.h
index 7aa0c1824..7a56454b8 100644
--- a/shared-module/audiocore/__init__.h
+++ b/shared-module/audiocore/__init__.h
@@ -31,6 +31,7 @@
#include <stdint.h>
#include "py/obj.h"
+#include "py/proto.h"
typedef enum {
GET_BUFFER_DONE, // No more data to read
@@ -38,6 +39,29 @@ typedef enum {
GET_BUFFER_ERROR, // Error while reading data.
} audioio_get_buffer_result_t;
+typedef uint32_t (*audiosample_sample_rate_fun)(mp_obj_t);
+typedef uint8_t (*audiosample_bits_per_sample_fun)(mp_obj_t);
+typedef uint8_t (*audiosample_channel_count_fun)(mp_obj_t);
+typedef void (*audiosample_reset_buffer_fun)(mp_obj_t,
+ bool single_channel, uint8_t audio_channel);
+typedef audioio_get_buffer_result_t (*audiosample_get_buffer_fun)(mp_obj_t,
+ bool single_channel, uint8_t channel, uint8_t** buffer,
+ uint32_t* buffer_length);
+typedef void (*audiosample_get_buffer_structure_fun)(mp_obj_t,
+ bool single_channel, bool* single_buffer,
+ bool* samples_signed, uint32_t *max_buffer_length,
+ uint8_t* spacing);
+
+typedef struct _audiosample_p_t {
+ MP_PROTOCOL_HEAD // MP_QSTR_protocol_audiosample
+ audiosample_sample_rate_fun sample_rate;
+ audiosample_bits_per_sample_fun bits_per_sample;
+ audiosample_channel_count_fun channel_count;
+ audiosample_reset_buffer_fun reset_buffer;
+ audiosample_get_buffer_fun get_buffer;
+ audiosample_get_buffer_structure_fun get_buffer_structure;
+} audiosample_p_t;
+
uint32_t audiosample_sample_rate(mp_obj_t sample_obj);
uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj);
uint8_t audiosample_channel_count(mp_obj_t sample_obj);
diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c
index a52489f85..afa3a0632 100644
--- a/shared-module/audiomixer/Mixer.c
+++ b/shared-module/audiomixer/Mixer.c
@@ -76,6 +76,14 @@ uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t* sel
return self->sample_rate;
}
+uint8_t common_hal_audiomixer_mixer_get_channel_count(audiomixer_mixer_obj_t* self) {
+ return self->channel_count;
+}
+
+uint8_t common_hal_audiomixer_mixer_get_bits_per_sample(audiomixer_mixer_obj_t* self) {
+ return self->bits_per_sample;
+}
+
bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t* self) {
for (uint8_t v = 0; v < self->voice_count; v++) {
if (common_hal_audiomixer_mixervoice_get_playing(MP_OBJ_TO_PTR(self->voice[v]))) {
diff --git a/shared-module/audiomp3/MP3Decoder.c b/shared-module/audiomp3/MP3Decoder.c
new file mode 100644
index 000000000..30357c616
--- /dev/null
+++ b/shared-module/audiomp3/MP3Decoder.c
@@ -0,0 +1,352 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Jeff Epler 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/audiomp3/MP3Decoder.h"
+
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+
+#include "py/mperrno.h"
+#include "py/runtime.h"
+
+#include "shared-module/audiomp3/MP3Decoder.h"
+#include "supervisor/shared/translate.h"
+#include "lib/mp3/src/mp3common.h"
+
+#define MAX_BUFFER_LEN (MAX_NSAMP * MAX_NGRAN * MAX_NCHAN * sizeof(int16_t))
+
+/** Fill the input buffer if it is less than half full.
+ *
+ * Returns true if the input buffer contains any useful data,
+ * false otherwise. (The input buffer will be padded to the end with
+ * 0 bytes, which do not interfere with MP3 decoding)
+ *
+ * Raises OSError if f_read fails.
+ *
+ * Sets self->eof if any read of the file returns 0 bytes
+ */
+STATIC bool mp3file_update_inbuf(audiomp3_mp3file_obj_t* self) {
+ // If buffer is over half full, do nothing
+ if (self->inbuf_offset < self->inbuf_length/2) return true;
+
+ // If we didn't previously reach the end of file, we can try reading now
+ if (!self->eof) {
+
+ // Move the unconsumed portion of the buffer to the start
+ uint8_t *end_of_buffer = self->inbuf + self->inbuf_length;
+ uint8_t *new_end_of_data = self->inbuf + self->inbuf_length - self->inbuf_offset;
+ memmove(self->inbuf, self->inbuf + self->inbuf_offset,
+ self->inbuf_length - self->inbuf_offset);
+ self->inbuf_offset = 0;
+
+ UINT to_read = end_of_buffer - new_end_of_data;
+ UINT bytes_read = 0;
+ memset(new_end_of_data, 0, to_read);
+ if (f_read(&self->file->fp, new_end_of_data, to_read, &bytes_read) != FR_OK) {
+ self->eof = true;
+ mp_raise_OSError(MP_EIO);
+ }
+
+ if (bytes_read == 0) {
+ self->eof = true;
+ }
+
+ if (to_read != bytes_read) {
+ new_end_of_data += bytes_read;
+ memset(new_end_of_data, 0, end_of_buffer - new_end_of_data);
+ }
+
+ }
+
+ // Return true iff there are at least some useful bytes in the buffer
+ return self->inbuf_offset < self->inbuf_length;
+}
+
+#define READ_PTR(self) (self->inbuf + self->inbuf_offset)
+#define BYTES_LEFT(self) (self->inbuf_length - self->inbuf_offset)
+#define CONSUME(self, n) (self->inbuf_offset += n)
+
+// http://id3.org/d3v2.3.0
+// http://id3.org/id3v2.3.0
+STATIC void mp3file_skip_id3v2(audiomp3_mp3file_obj_t* self) {
+ mp3file_update_inbuf(self);
+ if (BYTES_LEFT(self) < 10) {
+ return;
+ }
+ uint8_t *data = READ_PTR(self);
+ if (!(
+ data[0] == 'I' &&
+ data[1] == 'D' &&
+ data[2] == '3' &&
+ data[3] != 0xff &&
+ data[4] != 0xff &&
+ (data[5] & 0x1f) == 0 &&
+ (data[6] & 0x80) == 0 &&
+ (data[7] & 0x80) == 0 &&
+ (data[8] & 0x80) == 0 &&
+ (data[9] & 0x80) == 0)) {
+ return;
+ }
+ uint32_t size = (data[6] << 21) | (data[7] << 14) | (data[8] << 7) | (data[9]);
+ size += 10; // size excludes the "header" (but not the "extended header")
+ // First, deduct from size whatever is left in buffer
+ uint32_t to_consume = MIN(size, BYTES_LEFT(self));
+ CONSUME(self, to_consume);
+ size -= to_consume;
+
+ // Next, seek in the file after the header
+ f_lseek(&self->file->fp, f_tell(&self->file->fp) + size);
+ return;
+}
+
+/* If a sync word can be found, advance to it and return true. Otherwise,
+ * return false.
+ */
+STATIC bool mp3file_find_sync_word(audiomp3_mp3file_obj_t* self) {
+ do {
+ mp3file_update_inbuf(self);
+ int offset = MP3FindSyncWord(READ_PTR(self), BYTES_LEFT(self));
+ if (offset >= 0) {
+ CONSUME(self, offset);
+ mp3file_update_inbuf(self);
+ return true;
+ }
+ CONSUME(self, MAX(0, BYTES_LEFT(self) - 16));
+ } while (!self->eof);
+ return false;
+}
+
+STATIC bool mp3file_get_next_frame_info(audiomp3_mp3file_obj_t* self, MP3FrameInfo* fi) {
+ int err;
+ do {
+ err = MP3GetNextFrameInfo(self->decoder, fi, READ_PTR(self));
+ if (err == ERR_MP3_NONE) {
+ break;
+ }
+ CONSUME(self, 1);
+ mp3file_find_sync_word(self);
+ } while (!self->eof);
+ return err == ERR_MP3_NONE;
+}
+
+void common_hal_audiomp3_mp3file_construct(audiomp3_mp3file_obj_t* self,
+ pyb_file_obj_t* file,
+ uint8_t *buffer,
+ size_t buffer_size) {
+ // XXX Adafruit_MP3 uses a 2kB input buffer and two 4kB output buffers.
+ // for a whopping total of 10kB buffers (+mp3 decoder state and frame buffer)
+ // At 44kHz, that's 23ms of output audio data.
+ //
+ // We will choose a slightly different allocation strategy for the output:
+ // Make sure the buffers are sized exactly to match (a multiple of) the
+ // frame size; this is typically 2304 * 2 bytes, so a little bit bigger
+ // than the two 4kB output buffers, except that the alignment allows to
+ // never allocate that extra frame buffer.
+
+ self->inbuf_length = 2048;
+ self->inbuf_offset = self->inbuf_length;
+ self->inbuf = m_malloc(self->inbuf_length, false);
+ if (self->inbuf == NULL) {
+ common_hal_audiomp3_mp3file_deinit(self);
+ mp_raise_msg(&mp_type_MemoryError,
+ translate("Couldn't allocate input buffer"));
+ }
+ self->decoder = MP3InitDecoder();
+ if (self->decoder == NULL) {
+ common_hal_audiomp3_mp3file_deinit(self);
+ mp_raise_msg(&mp_type_MemoryError,
+ translate("Couldn't allocate decoder"));
+ }
+
+ if ((intptr_t)buffer & 1) {
+ buffer += 1; buffer_size -= 1;
+ }
+ if (buffer_size >= 2 * MAX_BUFFER_LEN) {
+ self->buffers[0] = (int16_t*)(void*)buffer;
+ self->buffers[1] = (int16_t*)(void*)(buffer + MAX_BUFFER_LEN);
+ } else {
+ self->buffers[0] = m_malloc(MAX_BUFFER_LEN, false);
+ if (self->buffers[0] == NULL) {
+ common_hal_audiomp3_mp3file_deinit(self);
+ mp_raise_msg(&mp_type_MemoryError,
+ translate("Couldn't allocate first buffer"));
+ }
+
+ self->buffers[1] = m_malloc(MAX_BUFFER_LEN, false);
+ if (self->buffers[1] == NULL) {
+ common_hal_audiomp3_mp3file_deinit(self);
+ mp_raise_msg(&mp_type_MemoryError,
+ translate("Couldn't allocate second buffer"));
+ }
+ }
+
+ common_hal_audiomp3_mp3file_set_file(self, file);
+}
+
+void common_hal_audiomp3_mp3file_set_file(audiomp3_mp3file_obj_t* self, pyb_file_obj_t* file) {
+ self->file = file;
+ f_lseek(&self->file->fp, 0);
+ self->inbuf_offset = self->inbuf_length;
+ self->eof = 0;
+ self->other_channel = -1;
+ mp3file_update_inbuf(self);
+ mp3file_find_sync_word(self);
+ // It **SHOULD** not be necessary to do this; the buffer should be filled
+ // with fresh content before it is returned by get_buffer(). The fact that
+ // this is necessary to avoid a glitch at the start of playback of a second
+ // track using the same decoder object means there's still a bug in
+ // get_buffer() that I didn't understand.
+ memset(self->buffers[0], 0, MAX_BUFFER_LEN);
+ memset(self->buffers[1], 0, MAX_BUFFER_LEN);
+ MP3FrameInfo fi;
+ if(!mp3file_get_next_frame_info(self, &fi)) {
+ mp_raise_msg(&mp_type_RuntimeError,
+ translate("Failed to parse MP3 file"));
+ }
+
+ self->sample_rate = fi.samprate;
+ self->channel_count = fi.nChans;
+ self->frame_buffer_size = fi.outputSamps*sizeof(int16_t);
+ self->len = 2 * self->frame_buffer_size;
+}
+
+void common_hal_audiomp3_mp3file_deinit(audiomp3_mp3file_obj_t* self) {
+ MP3FreeDecoder(self->decoder);
+ self->decoder = NULL;
+ self->inbuf = NULL;
+ self->buffers[0] = NULL;
+ self->buffers[1] = NULL;
+ self->file = NULL;
+}
+
+bool common_hal_audiomp3_mp3file_deinited(audiomp3_mp3file_obj_t* self) {
+ return self->buffers[0] == NULL;
+}
+
+uint32_t common_hal_audiomp3_mp3file_get_sample_rate(audiomp3_mp3file_obj_t* self) {
+ return self->sample_rate;
+}
+
+void common_hal_audiomp3_mp3file_set_sample_rate(audiomp3_mp3file_obj_t* self,
+ uint32_t sample_rate) {
+ self->sample_rate = sample_rate;
+}
+
+uint8_t common_hal_audiomp3_mp3file_get_bits_per_sample(audiomp3_mp3file_obj_t* self) {
+ return 16;
+}
+
+uint8_t common_hal_audiomp3_mp3file_get_channel_count(audiomp3_mp3file_obj_t* self) {
+ return self->channel_count;
+}
+
+bool audiomp3_mp3file_samples_signed(audiomp3_mp3file_obj_t* self) {
+ return true;
+}
+
+void audiomp3_mp3file_reset_buffer(audiomp3_mp3file_obj_t* self,
+ bool single_channel,
+ uint8_t channel) {
+ if (single_channel && channel == 1) {
+ return;
+ }
+ // We don't reset the buffer index in case we're looping and we have an odd number of buffer
+ // loads
+ f_lseek(&self->file->fp, 0);
+ self->inbuf_offset = self->inbuf_length;
+ self->eof = 0;
+ self->other_channel = -1;
+ mp3file_update_inbuf(self);
+ mp3file_skip_id3v2(self);
+ mp3file_find_sync_word(self);
+}
+
+audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t* self,
+ bool single_channel,
+ uint8_t channel,
+ uint8_t** bufptr,
+ uint32_t* buffer_length) {
+ if (!self->inbuf) {
+ return GET_BUFFER_ERROR;
+ }
+ if (!single_channel) {
+ channel = 0;
+ }
+
+ *buffer_length = self->frame_buffer_size;
+
+ if (channel == self->other_channel) {
+ *bufptr = (uint8_t*)(self->buffers[self->other_buffer_index] + channel);
+ self->other_channel = -1;
+ return GET_BUFFER_MORE_DATA;
+ }
+
+
+ self->buffer_index = !self->buffer_index;
+ self->other_channel = 1-channel;
+ self->other_buffer_index = self->buffer_index;
+ int16_t *buffer = (int16_t *)(void *)self->buffers[self->buffer_index];
+ *bufptr = (uint8_t*)buffer;
+
+ mp3file_skip_id3v2(self);
+ if (!mp3file_find_sync_word(self)) {
+ return self->eof ? GET_BUFFER_DONE : GET_BUFFER_ERROR;
+ }
+ int bytes_left = BYTES_LEFT(self);
+ uint8_t *inbuf = READ_PTR(self);
+ int err = MP3Decode(self->decoder, &inbuf, &bytes_left, buffer, 0);
+ CONSUME(self, BYTES_LEFT(self) - bytes_left);
+ if (err) {
+ return GET_BUFFER_DONE;
+ }
+
+ return GET_BUFFER_MORE_DATA;
+}
+
+void audiomp3_mp3file_get_buffer_structure(audiomp3_mp3file_obj_t* self, bool single_channel,
+ bool* single_buffer, bool* samples_signed,
+ uint32_t* max_buffer_length, uint8_t* spacing) {
+ *single_buffer = false;
+ *samples_signed = true;
+ *max_buffer_length = self->frame_buffer_size;
+ if (single_channel) {
+ *spacing = self->channel_count;
+ } else {
+ *spacing = 1;
+ }
+}
+
+float common_hal_audiomp3_mp3file_get_rms_level(audiomp3_mp3file_obj_t* self) {
+ float sumsq = 0.f;
+ // Assumes no DC component to the audio. Is that a safe assumption?
+ int16_t *buffer = (int16_t *)(void *)self->buffers[self->buffer_index];
+ for(size_t i=0; i<self->frame_buffer_size / sizeof(int16_t); i++) {
+ sumsq += (float)buffer[i] * buffer[i];
+ }
+ return sqrtf(sumsq) / (self->frame_buffer_size / sizeof(int16_t));
+}
diff --git a/shared-module/audiomp3/MP3Decoder.h b/shared-module/audiomp3/MP3Decoder.h
new file mode 100644
index 000000000..9ee1d0949
--- /dev/null
+++ b/shared-module/audiomp3/MP3Decoder.h
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Scott Shawcroft
+ * Copyright (c) 2019 Jeff Epler 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_MODULE_AUDIOIO_MP3FILE_H
+#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MP3FILE_H
+
+#include "extmod/vfs_fat.h"
+#include "py/obj.h"
+
+#include "shared-module/audiocore/__init__.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ struct _MP3DecInfo *decoder;
+ uint8_t* inbuf;
+ uint32_t inbuf_length;
+ uint32_t inbuf_offset;
+ int16_t* buffers[2];
+ uint32_t len;
+ uint32_t frame_buffer_size;
+
+ uint32_t sample_rate;
+ pyb_file_obj_t* file;
+
+ uint8_t buffer_index;
+ uint8_t channel_count;
+ bool eof;
+
+ int8_t other_channel;
+ int8_t other_buffer_index;
+} audiomp3_mp3file_obj_t;
+
+// These are not available from Python because it may be called in an interrupt.
+void audiomp3_mp3file_reset_buffer(audiomp3_mp3file_obj_t* self,
+ bool single_channel,
+ uint8_t channel);
+audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t* self,
+ bool single_channel,
+ uint8_t channel,
+ uint8_t** buffer,
+ uint32_t* buffer_length); // length in bytes
+void audiomp3_mp3file_get_buffer_structure(audiomp3_mp3file_obj_t* self, bool single_channel,
+ bool* single_buffer, bool* samples_signed,
+ uint32_t* max_buffer_length, uint8_t* spacing);
+
+float audiomp3_mp3file_get_rms_level(audiomp3_mp3file_obj_t* self);
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOIO_MP3FILE_H
diff --git a/shared-module/audiomp3/__init__.c b/shared-module/audiomp3/__init__.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/shared-module/audiomp3/__init__.c
diff --git a/shared-module/audiomp3/__init__.h b/shared-module/audiomp3/__init__.h
new file mode 100644
index 000000000..e7b1f3aab
--- /dev/null
+++ b/shared-module/audiomp3/__init__.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Jeff Epler 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_MODULE_AUDIOMP3__INIT__H
+#define MICROPY_INCLUDED_SHARED_MODULE_AUDIOMP3__INIT__H
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_AUDIOMP3__INIT__H
diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c
index dd07d7190..914bc4313 100644
--- a/shared-module/board/__init__.c
+++ b/shared-module/board/__init__.c
@@ -101,7 +101,7 @@ mp_obj_t common_hal_board_create_uart(void) {
const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX);
const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX);
- common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64);
+ common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1.0f, 64);
MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self);
return MP_STATE_VM(shared_uart_bus);
}
diff --git a/shared-module/displayio/Display.c b/shared-module/displayio/Display.c
index 06b81f2f8..299c8ad35 100644
--- a/shared-module/displayio/Display.c
+++ b/shared-module/displayio/Display.c
@@ -35,6 +35,7 @@
#include "shared-module/displayio/__init__.h"
#include "shared-module/displayio/display_core.h"
#include "supervisor/shared/display.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include <stdint.h>
@@ -113,7 +114,7 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
if (result != PWMOUT_OK) {
self->backlight_inout.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin);
- never_reset_pin_number(backlight_pin->number);
+ common_hal_never_reset_pin(backlight_pin);
} else {
self->backlight_pwm.base.type = &pulseio_pwmout_type;
common_hal_pulseio_pwmout_never_reset(&self->backlight_pwm);
@@ -307,13 +308,30 @@ STATIC void _refresh_display(displayio_display_obj_t* self) {
displayio_display_core_finish_refresh(&self->core);
}
+void common_hal_displayio_display_set_rotation(displayio_display_obj_t* self, int rotation){
+ bool transposed = (self->core.rotation == 90 || self->core.rotation == 270);
+ bool will_transposed = (rotation == 90 || rotation == 270);
+ if(transposed != will_transposed) {
+ int tmp = self->core.width;
+ self->core.width = self->core.height;
+ self->core.height = tmp;
+ }
+ displayio_display_core_set_rotation(&self->core, rotation);
+ supervisor_stop_terminal();
+ supervisor_start_terminal(self->core.width, self->core.height);
+ if (self->core.current_group != NULL) {
+ displayio_group_update_transform(self->core.current_group, &self->core.transform);
+ }
+}
+
uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t* self){
return self->core.rotation;
}
+
bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) {
if (!self->auto_refresh && !self->first_manual_refresh) {
- uint64_t current_time = ticks_ms;
+ uint64_t current_time = supervisor_ticks_ms64();
uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh;
// Test to see if the real frame time is below our minimum.
if (current_ms_since_real_refresh > maximum_ms_per_real_frame) {
@@ -327,7 +345,7 @@ bool common_hal_displayio_display_refresh(displayio_display_obj_t* self, uint32_
}
uint32_t remaining_time = target_ms_per_frame - (current_ms_since_real_refresh % target_ms_per_frame);
// We're ahead of the game so wait until we align with the frame rate.
- while (ticks_ms - self->last_refresh_call < remaining_time) {
+ while (supervisor_ticks_ms64() - self->last_refresh_call < remaining_time) {
RUN_BACKGROUND_TASKS;
}
}
@@ -350,20 +368,20 @@ STATIC void _update_backlight(displayio_display_obj_t* self) {
if (!self->auto_brightness || self->updating_backlight) {
return;
}
- if (ticks_ms - self->last_backlight_refresh < 100) {
+ if (supervisor_ticks_ms64() - self->last_backlight_refresh < 100) {
return;
}
// TODO(tannewt): Fade the backlight based on it's existing value and a target value. The target
// should account for ambient light when possible.
common_hal_displayio_display_set_brightness(self, 1.0);
- self->last_backlight_refresh = ticks_ms;
+ self->last_backlight_refresh = supervisor_ticks_ms64();
}
void displayio_display_background(displayio_display_obj_t* self) {
_update_backlight(self);
- if (self->auto_refresh && (ticks_ms - self->core.last_refresh) > self->native_ms_per_frame) {
+ if (self->auto_refresh && (supervisor_ticks_ms64() - self->core.last_refresh) > self->native_ms_per_frame) {
_refresh_display(self);
}
}
diff --git a/shared-module/displayio/EPaperDisplay.c b/shared-module/displayio/EPaperDisplay.c
index efbd9f3dd..91d4bb7f9 100644
--- a/shared-module/displayio/EPaperDisplay.c
+++ b/shared-module/displayio/EPaperDisplay.c
@@ -26,6 +26,7 @@
#include "shared-bindings/displayio/EPaperDisplay.h"
+#include "py/gc.h"
#include "py/runtime.h"
#include "shared-bindings/displayio/ColorConverter.h"
#include "shared-bindings/displayio/FourWire.h"
@@ -35,6 +36,7 @@
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h"
+#include "supervisor/shared/tick.h"
#include "supervisor/usb.h"
#include <stdint.h>
@@ -82,7 +84,7 @@ void common_hal_displayio_epaperdisplay_construct(displayio_epaperdisplay_obj_t*
if (busy_pin != NULL) {
self->busy.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->busy, busy_pin);
- never_reset_pin_number(busy_pin->number);
+ common_hal_never_reset_pin(busy_pin);
}
// Clear the color memory if it isn't in use.
@@ -175,7 +177,7 @@ uint32_t common_hal_displayio_epaperdisplay_get_time_to_refresh(displayio_epaper
return 0;
}
// Refresh at seconds per frame rate.
- uint32_t elapsed_time = ticks_ms - self->core.last_refresh;
+ uint32_t elapsed_time = supervisor_ticks_ms64() - self->core.last_refresh;
if (elapsed_time > self->milliseconds_per_frame) {
return 0;
}
@@ -298,7 +300,7 @@ bool displayio_epaperdisplay_refresh_area(displayio_epaperdisplay_obj_t* self, c
}
bool common_hal_displayio_epaperdisplay_refresh(displayio_epaperdisplay_obj_t* self) {
-
+
if (self->refreshing && self->busy.base.type == &digitalio_digitalinout_type) {
if (common_hal_digitalio_digitalinout_get_value(&self->busy) != self->busy_state) {
self->refreshing = false;
@@ -339,7 +341,7 @@ void displayio_epaperdisplay_background(displayio_epaperdisplay_obj_t* self) {
bool busy = common_hal_digitalio_digitalinout_get_value(&self->busy);
refresh_done = busy != self->busy_state;
} else {
- refresh_done = ticks_ms - self->core.last_refresh > self->refresh_time;
+ refresh_done = supervisor_ticks_ms64() - self->core.last_refresh > self->refresh_time;
}
if (refresh_done) {
self->refreshing = false;
@@ -365,6 +367,8 @@ void release_epaperdisplay(displayio_epaperdisplay_obj_t* self) {
void displayio_epaperdisplay_collect_ptrs(displayio_epaperdisplay_obj_t* self) {
displayio_display_core_collect_ptrs(&self->core);
+ gc_collect_ptr(self->start_sequence);
+ gc_collect_ptr(self->stop_sequence);
}
bool maybe_refresh_epaperdisplay(void) {
diff --git a/shared-module/displayio/FourWire.c b/shared-module/displayio/FourWire.c
index fcc4c1a20..256c29642 100644
--- a/shared-module/displayio/FourWire.c
+++ b/shared-module/displayio/FourWire.c
@@ -31,6 +31,7 @@
#include "py/gc.h"
#include "shared-bindings/busio/SPI.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/display_core.h"
@@ -48,8 +49,8 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
gc_never_free(self->bus);
self->frequency = baudrate;
- self->polarity = common_hal_busio_spi_get_polarity(spi);
- self->phase = common_hal_busio_spi_get_phase(spi);
+ self->polarity = 0;
+ self->phase = 0;
common_hal_digitalio_digitalinout_construct(&self->command, command);
common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL);
@@ -61,12 +62,12 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self,
self->reset.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->reset, reset);
common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
- never_reset_pin_number(reset->number);
+ common_hal_never_reset_pin(reset);
common_hal_displayio_fourwire_reset(self);
}
- never_reset_pin_number(command->number);
- never_reset_pin_number(chip_select->number);
+ common_hal_never_reset_pin(command);
+ common_hal_never_reset_pin(chip_select);
}
void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) {
@@ -74,9 +75,9 @@ void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) {
common_hal_busio_spi_deinit(self->bus);
}
- reset_pin_number(self->command.pin->number);
- reset_pin_number(self->chip_select.pin->number);
- reset_pin_number(self->reset.pin->number);
+ common_hal_reset_pin(self->command.pin);
+ common_hal_reset_pin(self->chip_select.pin);
+ common_hal_reset_pin(self->reset.pin);
}
bool common_hal_displayio_fourwire_reset(mp_obj_t obj) {
diff --git a/shared-module/displayio/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c
index 0307410d1..280476f19 100644
--- a/shared-module/displayio/I2CDisplay.c
+++ b/shared-module/displayio/I2CDisplay.c
@@ -33,6 +33,7 @@
#include "py/runtime.h"
#include "shared-bindings/busio/I2C.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
+#include "shared-bindings/microcontroller/Pin.h"
#include "shared-bindings/microcontroller/__init__.h"
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/display_core.h"
@@ -48,7 +49,7 @@ void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t* self,
self->reset.base.type = &digitalio_digitalinout_type;
common_hal_digitalio_digitalinout_construct(&self->reset, reset);
common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL);
- never_reset_pin_number(reset->number);
+ common_hal_never_reset_pin(reset);
common_hal_displayio_i2cdisplay_reset(self);
}
@@ -72,7 +73,7 @@ void common_hal_displayio_i2cdisplay_deinit(displayio_i2cdisplay_obj_t* self) {
common_hal_busio_i2c_deinit(self->bus);
}
- reset_pin_number(self->reset.pin->number);
+ common_hal_reset_pin(self->reset.pin);
}
bool common_hal_displayio_i2cdisplay_reset(mp_obj_t obj) {
diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c
index a73ea81d1..120b70f76 100644
--- a/shared-module/displayio/display_core.c
+++ b/shared-module/displayio/display_core.c
@@ -35,6 +35,7 @@
#include "shared-bindings/time/__init__.h"
#include "shared-module/displayio/__init__.h"
#include "supervisor/shared/display.h"
+#include "supervisor/shared/tick.h"
#include <stdint.h>
#include <string.h>
@@ -85,6 +86,15 @@ void displayio_display_core_construct(displayio_display_core_t* self,
self->height = height;
self->ram_width = ram_width;
self->ram_height = ram_height;
+
+ displayio_display_core_set_rotation(self, rotation);
+}
+
+void displayio_display_core_set_rotation( displayio_display_core_t* self,
+ int rotation) {
+ int height = self->height;
+ int width = self->width;
+
rotation = rotation % 360;
self->rotation = rotation;
self->transform.x = 0;
@@ -281,7 +291,7 @@ void displayio_display_core_set_region_to_update(displayio_display_core_t* self,
}
void displayio_display_core_start_refresh(displayio_display_core_t* self) {
- self->last_refresh = ticks_ms;
+ self->last_refresh = supervisor_ticks_ms64();
}
void displayio_display_core_finish_refresh(displayio_display_core_t* self) {
@@ -289,7 +299,7 @@ void displayio_display_core_finish_refresh(displayio_display_core_t* self) {
displayio_group_finish_refresh(self->current_group);
}
self->full_refresh = false;
- self->last_refresh = ticks_ms;
+ self->last_refresh = supervisor_ticks_ms64();
}
void release_display_core(displayio_display_core_t* self) {
diff --git a/shared-module/displayio/display_core.h b/shared-module/displayio/display_core.h
index 3a69cd40a..1c3d0f09c 100644
--- a/shared-module/displayio/display_core.h
+++ b/shared-module/displayio/display_core.h
@@ -68,6 +68,8 @@ uint16_t displayio_display_core_get_height(displayio_display_core_t* self);
void displayio_display_core_set_dither(displayio_display_core_t* self, bool dither);
bool displayio_display_core_get_dither(displayio_display_core_t* self);
+void displayio_display_core_set_rotation(displayio_display_core_t* self, int rotation);
+
bool displayio_display_core_bus_free(displayio_display_core_t *self);
bool displayio_display_core_begin_transaction(displayio_display_core_t* self);
void displayio_display_core_end_transaction(displayio_display_core_t* self);
diff --git a/shared-module/network/__init__.c b/shared-module/network/__init__.c
index 96648b260..925e9a2a3 100644
--- a/shared-module/network/__init__.c
+++ b/shared-module/network/__init__.c
@@ -31,6 +31,8 @@
#include "py/mphal.h"
#include "py/mperrno.h"
+#include "supervisor/shared/tick.h"
+
#include "shared-bindings/random/__init__.h"
#include "shared-module/network/__init__.h"
@@ -53,7 +55,7 @@ void network_module_deinit(void) {
void network_module_background(void) {
static uint32_t next_tick = 0;
- uint32_t this_tick = ticks_ms;
+ uint32_t this_tick = supervisor_ticks_ms32();
if (this_tick < next_tick) return;
next_tick = this_tick + 1000;
diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c
index bed7d163f..8744f2ed3 100644
--- a/shared-module/usb_hid/Device.c
+++ b/shared-module/usb_hid/Device.c
@@ -30,6 +30,7 @@
#include "shared-bindings/usb_hid/Device.h"
#include "shared-module/usb_hid/Device.h"
#include "supervisor/shared/translate.h"
+#include "supervisor/shared/tick.h"
#include "tusb.h"
uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) {
@@ -46,8 +47,8 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t*
}
// Wait until interface is ready, timeout = 2 seconds
- uint64_t end_ticks = ticks_ms + 2000;
- while ( (ticks_ms < end_ticks) && !tud_hid_ready() ) {
+ uint64_t end_ticks = supervisor_ticks_ms64() + 2000;
+ while ( (supervisor_ticks_ms64() < end_ticks) && !tud_hid_ready() ) {
RUN_BACKGROUND_TASKS;
}