maple "mavica" syrup 2024-04-25 22:52:05 +02:00 zatwierdzone przez GitHub
commit 0b68e13184
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
4 zmienionych plików z 103 dodań i 28 usunięć

Wyświetl plik

@ -82,7 +82,7 @@ other things. For these drivers see:
Constructor
-----------
.. class:: I2S(id, *, sck, ws, sd, mck=None, mode, bits, format, rate, ibuf)
.. class:: I2S(id, *, sck, ws=None, sd, mck=None, mode, bits, format, rate, ibuf)
Construct an I2S object of the given id:
@ -91,7 +91,8 @@ Constructor
Keyword-only parameters that are supported on all ports:
- ``sck`` is a pin object for the serial clock line
- ``ws`` is a pin object for the word select line
- ``ws`` is a pin object for the word select line;
can be left unset if using ``I2S.PDM_RX`` mode
- ``sd`` is a pin object for the serial data line
- ``mck`` is a pin object for the master clock line;
master clock frequency is sampling rate * 256
@ -155,6 +156,10 @@ Constants
for initialising the I2S bus ``mode`` to transmit
.. data:: I2S.PDM_RX
for initialising the I2S bus ``mode`` to receive in PDM mode
.. data:: I2S.STEREO
for initialising the I2S bus ``format`` to stereo

Wyświetl plik

