TinyFanControl-Firmware/src/main.c
2023-09-29 19:55:51 +02:00

100 lines
2 KiB
C

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/cm3/systick.h>
#include <libopencmsis/core_cm3.h>
#include "uart.h"
#include "temp_sensor.h"
#include "fan_ctrl_pwm.h"
#include "fan_ctrl_dc.h"
#include "fan_controller.h"
#define SYSTICK_FREQ 10 // Hz
static uint64_t timebase_ms = 0;
static bool systick_triggered = false;
static void clock_setup(void)
{
/* We are running on MSI (2.1 MHz) after boot. */
rcc_periph_clock_enable(RCC_GPIOA); // for basically everything
rcc_periph_clock_enable(RCC_GPIOC); // for UART only
/* Enable clocks for USART2. */
rcc_periph_clock_enable(RCC_USART2);
}
/* Set up systick to fire freq times per second */
static void init_systick(int freq)
{
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
/* clear counter so it starts right away */
STK_CVR = 0;
systick_set_reload(rcc_ahb_frequency / freq);
systick_counter_enable();
systick_interrupt_enable();
}
int main(void)
{
// delay startup a bit to allow debugger to connect before debug pins are
// reconfigured to UART.
for(uint32_t i = 0; i < 1000000; i++) {
__asm__("nop");
}
clock_setup();
init_systick(SYSTICK_FREQ);
uart_init();
temp_sensor_init();
fan_ctrl_pwm_init();
fan_ctrl_dc_init();
fan_controller_init();
uart_enqueue("TinyFanControl v" VERSION " initialized.\n");
fan_ctrl_pwm_enable(); // TODO: make DC/PWM configurable
// triggered every 1 ms
while (1) {
if(systick_triggered) {
systick_triggered = false;
timebase_ms += 1000 / SYSTICK_FREQ;
// start the measurement in the background.
temp_sensor_trigger_update();
}
// check for completion of a measurement
if(temp_sensor_has_new_values()) {
// if a temperature update is available, run the control loop.
fxp_t temperature = temp_sensor_get_ntc_temperature();
uint8_t duty = fan_controller_update(temperature);
fan_ctrl_pwm_set_duty(duty);
}
__WFI();
}
return 0;
}
/* Called when systick fires */
void sys_tick_handler(void)
{
systick_triggered = true;
}
void hard_fault_handler(void)
{
while (1);
}