Skip to content

Commit 76b2513

Browse files
committed
make leds work
1 parent 83ee282 commit 76b2513

File tree

10 files changed

+739
-0
lines changed

10 files changed

+739
-0
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[submodule "models/rsheldiii-openSCAD-projects"]
22
path = keycaps/rsheldiii-openSCAD-projects
33
url = https://github.com/rsheldiii/openSCAD-projects.git
4+
[submodule "firmware/libopencm3"]
5+
path = firmware/libopencm3
6+
url = https://github.com/libopencm3/libopencm3

firmware/libopencm3

Submodule libopencm3 added at 1f3abd4

firmware/rules.mk

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# rules.mk from template: https://github.com/libopencm3/libopencm3-template
2+
3+
# This version of rules.mk expects the following to be defined before
4+
# inclusion..
5+
### REQUIRED ###
6+
# OPENCM3_DIR - duh
7+
# PROJECT - will be the basename of the output elf, eg usb-gadget0-stm32f4disco
8+
# CFILES - basenames only, eg main.c blah.c
9+
# CXXFILES - same for C++ files. Must have cxx suffix!
10+
# DEVICE - the full device name, eg stm32f405ret6
11+
# _or_
12+
# LDSCRIPT - full path, eg ../../examples/stm32/f4/stm32f4-discovery/stm32f4-discovery.ld
13+
# OPENCM3_LIB - the basename, eg: opencm3_stm32f4
14+
# OPENCM3_DEFS - the target define eg: -DSTM32F4
15+
# ARCH_FLAGS - eg, -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
16+
# (ie, the full set of cpu arch flags, _none_ are defined in this file)
17+
#
18+
### OPTIONAL ###
19+
# INCLUDES - fully formed -I paths, if you want extra, eg -I../shared
20+
# BUILD_DIR - defaults to bin, should set this if you are building multiarch
21+
# OPT - full -O flag, defaults to -Os
22+
# CSTD - defaults -std=c99
23+
# CXXSTD - no default.
24+
# OOCD_INTERFACE - eg stlink-v2
25+
# OOCD_TARGET - eg stm32f4x
26+
# both only used if you use the "make flash" target.
27+
# OOCD_FILE - eg my.openocd.cfg
28+
# This overrides interface/target above, and is used as just -f FILE
29+
### TODO/FIXME/notes ###
30+
# No support for stylecheck.
31+
# No support for BMP/texane/random flash methods, no plans either
32+
# No support for magically finding the library.
33+
# C++ hasn't been actually tested with this..... sorry bout that. ;)
34+
# Second expansion/secondary not set, add this if you need them.
35+
36+
BUILD_DIR ?= bin
37+
OPT ?= -Os
38+
CSTD ?= -std=c99
39+
40+
# Be silent per default, but 'make V=1' will show all compiler calls.
41+
# If you're insane, V=99 will print out all sorts of things.
42+
V?=0
43+
ifeq ($(V),0)
44+
Q := @
45+
NULL := 2>/dev/null
46+
endif
47+
48+
# Tool paths.
49+
PREFIX ?= arm-none-eabi-
50+
CC = $(PREFIX)gcc
51+
CXX = $(PREFIX)g++
52+
LD = $(PREFIX)gcc
53+
OBJCOPY = $(PREFIX)objcopy
54+
OBJDUMP = $(PREFIX)objdump
55+
OOCD ?= openocd
56+
57+
OPENCM3_INC = $(OPENCM3_DIR)/include
58+
59+
# Inclusion of library header files
60+
INCLUDES += $(patsubst %,-I%, . $(OPENCM3_INC) )
61+
62+
OBJS = $(CFILES:%.c=$(BUILD_DIR)/%.o)
63+
OBJS += $(CXXFILES:%.cxx=$(BUILD_DIR)/%.o)
64+
OBJS += $(AFILES:%.S=$(BUILD_DIR)/%.o)
65+
GENERATED_BINS = $(PROJECT).elf $(PROJECT).bin $(PROJECT).map $(PROJECT).list $(PROJECT).lss
66+
67+
TGT_CPPFLAGS += -MD
68+
TGT_CPPFLAGS += -Wall -Wundef $(INCLUDES)
69+
TGT_CPPFLAGS += $(INCLUDES) $(OPENCM3_DEFS)
70+
71+
TGT_CFLAGS += $(OPT) $(CSTD) -ggdb3
72+
TGT_CFLAGS += $(ARCH_FLAGS)
73+
TGT_CFLAGS += -fno-common
74+
TGT_CFLAGS += -ffunction-sections -fdata-sections
75+
TGT_CFLAGS += -Wextra -Wshadow -Wno-unused-variable -Wimplicit-function-declaration
76+
TGT_CFLAGS += -Wredundant-decls -Wstrict-prototypes -Wmissing-prototypes
77+
78+
TGT_CXXFLAGS += $(OPT) $(CXXSTD) -ggdb3
79+
TGT_CXXFLAGS += $(ARCH_FLAGS)
80+
TGT_CXXFLAGS += -fno-common
81+
TGT_CXXFLAGS += -ffunction-sections -fdata-sections
82+
TGT_CXXFLAGS += -Wextra -Wshadow -Wredundant-decls -Weffc++
83+
84+
TGT_ASFLAGS += $(OPT) $(ARCH_FLAGS) -ggdb3
85+
86+
TGT_LDFLAGS += -T$(LDSCRIPT) -L$(OPENCM3_DIR)/lib -nostartfiles
87+
TGT_LDFLAGS += $(ARCH_FLAGS)
88+
TGT_LDFLAGS += -specs=nano.specs
89+
TGT_LDFLAGS += -Wl,--gc-sections
90+
# OPTIONAL
91+
#TGT_LDFLAGS += -Wl,-Map=$(PROJECT).map
92+
ifeq ($(V),99)
93+
TGT_LDFLAGS += -Wl,--print-gc-sections
94+
endif
95+
96+
# Linker script generator fills this in for us.
97+
ifeq (,$(DEVICE))
98+
LDLIBS += -l$(OPENCM3_LIB)
99+
endif
100+
# nosys is only in newer gcc-arm-embedded...
101+
#LDLIBS += -specs=nosys.specs
102+
LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
103+
104+
# Burn in legacy hell fortran modula pascal yacc idontevenwat
105+
.SUFFIXES:
106+
.SUFFIXES: .c .S .h .o .cxx .elf .bin .list .lss
107+
108+
# Bad make, never *ever* try to get a file out of source control by yourself.
109+
%: %,v
110+
%: RCS/%,v
111+
%: RCS/%
112+
%: s.%
113+
%: SCCS/s.%
114+
115+
all: $(PROJECT).elf $(PROJECT).bin
116+
flash: $(PROJECT).flash
117+
118+
# error if not using linker script generator
119+
ifeq (,$(DEVICE))
120+
$(LDSCRIPT):
121+
ifeq (,$(wildcard $(LDSCRIPT)))
122+
$(error Unable to find specified linker script: $(LDSCRIPT))
123+
endif
124+
else
125+
# if linker script generator was used, make sure it's cleaned.
126+
GENERATED_BINS += $(LDSCRIPT)
127+
endif
128+
129+
# Need a special rule to have a bin dir
130+
$(BUILD_DIR)/%.o: %.c
131+
@printf " CC\t$<\n"
132+
@mkdir -p $(dir $@)
133+
$(Q)$(CC) $(TGT_CFLAGS) $(CFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $@ -c $<
134+
135+
$(BUILD_DIR)/%.o: %.cxx
136+
@printf " CXX\t$<\n"
137+
@mkdir -p $(dir $@)
138+
$(Q)$(CXX) $(TGT_CXXFLAGS) $(CXXFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $@ -c $<
139+
140+
$(BUILD_DIR)/%.o: %.S
141+
@printf " AS\t$<\n"
142+
@mkdir -p $(dir $@)
143+
$(Q)$(CC) $(TGT_ASFLAGS) $(ASFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $@ -c $<
144+
145+
$(PROJECT).elf: $(OBJS) $(LDSCRIPT) $(LIBDEPS)
146+
@printf " LD\t$@\n"
147+
$(Q)$(LD) $(TGT_LDFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@
148+
149+
%.bin: %.elf
150+
@printf " OBJCOPY\t$@\n"
151+
$(Q)$(OBJCOPY) -O binary $< $@
152+
153+
%.lss: %.elf
154+
$(OBJDUMP) -h -S $< > $@
155+
156+
%.list: %.elf
157+
$(OBJDUMP) -S $< > $@
158+
159+
%.flash: %.elf
160+
@printf " FLASH\t$<\n"
161+
ifeq (,$(OOCD_FILE))
162+
$(Q)(echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \
163+
$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \
164+
-f target/$(OOCD_TARGET).cfg \
165+
-c "program $(realpath $(*).elf) verify reset exit" \
166+
$(NULL)
167+
else
168+
$(Q)(echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \
169+
$(OOCD) -f $(OOCD_FILE) \
170+
-c "program $(realpath $(*).elf) verify reset exit" \
171+
$(NULL)
172+
endif
173+
174+
clean:
175+
rm -rf $(BUILD_DIR) $(GENERATED_BINS)
176+
177+
.PHONY: all clean flash
178+
-include $(OBJS:.o=.d)
179+

firmware/uartkeys/Makefile

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
OPENCM3_DIR=../libopencm3
3+
PROJECT=uartkeys
4+
CFILES=main.c ws2812_new_dma.c ws2812_new.c
5+
6+
# target chip
7+
DEVICE=stm32f030c8t6
8+
9+
default: all
10+
11+
include $(OPENCM3_DIR)/mk/genlink-config.mk
12+
include $(OPENCM3_DIR)/mk/genlink-rules.mk
13+
include ../rules.mk
14+
15+

firmware/uartkeys/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# ....
2+
3+
```
4+
make -C ../libopencm3/ # if not done already
5+
make
6+
gdb-multiarch uartkeys.elf
7+
set mem inaccessible-by-default off
8+
target extended-remote /dev/ttyACM0
9+
monitor swdp_scan
10+
attach 1
11+
load
12+
run
13+
```

firmware/uartkeys/config.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef CONFIG_H
2+
#define CONFIG_H
3+
4+
#include <libopencm3/stm32/gpio.h>
5+
6+
#define F_CPU (48000000)
7+
#define F_SYS_TICK_CLK (F_CPU/8)
8+
9+
#ifndef N_VALUES_PER_LED
10+
#define N_VALUES_PER_LED (3)
11+
#endif
12+
13+
#ifndef N_LEDS_PER_STRIP
14+
#define N_LEDS_PER_STRIP (16)
15+
#endif
16+
17+
#define PORT_LED_DATA (GPIOA)
18+
#define PIN_LED_DATA (9)
19+
#define N_STRIPS (1)
20+
21+
#endif // CONFIG_H

firmware/uartkeys/main.c

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright (c) 2023 Erik Bosman <[email protected]>
3+
*
4+
* Permission is hereby granted, free of charge, to any person
5+
* obtaining a copy of this software and associated documentation
6+
* files (the "Software"), to deal in the Software without restriction,
7+
* including without limitation the rights to use, copy, modify,
8+
* merge, publish, distribute, sublicense, and/or sell copies of the
9+
* Software, and to permit persons to whom the Software is furnished to
10+
* do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be
13+
* included in all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*
24+
* (http://opensource.org/licenses/mit-license.html)
25+
*
26+
*/
27+
28+
#include <stdint.h>
29+
30+
#include <libopencmsis/core_cm3.h>
31+
32+
#include <libopencm3/stm32/rcc.h>
33+
#include <libopencm3/stm32/gpio.h>
34+
35+
#include "ws2812_new.h"
36+
37+
static void enable_sys_tick(uint32_t ticks)
38+
{
39+
STK_RVR = ticks;
40+
STK_CVR = 0;
41+
STK_CSR = STK_CSR_ENABLE|STK_CSR_TICKINT;
42+
}
43+
44+
volatile uint32_t tick=0;
45+
void SysTick_Handler(void)
46+
{
47+
ws2812_write();
48+
tick+=1;
49+
}
50+
51+
/*
52+
from math import tau, cos
53+
max_val=0xff00
54+
gamma=2.6
55+
56+
size = 256
57+
wave = [ ( 1 - cos(x*tau/size) )/2 for x in range(size) ]
58+
59+
def clamp(x):
60+
return min(max_val, max(0, x))
61+
62+
table = [ clamp(int(max_val * x**gamma)) for x in wave ]
63+
64+
for i in range(0, size, 8):
65+
print ( '\t'+' '.join('0x{:04x},'.format(x) for x in table[i:i+8]) )
66+
67+
*/
68+
uint16_t wave[256] =
69+
{
70+
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
71+
0x0000, 0x0000, 0x0001, 0x0001, 0x0003, 0x0004, 0x0006, 0x0009,
72+
0x000d, 0x0012, 0x0018, 0x0020, 0x0029, 0x0035, 0x0043, 0x0054,
73+
0x0069, 0x0081, 0x009d, 0x00bd, 0x00e3, 0x010f, 0x0141, 0x0179,
74+
0x01ba, 0x0202, 0x0253, 0x02ae, 0x0312, 0x0382, 0x03fe, 0x0486,
75+
0x051b, 0x05be, 0x0670, 0x0732, 0x0804, 0x08e7, 0x09dc, 0x0ae4,
76+
0x0c00, 0x0d2f, 0x0e74, 0x0fce, 0x113e, 0x12c6, 0x1465, 0x161c,
77+
0x17ec, 0x19d4, 0x1bd7, 0x1df3, 0x202a, 0x227b, 0x24e6, 0x276d,
78+
0x2a0f, 0x2ccb, 0x2fa3, 0x3295, 0x35a2, 0x38c9, 0x3c0a, 0x3f65,
79+
0x42d9, 0x4666, 0x4a0a, 0x4dc5, 0x5197, 0x557e, 0x597a, 0x5d89,
80+
0x61aa, 0x65dc, 0x6a1f, 0x6e6f, 0x72ce, 0x7737, 0x7bab, 0x8028,
81+
0x84ab, 0x8934, 0x8dc0, 0x924f, 0x96dd, 0x9b69, 0x9ff2, 0xa475,
82+
0xa8f1, 0xad63, 0xb1ca, 0xb623, 0xba6d, 0xbea6, 0xc2cb, 0xc6dc,
83+
0xcad5, 0xceb5, 0xd27b, 0xd624, 0xd9af, 0xdd19, 0xe062, 0xe387,
84+
0xe687, 0xe960, 0xec12, 0xee9a, 0xf0f8, 0xf32a, 0xf52f, 0xf705,
85+
0xf8ad, 0xfa25, 0xfb6d, 0xfc83, 0xfd68, 0xfe1a, 0xfe99, 0xfee6,
86+
0xff00, 0xfee6, 0xfe99, 0xfe1a, 0xfd68, 0xfc83, 0xfb6d, 0xfa25,
87+
0xf8ad, 0xf705, 0xf52f, 0xf32a, 0xf0f8, 0xee9a, 0xec12, 0xe960,
88+
0xe687, 0xe387, 0xe062, 0xdd19, 0xd9af, 0xd624, 0xd27b, 0xceb5,
89+
0xcad5, 0xc6dc, 0xc2cb, 0xbea6, 0xba6d, 0xb623, 0xb1ca, 0xad63,
90+
0xa8f1, 0xa475, 0x9ff2, 0x9b69, 0x96dd, 0x924f, 0x8dc0, 0x8934,
91+
0x84ab, 0x8028, 0x7bab, 0x7737, 0x72ce, 0x6e6f, 0x6a1f, 0x65dc,
92+
0x61aa, 0x5d89, 0x597a, 0x557e, 0x5197, 0x4dc5, 0x4a0a, 0x4666,
93+
0x42d9, 0x3f65, 0x3c0a, 0x38c9, 0x35a2, 0x3295, 0x2fa3, 0x2ccb,
94+
0x2a0f, 0x276d, 0x24e6, 0x227b, 0x202a, 0x1df3, 0x1bd7, 0x19d4,
95+
0x17ec, 0x161c, 0x1465, 0x12c6, 0x113e, 0x0fce, 0x0e74, 0x0d2f,
96+
0x0c00, 0x0ae4, 0x09dc, 0x08e7, 0x0804, 0x0732, 0x0670, 0x05be,
97+
0x051b, 0x0486, 0x03fe, 0x0382, 0x0312, 0x02ae, 0x0253, 0x0202,
98+
0x01ba, 0x0179, 0x0141, 0x010f, 0x00e3, 0x00bd, 0x009d, 0x0081,
99+
0x0069, 0x0054, 0x0043, 0x0035, 0x0029, 0x0020, 0x0018, 0x0012,
100+
0x000d, 0x0009, 0x0006, 0x0004, 0x0003, 0x0001, 0x0001, 0x0000,
101+
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
102+
};
103+
104+
static void prepare_next_frame(frame_t *f)
105+
{
106+
107+
static uint8_t n = 0;
108+
n+=1;
109+
110+
int i;
111+
for (i=0; i<N_VALUES; i+=3)
112+
{
113+
f->data[i] = wave[ (n)&0xff ]>>3;
114+
f->data[i+1] = wave[ (n+85)&0xff ]>>3;
115+
f->data[i+2] = wave[ (n+170)&0xff ]>>3;
116+
}
117+
}
118+
119+
int main(void)
120+
{
121+
rcc_clock_setup_in_hsi_out_48mhz();
122+
rcc_periph_clock_enable(RCC_GPIOA);
123+
gpio_mode_setup(PORT_LED_DATA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, MASK_LED_DATA);
124+
125+
//enable_sys_tick(SYSTICK_PERIOD);
126+
enable_sys_tick(F_SYS_TICK_CLK/1000);
127+
ws2812_init();
128+
129+
uint32_t t_last=tick;
130+
131+
frame_t *f = NULL;
132+
133+
for(;;)
134+
{
135+
f = ws2812_get_frame();
136+
137+
if (f != NULL && (tick-t_last > 50) )
138+
{
139+
prepare_next_frame(f);
140+
ws2812_swap_frame();
141+
t_last += 50;
142+
}
143+
}
144+
}
145+

0 commit comments

Comments
 (0)