forked from micropython/micropython
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: IFX-Anusha <Anusha.TR@infineon.com>
- Loading branch information
1 parent
7d0014b
commit c363aaa
Showing
5 changed files
with
268 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters