57{
58 const uint32_t SOURCE_CLOCK = clock_freq_;
59 if (config.frequency > SOURCE_CLOCK || config.frequency == 0)
60 {
61 return ErrorCode::ARG_ERR;
62 }
63
64 const uint32_t TOTAL_CYCLES_NEEDED = SOURCE_CLOCK / config.frequency;
65 uint32_t min_total_prescale = (TOTAL_CYCLES_NEEDED + MAX_TIMER_LOAD) >> 16;
66 if (min_total_prescale == 0)
67 {
68 min_total_prescale = 1;
69 }
70
71 uint32_t best_div = (min_total_prescale + MAX_PRESCALER - 1) >> 8;
72 if (best_div > MAX_DIVIDE_RATIO)
73 {
74 return ErrorCode::NOT_SUPPORT;
75 }
76 if (best_div == 0)
77 {
78 best_div = 1;
79 }
80
81 uint32_t best_prescaler = (min_total_prescale + best_div - 1) / best_div;
82 if (best_prescaler == 0)
83 {
84 best_prescaler = 1;
85 }
86
87 uint32_t best_load = (SOURCE_CLOCK / (best_div * best_prescaler * config.frequency));
88 if (best_load > 0)
89 {
90 best_load -= 1;
91 }
92
93 DL_Timer_ClockConfig clock_config;
94 DL_Timer_getClockConfig(timer_, &clock_config);
95
96 clock_config.divideRatio = static_cast<DL_TIMER_CLOCK_DIVIDE>(best_div - 1);
97 clock_config.prescale = static_cast<uint8_t>(best_prescaler - 1);
98
99 DL_Timer_setClockConfig(timer_, &clock_config);
100 DL_Timer_setLoadValue(timer_, best_load);
101
102 return ErrorCode::OK;
103}