@ -344,7 +344,11 @@ static void copy_appbuf_to_ringbuf_non_blocking(machine_i2s_obj_t *self) {
MP_NOINLINE static void machine_i2s_init_helper(machine_i2s_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_sck, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
#if MICROPY_PY_MACHINE_PDM
{ MP_QSTR_ws, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
#else
{ MP_QSTR_ws, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
#endif
{ MP_QSTR_sd, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
#if MICROPY_PY_MACHINE_I2S_MCK
{ MP_QSTR_mck, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
@ -517,6 +521,9 @@ static const mp_rom_map_elem_t machine_i2s_locals_dict_table[] = {
// Constants
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_INT(MICROPY_PY_MACHINE_I2S_CONSTANT_RX) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_INT(MICROPY_PY_MACHINE_I2S_CONSTANT_TX) },
#if MICROPY_PY_MACHINE_PDM
{ MP_ROM_QSTR(MP_QSTR_PDM_RX), MP_ROM_INT(MICROPY_PY_MACHINE_I2S_PDM_RX) },
#endif
{ MP_ROM_QSTR(MP_QSTR_STEREO), MP_ROM_INT(STEREO) },
{ MP_ROM_QSTR(MP_QSTR_MONO), MP_ROM_INT(MONO) },
};
@ -525,10 +532,18 @@ MP_DEFINE_CONST_DICT(machine_i2s_locals_dict, machine_i2s_locals_dict_table);
static mp_uint_t machine_i2s_stream_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
#if MICROPY_PY_MACHINE_PDM
if ((self->mode != MICROPY_PY_MACHINE_I2S_CONSTANT_RX) &&
(self->mode != MICROPY_PY_MACHINE_I2S_PDM_RX)) {
*errcode = MP_EPERM;
return MP_STREAM_ERROR;
}
#else
if (self->mode != MICROPY_PY_MACHINE_I2S_CONSTANT_RX) {
*errcode = MP_EPERM;
return MP_STREAM_ERROR;
}
#endif
uint8_t appbuf_sample_size_in_bytes = (self->bits / 8) * (self->format == STEREO ? 2: 1);
if (size % appbuf_sample_size_in_bytes != 0) {
@ -623,10 +638,18 @@ static mp_uint_t machine_i2s_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_
ret = 0;
if (flags & MP_STREAM_POLL_RD) {
#if MICROPY_PY_MACHINE_PDM
if ((self->mode != MICROPY_PY_MACHINE_I2S_CONSTANT_RX) &&
(self->mode != MICROPY_PY_MACHINE_I2S_PDM_RX)) {
*errcode = MP_EPERM;
return MP_STREAM_ERROR;
}
#else
if (self->mode != MICROPY_PY_MACHINE_I2S_CONSTANT_RX) {
*errcode = MP_EPERM;
return MP_STREAM_ERROR;
}
#endif
#if MICROPY_PY_MACHINE_I2S_RING_BUF
if (!ringbuf_is_empty(&self->ring_buffer)) {

Wyświetl plik

@ -29,6 +29,9 @@
#include "py/mphal.h"
#include "driver/i2s_std.h"
#if MICROPY_PY_MACHINE_PDM
#include "driver/i2s_pdm.h"
#endif
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
@ -125,6 +128,9 @@ static int8_t get_frame_mapping_index(i2s_data_bit_width_t bits, format_t format
static i2s_data_bit_width_t get_dma_bits(uint8_t mode, i2s_data_bit_width_t bits) {
if (mode == MICROPY_PY_MACHINE_I2S_CONSTANT_TX) {
return bits;
} else if (mode == MICROPY_PY_MACHINE_I2S_PDM_RX) { // PDM Rx
// fixed to 16-bit per ESP-IDF documentation
return I2S_DATA_BIT_WIDTH_16BIT;
} else { // Master Rx
// read 32 bit samples for I2S hardware. e.g. MEMS microphones
return I2S_DATA_BIT_WIDTH_32BIT;
@ -132,7 +138,8 @@ static i2s_data_bit_width_t get_dma_bits(uint8_t mode, i2s_data_bit_width_t bits
}
static i2s_slot_mode_t get_dma_format(uint8_t mode, format_t format) {
if (mode == MICROPY_PY_MACHINE_I2S_CONSTANT_TX) {
if ((mode == MICROPY_PY_MACHINE_I2S_CONSTANT_TX) ||
(mode == MICROPY_PY_MACHINE_I2S_PDM_RX)) {
if (format == MONO) {
return I2S_SLOT_MODE_MONO;
} else { // STEREO
@ -305,15 +312,20 @@ i2s_event_callbacks_t i2s_callbacks_null = {
};
static void mp_machine_i2s_init_helper(machine_i2s_obj_t *self, mp_arg_val_t *args) {
int8_t mode = args[ARG_mode].u_int;
int8_t ws = -1;
// are Pins valid?
int8_t sck = args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sck].u_obj);
int8_t ws = args[ARG_ws].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_ws].u_obj);
if (mode != (MICROPY_PY_MACHINE_I2S_PDM_RX)) {
ws = args[ARG_ws].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_ws].u_obj);
}
int8_t sd = args[ARG_sd].u_obj == MP_OBJ_NULL ? -1 : machine_pin_get_id(args[ARG_sd].u_obj);
// is Mode valid?
int8_t mode = args[ARG_mode].u_int;
if ((mode != (MICROPY_PY_MACHINE_I2S_CONSTANT_RX)) &&
(mode != (MICROPY_PY_MACHINE_I2S_CONSTANT_TX))) {
(mode != (MICROPY_PY_MACHINE_I2S_CONSTANT_TX)) &&
(mode != (MICROPY_PY_MACHINE_I2S_PDM_RX))) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid mode"));
}
@ -368,33 +380,64 @@ static void mp_machine_i2s_init_helper(machine_i2s_obj_t *self, mp_arg_val_t *ar
ESP_ERROR_CHECK(i2s_new_channel(&chan_config, NULL, &self->i2s_chan_handle));
}
i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(get_dma_bits(mode, bits), get_dma_format(mode, format));
slot_cfg.slot_mask = I2S_STD_SLOT_BOTH;
if (mode != MICROPY_PY_MACHINE_I2S_PDM_RX) {
i2s_std_slot_config_t slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(get_dma_bits(mode, bits), get_dma_format(mode, format));
slot_cfg.slot_mask = I2S_STD_SLOT_BOTH;
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(self->rate),
.slot_cfg = slot_cfg,
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = self->sck,
.ws = self->ws,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(self->rate),
.slot_cfg = slot_cfg,
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = self->sck,
.ws = self->ws,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
},
},
},
};
};
if (mode == MICROPY_PY_MACHINE_I2S_CONSTANT_TX) {
std_cfg.gpio_cfg.dout = self->sd;
std_cfg.gpio_cfg.din = I2S_GPIO_UNUSED;
} else { // rx
std_cfg.gpio_cfg.dout = I2S_GPIO_UNUSED;
std_cfg.gpio_cfg.din = self->sd;
if (mode == MICROPY_PY_MACHINE_I2S_CONSTANT_TX) {
std_cfg.gpio_cfg.dout = self->sd;
std_cfg.gpio_cfg.din = I2S_GPIO_UNUSED;
} else { // rx
std_cfg.gpio_cfg.dout = I2S_GPIO_UNUSED;
std_cfg.gpio_cfg.din = self->sd;
}
ESP_ERROR_CHECK(i2s_channel_init_std_mode(self->i2s_chan_handle, &std_cfg));
} else { // PDM mode
#if MICROPY_PY_MACHINE_PDM
// PDM can only be in id 0
if (self->i2s_id != 0) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid i2s id for PDM mode"));
}
i2s_pdm_rx_slot_config_t slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(get_dma_bits(mode, bits), get_dma_format(mode, format));
slot_cfg.slot_mask = I2S_PDM_SLOT_BOTH;
i2s_pdm_rx_config_t pdm_cfg = {
.clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(self->rate),
.slot_cfg = slot_cfg,
.gpio_cfg = {
.clk = self->sck,
.din = self->sd,
.invert_flags = {
.clk_inv = false,
},
},
};
pdm_cfg.clk_cfg.dn_sample_mode = I2S_PDM_DSR_MAX;
ESP_ERROR_CHECK(i2s_channel_init_pdm_rx_mode(self->i2s_chan_handle, &pdm_cfg));
#else
mp_raise_ValueError(MP_ERROR_TEXT("invalid mode"));
#endif
}
ESP_ERROR_CHECK(i2s_channel_init_std_mode(self->i2s_chan_handle, &std_cfg));
ESP_ERROR_CHECK(i2s_channel_register_event_callback(self->i2s_chan_handle, &i2s_callbacks, self));
ESP_ERROR_CHECK(i2s_channel_enable(self->i2s_chan_handle));
}

Wyświetl plik

@ -149,6 +149,10 @@
#define MICROPY_PY_MACHINE_I2S_FINALISER (1)
#define MICROPY_PY_MACHINE_I2S_CONSTANT_RX (I2S_DIR_RX)
#define MICROPY_PY_MACHINE_I2S_CONSTANT_TX (I2S_DIR_TX)
#ifndef MICROPY_PY_MACHINE_PDM
#define MICROPY_PY_MACHINE_PDM (SOC_I2S_SUPPORTS_PDM_RX)
#endif
#define MICROPY_PY_MACHINE_I2S_PDM_RX ((I2S_DIR_RX) | (BIT(2)))
#define MICROPY_PY_MACHINE_UART (1)
#define MICROPY_PY_MACHINE_UART_INCLUDEFILE "ports/esp32/machine_uart.c"
#define MICROPY_PY_MACHINE_UART_SENDBREAK (1)