dc33-retro-tech-addon/firmware/retro_tech_fw/code/main.c
true 805489c98f initial commit of in-progress port
what remains to be done:
- soft i2c master timings
- clock mode switching and render compensation when using i2c master code
- testing
2025-07-24 03:37:26 -07:00

153 lines
4.3 KiB
C

/*
* RETRO TECH 2025
* GAT Addon Firmware
* by true
*
* version 0.1.1
* Last Update 20250723
*
* code was made for different random addons I designed for dc32,
* then adapted to each one. it worked OK. this code was then more
* or less directly ported to another MCU. 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.
*/
#include <ch32x035.h>
#include <stdint.h>
#include "src/adc.h"
#include "src/btn.h"
#include "src/config.h"
#include "src/i2c_soft.h"
#include "src/led.h"
#include "src/led_rgbprog.h"
#include "src/rand.h"
#include "src/ui.h"
void systick_init(void)
{
SysTick->CMP = (SystemCoreClock / 512) - 1; // we want a 512Hz 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_50MHz;
// jogwheel digital inputs, active low (PA4-PA6)
gpio.GPIO_Mode = GPIO_Mode_IPU;
gpio.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_Init(GPIOA, &gpio);
// lightsense LED cathode (PA7, A8)
gpio.GPIO_Mode = GPIO_Mode_AIN;
gpio.GPIO_Pin = GPIO_Pin_7;
GPIOA->BSHR = GPIO_Pin_7;
GPIO_Init(GPIOA, &gpio);
// potentiometer (PB1, A9)
gpio.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(GPIOB, &gpio);
// lightsense LED anode
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
gpio.GPIO_Pin = GPIO_Pin_7;
GPIOB->BCR = GPIO_Pin_7;
GPIO_Init(GPIOB, &gpio);
// USB (unused in application) - PC16, PC17
// debug (not changed in application) - PC18, PC19
// EEP_WP EEPROM write protect (PA9) (active high)
// IS_SDB IS31FL3729 shutdown pin (PC3) (active low)
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
GPIOA->BCR = GPIO_Pin_9;
gpio.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &gpio);
GPIOC->BCR = GPIO_Pin_3;
gpio.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOC, &gpio);
// I2C SCL, SCA for addon header
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_Init(GPIOA, &gpio);
// software I2C, SCL for on-board devices
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIOA->BCR = GPIO_Pin_0 | GPIO_Pin_1;
gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOA, &gpio);
// UART RX/TX on addon header; not currently used
gpio.GPIO_Mode = GPIO_Mode_IPU;
gpio.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_Init(GPIOA, &gpio);
}
int main(void)
{
// configure core
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
SystemCoreClockUpdate();
// enable peripheral clocks
RCC_APB1PeriphClockCmd( RCC_APB1Periph_PWR | RCC_APB1Periph_I2C1, ENABLE);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_ADC1 | RCC_APB2Periph_TIM1, ENABLE);
// configure gpio pins, hard buttons (used for settings reset)
gpio_init();
// get saved settings, or reset if BTN1 is pushed
i2cm_init();
userconf_load((BTN_PORT->INDR & (1 << BTN1_PIN)) ? 0 : 1);
// configure hardware
adc_init();
btn_init();
led_init();
// configure random
tinymt32_init(&tinymt32_s, DBGMCU_GetCHIPID() | userconf.checksum);
// configure UI
ui_init();
// configure systick interrupt
systick_init();
// set up LEDs initially
led_rgb_firstrun();
// do system shit
while(1) {
__WFI();
// after sending LEDs, run LED render program
// to update the LED buffer for next time
// we have approx 7ms to render... plenty of time
if ((ticnt & 0x3) == 0) {
ui_render();
}
}
}