159 lines
3.5 KiB
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();
|
|
}
|
|
}
|
|
}
|
|
}
|