sc7-testo-firmware/src/main.c

159 lines
3.5 KiB
C

/*
* main.c: test-o continuity and diode tester
*
* your robot addon badge buddy for testing all the things
*
* file creation: 20231015 0021
*/
#include "testo.h"
#include "adc.h"
#include "flash.h"
#include "led.h"
#include "probe.h"
#include "userio.h"
uint16_t ctr;
uint32_t uptime;
static inline void gpio_init()
{
// set registers manually instead of with
// LL functions to save space.
// though we probably don't _need_ this space...
// PF2=OUT(high), low speed
// unused pins are analog
GPIOF->ODR = (1 << 2);
GPIOF->MODER = 0xFFFFFCDF;
// set I2C outputs as open drain
GPIOA->OTYPER = 0x000c;
// enable pullups on I2C outputs
GPIOA->PUPDR = 0x24000050;
// datasheet doesn't say what the speeds are for GPIO...
// so set SWDIO to very high speed, PA12 low speed, all other outputs as high speed
GPIOA->OSPEEDR = 0x2C002AA0;
// alternate function select
// PA6=T3C1, PA5=T3C2, PA4=T3C3, PA3=I2C_SCL, PA2=I2C_SDA
GPIOA->AFR[0] = 0x01DDCC00;
// PA12=OUT(high)
GPIOA->ODR = (1 << 12);
// PA14=ALT, PA13=ALT, PA12=OUT, PA11=OUT
// PA7=AN, PA6=AF, PA5=AF, PA4=AF
// PA3=AF, PA2=AF, PA1=AN, PA0=AN
// unused pins are digital inputs
GPIOA->MODER = 0x2900EAAF;
// PB1=OUT(HIGH), PB0=AN
// unused pins are analog, all outputs are low speed
GPIOB->OSPEEDR = 0x00000000;
GPIOB->ODR = (1 << 1);
GPIOB->MODER = 0xfffffff7;
}
static inline void clk_init()
{
// run all buses at core clock speed
LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
// enable GPIO and peripheral clocks
RCC->IOPENR = LL_IOP_GRP1_PERIPH_GPIOA |
LL_IOP_GRP1_PERIPH_GPIOB |
LL_IOP_GRP1_PERIPH_GPIOF;
RCC->APBENR1 = LL_APB1_GRP1_PERIPH_TIM3;
RCC->APBENR2 = LL_APB1_GRP2_PERIPH_ADC1;
}
static inline void systick_init()
{
// configure nvic
NVIC_EnableIRQ(SysTick_IRQn);
NVIC_SetPriority(SysTick_IRQn, 0);
// configure timebase with interrupt at 4096Hz
// this assumes we'll always be running at 8MHz
SysTick_Config((8000000 / 4096) - 1);
}
/*
* get things started, then
* low priority application execution
*/
int main()
{
// base hardware initialization
clk_init();
flash_init(); // also configures option bytes to enable PF2, if necessary
gpio_init();
// peripheral initialization
led_init();
adc_init();
// mainline loop interrupt
systick_init();
// let's go
__enable_irq();
while (1) {
// run LED programs out of interrupt context at 256Hz
if ((ctr & 0xf) == 0) {
}
// nap time
__WFI();
}
}
/*
* main application interrupt
*/
__attribute__ ((long_call, section(".ramfunc"))) void SysTick_Handler(void)
{
uint16_t cs;
ctr++;
// run LED programs quickly
led_next();
// limit counter to 4096 counts
ctr &= 0xfff;
if (!ctr) {
uptime++;
}
// run main logic at 1024Hz
if (!(ctr & 0x3)) {
// shifted counter for use in the program
cs = ctr >> 2;
// adc tested to result in about 61 reads/second
if (!adc_next()) {
// adc has new computed results
if (uptime || cs) {
// figure out knobs, buttons, switches
userio_parse();
// show probe measurement results, or if not in a measurement mode,
// run RGBLED program
probe_measure();
}
}
}
}