diff --git a/compiler/obc/c/async_avr.ml b/compiler/obc/c/async_avr.ml index eac9c4e..8044e15 100644 --- a/compiler/obc/c/async_avr.ml +++ b/compiler/obc/c/async_avr.ml @@ -52,10 +52,23 @@ struct let fold_lcm l = List.fold_left lcm (List.hd l) (List.tl l) + let count_of_ack base = function + | Timer_ms ms -> ms / base + + let incr_mod name modulo = + let one_const = Cconst (Ccint 1) in + let modulo_const = Cconst (Ccint modulo) in + let incr = Cbop ("+", Cvar name, one_const) in + Caffect (CLvar name, Cbop ("%", incr, modulo_const)) + let call_step_async base tick_var (od, ack) = let step = (cname_of_qn od.o_class) ^ "_async_step" in let global = async_global_var_name od in - Csexpr (Cfun_call (step, [Caddrof (Cvar global)])) + let call = Csexpr (Cfun_call (step, [Caddrof (Cvar global)])) in + let zero = Cconst (Ccint 0) in + let timer = Cconst (Ccint (count_of_ack base ack)) in + let cond = Cbop ("==", Cbop ("%", tick_var, timer), zero) in + Cif (cond, [call], []) let decls_and_defs objs = let trans = List.map @@ -68,13 +81,16 @@ struct (fun (_, ack) -> match ack with Timer_ms ms -> ms) trans in - let tick = "mod_ticks" in let body = match timers with | [] -> [] | _ -> let base_timer = fold_gcd timers in let max_timer = fold_lcm timers in - List.map (call_step_async base_timer (Cvar tick)) trans + let steps = + List.map (call_step_async base_timer (Cvar "tick")) trans + in + let incr = incr_mod "tick" (max_timer / base_timer) in + steps @ [incr] in (* run_timers is declared in avr.h (because of the ISR macro which * I don't know how to generate here) *) @@ -85,7 +101,7 @@ struct f_args = []; f_body = { var_decls = [ - mk_vardecl_val ~static:true tick Cty_int (Cconst (Ccint 0)) + mk_vardecl_val ~static:true "tick" Cty_int (Cconst (Ccint 0)) ]; block_body = body }