Add I2S MCLK support to iMX RT

This commit is contained in:
Scott Shawcroft 2023-08-17 11:39:14 -07:00
parent d0f313c1e8
commit 8c5c73df38
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
23 changed files with 122 additions and 11 deletions

View File

@ -98,7 +98,10 @@ void i2sout_reset(void) {
// Caller validates that pins are free. // Caller validates that pins are free.
void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, 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 *bit_clock, const mcu_pin_obj_t *word_select,
const mcu_pin_obj_t *data, bool left_justified) { const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) {
if (main_clock != NULL) {
mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_main_clock);
}
uint8_t serializer = 0xff; uint8_t serializer = 0xff;
uint8_t bc_clock_unit = 0xff; uint8_t bc_clock_unit = 0xff;
uint8_t ws_clock_unit = 0xff; uint8_t ws_clock_unit = 0xff;

View File

@ -49,8 +49,10 @@
// Caller validates that pins are free. // Caller validates that pins are free.
void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, 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 *bit_clock, const mcu_pin_obj_t *word_select,
const mcu_pin_obj_t *data, bool left_justified) { const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) {
if (main_clock != NULL) {
mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_main_clock);
}
port_i2s_allocate_init(&self->peripheral, left_justified); port_i2s_allocate_init(&self->peripheral, left_justified);
i2s_pin_config_t i2s_pin_config = { i2s_pin_config_t i2s_pin_config = {

View File

@ -74,13 +74,22 @@ STATIC void config_periph_pin(const mcu_periph_obj_t *periph) {
// Caller validates that pins are free. // Caller validates that pins are free.
void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, 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 *bit_clock, const mcu_pin_obj_t *word_select,
const mcu_pin_obj_t *data, bool left_justified) { const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) {
int instance = -1; int instance = -1;
const mcu_periph_obj_t *bclk_periph = find_pin_function(mcu_i2s_tx_bclk_list, bit_clock, &instance, MP_QSTR_bit_clock); const mcu_periph_obj_t *bclk_periph = find_pin_function(mcu_i2s_tx_bclk_list, bit_clock, &instance, MP_QSTR_bit_clock);
const mcu_periph_obj_t *sync_periph = find_pin_function(mcu_i2s_tx_sync_list, word_select, &instance, MP_QSTR_word_select); const mcu_periph_obj_t *sync_periph = find_pin_function(mcu_i2s_tx_sync_list, word_select, &instance, MP_QSTR_word_select);
const mcu_periph_obj_t *data_periph = find_pin_function(mcu_i2s_tx_data0_list, data, &instance, MP_QSTR_data); const mcu_periph_obj_t *data_periph = find_pin_function(mcu_i2s_tx_data0_list, data, &instance, MP_QSTR_data);
if (main_clock != NULL) {
const mcu_periph_obj_t *mclk_periph = find_pin_function(mcu_i2s_mclk_list, main_clock, &instance, MP_QSTR_main_clock);
self->mclk = main_clock;
claim_pin(main_clock);
config_periph_pin(mclk_periph);
IOMUXC_GPR->GPR1 |= IOMUXC_GPR_GPR1_SAI1_MCLK_DIR_MASK << (instance - 1);
}
self->instance = instance;
sai_transceiver_t config; sai_transceiver_t config;
SAI_GetClassicI2SConfig(&config, 16, kSAI_Stereo, 1); SAI_GetClassicI2SConfig(&config, 16, kSAI_Stereo, 1);
config.syncMode = kSAI_ModeAsync; config.syncMode = kSAI_ModeAsync;
@ -121,6 +130,11 @@ void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t *self) {
common_hal_reset_pin(self->data); common_hal_reset_pin(self->data);
self->data = NULL; self->data = NULL;
IOMUXC_GPR->GPR1 &= ~(IOMUXC_GPR_GPR1_SAI1_MCLK_DIR_MASK << (self->instance - 1));
common_hal_reset_pin(self->mclk);
self->mclk = NULL;
} }
void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self,

View File

@ -39,6 +39,8 @@ typedef struct {
const mcu_pin_obj_t *bit_clock; const mcu_pin_obj_t *bit_clock;
const mcu_pin_obj_t *word_select; const mcu_pin_obj_t *word_select;
const mcu_pin_obj_t *data; const mcu_pin_obj_t *data;
const mcu_pin_obj_t *mclk;
uint8_t instance;
} audiobusio_i2sout_obj_t; } audiobusio_i2sout_obj_t;
#endif #endif

