172 lines
4.2 KiB
C
172 lines
4.2 KiB
C
|
/*
|
||
|
* The GAT Stand
|
||
|
* GAT Host Firmware
|
||
|
* by true
|
||
|
*
|
||
|
* version 0.0.1
|
||
|
*
|
||
|
* notes:
|
||
|
*
|
||
|
* - last 2K of flash memory is reserved for configuration storage
|
||
|
*/
|
||
|
|
||
|
#include <ch32v20x.h>
|
||
|
|
||
|
#include "src/btn.h"
|
||
|
#include "src/gat_gpio.h"
|
||
|
#include "src/port_pwr.h"
|
||
|
#include "src/rgbled.h"
|
||
|
#include "src/rtc.h"
|
||
|
|
||
|
|
||
|
|
||
|
void btn_top_push_cb(uint8_t idx)
|
||
|
{
|
||
|
gat_toggle();
|
||
|
}
|
||
|
|
||
|
void btn_bot_push_cb(uint8_t idx)
|
||
|
{
|
||
|
usb2_toggle();
|
||
|
}
|
||
|
|
||
|
static inline void systick_init(void)
|
||
|
{
|
||
|
SysTick->CMP = (SystemCoreClock / 256 / 8) - 1; // we want a 256Hz interrupt
|
||
|
SysTick->CNT = 0; // clear counter
|
||
|
SysTick->CTLR = 0xB; // start counter in /8 mode, enable interrupts, auto-reset counter
|
||
|
SysTick->SR = 0; // clear count comparison flag
|
||
|
|
||
|
NVIC_EnableIRQ(SysTicK_IRQn); // enable interrupt
|
||
|
}
|
||
|
|
||
|
static void gpio_init()
|
||
|
{
|
||
|
GPIO_InitTypeDef gpio = {0};
|
||
|
|
||
|
gpio.GPIO_Speed = GPIO_Speed_2MHz;
|
||
|
|
||
|
// unused pins
|
||
|
gpio.GPIO_Mode = GPIO_Mode_IPD;
|
||
|
gpio.GPIO_Pin = GPIO_Pin_13;
|
||
|
GPIO_Init(GPIOC, &gpio);
|
||
|
|
||
|
gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
|
||
|
GPIO_Init(GPIOD, &gpio);
|
||
|
|
||
|
gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
|
||
|
GPIO_Init(GPIOA, &gpio);
|
||
|
|
||
|
gpio.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_5 | GPIO_Pin_15;
|
||
|
GPIO_Init(GPIOB, &gpio);
|
||
|
|
||
|
// OSC32K: don't need to configure these pins from defaults
|
||
|
// enabling RTC does whatever is needed for these pins (assumed from example)
|
||
|
|
||
|
// RGBLED (PA0, PA1, PA2)
|
||
|
RGBLED_PORT->BSHR = RGBLED_PIN_R | RGBLED_PIN_G | RGBLED_PIN_B;
|
||
|
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||
|
gpio.GPIO_Pin = RGBLED_PIN_R | RGBLED_PIN_G | RGBLED_PIN_B;
|
||
|
GPIO_Init(RGBLED_PORT, &gpio);
|
||
|
|
||
|
// GAT power enable (PA3)
|
||
|
GAT_EN_PORT->BCR = GAT_EN_PIN;
|
||
|
gpio.GPIO_Pin = GAT_EN_PIN;
|
||
|
GPIO_Init(GAT_EN_PORT, &gpio);
|
||
|
|
||
|
// GAT overcurrent detect (PA4)
|
||
|
gpio.GPIO_Mode = GPIO_Mode_IPU;
|
||
|
gpio.GPIO_Pin = GAT_OC_PIN;
|
||
|
GPIO_Init(GAT_EN_PORT, &gpio);
|
||
|
|
||
|
// buttons (PB10, PB11) and DIP switches (PB12, PB13, PB14)
|
||
|
gpio.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
|
||
|
GPIO_Init(GPIOB, &gpio);
|
||
|
|
||
|
// GAT GPIO will be configured later
|
||
|
|
||
|
// USB PA11, PA12 will be configured later
|
||
|
|
||
|
// USB2 power enable (PB4)
|
||
|
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
|
||
|
gpio.GPIO_Pin = USB2_EN_PIN;
|
||
|
GPIO_Init(USB2_EN_PORT, &gpio);
|
||
|
|
||
|
// unused pins that are used for I2C passthrough
|
||
|
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||
|
gpio.GPIO_Pin = GPIO_Pin_15;
|
||
|
GPIO_Init(GPIOA, &gpio);
|
||
|
gpio.GPIO_Pin = GPIO_Pin_3;
|
||
|
GPIO_Init(GPIOB, &gpio);
|
||
|
|
||
|
// USB PB6, PB7 will be configured later
|
||
|
|
||
|
// I2C (PB8, PB9) - remapped
|
||
|
GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
|
||
|
gpio.GPIO_Speed = GPIO_Speed_10MHz;
|
||
|
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
|
||
|
gpio.GPIO_Mode = GPIO_Pin_8 | GPIO_Pin_9;
|
||
|
GPIO_Init(GPIOB, &gpio);
|
||
|
}
|
||
|
|
||
|
int main(void)
|
||
|
{
|
||
|
// configure core
|
||
|
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
|
||
|
SystemCoreClockUpdate();
|
||
|
|
||
|
// enable peripheral clocks
|
||
|
RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR | RCC_APB1Periph_BKP |
|
||
|
RCC_APB1Periph_I2C1, ENABLE);
|
||
|
RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA |
|
||
|
RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD |
|
||
|
RCC_APB2Periph_ADC1, ENABLE);
|
||
|
|
||
|
// configure gpio pins
|
||
|
gpio_init();
|
||
|
|
||
|
// configure RTC
|
||
|
if (rtc_init()) {
|
||
|
// rtc failed to initialize. let the end user know.
|
||
|
// todo
|
||
|
}
|
||
|
|
||
|
// initialize buttons
|
||
|
btn_init();
|
||
|
btn[0].cb_push = btn_top_push_cb;
|
||
|
btn[1].cb_push = btn_bot_push_cb;
|
||
|
|
||
|
// set GAT GP pins weak pull to address the addon
|
||
|
gat_gpio_init();
|
||
|
|
||
|
// set output ports to saved state, or on if no batt / first boot
|
||
|
port_pwr_init();
|
||
|
|
||
|
// start up rgbled
|
||
|
rgbled_init();
|
||
|
|
||
|
// finally, get the system tick interrupt going
|
||
|
systick_init();
|
||
|
|
||
|
// let's do this
|
||
|
while (1) {
|
||
|
__WFI();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
uint8_t st_tick;
|
||
|
volatile uint32_t uptime;
|
||
|
|
||
|
void SysTick_Handler(void)
|
||
|
{
|
||
|
st_tick++;
|
||
|
if (!st_tick) uptime++;
|
||
|
|
||
|
btn_poll();
|
||
|
|
||
|
if (!(st_tick & 0x3)) {
|
||
|
rgbled_update();
|
||
|
}
|
||
|
}
|