Merge branch 'sk6812-assembly-test' into hardware-v2
This commit is contained in:
		@@ -12,7 +12,7 @@ endif
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#Add Files and Folders below#########################################################
 | 
					#Add Files and Folders below#########################################################
 | 
				
			||||||
CFILES 	= main.c syscalls/syscalls.c setup/system_init.c startup/startup_stm32f0xx.c
 | 
					CFILES 	= main.c syscalls/syscalls.c setup/system_init.c startup/startup_stm32f0xx.c
 | 
				
			||||||
ASFILES =
 | 
					ASFILES = sk6812.S
 | 
				
			||||||
INCLUDEPATH = -Iinclude -Iinclude/cmsis
 | 
					INCLUDEPATH = -Iinclude -Iinclude/cmsis
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OBJDIR=obj
 | 
					OBJDIR=obj
 | 
				
			||||||
@@ -39,7 +39,7 @@ LFLAGS += -mfloat-abi=soft --disable-newlib-supplied-syscalls -nostartfiles
 | 
				
			|||||||
LFLAGS += -Tstartup/stm32f030.ld -Wl,-Map=$(mapfile).map -Wl,--gc-sections -g
 | 
					LFLAGS += -Tstartup/stm32f030.ld -Wl,-Map=$(mapfile).map -Wl,--gc-sections -g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CFLAGS = -c -fmessage-length=0 -mlittle-endian -mthumb -mcpu=cortex-m0 -mthumb-interwork
 | 
					CFLAGS = -c -fmessage-length=0 -mlittle-endian -mthumb -mcpu=cortex-m0 -mthumb-interwork
 | 
				
			||||||
CFLAGS += -mfloat-abi=soft -nostartfiles -Wall -g
 | 
					CFLAGS += -mfloat-abi=soft -nostartfiles -Wall -g -O3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
####################################################################################
 | 
					####################################################################################
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										158
									
								
								firmware/main.c
									
									
									
									
									
								
							
							
						
						
									
										158
									
								
								firmware/main.c
									
									
									
									
									
								
							@@ -1,19 +1,165 @@
 | 
				
			|||||||
#include <stm32f0xx.h>
 | 
					#include <stm32f0xx.h>
 | 
				
			||||||
 | 
					#include <cmsis/core_cm0.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#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
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned int i = 0x12345678;
 | 
					unsigned int i = 0x12345678;
 | 
				
			||||||
unsigned char c = 2;
 | 
					unsigned char c = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(void) {
 | 
					extern void sk6812_send_led(uint32_t rgbw);
 | 
				
			||||||
	RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
 | 
					
 | 
				
			||||||
	GPIOB->MODER |= (1<<1*2);
 | 
					volatile uint32_t wait_tick = 0;
 | 
				
			||||||
	GPIOB->ODR |= (1<<1);
 | 
					
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SysTick_Config(800000);
 | 
						SysTick_Config(800000);
 | 
				
			||||||
	while(1) {
 | 
						while(1) {
 | 
				
			||||||
		i++;
 | 
					
 | 
				
			||||||
 | 
							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) {
 | 
					void SysTick_Handler(void) {
 | 
				
			||||||
	GPIOB->ODR ^= (1<<1);
 | 
						wait_tick++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -61,10 +61,44 @@ static void __init_default_clocks(void)
 | 
				
			|||||||
  RCC->CIR = 0x00000000;
 | 
					  RCC->CIR = 0x00000000;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void __setup_clocks(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						uint32_t tmp;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						/* 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;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
						/* HSI Already running. Switch on PLL */
 | 
				
			||||||
 | 
						RCC->CR |= RCC_CR_PLLON;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						/* Wait for PLL to be ready */
 | 
				
			||||||
 | 
						while (!(RCC->CR & RCC_CR_PLLRDY));
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						/* Switch System Clock to PLL */
 | 
				
			||||||
 | 
						tmp = RCC->CFGR;
 | 
				
			||||||
 | 
						tmp &= ~0x3;
 | 
				
			||||||
 | 
						tmp |= RCC_CFGR_SW_1;
 | 
				
			||||||
 | 
						RCC->CFGR = tmp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Turn off HSI */
 | 
				
			||||||
 | 
						RCC->CR &= ~RCC_CR_HSEON;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __system_init(void)
 | 
					void __system_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__init_default_clocks();
 | 
						__init_default_clocks();
 | 
				
			||||||
 
 | 
						__setup_clocks(); 
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								firmware/sk6812.S
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								firmware/sk6812.S
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					.global sk6812_send_led
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.equ BSRR_REGISTER, 0x48000018
 | 
				
			||||||
 | 
					.equ PINNUM, 3
 | 
				
			||||||
 | 
					.syntax unified
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sk6812_send_led:
 | 
				
			||||||
 | 
						push {lr}
 | 
				
			||||||
 | 
						push {r4, r5, r6}
 | 
				
			||||||
 | 
						ldr r1, =BSRR_REGISTER
 | 
				
			||||||
 | 
						ldr r2, =(1<<PINNUM)
 | 
				
			||||||
 | 
						ldr r3, =(1<<(PINNUM+16))
 | 
				
			||||||
 | 
						ldr r4, =32
 | 
				
			||||||
 | 
						ldr r5, =0x80000000
 | 
				
			||||||
 | 
					_bitloop:
 | 
				
			||||||
 | 
						tst r0, r5
 | 
				
			||||||
 | 
						beq sk6812_send_zero	
 | 
				
			||||||
 | 
						bne sk6812_send_one
 | 
				
			||||||
 | 
					_bitloop_ret:
 | 
				
			||||||
 | 
						lsls r0, r0, #1
 | 
				
			||||||
 | 
						subs r4, r4, #1
 | 
				
			||||||
 | 
						bne _bitloop
 | 
				
			||||||
 | 
						pop {r4, r5, r6}
 | 
				
			||||||
 | 
						pop {pc}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					sk6812_send_one:
 | 
				
			||||||
 | 
						str r2, [r1]
 | 
				
			||||||
 | 
						ldr r6, =0x5
 | 
				
			||||||
 | 
						bl wait_r6
 | 
				
			||||||
 | 
						str r3, [r1]
 | 
				
			||||||
 | 
						ldr r6, =0x2
 | 
				
			||||||
 | 
						bl wait_r6
 | 
				
			||||||
 | 
						b _bitloop_ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sk6812_send_zero:
 | 
				
			||||||
 | 
						str r2, [r1]
 | 
				
			||||||
 | 
						ldr r6, =0x1
 | 
				
			||||||
 | 
						bl wait_r6
 | 
				
			||||||
 | 
						str r3, [r1]
 | 
				
			||||||
 | 
						ldr r6, =0x5
 | 
				
			||||||
 | 
						bl wait_r6
 | 
				
			||||||
 | 
						b _bitloop_ret
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					wait_r6:
 | 
				
			||||||
 | 
						subs r6, r6, #1
 | 
				
			||||||
 | 
						bne wait_r6
 | 
				
			||||||
 | 
						bx lr
 | 
				
			||||||
		Reference in New Issue
	
	Block a user