dc32-peppercon9-addon/firmware/user/main.c

156 lines
4.3 KiB
C

/*
* Peppercon9
* GAT Addon Firmware
* by true
*
* version 0.0.1
*
* code was made for different random addons I designed for dc32,
* then adapted to each one. so things might be a mess.
*
* I had only a few hours on and off over a week to get the code done.
* lots of shit was copied from demo code and adapted to work. certainly
* isn't the best way to get this done.
*
* I know I could save some power, but seeing as all the badges burn it in
* LEDs and almost nobody else power optimizes their badge code, who cares?
*
* sorry. wasn't procrastination I swear. all the ideas were last minute.
*
* notes:
*
* - last 2K of flash memory is reserved for configuration storage
* - accelerometer code isn't done by DC32
*/
#include <ch32v20x.h>
#include <stdint.h>
#include "src/adc.h"
#include "src/btn.h"
#include "src/config.h"
#include "src/i2c.h"
#include "src/led.h"
#include "src/lis2dw.h"
#include "src/rand.h"
#include "src/touch.h"
#include "src/ui.h"
void systick_init(void)
{
SysTick->CMP = (SystemCoreClock / 1024) - 1; // we want a 1024Hz interrupt
SysTick->CNT = 0; // clear counter
SysTick->CTLR = 0xF; // start counter in /1 mode, enable interrupts, auto-reset counter
SysTick->SR = 0; // clear count comparison flag
NVIC_EnableIRQ(SysTicK_IRQn); // enable interrupt
}
void gpio_init()
{
GPIO_InitTypeDef gpio = {0};
gpio.GPIO_Speed = GPIO_Speed_2MHz;
// unused osc pins
gpio.GPIO_Mode = GPIO_Mode_IPD;
gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_7;
GPIO_Init(GPIOD, &gpio);
// unused PORTA pins (0=none, 1=none, 5=SWI2C_SCL, 9=none)
gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_5 | GPIO_Pin_9;
GPIO_Init(GPIOA, &gpio);
// unused PORTB pins (5=SWI2C_SDA)
gpio.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOB, &gpio);
// lightsense LED anode and cathode (2=anode, 3=cathode)
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
gpio.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_Init(GPIOA, &gpio);
// TBTN1 front touch button, right side (A4)
gpio.GPIO_Mode = GPIO_Mode_AIN;
gpio.GPIO_Pin = GPIO_Pin_4;
GPIO_Init(GPIOA, &gpio);
// TBTN2 front touch button, left side (A9)
gpio.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(GPIOB, &gpio);
// rear RGBLED (6=T3C1 blue, 7=T3C2 green)
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOA, &gpio);
// rear RGBLED (1=T3C3 red)
gpio.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOB, &gpio);
// accelerometer interrupt
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio.GPIO_Pin = GPIO_Pin_15;
GPIO_Init(GPIOA, &gpio);
// I2C SCL, SCA for on-board devices
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init(GPIOB, &gpio);
}
int main(void)
{
// configure core
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
SystemCoreClockUpdate();
// enable peripheral clocks
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 | RCC_APB1Periph_I2C1 |
RCC_APB1Periph_PWR, ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD |
RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE);
// configure gpio pins
gpio_init();
// get saved settings
i2c_init();
userconf_load();
// configure hardware
adc_init(); // configure ADC1 for lightsense, also configures ADC clock divider
btn_init(); // configures ADC2 touch buttons on the front
lis2dw_init(); // looking at badge: Y+ up, X+ right, Z+ in front of badge
led_init(); // configure matrix IC as well as RGB PWM
// by default, top LED is in light sense mode
adc_set_mode_lsens(LSENS_READING_IDLE);
// configure random
tinymt32_init(&tinymt32_s, DBGMCU_GetCHIPID() | userconf.checksum);
// configure UI
ui_init();
// configure systick interrupt
systick_init();
rgb[0] = 10;
rgb[1] = 10;
rgb[2] = 10;
// do system shit
while(1) {
__WFI();
// after sending LEDs, run our program
// to update the LED buffer for next time
if ((ticnt & 0x7) == 0) {
ui_render();
}
}
}