i2s basic api

This commit is contained in:
0x1abin
2018-03-16 11:37:01 +08:00
parent 113cab65e9
commit 3ee6b4a00e
@@ -31,7 +31,7 @@
#include "py/mperrno.h"
typedef enum {
I2S, I2S_MERUS, DAC_BUILT_IN, PDM
I2S, DAC_BUILT_IN, PDM, I2S_MERUS
} output_mode_t;
@@ -46,59 +46,45 @@ typedef struct {
extern const mp_obj_type_t machine_i2s_type;
// STATIC mp_obj_t machine_i2s_obj_set_pin(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
STATIC void machine_i2s_obj_init_helper(machine_i2s_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_mode, ARG_bclk, ARG_ws, ARG_data_out, ARG_data_in, ARG_samplerate, ARG_bitdepth, ARG_channel, ARG_volume};
enum { ARG_mode, ARG_rate, ARG_bits, ARG_channel_format, ARG_comm_format, ARG_dma_count, ARG_dma_len};
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DAC_BUILT_IN} },
{ MP_QSTR_bclk, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 2} },
{ MP_QSTR_ws, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 13} },
{ MP_QSTR_data_out, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5} },
{ MP_QSTR_data_in, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_samplerate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 48000} },
{ MP_QSTR_bitdepth, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16} },
{ MP_QSTR_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 2} },
{ MP_QSTR_volume, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 80} },
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DAC_BUILT_IN} },
{ MP_QSTR_rate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16000} },
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16} },
{ MP_QSTR_channel_format, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = I2S_CHANNEL_FMT_RIGHT_LEFT} },
{ MP_QSTR_data_format, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = I2S_COMM_FORMAT_I2S_MSB} },
{ MP_QSTR_dma_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 4} },
{ MP_QSTR_dma_len, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1024} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
output_mode_t mode = args[ARG_mode].u_int;
self->output_mode = mode;
self->config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX | (mode == DAC_BUILT_IN ? I2S_MODE_DAC_BUILT_IN : 0));
self->config.sample_rate = args[ARG_samplerate].u_int;
self->config.bits_per_sample = args[ARG_bitdepth].u_int;
self->config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;
self->config.communication_format = (i2s_comm_format_t)((mode == DAC_BUILT_IN ? 0 : I2S_COMM_FORMAT_I2S) | I2S_COMM_FORMAT_I2S_MSB);
self->config.mode = (i2s_mode_t)(args[ARG_mode].u_int);
self->config.sample_rate = (int)args[ARG_rate].u_int;
self->config.bits_per_sample = (i2s_bits_per_sample_t)args[ARG_bits].u_int;
self->config.channel_format = (i2s_channel_fmt_t)args[ARG_channel_format].u_int;
self->config.communication_format = (i2s_comm_format_t)args[ARG_data_format].u_int;
self->config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, //Interrupt level 1
self->config.dma_buf_count = 4;
self->config.dma_buf_len = 1024;
self->config.dma_buf_count = (int)args[ARG_dma_count].u_int;
self->config.dma_buf_len = (int)args[ARG_dma_len].u_int;
self->config.use_apll = 0;
self->num_channels = args[ARG_channel].u_int;
self->volume = args[ARG_volume].u_int;
self->num_channels = 2;
self->volume = 100;
if (i2s_driver_install(self->port, &self->config, 0, NULL) != ESP_OK) {
mp_raise_ValueError("I2S: failed to enable");
}
if (mode == DAC_BUILT_IN) {
if ((self->config.mode & I2S_MODE_DAC_BUILT_IN) || (self->config.mod & I2S_MODE_PDM)) {
i2s_set_pin(self->port, NULL);
i2s_set_dac_mode(I2S_DAC_CHANNEL_RIGHT_EN);
} else {
i2s_pin_config_t pin_config = {
.bck_io_num = args[ARG_bclk].u_int,
.ws_io_num = args[ARG_ws].u_int,
.data_out_num = args[ARG_data_out].u_int,
.data_in_num = args[ARG_data_in].u_int,
};
if (i2s_set_pin(self->port, &pin_config) != ESP_OK) {
i2s_driver_uninstall(self->port);
mp_raise_ValueError("I2S: failed to set pins in");
}
}
i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN); // default
}
i2s_set_clk(self->port, self->config.sample_rate, self->config.bits_per_sample, self->num_channels);
// i2s_zero_dma_buffer(self->port);
}
//----------------------------------------------------------------------
@@ -141,7 +127,7 @@ STATIC mp_obj_t machine_i2s_obj_deinit(mp_obj_t self_in) {
MP_DEFINE_CONST_FUN_OBJ_1(machine_i2s_deinit_obj, machine_i2s_obj_deinit);
//-----------------------------------------------------------------------
STATIC mp_obj_t machine_i2s_obj_sample_rates(mp_obj_t self_in, mp_obj_t rate) {
STATIC mp_obj_t machine_i2s_sample_rates(mp_obj_t self_in, mp_obj_t rate) {
machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
self->config.sample_rate = mp_obj_get_int(rate);
@@ -149,10 +135,10 @@ STATIC mp_obj_t machine_i2s_obj_sample_rates(mp_obj_t self_in, mp_obj_t rate) {
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_set_sample_rates_obj, machine_i2s_obj_sample_rates);
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_sample_rates_obj, machine_i2s_sample_rates);
//-----------------------------------------------------------------------
STATIC mp_obj_t machine_i2s_obj_bits_per_sample(mp_obj_t self_in, mp_obj_t bits) {
STATIC mp_obj_t machine_i2s_bits_per_sample(mp_obj_t self_in, mp_obj_t bits) {
machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
self->config.bits_per_sample = (i2s_bits_per_sample_t)mp_obj_get_int(bits);
@@ -160,10 +146,10 @@ STATIC mp_obj_t machine_i2s_obj_bits_per_sample(mp_obj_t self_in, mp_obj_t bits)
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_obj_bits_per_sample_obj, machine_i2s_obj_bits_per_sample);
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_bits_per_sample_obj, machine_i2s_bits_per_sample);
//-----------------------------------------------------------------------
STATIC mp_obj_t machine_i2s_obj_set_channel(mp_obj_t self_in, mp_obj_t channel) {
STATIC mp_obj_t machine_i2s_set_channel(mp_obj_t self_in, mp_obj_t channel) {
machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
self->num_channels = (i2s_channel_t)mp_obj_get_int(channel);
@@ -171,7 +157,62 @@ STATIC mp_obj_t machine_i2s_obj_set_channel(mp_obj_t self_in, mp_obj_t channel)
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_obj_set_channel_obj, machine_i2s_obj_set_channel);
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_set_channel_obj, machine_i2s_set_channel);
//-----------------------------------------------------------------------
STATIC mp_obj_t machine_i2s_set_dac_mode(mp_obj_t self_in, mp_obj_t dac_mode) {
machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint8_t _dac_mode = mp_obj_get_int(dac_mode);
if (self->port == I2S_NUM_0) {
i2s_set_dac_mode((i2s_dac_mode_t)_dac_mode);
} else {
mp_raise_ValueError("PDM and built-in DAC functions are only supported on I2S0 for current ESP32 chip.");
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_set_dac_mode_obj, machine_i2s_set_dac_mode);
//-------------------------------------------------------------------------------------------------
STATIC mp_obj_t machine_i2s_set_pin(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
const mp_arg_t allowed_args[] = {
{ MP_QSTR_bck, MP_ARG_REQUIRED | MP_ARG_INT, { .u_int = 0 } },
{ MP_QSTR_ws, MP_ARG_REQUIRED | MP_ARG_INT, { .u_int = 0 } },
{ MP_QSTR_out, MP_ARG_REQUIRED | MP_ARG_INT, { .u_int = 0 } },
{ MP_QSTR_in, MP_ARG_INT, { .u_int = -1 } },
};
machine_i2s_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
mp_int_t bck_io_num = args[0].u_int;
mp_int_t ws_io_num = args[1].u_int;
mp_int_t data_out_num = args[2].u_int;
mp_int_t data_in_num = -1;
if (args[3].u_int >= 0) {
mp_int_t data_in_num = args[3].u_int;
}
i2s_pin_config_t pin_config = {
.bck_io_num = bck_io_num,
.ws_io_num = ws_io_num,
.data_out_num = data_out_num,
.data_in_num = data_in_num,
};
if (i2s_set_pin(self->port, &pin_config) != ESP_OK) {
i2s_driver_uninstall(self->port);
mp_raise_ValueError("I2S: failed to set pins in");
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2s_set_pin_obj, 3, machine_i2s_set_pin);
//-----------------------------------------------------------------------
STATIC mp_obj_t machine_i2s_obj_set_volume(mp_obj_t self_in, mp_obj_t volume) {
@@ -184,7 +225,7 @@ STATIC mp_obj_t machine_i2s_obj_set_volume(mp_obj_t self_in, mp_obj_t volume) {
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_obj_set_volume_obj, machine_i2s_obj_set_volume);
//----------------------------------------------------------------------
STATIC mp_obj_t machine_i2s_obj_write(const mp_obj_t self_in, mp_obj_t buf_in) {
STATIC mp_obj_t machine_i2s_write(const mp_obj_t self_in, mp_obj_t buf_in) {
const machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t bufinfo;
@@ -196,7 +237,28 @@ STATIC mp_obj_t machine_i2s_obj_write(const mp_obj_t self_in, mp_obj_t buf_in) {
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_write_obj, machine_i2s_obj_write);
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_write_obj, machine_i2s_write);
//----------------------------------------------------------------------
STATIC mp_obj_t machine_i2s_read(const mp_obj_t self_in, mp_obj_t buf_len) {
const machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint8_t *rdbuf = malloc(buf_len);
if (i2s_read_bytes(self->port, (char*)rdbuf, buf_len, portMAX_DELAY) == ESP_FAIL) {
mp_raise_OSError(MP_EIO);
return mp_const_none;
}
mp_obj_t res = mp_const_none;
if (rdbuf) res = mp_obj_new_str_of_type(&mp_type_bytes, (byte*)rdbuf, buf_len);
else res = mp_obj_new_str_of_type(&mp_type_bytes, (byte*)"", 0);
if (rdbuf) free(rdbuf);
return res;
}
MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_read_obj, machine_i2s_read);
//----------------------------------------------------------------------
STATIC mp_obj_t machine_i2s_obj_stream_out(const mp_obj_t self_in, mp_obj_t buf_in) {
@@ -278,19 +340,49 @@ MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_obj_stream_out_obj, machine_i2s_obj_stream
//----------------------------------------------------------------------
STATIC const mp_rom_map_elem_t machine_i2s_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_i2s_init_obj)},
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_i2s_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&machine_i2s_set_sample_rates_obj) },
{ MP_ROM_QSTR(MP_QSTR_bits_per_sample), MP_ROM_PTR(&machine_i2s_obj_bits_per_sample_obj) },
{ MP_ROM_QSTR(MP_QSTR_channel), MP_ROM_PTR(&machine_i2s_obj_set_channel_obj) },
{ MP_ROM_QSTR(MP_QSTR_volume), MP_ROM_PTR(&machine_i2s_obj_set_volume_obj) },
{ MP_ROM_QSTR(MP_QSTR_stream_out), MP_ROM_PTR(&machine_i2s_obj_stream_out_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&machine_i2s_write_obj) },
// Standard methods
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_i2s_init_obj)},
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_i2s_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&machine_i2s_sample_rates_obj) },
{ MP_ROM_QSTR(MP_QSTR_bits), MP_ROM_PTR(&machine_i2s_bits_per_sample_obj) },
{ MP_ROM_QSTR(MP_QSTR_nchannel), MP_ROM_PTR(&machine_i2s_set_channel_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_pin), MP_ROM_PTR(&machine_i2s_set_pin_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_dac_mode), MP_ROM_PTR(&machine_i2s_set_dac_mode_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&machine_i2s_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&machine_i2s_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_MODE_IN_DAC), MP_ROM_INT(DAC_BUILT_IN) },
{ MP_ROM_QSTR(MP_QSTR_MODE_I2S), MP_ROM_INT(I2S) },
{ MP_ROM_QSTR(MP_QSTR_I2S_NUM_0), MP_ROM_INT(I2S_NUM_0) },
{ MP_ROM_QSTR(MP_QSTR_I2S_NUM_1), MP_ROM_INT(I2S_NUM_1) },
{ MP_ROM_QSTR(MP_QSTR_volume), MP_ROM_PTR(&machine_i2s_obj_set_volume_obj) },
{ MP_ROM_QSTR(MP_QSTR_stream_out), MP_ROM_PTR(&machine_i2s_obj_stream_out_obj) },
// Constants
{ MP_ROM_QSTR(MP_QSTR_I2S_NUM_0), MP_ROM_INT(I2S_NUM_0) },
{ MP_ROM_QSTR(MP_QSTR_I2S_NUM_1), MP_ROM_INT(I2S_NUM_1) },
{ MP_ROM_QSTR(MP_QSTR_MODE_MASTER), MP_ROM_INT(I2S_MODE_MASTER) },
{ MP_ROM_QSTR(MP_QSTR_MODE_SLAVE), MP_ROM_INT(I2S_MODE_SLAVE) },
{ MP_ROM_QSTR(MP_QSTR_MODE_TX), MP_ROM_INT(I2S_MODE_TX) },
{ MP_ROM_QSTR(MP_QSTR_MODE_RX), MP_ROM_INT(I2S_MODE_RX) },
{ MP_ROM_QSTR(MP_QSTR_MODE_DAC_BUILT_IN), MP_ROM_INT(I2S_MODE_DAC_BUILT_IN) },
{ MP_ROM_QSTR(MP_QSTR_MODE_ADC_BUILT_IN), MP_ROM_INT(I2S_MODE_ADC_BUILT_IN) },
{ MP_ROM_QSTR(MP_QSTR_MODE_PDM), MP_ROM_INT(I2S_MODE_PDM) },
{ MP_ROM_QSTR(MP_QSTR_FORMAT_I2S), MP_ROM_INT(I2S_COMM_FORMAT_I2S) },
{ MP_ROM_QSTR(MP_QSTR_FORMAT_I2S_MSB), MP_ROM_INT(I2S_COMM_FORMAT_I2S_MSB) },
{ MP_ROM_QSTR(MP_QSTR_FORMAT_I2S_LSB), MP_ROM_INT(I2S_COMM_FORMAT_I2S_LSB) },
{ MP_ROM_QSTR(MP_QSTR_FORMAT_PCM), MP_ROM_INT(I2S_COMM_FORMAT_PCM) },
{ MP_ROM_QSTR(MP_QSTR_FORMAT_PCM_SHORT), MP_ROM_INT(I2S_COMM_FORMAT_PCM_SHORT) },
{ MP_ROM_QSTR(MP_QSTR_FORMAT_PCM_LONG), MP_ROM_INT(I2S_COMM_FORMAT_PCM_LONG) },
{ MP_ROM_QSTR(MP_QSTR_CHANNEL_RIGHT_LEFT),MP_ROM_INT(I2S_CHANNEL_FMT_RIGHT_LEFT) },
{ MP_ROM_QSTR(MP_QSTR_CHANNEL_ALL_RIGHT), MP_ROM_INT(I2S_CHANNEL_FMT_ALL_RIGHT) },
{ MP_ROM_QSTR(MP_QSTR_CHANNEL_ALL_LEFT), MP_ROM_INT(I2S_CHANNEL_FMT_ALL_LEFT) },
{ MP_ROM_QSTR(MP_QSTR_CHANNEL_ONLY_RIGHT),MP_ROM_INT(I2S_CHANNEL_FMT_ONLY_RIGHT) },
{ MP_ROM_QSTR(MP_QSTR_CHANNEL_ONLY_LEFT), MP_ROM_INT(I2S_CHANNEL_FMT_ONLY_LEFT) },
{ MP_ROM_QSTR(MP_QSTR_DAC_DISABLE), MP_ROM_INT(I2S_DAC_CHANNEL_DISABLE) },
{ MP_ROM_QSTR(MP_QSTR_DAC_RIGHT_EN), MP_ROM_INT(I2S_DAC_CHANNEL_RIGHT_EN) },
{ MP_ROM_QSTR(MP_QSTR_DAC_LEFT_EN), MP_ROM_INT(I2S_DAC_CHANNEL_LEFT_EN) },
{ MP_ROM_QSTR(MP_QSTR_DAC_BOTH_EN), MP_ROM_INT(I2S_DAC_CHANNEL_BOTH_EN) },
};
STATIC MP_DEFINE_CONST_DICT(machine_i2s_locals_dict, machine_i2s_locals_dict_table);
@@ -300,4 +392,4 @@ const mp_obj_type_t machine_i2s_type = {
.name = MP_QSTR_I2S,
.make_new = machine_i2s_make_new,
.locals_dict = (mp_obj_dict_t*)&machine_i2s_locals_dict,
};
};