Skip to content

Commit

Permalink
ports/psoc6: Stop function,multiple instances & I2S Doc.
Browse files Browse the repository at this point in the history
Signed-off-by: IFX-Anusha <Anusha.TR@infineon.com>
  • Loading branch information
IFX-Anusha committed Nov 17, 2023
1 parent f1d7bb4 commit f6313a9
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 9 deletions.
4 changes: 3 additions & 1 deletion docs/psoc6/feature_list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ Table :ref:`configuration details <table_mpy_configuration>` below lists specifi
+-----------------+----------------------------------------------------------------------------------------------------------------------+
| machine.Timer | mode = Timer.PERIODIC is not supported |
+-----------------+----------------------------------------------------------------------------------------------------------------------+
| machine.SPI | Option ``MICROPY_PY_MACHINE_SPI``, ``MICROPY_PY_MACHINE_SPI_MSB`` , ``MICROPY_PY_MACHINE_SPI_MSB`` enabled. |
| machine.SPI | Option ``MICROPY_PY_MACHINE_SPI``, ``MICROPY_PY_MACHINE_SPI_MSB`` , ``MICROPY_PY_MACHINE_SPI_MSB`` enabled. |
+-----------------+----------------------------------------------------------------------------------------------------------------------+
| machine.I2S | Non Blocking Mode & asyncio mode is not supported |
+-----------------+----------------------------------------------------------------------------------------------------------------------+
| psoc6 | Option to enable the external instead of the internal flash: ``MICROPY_ENABLE_EXT_QSPI_FLASH``. |
| | |
Expand Down
36 changes: 36 additions & 0 deletions docs/psoc6/quickref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,39 @@ To use the APIs:
adc = adcBlock.connect(0, "P10_0") # connect channel 0 to pin P10_0
val = adc.read_uv() # read an analog value in micro volts

I2S bus
-------

See :ref:`machine.I2S <machine.I2S>`.

PSoC6 implements additional method which is explained below.

Methods
^^^^^^^
.. method:: I2S.stop()

This method is to stop either the transmission or reception. This function should be called by user once the readinto or
write is done.

::

from machine import I2S, Pin
import array
buf=bytearray(10) #Initilase buffer with required values for transmission & as empty buffer for reception

audio_out = I2S(0, sck="P13_1", ws="P13_2", sd="P13_3", mode=I2S.TX, bits=16, format=I2S.STEREO, rate=22050, ibuf=20000) #create I2S object
num_written = audio_out.write(buf) # write buffer of audio samples to I2S device

audio_in = I2S(1, sck="P5_4", ws="P5_5", sd="P5_6", mode=I2S.RX, bits=16, format=I2S.STEREO, rate=22050, ibuf=20000) # create I2S object
num_read = audio_in.readinto(buf)# fill buffer with audio samples from I2S device
audio_out.stop() # stop transmission
audio_in.stop() # stop reception

PSoc6 supports two I2S Bus. So id could be either 0 or 1. Please note that if both instances are running together then the sample rate should
be either 8/16/32/48 or 22.05/44.01. Both the set of frequencies can't work together(For eg eg. 8 & 22.01 will cause error)
Supported sample rates are 8KHz, 16KHz, 32KHz, 48KHz, 22.05KHz, 44.1KHz.
PSoC6 supports only STEREO Mode.

.. note:: I2S Blocking mode is only supported

49 changes: 41 additions & 8 deletions ports/psoc6/modules/machine/machine_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
/* Clock Settings */
#define AUDIO_SYS_CLOCK_HZ 98000000u /* in Hz (Ideally 98.304 MHz) */
#define AUDIO_SYS_CLOCK_HZ_1 90000000u

uint32_t Audio_sys_clock_fz;
uint8_t clock_set;

void clock_init(void);