View File

@ -174,6 +174,12 @@ const mcu_periph_obj_t mcu_i2s_tx_sync_list[2] = {
PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_SD_00), PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_SD_00),
}; };
const mcu_periph_obj_t mcu_i2s_mclk_list[2] = {
PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_08),
PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_00),
};
const mcu_periph_obj_t mcu_mqs_left_list[1] = { const mcu_periph_obj_t mcu_mqs_left_list[1] = {
PERIPH_PIN(3, 4, 0, 0, &pin_GPIO_AD_01), PERIPH_PIN(3, 4, 0, 0, &pin_GPIO_AD_01),
}; };

View File

@ -56,6 +56,7 @@ extern const mcu_periph_obj_t mcu_i2s_rx_sync_list[2];
extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[2]; extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[2];
extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[2]; extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[2];
extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[2]; extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[2];
extern const mcu_periph_obj_t mcu_i2s_mclk_list[2];
extern const mcu_periph_obj_t mcu_mqs_left_list[1]; extern const mcu_periph_obj_t mcu_mqs_left_list[1];
extern const mcu_periph_obj_t mcu_mqs_right_list[1]; extern const mcu_periph_obj_t mcu_mqs_right_list[1];

View File

@ -159,6 +159,16 @@ const mcu_periph_obj_t mcu_i2s_tx_sync_list[4] = {
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_07), PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_07),
}; };
const mcu_periph_obj_t mcu_i2s_mclk_list[5] = {
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_20),
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B0_03),
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_16),
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_17),
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_SD_B1_05),
};
const mcu_periph_obj_t mcu_mqs_left_list[2] = { const mcu_periph_obj_t mcu_mqs_left_list[2] = {
PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_EMC_17), PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_EMC_17),
PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_07), PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_07),

View File

@ -56,6 +56,7 @@ extern const mcu_periph_obj_t mcu_i2s_rx_sync_list[3];
extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[4]; extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[4];
extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[4]; extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[4];
extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[4]; extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[4];
extern const mcu_periph_obj_t mcu_i2s_mclk_list[5];
extern const mcu_periph_obj_t mcu_mqs_left_list[2]; extern const mcu_periph_obj_t mcu_mqs_left_list[2];
extern const mcu_periph_obj_t mcu_mqs_right_list[2]; extern const mcu_periph_obj_t mcu_mqs_right_list[2];

View File

@ -268,6 +268,20 @@ const mcu_periph_obj_t mcu_i2s_tx_sync_list[7] = {
PERIPH_PIN(3, 3, kIOMUXC_SAI3_TX_SYNC_SELECT_INPUT, 1, &pin_GPIO_EMC_34), PERIPH_PIN(3, 3, kIOMUXC_SAI3_TX_SYNC_SELECT_INPUT, 1, &pin_GPIO_EMC_34),
}; };
const mcu_periph_obj_t mcu_i2s_mclk_list[9] = {
PERIPH_PIN(1, 2, kIOMUXC_SAI1_MCLK_SELECT_INPUT, 0, &pin_GPIO_SD_B0_00),
PERIPH_PIN(1, 3, kIOMUXC_SAI1_MCLK_SELECT_INPUT, 1, &pin_GPIO_AD_B0_03),
PERIPH_PIN(1, 3, kIOMUXC_SAI1_MCLK_SELECT_INPUT, 2, &pin_GPIO_AD_B1_00),
PERIPH_PIN(1, 3, kIOMUXC_SAI1_MCLK_SELECT_INPUT, 3, &pin_GPIO_EMC_20),
PERIPH_PIN(2, 3, kIOMUXC_SAI2_MCLK_SELECT_INPUT, 0, &pin_GPIO_SD_B0_00),
PERIPH_PIN(2, 3, kIOMUXC_SAI2_MCLK_SELECT_INPUT, 1, &pin_GPIO_EMC_16),
PERIPH_PIN(3, 3, kIOMUXC_SAI3_MCLK_SELECT_INPUT, 0, &pin_GPIO_SD_B1_05),
PERIPH_PIN(3, 3, kIOMUXC_SAI3_MCLK_SELECT_INPUT, 1, &pin_GPIO_EMC_17),
PERIPH_PIN(3, 3, kIOMUXC_SAI3_MCLK_SELECT_INPUT, 2, &pin_GPIO_EMC_28),
};
const mcu_periph_obj_t mcu_mqs_left_list[3] = { const mcu_periph_obj_t mcu_mqs_left_list[3] = {
PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_EMC_17), PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_EMC_17),
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_38), PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_38),

