diff options
| author | Limor "Ladyada" Fried <limor@ladyada.net> | 2020-01-23 12:32:19 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-23 12:32:19 -0500 |
| commit | fe70072d68f4b10b4193274d965cf830411cc7f6 (patch) | |
| tree | 86bf30191dcbcd0605d0cc877a1bc978d0a9bc86 /shared-module | |
| parent | 4675783545d782540d5e3d064dfe1a96b9e6c91e (diff) | |
| parent | b3c09e1bc06331a83c063ab66536c9aa729de210 (diff) | |
Merge branch 'master' into ndbit6
Diffstat (limited to 'shared-module')
| -rw-r--r-- | shared-module/_pixelbuf/PixelBuf.c | 14 | ||||
| -rw-r--r-- | shared-module/_pixelbuf/PixelBuf.h | 8 | ||||
| -rw-r--r-- | shared-module/audiocore/RawSample.c | 6 | ||||
| -rw-r--r-- | shared-module/audiocore/__init__.c | 92 | ||||
| -rw-r--r-- | shared-module/audiocore/__init__.h | 24 | ||||
| -rw-r--r-- | shared-module/audiomixer/Mixer.c | 8 | ||||
| -rw-r--r-- | shared-module/audiomp3/MP3Decoder.c | 352 | ||||
| -rw-r--r-- | shared-module/audiomp3/MP3Decoder.h | 72 | ||||
| -rw-r--r-- | shared-module/audiomp3/__init__.c | 0 | ||||
| -rw-r--r-- | shared-module/audiomp3/__init__.h | 30 | ||||
| -rw-r--r-- | shared-module/board/__init__.c | 2 | ||||
| -rw-r--r-- | shared-module/displayio/Display.c | 30 | ||||
| -rw-r--r-- | shared-module/displayio/EPaperDisplay.c | 12 | ||||
| -rw-r--r-- | shared-module/displayio/FourWire.c | 17 | ||||
| -rw-r--r-- | shared-module/displayio/I2CDisplay.c | 5 | ||||
| -rw-r--r-- | shared-module/displayio/display_core.c | 14 | ||||
| -rw-r--r-- | shared-module/displayio/display_core.h | 2 | ||||
| -rw-r--r-- | shared-module/network/__init__.c | 4 | ||||
| -rw-r--r-- | shared-module/usb_hid/Device.c | 5 |
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; } |
