3838#include "hal/timer_hal.h"
3939#include "hal/timer_ll.h"
4040#include "soc/timer_periph.h"
41+ #include "soc/soc_caps.h"
4142
4243#define TIMER_DIVIDER 8
4344
@@ -87,10 +88,40 @@ STATIC void machine_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_pr
8788 mp_printf (print , "Timer(%u, mode=%q, period=%lu)" , (self -> group << 1 ) | self -> index , mode , period );
8889}
8990
91+ STATIC bool find_free_timer (mp_int_t * group , mp_int_t * index ) {
92+ // from highest to lowest id
93+ for (* group = SOC_TIMER_GROUPS - 1 ; * group >= 0 ; -- (* group )) {
94+ for (* index = SOC_TIMER_GROUP_TIMERS_PER_GROUP - 1 ; * index >= 0 ; -- (* index )) {
95+ bool free = true;
96+ // Check whether the timer is already initialized, if so skip it
97+ for (machine_timer_obj_t * t = MP_STATE_PORT (machine_timer_obj_head ); t ; t = t -> next ) {
98+ if (t -> group == * group && t -> index == * index ) {
99+ free = false;
100+ break ;
101+ }
102+ }
103+ if (free ) {
104+ return true;
105+ }
106+ }
107+ }
108+ return false;
109+ }
110+
90111STATIC 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 ) {
91112 mp_arg_check_num (n_args , n_kw , 1 , MP_OBJ_FUN_ARGS_MAX , true);
92- mp_uint_t group = (mp_obj_get_int (args [0 ]) >> 1 ) & 1 ;
93- mp_uint_t index = mp_obj_get_int (args [0 ]) & 1 ;
113+ mp_int_t group = (mp_obj_get_int (args [0 ]) >> 1 ) & 1 ;
114+ mp_int_t index = mp_obj_get_int (args [0 ]) & 1 ;
115+
116+ mp_int_t id = mp_obj_get_int (args [0 ]);
117+ if (id == -2 ) {
118+ if (!find_free_timer (& group , & index )) {
119+ mp_raise_msg_varg (& mp_type_RuntimeError , MP_ERROR_TEXT ("out of Timers:%d" ), SOC_TIMER_GROUP_TOTAL_TIMERS );
120+ }
121+ } else if ((id < 0 ) || (id > SOC_TIMER_GROUP_TOTAL_TIMERS )) {
122+ mp_raise_msg_varg (& mp_type_ValueError , MP_ERROR_TEXT ("id must be from 0 to %d" ), SOC_TIMER_GROUP_TOTAL_TIMERS );
123+
124+ }
94125
95126 machine_timer_obj_t * self = NULL ;
96127
@@ -110,6 +141,8 @@ STATIC mp_obj_t machine_timer_make_new(const mp_obj_type_t *type, size_t n_args,
110141 // Add the timer to the linked-list of timers
111142 self -> next = MP_STATE_PORT (machine_timer_obj_head );
112143 MP_STATE_PORT (machine_timer_obj_head ) = self ;
144+ } else {
145+ mp_raise_msg (& mp_type_RuntimeError , MP_ERROR_TEXT ("already used" ));
113146 }
114147
115148 if (n_args > 1 || n_kw > 0 ) {
0 commit comments