1313
1414#include <main.h>
1515#include <interfaces/power.h>
16+ #include <libopencm3/stm32/rcc.h>
1617#include <libopencm3/stm32/gpio.h>
18+ #include <libopencm3/stm32/timer.h>
1719#include <interfaces/dac.h>
1820
1921#include "generic-power.h"
@@ -30,9 +32,17 @@ static power_ret_t generic_power_enable(Power *self, bool enable) {
3032
3133 power -> enabled = enable ;
3234 if (enable != power -> enable_invert ) {
33- gpio_set (power -> locm3_enable_port , power -> locm3_enable_pin );
35+ if (power -> timer ) {
36+ timer_set_oc_value (power -> timer , power -> timer_oc , (uint32_t )((power -> voltage_v / power -> vref_v ) * 255.0f ));
37+ } else {
38+ gpio_set (power -> locm3_enable_port , power -> locm3_enable_pin );
39+ }
3440 } else {
35- gpio_clear (power -> locm3_enable_port , power -> locm3_enable_pin );
41+ if (power -> timer ) {
42+ timer_set_oc_value (power -> timer , power -> timer_oc , 255 - (uint32_t )((power -> voltage_v / power -> vref_v ) * 255.0f ));
43+ } else {
44+ gpio_clear (power -> locm3_enable_port , power -> locm3_enable_pin );
45+ }
3646 }
3747
3848 return POWER_RET_OK ;
@@ -42,6 +52,7 @@ static power_ret_t generic_power_enable(Power *self, bool enable) {
4252static power_ret_t generic_power_set_voltage (Power * self , float voltage_v ) {
4353 GenericPower * power = (GenericPower * )self -> parent ;
4454
55+ power -> voltage_v = voltage_v ;
4556 if (power -> dac_p == NULL || power -> vref_v == 0.0f ) {
4657 /* No DAC is set, cannot set output voltage. The same applies if we don't know the reference voltage. */
4758 return POWER_RET_FAILED ;
@@ -104,6 +115,35 @@ generic_power_ret_t generic_power_set_enable_gpio(GenericPower *self, uint32_t p
104115 return GENERIC_POWER_RET_OK ;
105116}
106117
118+
119+ generic_power_ret_t generic_power_set_pwm (GenericPower * self , uint32_t timer , enum tim_oc_id timer_oc ) {
120+ if (!(TIM_CR1 (timer ) & TIM_CR1_CEN )) {
121+ /* Timer counter is not enbaled. */
122+ timer_set_mode (timer , TIM_CR1_CKD_CK_INT , TIM_CR1_CMS_EDGE , TIM_CR1_DIR_UP );
123+ timer_continuous_mode (timer );
124+ timer_direction_up (timer );
125+ timer_enable_preload (timer );
126+ timer_enable_break_main_output (timer );
127+ timer_disable_preload (timer );
128+ /* Always configure for 4 MHz output */
129+ /** @todo check the computation, it should probably be more elaborate than this. */
130+ timer_set_prescaler (timer , (rcc_apb1_frequency / 4e6 ) - 1 );
131+ timer_set_period (timer , 255 );
132+ timer_enable_counter (timer );
133+ }
134+
135+ timer_enable_oc_preload (timer , timer_oc );
136+ timer_set_oc_mode (timer , timer_oc , TIM_OCM_PWM1 );
137+ timer_set_oc_value (timer , timer_oc , 0 );
138+ timer_enable_oc_output (timer , timer_oc );
139+
140+ self -> timer = timer ;
141+ self -> timer_oc = timer_oc ;
142+
143+ return GENERIC_POWER_RET_OK ;
144+ }
145+
146+
107147generic_power_ret_t generic_power_set_voltage_dac (GenericPower * self , Dac * dac_p , Dac * dac_m ) {
108148 if (dac_p && dac_m ) {
109149 u_log (system_log , LOG_TYPE_INFO , U_LOG_MODULE_PREFIX ("voltage output is differential" ));
0 commit comments