Skip to content

Commit

Permalink
constructor & init function.
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 Aug 8, 2023
1 parent 7d0014b commit c363aaa
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 0 deletions.
1 change: 1 addition & 0 deletions ports/psoc6/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ MOD_SRC_C += $(addprefix modules/,\
machine/machine_timer.c \
machine/machine_adc.c \
machine/machine_adcblock.c \
machine/machine_i2s.c\
\
psoc6/modpsoc6.c \
psoc6/psoc6_fatfs.c \
Expand Down
263 changes: 263 additions & 0 deletions ports/psoc6/modules/machine/machine_i2s.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

#include "py/obj.h"
#include "py/runtime.h"
#include "py/mphal.h"
#include "py/misc.h"
#include "py/stream.h"
#include "py/objstr.h"

// MTB includes
#include "cybsp.h"
#include "cyhal.h"

// port-specific includes
#include "drivers/machine/psoc6_gpio.h"
#include "modmachine.h"
#include "mplogger.h"
#include "pins.h"

#define MAX_I2S_PSOC6 (2)

#if MICROPY_PY_MACHINE_I2S

typedef enum {
RX,
TX
} i2s_mode_t;

typedef enum {
MONO,
STEREO
} format_t;

typedef enum {
BLOCKING,
NON_BLOCKING,
ASYNCIO
} io_mode_t;

typedef struct _machine_i2s_obj_t {
mp_obj_base_t base;
cyhal_i2s_t i2s_obj;
uint8_t i2s_id;
mp_hal_pin_obj_t sck;
mp_hal_pin_obj_t ws;
mp_hal_pin_obj_t sd;
i2s_mode_t mode;
int8_t bits;
format_t format;
int32_t rate;
int32_t ibuf;
mp_obj_t callback_for_non_blocking;
io_mode_t io_mode;
uint8_t sm;
uint prog_offset;
} machine_i2s_obj_t;

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) {

enum {
ARG_sck,
ARG_ws,
ARG_sd,
ARG_mode,
ARG_bits,
ARG_format,
ARG_rate,
ARG_ibuf,
};

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} },
{ MP_QSTR_ws, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_sd, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_format, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_rate, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_ibuf, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = -1} },
};

mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_pos_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);

// are Pins valid?
mp_hal_pin_obj_t sck = args[ARG_sck].u_obj == MP_OBJ_NULL ? -1 : mp_hal_get_pin_obj(args[ARG_sck].u_obj);
mp_hal_pin_obj_t ws = args[ARG_ws].u_obj == MP_OBJ_NULL ? -1 : mp_hal_get_pin_obj(args[ARG_ws].u_obj);
mp_hal_pin_obj_t sd = args[ARG_sd].u_obj == MP_OBJ_NULL ? -1 : mp_hal_get_pin_obj(args[ARG_sd].u_obj);


// is Mode valid?
i2s_mode_t i2s_mode = args[ARG_mode].u_int;
if ((i2s_mode != RX) &&
(i2s_mode != TX)) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid mode"));
}

// is Bits valid?
int8_t i2s_bits = args[ARG_bits].u_int;
if ((i2s_bits != 16) &&
(i2s_bits != 32)) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid bits"));
}

// is Format valid?
format_t i2s_format = args[ARG_format].u_int;
if ((i2s_format != MONO) &&
(i2s_format != STEREO)) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid format"));
}


self->sck = sck;
self->ws = ws;
self->sd = sd;
self->mode = i2s_mode;
self->bits = i2s_bits;
self->format = i2s_format;
self->rate = args[ARG_rate].u_int;
self->callback_for_non_blocking = MP_OBJ_NULL;
self->io_mode = BLOCKING;



if (i2s_mode == RX) {
cyhal_i2s_pins_t tx_pins = { .sck = self->sck, .ws = self->ws, .data = self->sd };
cyhal_i2s_config_t config =
{
.is_tx_slave = false,
.is_rx_slave = false,
.mclk_hz = 0,
.channel_length = 32,
.word_length = self->bits,
.sample_rate_hz = self->rate,
};
cy_rslt_t result = cyhal_i2s_init(&self->i2s_obj, &tx_pins, NULL, &config, NULL);
if (result != CY_RSLT_SUCCESS) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2S initialisation failed with return code %lx !"), result);
}
} else {
cyhal_i2s_pins_t rx_pins = { .sck = self->sck, .ws = self->ws, .data = self->sd };
cyhal_i2s_config_t config =
{
.is_tx_slave = false,
.is_rx_slave = true,
.mclk_hz = 0,
.channel_length = 32,
.word_length = self->bits,
.sample_rate_hz = self->rate,
};
cy_rslt_t result = cyhal_i2s_init(&self->i2s_obj, NULL, &rx_pins, &config, NULL);
if (result != CY_RSLT_SUCCESS) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("I2S initialisation failed with return code %lx !"), result);
}
}

}