View File

@ -56,6 +56,7 @@ extern const mcu_periph_obj_t mcu_i2s_rx_sync_list[7];
extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[7]; extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[7];
extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[7]; extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[7];
extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[7]; extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[7];
extern const mcu_periph_obj_t mcu_i2s_mclk_list[9];
extern const mcu_periph_obj_t mcu_mqs_left_list[3]; extern const mcu_periph_obj_t mcu_mqs_left_list[3];
extern const mcu_periph_obj_t mcu_mqs_right_list[3]; extern const mcu_periph_obj_t mcu_mqs_right_list[3];

View File

@ -254,6 +254,17 @@ const mcu_periph_obj_t mcu_i2s_tx_sync_list[6] = {
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_02), PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_02),
}; };
const mcu_periph_obj_t mcu_i2s_mclk_list[6] = {
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B0_13),
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_03),
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_07),
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_10),
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_37),
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_04),
};
const mcu_periph_obj_t mcu_mqs_left_list[3] = { const mcu_periph_obj_t mcu_mqs_left_list[3] = {
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_14), PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_14),
PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_05), PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_05),

View File

@ -56,6 +56,7 @@ extern const mcu_periph_obj_t mcu_i2s_rx_sync_list[6];
extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[6]; extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[6];
extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[6]; extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[6];
extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[6]; extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[6];
extern const mcu_periph_obj_t mcu_i2s_mclk_list[6];
extern const mcu_periph_obj_t mcu_mqs_left_list[3]; extern const mcu_periph_obj_t mcu_mqs_left_list[3];
extern const mcu_periph_obj_t mcu_mqs_right_list[3]; extern const mcu_periph_obj_t mcu_mqs_right_list[3];

View File

@ -267,6 +267,17 @@ const mcu_periph_obj_t mcu_i2s_tx_sync_list[6] = {
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_39), PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_39),
}; };
const mcu_periph_obj_t mcu_i2s_mclk_list[6] = {
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_09),
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B0_13),
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_03),
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_07),
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_10),
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_37),
};
const mcu_periph_obj_t mcu_mqs_left_list[3] = { const mcu_periph_obj_t mcu_mqs_left_list[3] = {
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_14), PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_14),
PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_05), PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_05),

View File

@ -56,6 +56,7 @@ extern const mcu_periph_obj_t mcu_i2s_rx_sync_list[6];
extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[6]; extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[6];
extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[6]; extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[6];
extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[6]; extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[6];
extern const mcu_periph_obj_t mcu_i2s_mclk_list[6];
extern const mcu_periph_obj_t mcu_mqs_left_list[3]; extern const mcu_periph_obj_t mcu_mqs_left_list[3];
extern const mcu_periph_obj_t mcu_mqs_right_list[3]; extern const mcu_periph_obj_t mcu_mqs_right_list[3];

View File

@ -272,6 +272,18 @@ const mcu_periph_obj_t mcu_i2s_tx_sync_list[7] = {
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_02), PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_02),
}; };
const mcu_periph_obj_t mcu_i2s_mclk_list[7] = {
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_AD_B1_09),
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_B0_13),
PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_SD_B1_03),
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_07),
PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_AD_B0_10),
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_37),
PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_SD_B1_04),
};
const mcu_periph_obj_t mcu_mqs_left_list[3] = { const mcu_periph_obj_t mcu_mqs_left_list[3] = {
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_14), PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_14),
PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_05), PERIPH_PIN(3, 1, 0, 0, &pin_GPIO_AD_B0_05),

