#include <libopencm3/cm3/systick.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
+#include <libopencm3/stm32/timer.h>
#include <libopencm3/stm32/usart.h>
static void clock_setup(void)
rcc_clock_setup_in_hse_8mhz_out_72mhz();
rcc_periph_clock_enable(RCC_GPIOA);
+ rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_GPIOC);
rcc_periph_clock_enable(RCC_USART1);
rcc_periph_clock_enable(RCC_TIM3);
+ rcc_periph_clock_enable(RCC_TIM4);
rcc_periph_clock_enable(RCC_DMA1);
}
static void gpio_setup(void)
{
+ // PC13 = BluePill LED
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO13);
+ gpio_clear(GPIOC, GPIO13);
+
+ // PC14 = bypass LED*
+ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO14);
+ gpio_set(GPIOC, GPIO14);
+
+ // PC15 = bypass opto-coupler
+ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO15);
+ gpio_clear(GPIOC, GPIO15);
}
static volatile u32 ms_ticks;
systick_interrupt_enable();
}
-void delay_ms(uint ms)
+static void delay_ms(uint ms)
{
u32 start_ticks = ms_ticks;
while (ms_ticks - start_ticks < ms)
usart_set_baudrate(USART1, 115200);
usart_set_databits(USART1, 8);
usart_set_stopbits(USART1, USART_STOPBITS_1);
- usart_set_mode(USART1, USART_MODE_TX);
+ usart_set_mode(USART1, USART_MODE_TX_RX);
usart_set_parity(USART1, USART_PARITY_NONE);
usart_set_flow_control(USART1, USART_FLOWCONTROL_NONE);
usart_enable(USART1);
}
+static bool bypass_active;
+static byte pwm;
+
+static void show_temperature(void)
+{
+ debug_putc('#');
+ for (uint i=0; ds_sensors[i].address[0]; i++) {
+ debug_putc(' ');
+ int t = ds_sensors[i].current_temp;
+ if (t == DS_TEMP_UNKNOWN)
+ debug_puts("---.---");
+ else
+ debug_printf("%3d.%03d", t / 1000, t % 1000);
+ }
+ debug_printf(" %d", bypass_active);
+ debug_printf(" %d", pwm);
+ debug_puts("\r\n");
+}
+
+static void pwm_init(void)
+{
+ timer_set_prescaler(TIM4, 3); // clock = 72 MHz / 2 = 36 MHz
+ timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
+ timer_disable_preload(TIM4);
+ timer_set_period(TIM4, 255); // PWM frequency = 18 MHz / 256 = 70.3125 kHz FIXME
+ timer_set_oc_mode(TIM4, TIM_OC1, TIM_OCM_PWM1);
+ timer_set_oc_value(TIM4, TIM_OC1, 1);
+ pwm = 1;
+ /*
+ * 1 0.03
+ * 4 0.48
+ * 8 1.54
+ * 12 2.71
+ * 16 3.99
+ * 24 6.34
+ * 32 7.85
+ * 64 7.95
+ * 128 8.02
+ * 255
+ */
+ timer_set_oc_polarity_high(TIM4, TIM_OC1);
+ timer_enable_counter(TIM4);
+ timer_enable_oc_output(TIM4, TIM_OC1);
+
+ gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO6);
+}
+
int main(void)
{
clock_setup();
gpio_setup();
tick_setup();
usart_setup();
+ pwm_init();
+
+ ds_init();
+ byte cycles = 0;
for (;;) {
gpio_toggle(GPIOC, GPIO13);
- ds_init();
- delay_ms(1000);
+ delay_ms(100);
+ ds_step();
+ if (usart_get_flag(USART1, USART_SR_RXNE)) {
+ uint ch = usart_recv(USART1);
+ if (ch == 'B') {
+ bypass_active = 1;
+ gpio_set(GPIOC, GPIO15); // opto-coupler
+ gpio_clear(GPIOC, GPIO14); // LED
+ } else if (ch == 'b') {
+ bypass_active = 0;
+ gpio_clear(GPIOC, GPIO15); // opto-coupler
+ gpio_set(GPIOC, GPIO14); // LED
+ } else if (ch >= '0' && ch <= '9') {
+ pwm = 3*(ch - '0') + 1;
+ /*
+ * ch pwm %
+ * 0 1 0
+ * 1 4 0
+ * 2 7 18
+ * 3 10 31
+ * 4 13 44
+ * 5 16 57
+ * 6 19 71
+ * 7 22 84
+ * 8 25 97
+ * 9 28 100
+ *
+ * % = pwm*4.389 - 12.723
+ */
+ timer_set_oc_value(TIM4, TIM_OC1, pwm);
+ }
+ }
+ if (cycles++ >= 50) {
+ cycles = 0;
+ show_temperature();
+ }
}
return 0;