/* * The GAT Stand * GAT Host Firmware * by true * * version 0.0.1 * * notes: * * - last 2K of flash memory is reserved for configuration storage */ #include #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(); } }