100 lines
2 KiB
C
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);
|
|
}
|