From 4474015dd800acdab37339e8590daf18deac891e Mon Sep 17 00:00:00 2001 From: IFX-Anusha Date: Tue, 11 Jul 2023 16:38:11 +0530 Subject: [PATCH] ports/psoc6: Timer Module. Signed-off-by: IFX-Anusha --- ports/psoc6/Makefile | 1 + ports/psoc6/modules/machine/machine_timer.c | 118 +++++++++++--------- ports/psoc6/modules/machine/modmachine.c | 1 + ports/psoc6/modules/machine/modmachine.h | 1 + 4 files changed, 67 insertions(+), 54 deletions(-) diff --git a/ports/psoc6/Makefile b/ports/psoc6/Makefile index 13bdab91b3c6..1a1d72258c6d 100644 --- a/ports/psoc6/Makefile +++ b/ports/psoc6/Makefile @@ -140,6 +140,7 @@ MOD_SRC_C += $(addprefix modules/,\ machine/machine_rtc.c \ machine/machine_spi.c \ machine/pins.c \ + machine/machine_timer.c \ \ psoc6/modpsoc6.c \ psoc6/psoc6_fatfs.c \ diff --git a/ports/psoc6/modules/machine/machine_timer.c b/ports/psoc6/modules/machine/machine_timer.c index f164ea8fef1b..94b927178590 100644 --- a/ports/psoc6/modules/machine/machine_timer.c +++ b/ports/psoc6/modules/machine/machine_timer.c @@ -1,99 +1,114 @@ // mpy includes #include "py/runtime.h" -#include "extmod/machine_spi.h" #include "py/mphal.h" -#include "py/mperrno.h" -#include "extmod/machine_spi.h" + // MTB includes #include "cybsp.h" -#include "cyhal.h"s +#include "cyhal.h" + -#define ALARM_ID_INVALID (-1) #define TIMER_MODE_ONE_SHOT (0) #define TIMER_MODE_PERIODIC (1) typedef struct _machine_timer_obj_t { mp_obj_base_t base; - struct alarm_pool *pool; - alarm_id_t alarm_id; + cyhal_timer_t timer_obj; uint32_t mode; - uint64_t delta_us; // for periodic mode + uint32_t period; + uint32_t freq; mp_obj_t callback; } machine_timer_obj_t; const mp_obj_type_t machine_timer_type; -STATIC int64_t alarm_callback(alarm_id_t id, void *user_data) { - machine_timer_obj_t *self = user_data; +static void isr_timer(void *callback_arg, cyhal_timer_event_t event) { + mp_printf(&mp_plat_print, "Here isr"); + machine_timer_obj_t *self = callback_arg; mp_sched_schedule(self->callback, MP_OBJ_FROM_PTR(self)); - if (self->mode == TIMER_MODE_ONE_SHOT) { - return 0; - } else { - return -self->delta_us; - } } + STATIC void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { machine_timer_obj_t *self = MP_OBJ_TO_PTR(self_in); qstr mode = self->mode == TIMER_MODE_ONE_SHOT ? MP_QSTR_ONE_SHOT : MP_QSTR_PERIODIC; - mp_printf(print, "Timer(mode=%q, period=%u, tick_hz=1000000)", mode, self->delta_us); + mp_printf(print, "Timer(mode=%q, period=%u, tick_hz=1000)", mode, self->period); } STATIC mp_obj_t machine_timer_init_helper(machine_timer_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_mode, ARG_callback, ARG_period, ARG_tick_hz, ARG_freq, }; + enum { ARG_mode, ARG_callback, ARG_period, ARG_freq, }; static const mp_arg_t allowed_args[] = { { MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = TIMER_MODE_PERIODIC} }, { MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, - { MP_QSTR_period, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0xffffffff} }, - { MP_QSTR_tick_hz, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} }, - { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + { MP_QSTR_period, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 9999u} }, + { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 10000u} }, }; - // Parse args 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); self->mode = args[ARG_mode].u_int; - if (args[ARG_freq].u_obj != mp_const_none) { - // Frequency specified in Hz - #if MICROPY_PY_BUILTINS_FLOAT - self->delta_us = (uint64_t)(MICROPY_FLOAT_CONST(1000000.0) / mp_obj_get_float(args[ARG_freq].u_obj)); - #else - self->delta_us = 1000000 / mp_obj_get_int(args[ARG_freq].u_obj); - #endif - } else { - // Period specified - self->delta_us = (uint64_t)args[ARG_period].u_int * 1000000 / args[ARG_tick_hz].u_int; - } - if (self->delta_us < 1) { - self->delta_us = 1; - } + self->freq = args[ARG_freq].u_int; + self->period = args[ARG_period].u_int; - self->callback = args[ARG_callback].u_obj; - self->alarm_id = alarm_pool_add_alarm_in_us(self->pool, self->delta_us, alarm_callback, self, true); - if (self->alarm_id == -1) { - mp_raise_OSError(MP_ENOMEM); + if (args[ARG_callback].u_obj != mp_const_none) { + self->callback = args[ARG_callback].u_obj; } + // Timer initialisation of port + cy_rslt_t rslt; + + const cyhal_timer_cfg_t timer_cfg = + { + .compare_value = 0, /* Timer compare value, not used */ + .period = self->period, /* Defines the timer period */ + .direction = CYHAL_TIMER_DIR_UP, /* Timer counts up */ + .is_compare = false, /* Don't use compare mode */ + .is_continuous = self->mode, /* Run the timer */ + .value = 0 /* Initial value of counter */ + }; + + /* Initialize the timer object. Does not use pin output ('pin' is NC) and + * does not use a pre-configured clock source ('clk' is NULL). */ + + rslt = cyhal_timer_init(&self->timer_obj, NC, NULL); + CY_ASSERT(CY_RSLT_SUCCESS == rslt); + + /* Apply timer configuration such as period, count direction, run mode, etc. */ + rslt = cyhal_timer_configure(&self->timer_obj, &timer_cfg); + + /* Set the frequency of timer to Defined frequency */ + rslt = cyhal_timer_set_frequency(&self->timer_obj, self->freq); + + /* Assign the ISR to execute on timer interrupt */ + cyhal_timer_register_callback(&self->timer_obj, isr_timer, self); + + /* Set the event on which timer interrupt occurs and enable it */ + cyhal_timer_enable_event(&self->timer_obj, CYHAL_TIMER_IRQ_TERMINAL_COUNT, 3, true); + + /* Start the timer with the configured settings */ + rslt = cyhal_timer_start(&self->timer_obj); + + CY_ASSERT(CY_RSLT_SUCCESS == rslt); + return mp_const_none; } STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - machine_timer_obj_t *self = m_new_obj_with_finaliser(machine_timer_obj_t); + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + machine_timer_obj_t *self = mp_obj_malloc(machine_timer_obj_t, &machine_timer_type); + self->base.type = &machine_timer_type; - self->pool = alarm_pool_get_default(); - self->alarm_id = ALARM_ID_INVALID; - // Get timer id (only soft timer (-1) supported at the moment) - mp_int_t id = -1; + mp_int_t id = 0; if (n_args > 0) { id = mp_obj_get_int(args[0]); --n_args; ++args; } - if (id != -1) { - mp_raise_ValueError(MP_ERROR_TEXT("Timer doesn't exist")); + // Get timer id + if (id != 0) { + mp_raise_ValueError(MP_ERROR_TEXT("Specified Timer doesn't exist. Currently only id 0 is comfigured")); } if (n_args > 0 || n_kw > 0) { @@ -108,22 +123,16 @@ STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args, STATIC mp_obj_t machine_timer_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { machine_timer_obj_t *self = MP_OBJ_TO_PTR(args[0]); - if (self->alarm_id != ALARM_ID_INVALID) { - alarm_pool_cancel_alarm(self->pool, self->alarm_id); - self->alarm_id = ALARM_ID_INVALID; - } return machine_timer_init_helper(self, n_args - 1, args + 1, kw_args); } STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_timer_init_obj, 1, machine_timer_init); STATIC mp_obj_t machine_timer_deinit(mp_obj_t self_in) { machine_timer_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (self->alarm_id != ALARM_ID_INVALID) { - alarm_pool_cancel_alarm(self->pool, self->alarm_id); - self->alarm_id = ALARM_ID_INVALID; - } + cyhal_timer_free(&self->timer_obj); return mp_const_none; } + STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_timer_deinit_obj, machine_timer_deinit); STATIC const mp_rom_map_elem_t machine_timer_locals_dict_table[] = { @@ -134,6 +143,7 @@ STATIC const mp_rom_map_elem_t machine_timer_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_ONE_SHOT), MP_ROM_INT(TIMER_MODE_ONE_SHOT) }, { MP_ROM_QSTR(MP_QSTR_PERIODIC), MP_ROM_INT(TIMER_MODE_PERIODIC) }, }; + STATIC MP_DEFINE_CONST_DICT(machine_timer_locals_dict, machine_timer_locals_dict_table); MP_DEFINE_CONST_OBJ_TYPE( diff --git a/ports/psoc6/modules/machine/modmachine.c b/ports/psoc6/modules/machine/modmachine.c index 0fe8877ed964..ef5b71e7a363 100644 --- a/ports/psoc6/modules/machine/modmachine.c +++ b/ports/psoc6/modules/machine/modmachine.c @@ -262,6 +262,7 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&machine_pwm_type) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_spi_type) }, { MP_ROM_QSTR(MP_QSTR_SoftSPI), MP_ROM_PTR(&mp_machine_soft_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&machine_timer_type) }, }; STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table); diff --git a/ports/psoc6/modules/machine/modmachine.h b/ports/psoc6/modules/machine/modmachine.h index 6def0227f738..c4dfc139dcfc 100644 --- a/ports/psoc6/modules/machine/modmachine.h +++ b/ports/psoc6/modules/machine/modmachine.h @@ -11,6 +11,7 @@ extern const mp_obj_type_t machine_pin_type; extern const mp_obj_type_t machine_rtc_type; extern const mp_obj_type_t machine_pwm_type; extern const mp_obj_type_t machine_spi_type; +extern const mp_obj_type_t machine_timer_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