View File

@ -56,6 +56,7 @@ extern const mcu_periph_obj_t mcu_i2s_rx_sync_list[7];
extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[7]; extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[7];
extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[7]; extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[7];
extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[7]; extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[7];
extern const mcu_periph_obj_t mcu_i2s_mclk_list[7];
extern const mcu_periph_obj_t mcu_mqs_left_list[3]; extern const mcu_periph_obj_t mcu_mqs_left_list[3];
extern const mcu_periph_obj_t mcu_mqs_right_list[3]; extern const mcu_periph_obj_t mcu_mqs_right_list[3];

View File

@ -237,6 +237,15 @@ const mcu_periph_obj_t mcu_i2s_tx_sync_list[4] = {
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_B2_16), PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_B2_16),
}; };
const mcu_periph_obj_t mcu_i2s_mclk_list[4] = {
PERIPH_PIN(1, 0, 0, 0, &pin_GPIO_AD_17),
PERIPH_PIN(1, 4, 0, 0, &pin_GPIO_DISP_B2_03),
PERIPH_PIN(2, 2, 0, 0, &pin_GPIO_EMC_B2_04),
PERIPH_PIN(3, 3, 0, 0, &pin_GPIO_EMC_B2_17),
};
const mcu_periph_obj_t mcu_mqs_left_list[2] = { const mcu_periph_obj_t mcu_mqs_left_list[2] = {
PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_EMC_B1_41), PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_EMC_B1_41),
PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_DISP_B2_01), PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_DISP_B2_01),

View File

@ -56,6 +56,7 @@ extern const mcu_periph_obj_t mcu_i2s_rx_sync_list[4];
extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[4]; extern const mcu_periph_obj_t mcu_i2s_tx_bclk_list[4];
extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[4]; extern const mcu_periph_obj_t mcu_i2s_tx_data0_list[4];
extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[4]; extern const mcu_periph_obj_t mcu_i2s_tx_sync_list[4];
extern const mcu_periph_obj_t mcu_i2s_mclk_list[4];
extern const mcu_periph_obj_t mcu_mqs_left_list[2]; extern const mcu_periph_obj_t mcu_mqs_left_list[2];
extern const mcu_periph_obj_t mcu_mqs_right_list[2]; extern const mcu_periph_obj_t mcu_mqs_right_list[2];

View File

@ -6,7 +6,7 @@ SIGNALS = {
"LPI2C": ["SDA", "SCL"], "LPI2C": ["SDA", "SCL"],
"LPSPI": ["SCK", "SDO", "SDI"], "LPSPI": ["SCK", "SDO", "SDI"],
"LPUART": ["RX", "TX", "RTS", "CTS"], "LPUART": ["RX", "TX", "RTS", "CTS"],
"I2S": ["RX_DATA0", "RX_SYNC", "TX_BCLK", "TX_DATA0", "TX_SYNC"], "I2S": ["RX_DATA0", "RX_SYNC", "TX_BCLK", "TX_DATA0", "TX_SYNC", "MCLK"],
"MQS": ["LEFT", "RIGHT"], "MQS": ["LEFT", "RIGHT"],
} }

View File

@ -202,7 +202,10 @@ static void i2s_buffer_fill(audiobusio_i2sout_obj_t *self) {
void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, 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 *bit_clock, const mcu_pin_obj_t *word_select,
const mcu_pin_obj_t *data, bool left_justified) { const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) {
if (main_clock != NULL) {
mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_main_clock);
}
if (instance) { if (instance) {
mp_raise_RuntimeError(translate("Device in use")); mp_raise_RuntimeError(translate("Device in use"));
} }

View File

@ -103,7 +103,10 @@ void i2sout_reset(void) {
// Caller validates that pins are free. // Caller validates that pins are free.
void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, 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 *bit_clock, const mcu_pin_obj_t *word_select,
const mcu_pin_obj_t *data, bool left_justified) { const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) {
if (main_clock != NULL) {
mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_main_clock);
}
if (bit_clock->number != word_select->number - 1) { if (bit_clock->number != word_select->number - 1) {
mp_raise_ValueError(translate("Bit clock and word select must be sequential pins")); mp_raise_ValueError(translate("Bit clock and word select must be sequential pins"));
} }

