Merge pull request #7764 from jepler/mimxrt10xx-i2sout-v2
mimxrt10xx: implement i2sout
This commit is contained in:
commit
cd69e1cec3
|
@ -119,6 +119,7 @@ SRC_SDK := \
|
|||
drivers/lpuart/fsl_lpuart.c \
|
||||
drivers/ocotp/fsl_ocotp.c \
|
||||
drivers/pwm/fsl_pwm.c \
|
||||
drivers/sai/fsl_sai.c \
|
||||
drivers/snvs_hp/fsl_snvs_hp.c \
|
||||
drivers/snvs_lp/fsl_snvs_lp.c \
|
||||
drivers/tempmon/fsl_tempmon.c \
|
||||
|
@ -146,11 +147,6 @@ SRC_C += \
|
|||
|
||||
endif
|
||||
|
||||
# TODO
|
||||
#ifeq ($(CIRCUITPY_AUDIOBUSIO),1)
|
||||
#SRC_C += peripherals/samd/i2s.c peripherals/samd/$(CHIP_FAMILY)/i2s.c
|
||||
#endif
|
||||
#
|
||||
SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
|
||||
$(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
|
||||
$(addprefix common-hal/, $(SRC_COMMON_HAL))
|
||||
|
|
|
@ -35,9 +35,6 @@ void PLACE_IN_ITCM(port_background_task)(void) {
|
|||
}
|
||||
|
||||
void port_background_tick(void) {
|
||||
#if CIRCUITPY_AUDIOIO || CIRCUITPY_AUDIOBUSIO
|
||||
audio_dma_background();
|
||||
#endif
|
||||
}
|
||||
|
||||
void port_start_background_task(void) {
|
||||
|
|
|
@ -57,5 +57,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
|
|||
{ MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_I2S_WSEL), MP_ROM_PTR(&pin_GPIO_06) }, // D10
|
||||
{ MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_ROM_PTR(&pin_GPIO_07) }, // D9
|
||||
{ MP_ROM_QSTR(MP_QSTR_I2S_DOUT), MP_ROM_PTR(&pin_GPIO_04) }, // D12
|
||||
};
|
||||
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpconfigport.h"
|
||||
|
||||
// Some boards don't implement I2SOut, so suppress any routines from here.
|
||||
#if CIRCUITPY_AUDIOBUSIO_I2SOUT
|
||||
|
||||
#include "py/gc.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/runtime.h"
|
||||
#include "common-hal/audiobusio/I2SOut.h"
|
||||
#include "shared-bindings/audiobusio/I2SOut.h"
|
||||
#include "shared-bindings/audiocore/RawSample.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "supervisor/shared/translate/translate.h"
|
||||
#include "supervisor/shared/tick.h"
|
||||
|
||||
// Where required we use identifier names that are required by NXP's
|
||||
// API, even though they do not conform to the naming standards that Adafruit
|
||||
// strives to adhere to. https://www.adafruit.com/blacklivesmatter
|
||||
#include "sdk/drivers/sai/fsl_sai.h"
|
||||
|
||||
STATIC void config_periph_pin(const mcu_periph_obj_t *periph) {
|
||||
if (!periph) {
|
||||
return;
|
||||
}
|
||||
if (periph->pin->mux_reg) {
|
||||
IOMUXC_SetPinMux(
|
||||
periph->pin->mux_reg, periph->mux_mode,
|
||||
periph->input_reg, periph->input_idx,
|
||||
0,
|
||||
1);
|
||||
}
|
||||
|
||||
IOMUXC_SetPinConfig(0, 0, 0, 0,
|
||||
periph->pin->cfg_reg,
|
||||
IOMUXC_SW_PAD_CTL_PAD_HYS(0)
|
||||
| IOMUXC_SW_PAD_CTL_PAD_PUS(0)
|
||||
| IOMUXC_SW_PAD_CTL_PAD_PUE(0)
|
||||
| IOMUXC_SW_PAD_CTL_PAD_PKE(1)
|
||||
| IOMUXC_SW_PAD_CTL_PAD_ODE(0)
|
||||
| IOMUXC_SW_PAD_CTL_PAD_SPEED(2)
|
||||
| IOMUXC_SW_PAD_CTL_PAD_DSE(4)
|
||||
| IOMUXC_SW_PAD_CTL_PAD_SRE(0));
|
||||
}
|
||||
|
||||
// Caller validates that pins are free.
|
||||
void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self,
|
||||
const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select,
|
||||
const mcu_pin_obj_t *data, bool left_justified) {
|
||||
|
||||
int instance = -1;
|
||||
const mcu_periph_obj_t *bclk_periph = find_pin_function(mcu_sai_tx_bclk_list, bit_clock, &instance, MP_QSTR_bit_clock);
|
||||
const mcu_periph_obj_t *sync_periph = find_pin_function(mcu_sai_tx_sync_list, word_select, &instance, MP_QSTR_word_select);
|
||||
const mcu_periph_obj_t *data_periph = find_pin_function(mcu_sai_tx_data0_list, data, &instance, MP_QSTR_data);
|
||||
|
||||
sai_transceiver_t config;
|
||||
SAI_GetClassicI2SConfig(&config, 16, kSAI_Stereo, 1);
|
||||
config.syncMode = kSAI_ModeAsync;
|
||||
config.fifo.fifoPacking = kSAI_FifoPackingDisabled;
|
||||
// These identifier names are required by NXP's API, even though they do
|
||||
// not conform to the naming standards that Adafruit strives to adhere to.
|
||||
// https://www.adafruit.com/blacklivesmatter
|
||||
config.masterSlave = kSAI_Master;
|
||||
port_i2s_initialize(&self->i2s, instance, &config);
|
||||
|
||||
self->bit_clock = bit_clock;
|
||||
self->word_select = word_select;
|
||||
self->data = data;
|
||||
claim_pin(bit_clock);
|
||||
claim_pin(word_select);
|
||||
claim_pin(data);
|
||||
config_periph_pin(data_periph);
|
||||
config_periph_pin(sync_periph);
|
||||
config_periph_pin(bclk_periph);
|
||||
}
|
||||
|
||||
bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t *self) {
|
||||
return port_i2s_deinited(&self->i2s);
|
||||
}
|
||||
|
||||
void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t *self) {
|
||||
if (common_hal_audiobusio_i2sout_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
port_i2s_deinit(&self->i2s);
|
||||
|
||||
common_hal_reset_pin(self->bit_clock);
|
||||
self->bit_clock = NULL;
|
||||
|
||||
common_hal_reset_pin(self->word_select);
|
||||
self->word_select = NULL;
|
||||
|
||||
common_hal_reset_pin(self->data);
|
||||
self->data = NULL;
|
||||
}
|
||||
|
||||
void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self,
|
||||
mp_obj_t sample, bool loop) {
|
||||
if (common_hal_audiobusio_i2sout_get_playing(self)) {
|
||||
common_hal_audiobusio_i2sout_stop(self);
|
||||
}
|
||||
port_i2s_play(&self->i2s, sample, loop);
|
||||
}
|
||||
|
||||
void common_hal_audiobusio_i2sout_pause(audiobusio_i2sout_obj_t *self) {
|
||||
port_i2s_pause(&self->i2s);
|
||||
}
|
||||
|
||||
void common_hal_audiobusio_i2sout_resume(audiobusio_i2sout_obj_t *self) {
|
||||
port_i2s_resume(&self->i2s);
|
||||
}
|
||||
|
||||
bool common_hal_audiobusio_i2sout_get_paused(audiobusio_i2sout_obj_t *self) {
|
||||
return port_i2s_get_paused(&self->i2s);
|
||||
}
|
||||
|
||||
void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t *self) {
|
||||
port_i2s_stop(&self->i2s);
|
||||
}
|
||||
|
||||
bool common_hal_audiobusio_i2sout_get_playing(audiobusio_i2sout_obj_t *self) {
|
||||
return port_i2s_get_playing(&self->i2s);
|
||||
}
|
||||
|
||||
#endif // CIRCUITPY_AUDIOBUSIO_I2SOUT
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "supervisor/background_callback.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "common-hal/audiobusio/__init__.h"
|
||||
|
||||
// Some boards don't implement I2SOut, so suppress any routines from here.
|
||||
#if CIRCUITPY_AUDIOBUSIO_I2SOUT
|
||||
|
||||
#include "sdk/drivers/sai/fsl_sai.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
i2s_t i2s;
|
||||
const mcu_pin_obj_t *bit_clock;
|
||||
const mcu_pin_obj_t *word_select;
|
||||
const mcu_pin_obj_t *data;
|
||||
} audiobusio_i2sout_obj_t;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,417 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 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 <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "common-hal/audiobusio/__init__.h"
|
||||
#include "shared-module/audiocore/__init__.h"
|
||||
|
||||
#define SAI_CLOCK_SOURCE_SELECT (2U)
|
||||
#define SAI_CLOCK_SOURCE_DIVIDER (63U)
|
||||
#define SAI_CLOCK_SOURCE_PRE_DIVIDER (0U)
|
||||
|
||||
#define SAI_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_AudioPllClk) / (SAI_CLOCK_SOURCE_DIVIDER + 1U) / \
|
||||
(SAI_CLOCK_SOURCE_PRE_DIVIDER + 1U))
|
||||
|
||||
#define AUDIO_BUFFER_FRAME_COUNT (128) // in uint32_t; there are 4, giving 2048 bytes. In all they hold 10ms @ stereo 16-bit 48kHz before all buffers drain
|
||||
|
||||
/*
|
||||
* AUDIO PLL setting: Frequency = Fref * (DIV_SELECT + NUM / DENOM)
|
||||
* = 24 * (32 + 77/100)
|
||||
* = 786.48 MHz
|
||||
*/
|
||||
const clock_audio_pll_config_t audioPllConfig = {
|
||||
.loopDivider = 32, /* PLL loop divider. Valid range for DIV_SELECT divider value: 27~54. */
|
||||
.postDivider = 1, /* Divider after the PLL, should only be 1, 2, 4, 8, 16. */
|
||||
.numerator = 77, /* 30 bit numerator of fractional loop divider. */
|
||||
.denominator = 100, /* 30 bit denominator of fractional loop divider */
|
||||
};
|
||||
|
||||
static I2S_Type *const i2s_instances[] = I2S_BASE_PTRS;
|
||||
static uint8_t i2s_in_use;
|
||||
|
||||
static I2S_Type *SAI_GetPeripheral(int idx) {
|
||||
if (idx < 0 || idx >= (int)MP_ARRAY_SIZE(i2s_instances)) {
|
||||
return NULL;
|
||||
}
|
||||
return i2s_instances[idx];
|
||||
}
|
||||
|
||||
static int SAI_GetInstance(I2S_Type *peripheral) {
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(i2s_instances); i++) { if (peripheral == i2s_instances[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool i2s_clock_off(I2S_Type *peripheral) {
|
||||
int index = SAI_GetInstance(peripheral);
|
||||
switch (index) {
|
||||
#if defined(SAI0)
|
||||
case 0:
|
||||
CLOCK_DisableClock(kCLOCK_Sai0);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI1)
|
||||
case 1:
|
||||
CLOCK_DisableClock(kCLOCK_Sai1);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI2)
|
||||
case 2:
|
||||
CLOCK_DisableClock(kCLOCK_Sai2);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI3)
|
||||
case 3:
|
||||
CLOCK_DisableClock(kCLOCK_Sai3);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI4)
|
||||
case 4:
|
||||
CLOCK_DisableClock(kCLOCK_Sai4);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI5)
|
||||
case 5:
|
||||
CLOCK_DisableClock(kCLOCK_Sai5);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI6)
|
||||
case 6:
|
||||
CLOCK_DisableClock(kCLOCK_Sai6);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI7)
|
||||
case 7:
|
||||
CLOCK_DisableClock(kCLOCK_Sai7);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool i2s_clocking(I2S_Type *peripheral) {
|
||||
int index = SAI_GetInstance(peripheral);
|
||||
switch (index) {
|
||||
#if defined(SAI0)
|
||||
case 0:
|
||||
CLOCK_SetDiv(kCLOCK_Sai0PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER);
|
||||
CLOCK_SetDiv(kCLOCK_Sai0Div, SAI_CLOCK_SOURCE_DIVIDER);
|
||||
CLOCK_SetMux(kCLOCK_Sai0Mux, SAI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_EnableClock(kCLOCK_Sai0);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI1)
|
||||
case 1:
|
||||
CLOCK_SetDiv(kCLOCK_Sai1PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER);
|
||||
CLOCK_SetDiv(kCLOCK_Sai1Div, SAI_CLOCK_SOURCE_DIVIDER);
|
||||
CLOCK_SetMux(kCLOCK_Sai1Mux, SAI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_EnableClock(kCLOCK_Sai1);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI2)
|
||||
case 2:
|
||||
CLOCK_SetDiv(kCLOCK_Sai2PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER);
|
||||
CLOCK_SetDiv(kCLOCK_Sai2Div, SAI_CLOCK_SOURCE_DIVIDER);
|
||||
CLOCK_SetMux(kCLOCK_Sai2Mux, SAI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_EnableClock(kCLOCK_Sai2);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI3)
|
||||
case 3:
|
||||
CLOCK_SetDiv(kCLOCK_Sai3PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER);
|
||||
CLOCK_SetDiv(kCLOCK_Sai3Div, SAI_CLOCK_SOURCE_DIVIDER);
|
||||
CLOCK_SetMux(kCLOCK_Sai3Mux, SAI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_EnableClock(kCLOCK_Sai3);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI4)
|
||||
case 4:
|
||||
CLOCK_SetDiv(kCLOCK_Sai4PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER);
|
||||
CLOCK_SetDiv(kCLOCK_Sai4Div, SAI_CLOCK_SOURCE_DIVIDER);
|
||||
CLOCK_SetMux(kCLOCK_Sai4Mux, SAI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_EnableClock(kCLOCK_Sai4);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI5)
|
||||
case 5:
|
||||
CLOCK_SetDiv(kCLOCK_Sai5PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER);
|
||||
CLOCK_SetDiv(kCLOCK_Sai5Div, SAI_CLOCK_SOURCE_DIVIDER);
|
||||
CLOCK_SetMux(kCLOCK_Sai5Mux, SAI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_EnableClock(kCLOCK_Sai5);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI6)
|
||||
case 6:
|
||||
CLOCK_SetDiv(kCLOCK_Sai6PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER);
|
||||
CLOCK_SetDiv(kCLOCK_Sai6Div, SAI_CLOCK_SOURCE_DIVIDER);
|
||||
CLOCK_SetMux(kCLOCK_Sai6Mux, SAI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_EnableClock(kCLOCK_Sai6);
|
||||
return true;
|
||||
#endif
|
||||
#if defined(SAI7)
|
||||
case 7:
|
||||
CLOCK_SetDiv(kCLOCK_Sai7PreDiv, SAI_CLOCK_SOURCE_PRE_DIVIDER);
|
||||
CLOCK_SetDiv(kCLOCK_Sai7Div, SAI_CLOCK_SOURCE_DIVIDER);
|
||||
CLOCK_SetMux(kCLOCK_Sai7Mux, SAI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_EnableClock(kCLOCK_Sai7);
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool i2s_queue_available(i2s_t *self) {
|
||||
return !self->handle.saiQueue[self->handle.queueUser].data;
|
||||
}
|
||||
|
||||
static void i2s_fill_buffer(i2s_t *self) {
|
||||
if (!self->peripheral) {
|
||||
return;
|
||||
}
|
||||
while (i2s_queue_available(self)) {
|
||||
uint32_t *buffer = self->buffers[self->buffer_idx];
|
||||
uint32_t *ptr = buffer, *end = buffer + AUDIO_BUFFER_FRAME_COUNT;
|
||||
self->buffer_idx = (self->buffer_idx + 1) % SAI_XFER_QUEUE_SIZE;
|
||||
|
||||
while (self->playing && !self->paused && ptr < end) {
|
||||
if (self->sample_data == self->sample_end) {
|
||||
if (self->stopping) {
|
||||
// non-looping sample, previously returned GET_BUFFER_DONE
|
||||
self->playing = false;
|
||||
break;
|
||||
}
|
||||
uint32_t sample_buffer_length;
|
||||
audioio_get_buffer_result_t get_buffer_result =
|
||||
audiosample_get_buffer(self->sample, false, 0,
|
||||
&self->sample_data, &sample_buffer_length);
|
||||
self->sample_end = self->sample_data + sample_buffer_length;
|
||||
if (get_buffer_result == GET_BUFFER_DONE) {
|
||||
if (self->loop) {
|
||||
audiosample_reset_buffer(self->sample, false, 0);
|
||||
} else {
|
||||
self->stopping = true;
|
||||
}
|
||||
}
|
||||
if (get_buffer_result == GET_BUFFER_ERROR || sample_buffer_length == 0) {
|
||||
self->stopping = true;
|
||||
}
|
||||
}
|
||||
size_t input_bytecount = self->sample_end - self->sample_data;
|
||||
size_t bytes_per_input_frame = self->channel_count * self->bytes_per_sample;
|
||||
size_t framecount = MIN((size_t)(end - ptr), input_bytecount / bytes_per_input_frame);
|
||||
|
||||
#define SAMPLE_TYPE(is_signed, channel_count, bytes_per_sample) ((is_signed) | ((channel_count) << 1) | ((bytes_per_sample) << 3))
|
||||
|
||||
switch (SAMPLE_TYPE(self->samples_signed, self->channel_count, self->bytes_per_sample)) {
|
||||
|
||||
case SAMPLE_TYPE(true, 2, 2):
|
||||
memcpy(ptr, self->sample_data, 4 * framecount);
|
||||
break;
|
||||
|
||||
case SAMPLE_TYPE(false, 2, 2):
|
||||
audiosample_convert_u16s_s16s((int16_t *)ptr, (uint16_t *)(void *)self->sample_data, framecount);
|
||||
break;
|
||||
|
||||
case SAMPLE_TYPE(true, 1, 2):
|
||||
audiosample_convert_s16m_s16s((int16_t *)ptr, (int16_t *)(void *)self->sample_data, framecount);
|
||||
break;
|
||||
|
||||
case SAMPLE_TYPE(false, 1, 2):
|
||||
audiosample_convert_u16m_s16s((int16_t *)ptr, (uint16_t *)(void *)self->sample_data, framecount);
|
||||
break;
|
||||
|
||||
case SAMPLE_TYPE(true, 2, 1):
|
||||
audiosample_convert_s8s_s16s((int16_t *)ptr, (int8_t *)(void *)self->sample_data, framecount);
|
||||
memcpy(ptr, self->sample_data, 4 * framecount);
|
||||
break;
|
||||
|
||||
case SAMPLE_TYPE(false, 2, 1):
|
||||
audiosample_convert_u8s_s16s((int16_t *)ptr, (uint8_t *)(void *)self->sample_data, framecount);
|
||||
break;
|
||||
|
||||
case SAMPLE_TYPE(true, 1, 1):
|
||||
audiosample_convert_s8m_s16s((int16_t *)ptr, (int8_t *)(void *)self->sample_data, framecount);
|
||||
break;
|
||||
|
||||
case SAMPLE_TYPE(false, 1, 1):
|
||||
audiosample_convert_u8m_s16s((int16_t *)ptr, (uint8_t *)(void *)self->sample_data, framecount);
|
||||
break;
|
||||
}
|
||||
self->sample_data += bytes_per_input_frame * framecount; // in bytes
|
||||
ptr += framecount; // in frames
|
||||
}
|
||||
// Fill any remaining portion of the buffer with 'no sound'
|
||||
memset(ptr, 0, (end - ptr) * sizeof(uint32_t));
|
||||
sai_transfer_t xfer = {
|
||||
.data = (uint8_t *)buffer,
|
||||
.dataSize = AUDIO_BUFFER_FRAME_COUNT * sizeof(uint32_t),
|
||||
};
|
||||
int r = SAI_TransferSendNonBlocking(self->peripheral, &self->handle, &xfer);
|
||||
if (r != kStatus_Success) {
|
||||
mp_printf(&mp_plat_print, "transfer returned %d\n", (int)r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void i2s_callback_fun(void *self_in) {
|
||||
i2s_t *self = self_in;
|
||||
i2s_fill_buffer(self);
|
||||
}
|
||||
|
||||
static void i2s_transfer_callback(I2S_Type *base, sai_handle_t *handle, status_t status, void *self_in) {
|
||||
i2s_t *self = self_in;
|
||||
if (status == kStatus_SAI_TxIdle) {
|
||||
// a block has been finished
|
||||
background_callback_add(&self->callback, i2s_callback_fun, self_in);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void port_i2s_initialize(i2s_t *self, int instance, sai_transceiver_t *config) {
|
||||
if (!i2s_in_use) {
|
||||
// need to set audio pll up!
|
||||
|
||||
/* DeInit Audio PLL. */
|
||||
CLOCK_DeinitAudioPll();
|
||||
/* Bypass Audio PLL. */
|
||||
CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1);
|
||||
/* Set divider for Audio PLL. */
|
||||
CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
|
||||
CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK;
|
||||
/* Enable Audio PLL output. */
|
||||
CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK;
|
||||
|
||||
CLOCK_InitAudioPll(&audioPllConfig);
|
||||
}
|
||||
|
||||
I2S_Type *peripheral = SAI_GetPeripheral(instance);
|
||||
if (!peripheral) {
|
||||
mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_I2SOut);
|
||||
}
|
||||
if (i2s_in_use & (1 << instance)) {
|
||||
mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_I2SOut);
|
||||
}
|
||||
if (!i2s_clocking(peripheral)) {
|
||||
mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_I2SOut);
|
||||
}
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(self->buffers); i++) {
|
||||
self->buffers[i] = m_malloc(AUDIO_BUFFER_FRAME_COUNT * sizeof(uint32_t), false);
|
||||
}
|
||||
self->peripheral = peripheral;
|
||||
SAI_Init(self->peripheral);
|
||||
SAI_TransferTxCreateHandle(peripheral, &self->handle, i2s_transfer_callback, (void *)self);
|
||||
SAI_TransferTxSetConfig(peripheral, &self->handle, config);
|
||||
self->sample_rate = 0;
|
||||
i2s_in_use |= (1 << instance);
|
||||
}
|
||||
|
||||
bool port_i2s_deinited(i2s_t *self) {
|
||||
return !self->peripheral;
|
||||
}
|
||||
|
||||
void port_i2s_deinit(i2s_t *self) {
|
||||
if (port_i2s_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
SAI_TransferAbortSend(self->peripheral, &self->handle);
|
||||
i2s_clock_off(self->peripheral);
|
||||
i2s_in_use &= ~(1 << SAI_GetInstance(self->peripheral));
|
||||
if (!i2s_in_use) {
|
||||
CCM_ANALOG->PLL_AUDIO = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK | CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK | CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC(kCLOCK_PllClkSrc24M);
|
||||
}
|
||||
self->peripheral = NULL;
|
||||
for (size_t i = 0; i < MP_ARRAY_SIZE(self->buffers); i++) {
|
||||
self->buffers[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) {
|
||||
self->sample = sample;
|
||||
self->loop = loop;
|
||||
self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8;
|
||||
self->channel_count = audiosample_channel_count(sample);
|
||||
uint32_t sample_rate = audiosample_sample_rate(sample);
|
||||
if (sample_rate != self->sample_rate) {
|
||||
SAI_TxSetBitClockRate(self->peripheral, SAI_CLOCK_FREQ, sample_rate, 16, 2);
|
||||
self->sample_rate = sample_rate;
|
||||
}
|
||||
bool single_buffer;
|
||||
bool samples_signed;
|
||||
uint32_t max_buffer_length;
|
||||
uint8_t spacing;
|
||||
audiosample_get_buffer_structure(sample, false, &single_buffer, &samples_signed,
|
||||
&max_buffer_length, &spacing);
|
||||
self->samples_signed = samples_signed;
|
||||
self->playing = true;
|
||||
self->paused = false;
|
||||
self->stopping = false;
|
||||
self->sample_data = self->sample_end = NULL;
|
||||
|
||||
audiosample_reset_buffer(self->sample, false, 0);
|
||||
|
||||
// TODO
|
||||
#if 0
|
||||
uint32_t sample_rate = audiosample_sample_rate(sample);
|
||||
if (sample_rate != self->i2s_config.sample_rate) {
|
||||
CHECK_ESP_RESULT(i2s_set_sample_rates(self->instance, audiosample_sample_rate(sample)));
|
||||
self->i2s_config.sample_rate = sample_rate;
|
||||
}
|
||||
#endif
|
||||
background_callback_add(&self->callback, i2s_callback_fun, self);
|
||||
}
|
||||
|
||||
bool port_i2s_get_playing(i2s_t *self) {
|
||||
return self->playing;
|
||||
}
|
||||
|
||||
bool port_i2s_get_paused(i2s_t *self) {
|
||||
return self->paused;
|
||||
}
|
||||
|
||||
void port_i2s_stop(i2s_t *self) {
|
||||
self->sample = NULL;
|
||||
self->paused = false;
|
||||
self->playing = false;
|
||||
self->stopping = false;
|
||||
}
|
||||
|
||||
void port_i2s_pause(i2s_t *self) {
|
||||
self->paused = true;
|
||||
}
|
||||
|
||||
void port_i2s_resume(i2s_t *self) {
|
||||
self->paused = false;
|
||||
}
|
||||
|
||||
void i2s_reset() {
|
||||
// this port relies on object finalizers for reset
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdk/drivers/sai/fsl_sai.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
#include "supervisor/background_callback.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
I2S_Type *peripheral;
|
||||
sai_handle_t handle;
|
||||
mp_obj_t sample;
|
||||
uint32_t *buffers[SAI_XFER_QUEUE_SIZE];
|
||||
uint8_t *sample_data, *sample_end;
|
||||
background_callback_t callback;
|
||||
bool playing, paused, loop, stopping;
|
||||
bool samples_signed;
|
||||
uint8_t channel_count, bytes_per_sample;
|
||||
uint8_t buffer_idx;
|
||||
uint32_t sample_rate;
|
||||
} i2s_t;
|
||||
|
||||
|
||||
void i2s_reset(void);
|
||||
void port_i2s_initialize(i2s_t *self, int instance, sai_transceiver_t *config);
|
||||
void port_i2s_deinit(i2s_t *self);
|
||||
bool port_i2s_deinited(i2s_t *self);
|
||||
void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop);
|
||||
void port_i2s_stop(i2s_t *self);
|
||||
bool port_i2s_get_playing(i2s_t *self);
|
||||
bool port_i2s_get_paused(i2s_t *self);
|
||||
void port_i2s_pause(i2s_t *self);
|
||||
void port_i2s_resume(i2s_t *self);
|
|
@ -25,8 +25,9 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
|
||||
STATIC bool claimed_pins[IOMUXC_SW_PAD_CTL_PAD_COUNT];
|
||||
STATIC bool never_reset_pins[IOMUXC_SW_PAD_CTL_PAD_COUNT];
|
||||
|
@ -116,3 +117,19 @@ void claim_pin(const mcu_pin_obj_t *pin) {
|
|||
void common_hal_mcu_pin_reset_number(uint8_t pin_no) {
|
||||
common_hal_reset_pin((mcu_pin_obj_t *)(mcu_pin_globals.map.table[pin_no].value));
|
||||
}
|
||||
|
||||
const mcu_periph_obj_t *find_pin_function_sz(const mcu_periph_obj_t *list, size_t sz, const mcu_pin_obj_t *pin, int *instance, uint16_t name) {
|
||||
if (!pin) {
|
||||
return NULL;
|
||||
}
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
if (*instance != -1 && *instance != list[i].bank_idx) {
|
||||
continue;
|
||||
}
|
||||
if (pin == list[i].pin) {
|
||||
*instance = list[i].bank_idx;
|
||||
return &list[i];
|
||||
}
|
||||
}
|
||||
mp_raise_ValueError_varg(translate("Invalid %q pin"), name);
|
||||
}
|
||||
|
|
|
@ -25,11 +25,9 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_MICROCONTROLLER_PIN_H
|
||||
#define MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_MICROCONTROLLER_PIN_H
|
||||
|
||||
#include <assert.h>
|
||||
#pragma once
|
||||
|
||||
#include "periph.h"
|
||||
#include "pins.h"
|
||||
|
||||
void reset_all_pins(void);
|
||||
|
@ -45,4 +43,8 @@ extern const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[];
|
|||
// the port-default reset behavior.
|
||||
extern bool mimxrt10xx_board_reset_pin_number(const mcu_pin_obj_t *pin);
|
||||
|
||||
#endif // MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_MICROCONTROLLER_PIN_H
|
||||
// Find the entry in the peripheral list for this pin. If instance is (-1), any instance (bank_idx) may be used. Otherwise, the bank_idx must match the instance.
|
||||
// If instance was -1, and the function succeeds, then instance is updated with the new bank_idx.
|
||||
// If the pin is NULL then NULL is always returned. But if it was not NULL, and no match was found, then a ValueError is raised.
|
||||
const mcu_periph_obj_t *find_pin_function_sz(const mcu_periph_obj_t *list, size_t sz, const mcu_pin_obj_t *pin, int *instance, uint16_t name);
|
||||
#define find_pin_function(list, pin, instance, name) (find_pin_function_sz((list), MP_ARRAY_SIZE((list)), (pin), (instance), (name)))
|
||||
|
|
|
@ -11,8 +11,12 @@ CIRCUITPY_TUSB_MEM_ALIGN = 32
|
|||
|
||||
INTERNAL_FLASH_FILESYSTEM = 1
|
||||
|
||||
CIRCUITPY_AUDIOBUSIO = 1
|
||||
CIRCUITPY_AUDIOBUSIO_PDMIN = 0
|
||||
CIRCUITPY_AUDIOCORE = 1
|
||||
CIRCUITPY_AUDIOIO = 0
|
||||
CIRCUITPY_AUDIOBUSIO = 0
|
||||
CIRCUITPY_AUDIOMIXER = 1
|
||||
CIRCUITPY_AUDIOMP3 = 1
|
||||
CIRCUITPY_BUSDEVICE = 1
|
||||
CIRCUITPY_COUNTIO = 0
|
||||
CIRCUITPY_FREQUENCYIO = 0
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "py/mphal.h"
|
||||
#include "mimxrt10xx/periph.h"
|
||||
|
||||
LPI2C_Type *mcu_i2c_banks[2] = { LPI2C1, LPI2C2 };
|
||||
LPI2C_Type *const mcu_i2c_banks[2] = { LPI2C1, LPI2C2 };
|
||||
|
||||
const mcu_periph_obj_t mcu_i2c_sda_list[8] = {
|
||||
PERIPH_PIN(1, 0, kIOMUXC_LPI2C1_SDA_SELECT_INPUT, 0, &pin_GPIO_AD_13),
|
||||
|
@ -55,7 +55,7 @@ const mcu_periph_obj_t mcu_i2c_scl_list[8] = {
|
|||
PERIPH_PIN(2, 3, kIOMUXC_LPI2C2_SCL_SELECT_INPUT, 3, &pin_GPIO_10),
|
||||
};
|
||||
|
||||
LPSPI_Type *mcu_spi_banks[2] = { LPSPI1, LPSPI2 };
|
||||
LPSPI_Type *const mcu_spi_banks[2] = { LPSPI1, LPSPI2 };
|
||||
|
||||
const mcu_periph_obj_t mcu_spi_sck_list[4] = {
|
||||
PERIPH_PIN(1, 0, kIOMUXC_LPSPI1_SCK_SELECT_INPUT, 0, &pin_GPIO_AD_06),
|
||||
|
@ -81,7 +81,7 @@ const mcu_periph_obj_t mcu_spi_miso_list[4] = {
|
|||
PERIPH_PIN(2, 1, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 1, &pin_GPIO_SD_09),
|
||||
};
|
||||
|
||||
LPUART_Type *mcu_uart_banks[4] = { LPUART1, LPUART2, LPUART3, LPUART4 };
|
||||
LPUART_Type *const mcu_uart_banks[4] = { LPUART1, LPUART2, LPUART3, LPUART4 };
|
||||
|
||||
const mcu_periph_obj_t mcu_uart_rx_list[9] = {
|
||||
PERIPH_PIN(1, 2, kIOMUXC_LPUART1_RXD_SELECT_INPUT, 0, &pin_GPIO_SD_11),
|
||||
|
@ -166,3 +166,28 @@ const mcu_pwm_obj_t mcu_pwm_list[20] = {
|
|||
|
||||
PWM_PIN(PWM1, kPWM_Module_3, kPWM_PwmX, IOMUXC_GPIO_AD_09_FLEXPWM1_PWM3_X, &pin_GPIO_AD_09),
|
||||
};
|
||||
|
||||
const mcu_periph_obj_t mcu_sai_rx_bclk_list[] = {
|
||||
PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_08),
|
||||
PERIPH_PIN(2, 1, 0, 0, &pin_GPIO_00),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_rx_data0_list[] = {
|
||||
PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_03),
|
||||
PERIPH_PIN(2, 1, 0, 0, &pin_GPIO_SD_03),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_rx_sync_list[] = {
|
||||
PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_02),
|
||||
PERIPH_PIN(2, 1, 0, 0, &pin_GPIO_SD_04),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_tx_bclk_list[] = {
|
||||
PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_06),
|
||||
PERIPH_PIN(2, 1, 0, 0, &pin_GPIO_SD_01),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_tx_data0_list[] = {
|
||||
PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_04),
|
||||
PERIPH_PIN(2, 1, 0, 0, &pin_GPIO_SD_02),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_tx_sync_list[] = {
|
||||
PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_07),
|
||||
PERIPH_PIN(2, 1, 0, 0, &pin_GPIO_SD_00),
|
||||
};
|
||||
|
|
|
@ -27,18 +27,18 @@
|
|||
#ifndef MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H
|
||||
#define MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H
|
||||
|
||||
extern LPI2C_Type *mcu_i2c_banks[2];
|
||||
extern LPI2C_Type *const mcu_i2c_banks[2];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_i2c_sda_list[8];
|
||||
extern const mcu_periph_obj_t mcu_i2c_scl_list[8];
|
||||
|
||||
extern LPSPI_Type *mcu_spi_banks[2];
|
||||
extern LPSPI_Type *const mcu_spi_banks[2];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_spi_sck_list[4];
|
||||
extern const mcu_periph_obj_t mcu_spi_mosi_list[4];
|
||||
extern const mcu_periph_obj_t mcu_spi_miso_list[4];
|
||||
|
||||
extern LPUART_Type *mcu_uart_banks[4];
|
||||
extern LPUART_Type *const mcu_uart_banks[4];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_uart_rx_list[9];
|
||||
extern const mcu_periph_obj_t mcu_uart_tx_list[9];
|
||||
|
@ -47,4 +47,11 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[4];
|
|||
|
||||
extern const mcu_pwm_obj_t mcu_pwm_list[20];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_sai_rx_bclk_list[2];
|
||||
extern const mcu_periph_obj_t mcu_sai_rx_data0_list[2];
|
||||
extern const mcu_periph_obj_t mcu_sai_rx_sync_list[2];
|
||||
extern const mcu_periph_obj_t mcu_sai_tx_bclk_list[2];
|
||||
extern const mcu_periph_obj_t mcu_sai_tx_data0_list[2];
|
||||
extern const mcu_periph_obj_t mcu_sai_tx_sync_list[2];
|
||||
|
||||
#endif // MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1011_PERIPHERALS_MIMXRT1011_PERIPH_H
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "py/mphal.h"
|
||||
#include "mimxrt10xx/periph.h"
|
||||
|
||||
LPI2C_Type *mcu_i2c_banks[4] = { LPI2C1, LPI2C2, LPI2C3, LPI2C4 };
|
||||
LPI2C_Type *const mcu_i2c_banks[4] = { LPI2C1, LPI2C2, LPI2C3, LPI2C4 };
|
||||
|
||||
const mcu_periph_obj_t mcu_i2c_sda_list[8] = {
|
||||
PERIPH_PIN(1, 6, kIOMUXC_LPI2C1_SDA_SELECT_INPUT, 0, &pin_GPIO_EMC_03),
|
||||
|
@ -60,7 +60,7 @@ const mcu_periph_obj_t mcu_i2c_scl_list[8] = {
|
|||
PERIPH_PIN(4, 3, kIOMUXC_LPI2C4_SCL_SELECT_INPUT, 1, &pin_GPIO_SD_B1_02),
|
||||
};
|
||||
|
||||
LPSPI_Type *mcu_spi_banks[4] = { LPSPI1, LPSPI2, LPSPI3, LPSPI4 };
|
||||
LPSPI_Type *const mcu_spi_banks[4] = { LPSPI1, LPSPI2, LPSPI3, LPSPI4 };
|
||||
|
||||
const mcu_periph_obj_t mcu_spi_sck_list[8] = {
|
||||
PERIPH_PIN(1, 4, kIOMUXC_LPSPI1_SCK_SELECT_INPUT, 0, &pin_GPIO_SD_B0_02),
|
||||
|
@ -104,7 +104,7 @@ const mcu_periph_obj_t mcu_spi_miso_list[8] = {
|
|||
PERIPH_PIN(4, 4, kIOMUXC_LPSPI2_SDI_SELECT_INPUT, 1, &pin_GPIO_EMC_35),
|
||||
};
|
||||
|
||||
LPUART_Type *mcu_uart_banks[8] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 };
|
||||
LPUART_Type *const mcu_uart_banks[8] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 };
|
||||
|
||||
const mcu_periph_obj_t mcu_uart_rx_list[16] = {
|
||||
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_07),
|
||||
|
@ -256,3 +256,58 @@ const mcu_pwm_obj_t mcu_pwm_list[39] = {
|
|||
PWM_PIN(PWM2, kPWM_Module_2, kPWM_PwmX, IOMUXC_GPIO_EMC_12_FLEXPWM2_PWMX02, &pin_GPIO_EMC_12),
|
||||
PWM_PIN(PWM2, kPWM_Module_3, kPWM_PwmX, IOMUXC_GPIO_EMC_13_FLEXPWM2_PWMX03, &pin_GPIO_EMC_13),
|
||||
};
|
||||
|
||||
const mcu_periph_obj_t mcu_sai_rx_bclk_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_14),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_19),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_06),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_09),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_02),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_29),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_09),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_rx_data0_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_13),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_21),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_05),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_08),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_03),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_30),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_11),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_rx_sync_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_15),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_28),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_04),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_07),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_01),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_30),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_10),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_tx_bclk_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_11),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_26),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_01),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_04),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_04),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_33),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B0_06),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_tx_data0_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_12),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_25),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_03),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_06),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_04),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_32),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_08),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_tx_sync_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_10),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_27),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_02),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_05),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_SD_B0_06),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_34),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_07),
|
||||
};
|
||||
|
|
|
@ -25,21 +25,20 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PERIPH_H
|
||||
#define MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PERIPH_H
|
||||
#pragma once
|
||||
|
||||
extern LPI2C_Type *mcu_i2c_banks[4];
|
||||
extern LPI2C_Type *const mcu_i2c_banks[4];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_i2c_sda_list[8];
|
||||
extern const mcu_periph_obj_t mcu_i2c_scl_list[8];
|
||||
|
||||
extern LPSPI_Type *mcu_spi_banks[4];
|
||||
extern LPSPI_Type *const mcu_spi_banks[4];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_spi_sck_list[8];
|
||||
extern const mcu_periph_obj_t mcu_spi_mosi_list[8];
|
||||
extern const mcu_periph_obj_t mcu_spi_miso_list[8];
|
||||
|
||||
extern LPUART_Type *mcu_uart_banks[8];
|
||||
extern LPUART_Type *const mcu_uart_banks[8];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_uart_rx_list[16];
|
||||
extern const mcu_periph_obj_t mcu_uart_tx_list[16];
|
||||
|
@ -48,4 +47,9 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[10];
|
|||
|
||||
extern const mcu_pwm_obj_t mcu_pwm_list[39];
|
||||
|
||||
#endif // MICROPY_INCLUDED_MIMXRT10XX_PERIPHERALS_MIMXRT1021_PERIP_H
|
||||
extern const mcu_periph_obj_t mcu_sai_rx_bclk_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_rx_data0_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_rx_sync_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_tx_bclk_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_tx_data0_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_tx_sync_list[7];
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "py/mphal.h"
|
||||
#include "mimxrt10xx/periph.h"
|
||||
|
||||
LPI2C_Type *mcu_i2c_banks[4] = { LPI2C1, LPI2C2, LPI2C3, LPI2C4 };
|
||||
LPI2C_Type *const mcu_i2c_banks[4] = { LPI2C1, LPI2C2, LPI2C3, LPI2C4 };
|
||||
|
||||
const mcu_periph_obj_t mcu_i2c_sda_list[9] = {
|
||||
PERIPH_PIN(1, 2, kIOMUXC_LPI2C1_SDA_SELECT_INPUT, 0, &pin_GPIO_SD_B1_05),
|
||||
|
@ -61,7 +61,7 @@ const mcu_periph_obj_t mcu_i2c_scl_list[9] = {
|
|||
PERIPH_PIN(4, 0, kIOMUXC_LPI2C4_SCL_SELECT_INPUT, 1, &pin_GPIO_AD_B0_12),
|
||||
};
|
||||
|
||||
LPSPI_Type *mcu_spi_banks[4] = { LPSPI1, LPSPI2, LPSPI3, LPSPI4 };
|
||||
LPSPI_Type *const mcu_spi_banks[4] = { LPSPI1, LPSPI2, LPSPI3, LPSPI4 };
|
||||
|
||||
const mcu_periph_obj_t mcu_spi_sck_list[8] = {
|
||||
PERIPH_PIN(1, 3, kIOMUXC_LPSPI1_SCK_SELECT_INPUT, 0, &pin_GPIO_EMC_27),
|
||||
|
@ -105,7 +105,7 @@ const mcu_periph_obj_t mcu_spi_miso_list[8] = {
|
|||
PERIPH_PIN(4, 1, kIOMUXC_LPSPI4_SDI_SELECT_INPUT, 1, &pin_GPIO_B1_05),
|
||||
};
|
||||
|
||||
LPUART_Type *mcu_uart_banks[8] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 };
|
||||
LPUART_Type *const mcu_uart_banks[8] = { LPUART1, LPUART2, LPUART3, LPUART4, LPUART5, LPUART6, LPUART7, LPUART8 };
|
||||
|
||||
const mcu_periph_obj_t mcu_uart_rx_list[18] = {
|
||||
PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B0_13),
|
||||
|
@ -306,3 +306,59 @@ const mcu_pwm_obj_t mcu_pwm_list[67] = {
|
|||
PWM_PIN(PWM4, kPWM_Module_3, kPWM_PwmB, IOMUXC_GPIO_EMC_18_FLEXPWM4_PWMB03, &pin_GPIO_EMC_18),
|
||||
|
||||
};
|
||||
|
||||
const mcu_periph_obj_t mcu_sai_rx_bclk_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_11),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B0_15),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_05),
|
||||
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_10),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_06),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_35),
|
||||
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_00),
|
||||
};
|
||||
|
||||
const mcu_periph_obj_t mcu_sai_rx_data0_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B1_00),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_12),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_06),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_08),
|
||||
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_08),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_33),
|
||||
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_00),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_rx_sync_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_11),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B0_15),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_05),
|
||||
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_09),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_06),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_34),
|
||||
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_05),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_tx_bclk_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_08),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B1_02),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_14),
|
||||
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_AD_B0_05),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_06),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_38),
|
||||
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_03),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_tx_data0_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_13),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B1_01),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_07),
|
||||
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_04),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_09),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_36),
|
||||
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_01),
|
||||
};
|
||||
const mcu_periph_obj_t mcu_sai_tx_sync_list[] = {
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_15),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B1_03),
|
||||
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_09),
|
||||
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_AD_B0_04),
|
||||
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_05),
|
||||
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_39),
|
||||
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_02),
|
||||
};
|
||||
|
|
|
@ -27,18 +27,18 @@
|
|||
#ifndef MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H
|
||||
#define MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H
|
||||
|
||||
extern LPI2C_Type *mcu_i2c_banks[4];
|
||||
extern LPI2C_Type *const mcu_i2c_banks[4];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_i2c_sda_list[9];
|
||||
extern const mcu_periph_obj_t mcu_i2c_scl_list[9];
|
||||
|
||||
extern LPSPI_Type *mcu_spi_banks[4];
|
||||
extern LPSPI_Type *const mcu_spi_banks[4];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_spi_sck_list[8];
|
||||
extern const mcu_periph_obj_t mcu_spi_mosi_list[8];
|
||||
extern const mcu_periph_obj_t mcu_spi_miso_list[8];
|
||||
|
||||
extern LPUART_Type *mcu_uart_banks[8];
|
||||
extern LPUART_Type *const mcu_uart_banks[8];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_uart_rx_list[18];
|
||||
extern const mcu_periph_obj_t mcu_uart_tx_list[18];
|
||||
|
@ -47,4 +47,11 @@ extern const mcu_periph_obj_t mcu_uart_cts_list[9];
|
|||
|
||||
extern const mcu_pwm_obj_t mcu_pwm_list[67];
|
||||
|
||||
extern const mcu_periph_obj_t mcu_sai_rx_bclk_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_rx_data0_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_rx_sync_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_tx_bclk_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_tx_data0_list[7];
|
||||
extern const mcu_periph_obj_t mcu_sai_tx_sync_list[7];
|
||||
|
||||
#endif // MICROPY_INCLUDED_MIMXRT10XX_MIMXRT1062_PERIPHERALS_MIMXRT1011_PERIPH_H
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "pins.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t bank_idx : 4;
|
||||
uint8_t bank_idx : 4; // e.g. the peripheral number
|
||||
uint8_t mux_mode : 4;
|
||||
uint32_t input_reg;
|
||||
uint8_t input_idx;
|
||||
|
@ -72,9 +72,9 @@ typedef struct {
|
|||
.pin = p_pin, \
|
||||
}
|
||||
|
||||
extern LPI2C_Type *mcu_i2c_banks[];
|
||||
extern LPSPI_Type *mcu_spi_banks[];
|
||||
extern LPUART_Type *mcu_uart_banks[];
|
||||
extern LPI2C_Type *const mcu_i2c_banks[];
|
||||
extern LPSPI_Type *const mcu_spi_banks[];
|
||||
extern LPUART_Type *const mcu_uart_banks[];
|
||||
|
||||
#ifdef MIMXRT1011_SERIES
|
||||
#include "MIMXRT1011/periph.h"
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
|
||||
#include "fsl_device_registers.h"
|
||||
|
||||
#if CIRCUITPY_AUDIOBUSIO
|
||||
#include "common-hal/audiobusio/__init__.h"
|
||||
#endif
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/pwmio/PWMOut.h"
|
||||
#include "common-hal/rtc/RTC.h"
|
||||
|
@ -414,8 +418,7 @@ void reset_port(void) {
|
|||
audioout_reset();
|
||||
#endif
|
||||
#if CIRCUITPY_AUDIOBUSIO
|
||||
i2sout_reset();
|
||||
// pdmin_reset();
|
||||
i2s_reset();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_TOUCHIO && CIRCUITPY_TOUCHIO_USE_NATIVE
|
||||
|
|
Loading…
Reference in New Issue