#include #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_IN_FARBE_UND_BUNT, RING_MODE_MAX }; volatile int32_t temperature; extern void sk6812_send_led(uint32_t rgbw); volatile uint32_t wait_tick = 0; static void wait_for_ticks(uint32_t ticks) { wait_tick = 0; while (wait_tick < ticks); } int main(void) { 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; 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; temperature_adc_init(); SysTick_Config(800000); while(1) { temperature = temperature_adc_get_temp(); 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; case RING_MODE_IN_FARBE_UND_BUNT: for(int i = 0; i < RING_MAX_LED; i ++) { switch ((led_val + (i / 3)) % 3) { case 0: led_calc_val[i] = 0x00FF0000UL; break; case 1: led_calc_val[i] = 0xFF000000UL; break; case 2: led_calc_val[i] = 0x0000FF00UL; break; default: break; } } break; default: for(int i = 0; i < RING_MAX_LED; i ++) { led_calc_val[i] = 0x00000000UL; } break; } __disable_irq(); for(int i = 0; i < RING_MAX_LED; i ++) { sk6812_send_led(led_calc_val[i]); } __enable_irq(); 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++; }