Expand Down Expand Up @@ -149,8 +151,11 @@ STATIC void machine_i2s_init_helper(machine_i2s_obj_t *self, size_t n_pos_args,
self->callback_for_non_blocking = MP_OBJ_NULL;
self->io_mode = BLOCKING;

clock_init();
cyhal_system_delay_ms(1);
if (clock_set == 0) {
clock_init();
cyhal_system_delay_ms(1);
}


if (i2s_mode == TX) { // TX is a master
cyhal_i2s_pins_t tx_pins = { .sck = self->sck, .ws = self->ws, .data = self->sd, .mclk = NC };
Expand Down Expand Up @@ -193,6 +198,21 @@ STATIC mp_obj_t machine_i2s_deinit(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_i2s_deinit_obj, machine_i2s_deinit);

STATIC machine_i2s_obj_t *mp_machine_i2s_make_new_instance(mp_int_t i2s_id) {

machine_i2s_obj_t *self;
if (MP_STATE_PORT(machine_i2s_obj[i2s_id]) == NULL) {
self = mp_obj_malloc(machine_i2s_obj_t, &machine_i2s_type);
MP_STATE_PORT(machine_i2s_obj[i2s_id]) = self;
self->i2s_id = i2s_id;
} else {
self = MP_STATE_PORT(machine_i2s_obj[i2s_id]);
machine_i2s_deinit(MP_OBJ_FROM_PTR(self));
}

return self;
}


STATIC void machine_i2s_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
Expand All @@ -216,12 +236,13 @@ STATIC void machine_i2s_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
STATIC mp_obj_t machine_i2s_make_new(const mp_obj_type_t *type, size_t n_pos_args, size_t n_kw_args, const mp_obj_t *args) {
mp_arg_check_num(n_pos_args, n_kw_args, 1, MP_OBJ_FUN_ARGS_MAX, true);

i2s_mode_t i2s_id = mp_obj_get_int(args[0]);
if (i2s_id != 0) {
mp_int_t i2s_id = mp_obj_get_int(args[0]);
if ((i2s_id != 0) && (i2s_id != 1)) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid id"));
}
machine_i2s_obj_t *self = mp_machine_i2s_make_new_instance(i2s_id);

machine_i2s_obj_t *self = mp_obj_malloc(machine_i2s_obj_t, &machine_i2s_type);
// machine_i2s_obj_t *self = mp_obj_malloc(machine_i2s_obj_t, &machine_i2s_type);
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw_args, args + n_pos_args);
machine_i2s_init_helper(self, n_pos_args - 1, args + 1, &kw_args);
Expand Down Expand Up @@ -257,6 +278,18 @@ STATIC mp_obj_t machine_i2s_irq(mp_obj_t self_in, mp_obj_t handler) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_i2s_irq_obj, machine_i2s_irq);

STATIC mp_obj_t machine_i2s_stop(mp_obj_t self_in) {
machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (self->mode == TX) {
cyhal_i2s_stop_tx(&self->i2s_obj);
} else {
cyhal_i2s_stop_rx(&self->i2s_obj);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_i2s_stop_obj, machine_i2s_stop);


// Shift() is typically used as a volume control.
// shift=1 increases volume by 6dB, shift=-1 decreases volume by 6dB
STATIC mp_obj_t machine_i2s_shift(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
Expand Down Expand Up @@ -323,6 +356,8 @@ void clock_init(void) {
cyhal_clock_t clock_pll;
cy_rslt_t result;

clock_set = 1;

/* Initialize, take ownership of PLL0/PLL */
result = cyhal_clock_reserve(&clock_pll, &CYHAL_CLOCK_PLL[0]);
if (CY_RSLT_SUCCESS != result) {
Expand Down Expand Up @@ -378,6 +413,7 @@ STATIC const mp_rom_map_elem_t machine_i2s_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_i2s_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_i2s_irq_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&machine_i2s_stop_obj) },

// Static method
{ MP_ROM_QSTR(MP_QSTR_shift), MP_ROM_PTR(&machine_i2s_shift_obj) },
Expand Down Expand Up @@ -435,7 +471,6 @@ STATIC mp_uint_t machine_i2s_stream_read(mp_obj_t self_in, void *buf_in, mp_uint
if (result != CY_RSLT_SUCCESS) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2S read failed with return code %lx !"), result);
}
cyhal_i2s_stop_rx(&self->i2s_obj);
return bufinfo.len;
}
}
Expand Down Expand Up @@ -476,8 +511,6 @@ STATIC mp_uint_t machine_i2s_stream_write(mp_obj_t self_in, const void *buf_in,
if (result != CY_RSLT_SUCCESS) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2S transmission failed with return code %lx !"), result);
}
cyhal_system_delay_ms(1000);
cyhal_i2s_stop_tx(&self->i2s_obj);
return bufinfo.len;
}
}
Expand Down

0 comments on commit f6313a9

Please sign in to comment.