Skip to content

Commit

Permalink
ports/psoc6: Timer Module.
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 Jul 11, 2023
1 parent 0617c88 commit 4474015
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 54 deletions.
1 change: 1 addition & 0 deletions ports/psoc6/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
118 changes: 64 additions & 54 deletions ports/psoc6/modules/machine/machine_timer.c
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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[] = {
Expand All @@ -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(
Expand Down
1 change: 1 addition & 0 deletions ports/psoc6/modules/machine/modmachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

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 @@ -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
Expand Down

0 comments on commit 4474015

Please sign in to comment.