STATIC mp_obj_t machine_i2s_deinit(mp_obj_t self_in) {
machine_i2s_obj_t *self = MP_OBJ_TO_PTR(self_in);
cyhal_i2s_free(&self->i2s_id);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_i2s_deinit_obj, machine_i2s_deinit);


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);
mp_printf(print, "I2S(id=%u,\n"
"sck="MP_HAL_PIN_FMT ",\n"
"ws="MP_HAL_PIN_FMT ",\n"
"sd="MP_HAL_PIN_FMT ",\n"
"mode=%u,\n"
"bits=%u, format=%u,\n"
"rate=%d, ibuf=%d)",
self->i2s_id,
mp_hal_pin_name(self->sck),
mp_hal_pin_name(self->ws),
mp_hal_pin_name(self->sd),
self->mode,
self->bits, self->format,
self->rate, self->ibuf
);
}

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 >= MAX_I2S_PSOC6) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid 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));
}
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);

return MP_OBJ_FROM_PTR(self);
}

STATIC mp_obj_t machine_i2s_init(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
machine_i2s_obj_t *self = pos_args[0];
machine_i2s_deinit(self);
machine_i2s_init_helper(self, n_pos_args - 1, pos_args + 1, kw_args);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2s_init_obj, 1, machine_i2s_init);




STATIC const mp_rom_map_elem_t machine_i2s_locals_dict_table[] = {
// Methods
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_i2s_init_obj) },
// { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
// { 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) },

// Static method
// { MP_ROM_QSTR(MP_QSTR_shift), MP_ROM_PTR(&machine_i2s_shift_obj) },

// Constants
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_INT(RX) },
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_INT(TX) },
{ MP_ROM_QSTR(MP_QSTR_STEREO), MP_ROM_INT(STEREO) },
{ MP_ROM_QSTR(MP_QSTR_MONO), MP_ROM_INT(MONO) },
};
MP_DEFINE_CONST_DICT(machine_i2s_locals_dict, machine_i2s_locals_dict_table);

STATIC const mp_stream_p_t i2s_stream_p = {
// .read = machine_i2s_stream_read,
// .write = machine_i2s_stream_write,
// .ioctl = machine_i2s_ioctl,
.is_text = false,
};

MP_DEFINE_CONST_OBJ_TYPE(
machine_i2s_type,
MP_QSTR_I2S,
MP_TYPE_FLAG_ITER_IS_STREAM,
make_new, machine_i2s_make_new,
print, machine_i2s_print,
protocol, &i2s_stream_p,
locals_dict, &machine_i2s_locals_dict
);

MP_REGISTER_ROOT_POINTER(void *machine_i2s_obj[2]);

#endif // MICROPY_PY_MACHINE_I2S
2 changes: 2 additions & 0 deletions ports/psoc6/modules/machine/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) },
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
{ MP_ROM_QSTR(MP_QSTR_ADCBlock), MP_ROM_PTR(&machine_adcblock_type) },
{ MP_ROM_QSTR(MP_QSTR_I2S), MP_ROM_PTR(&machine_i2s_type) },
};

STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);


Expand Down
1 change: 1 addition & 0 deletions ports/psoc6/modules/machine/modmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ extern const mp_obj_type_t machine_spi_type;
extern const mp_obj_type_t machine_timer_type;
extern const mp_obj_type_t machine_adc_type;
extern const mp_obj_type_t machine_adcblock_type;
extern const mp_obj_type_t machine_i2s_type;

/* Note: the static functions' prototypes in the .c file cannot be declared here
since they are static. The static type in those functions come from MPY hence
Expand Down
1 change: 1 addition & 0 deletions ports/psoc6/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
#define MICROPY_PY_MACHINE_PWM_INCLUDEFILE "ports/psoc6/modules/machine/machine_pwm.c"
#define MICROPY_PY_MACHINE_I2C (1)
#define MICROPY_PY_MACHINE_SOFTI2C (1)
#define MICROPY_PY_MACHINE_I2S (1)

#define MICROPY_PY_MACHINE_SPI (1)
#define MICROPY_PY_MACHINE_SPI_MSB (0)
Expand Down

0 comments on commit c363aaa

Please sign in to comment.