View File

@ -44,13 +44,15 @@
//| word_select: microcontroller.Pin, //| word_select: microcontroller.Pin,
//| data: microcontroller.Pin, //| data: microcontroller.Pin,
//| *, //| *,
//| left_justified: bool //| main_clock: microcontroller.Pin = None,
//| left_justified: bool = False
//| ) -> None: //| ) -> None:
//| """Create a I2SOut object associated with the given pins. //| """Create a I2SOut object associated with the given pins.
//| //|
//| :param ~microcontroller.Pin bit_clock: The bit clock (or serial clock) pin //| :param ~microcontroller.Pin bit_clock: The bit clock (or serial clock) pin
//| :param ~microcontroller.Pin word_select: The word select (or left/right clock) pin //| :param ~microcontroller.Pin word_select: The word select (or left/right clock) pin
//| :param ~microcontroller.Pin data: The data pin //| :param ~microcontroller.Pin data: The data pin
//| :param ~microcontroller.Pin main_clock: The main clock pin
//| :param bool left_justified: True when data bits are aligned with the word select clock. False //| :param bool left_justified: True when data bits are aligned with the word select clock. False
//| when they are shifted by one to match classic I2S protocol. //| when they are shifted by one to match classic I2S protocol.
//| //|
@ -100,11 +102,12 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a
mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_I2SOut); mp_raise_NotImplementedError_varg(translate("%q"), MP_QSTR_I2SOut);
return NULL; // Not reachable. return NULL; // Not reachable.
#else #else
enum { ARG_bit_clock, ARG_word_select, ARG_data, ARG_left_justified }; enum { ARG_bit_clock, ARG_word_select, ARG_data, ARG_main_clock, ARG_left_justified };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_bit_clock, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_bit_clock, MP_ARG_OBJ | MP_ARG_REQUIRED },
{ MP_QSTR_word_select, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_word_select, MP_ARG_OBJ | MP_ARG_REQUIRED },
{ MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED },
{ MP_QSTR_main_clock, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
{ MP_QSTR_left_justified, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_left_justified, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = false} },
}; };
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@ -113,10 +116,11 @@ STATIC mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a
const mcu_pin_obj_t *bit_clock = validate_obj_is_free_pin(args[ARG_bit_clock].u_obj, MP_QSTR_bit_clock); const mcu_pin_obj_t *bit_clock = validate_obj_is_free_pin(args[ARG_bit_clock].u_obj, MP_QSTR_bit_clock);
const mcu_pin_obj_t *word_select = validate_obj_is_free_pin(args[ARG_word_select].u_obj, MP_QSTR_word_select); const mcu_pin_obj_t *word_select = validate_obj_is_free_pin(args[ARG_word_select].u_obj, MP_QSTR_word_select);
const mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj, MP_QSTR_data); const mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj, MP_QSTR_data);
const mcu_pin_obj_t *main_clock = validate_obj_is_free_pin_or_none(args[ARG_main_clock].u_obj, MP_QSTR_main_clock);
audiobusio_i2sout_obj_t *self = m_new_obj_with_finaliser(audiobusio_i2sout_obj_t); audiobusio_i2sout_obj_t *self = m_new_obj_with_finaliser(audiobusio_i2sout_obj_t);
self->base.type = &audiobusio_i2sout_type; self->base.type = &audiobusio_i2sout_type;
common_hal_audiobusio_i2sout_construct(self, bit_clock, word_select, data, args[ARG_left_justified].u_bool); common_hal_audiobusio_i2sout_construct(self, bit_clock, word_select, data, main_clock, args[ARG_left_justified].u_bool);
return MP_OBJ_FROM_PTR(self); return MP_OBJ_FROM_PTR(self);
#endif #endif

View File

@ -37,7 +37,7 @@ extern const mp_obj_type_t audiobusio_i2sout_type;
void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, 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, const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, const mcu_pin_obj_t *data,
bool left_justified); const mcu_pin_obj_t *main_clock, bool left_justified);
void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t *self); void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t *self);
bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t *self); bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t *self);