diff --git a/firmware/main.c b/firmware/main.c index 7c2e48e..c31ea20 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -1,5 +1,19 @@ #include #include +#include + +#define RING_MAX_LED 30u + +enum ring_modes { + RING_MODE_ALL, + RING_MODE_RED, + RING_MODE_GREEN, + RING_MODE_BLUE, + RING_MODE_WHITE, + RING_MODE_ARC, + RING_MODE_QUARTER, + RING_MODE_MAX +}; unsigned int i = 0x12345678; unsigned char c = 2; @@ -16,20 +30,116 @@ static void wait_for_ticks(uint32_t ticks) int main(void) { - uint32_t led_val = 0xAAUL; + uint32_t led_val = 0x00UL; + uint32_t led_calc_val[RING_MAX_LED] = {0x00UL}; + bool button_pressed = false; + enum ring_modes mode = RING_MODE_ALL; RCC->AHBENR |= RCC_AHBENR_GPIOAEN; - GPIOA->MODER |= (1<<3*2); + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; + + GPIOA->MODER |= (2<<7*2)|(2<<6*2)|(1<<3*2); + + /* enable pullups on encoder inputs */ + GPIOA->PUPDR |= (1<<7*2)|(1<<6*2)|(1<<0*2); + /* enable TIM3 on encoder inputs */ + GPIOA->AFR[0] |= (1<<7*4)|(1<<6*4); + + TIM3->ARR = 0xFFFF; + TIM3->CNT = 0; + TIM3->CR2 = 0; + TIM3->SMCR = TIM_SMCR_SMS_0; + TIM3->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_1; + TIM3->CCER = TIM_CCER_CC1P | TIM_CCER_CC2P; + TIM3->PSC = 0; + TIM3->CR1 = TIM_CR1_CEN; + SysTick_Config(800000); while(1) { + + switch (mode) + { + case RING_MODE_ALL: + for(int i = 0; i < RING_MAX_LED; i ++) { + led_calc_val[i] = (led_val << 24) + (led_val << 16) + (led_val << 8) + led_val; + } + break; + case RING_MODE_RED: + for(int i = 0; i < RING_MAX_LED; i ++) { + led_calc_val[i] = led_val << 16; + } + break; + case RING_MODE_GREEN: + for(int i = 0; i < RING_MAX_LED; i ++) { + led_calc_val[i] = led_val << 24; + } + break; + case RING_MODE_BLUE: + for(int i = 0; i < RING_MAX_LED; i ++) { + led_calc_val[i] = led_val << 8; + } + break; + case RING_MODE_WHITE: + for(int i = 0; i < RING_MAX_LED; i ++) { + led_calc_val[i] = led_val; + } + break; + case RING_MODE_ARC: + for(int i = 0; i < RING_MAX_LED; i ++) { + if(led_val > i*8) { + led_calc_val[i] = 0xFFFFFFFFUL; + } + else { + led_calc_val[i] = 0x00000000UL; + } + } + break; + case RING_MODE_QUARTER: + for(int i = 0; i < RING_MAX_LED; i ++) { + if((led_val / 7 > i) && (led_val / 7 < (i + 7))) { + led_calc_val[i] = 0xFFFFFFFFUL; + } + else { + led_calc_val[i] = 0x00000000UL; + } + } + break; + default: + for(int i = 0; i < RING_MAX_LED; i ++) { + led_calc_val[i] = 0x00000000UL; + } + break; + } __disable_irq(); - sk6812_send_led(led_val); + for(int i = 0; i < RING_MAX_LED; i ++) { + sk6812_send_led(led_calc_val[i]); + } __enable_irq(); - wait_for_ticks(30); - led_val += 20; + wait_for_ticks(5); + + if((int16_t)TIM3->CNT > (int16_t)led_val) { + led_val = 0u; + } + else if(((int16_t)led_val - (int16_t)TIM3->CNT) > UINT8_MAX) { + led_val = 255u; + } + else { + led_val = (int16_t)led_val - (int16_t)TIM3->CNT; + } + TIM3->CNT = 0u; + + if(button_pressed) { + if(GPIOA->IDR & GPIO_IDR_0) { + button_pressed = false; + } + } + else if(!(GPIOA->IDR & GPIO_IDR_0)) { + mode = (mode + 1) % RING_MODE_MAX; + button_pressed = true; + } } } void SysTick_Handler(void) { wait_tick++; -} +} \ No newline at end of file diff --git a/firmware/setup/system_init.c b/firmware/setup/system_init.c index c06d710..6b823c2 100644 --- a/firmware/setup/system_init.c +++ b/firmware/setup/system_init.c @@ -64,11 +64,18 @@ static void __init_default_clocks(void) void __setup_clocks(void) { uint32_t tmp; - - /* TODO: Switch HSE on for better accuracy */ - /* Switch PLL source to HSI OSC */ - RCC->CFGR &= ~RCC_CFGR_PLLSRC; + /* Switch PLL source to HSE OSC */ + RCC->CFGR |= RCC_CFGR_PLLSRC; + + /* Divide HSE by 2 to match HSI */ + RCC->CFGR2 = 0x00000001; + + /* Enable HSE and wait for it to become ready */ + RCC->CR |= RCC_CR_HSEON; + + /* Wait for HSE to be ready */ + while (!(RCC->CR & RCC_CR_HSERDY)); /* Set PLL multiplication to 12 (4 MHz * 12 = 48 MHz SysClk) */ RCC->CFGR |= RCC_CFGR_PLLMUL_3 | RCC_CFGR_PLLMUL_1; @@ -84,6 +91,9 @@ void __setup_clocks(void) tmp &= ~0x3; tmp |= RCC_CFGR_SW_1; RCC->CFGR = tmp; + + /* Turn off HSI */ + RCC->CR &= ~RCC_CR_HSEON; } void __system_init(void)