Browse Source

Initial checkin (cdcacm).

flabbergast 1 year ago
commit
f767e7d75b
12 changed files with 893 additions and 0 deletions
  1. 6
    0
      .gitignore
  2. 3
    0
      .gitmodules
  3. 57
    0
      README.md
  4. 43
    0
      common.f0.mk
  5. 44
    0
      common.l0.mk
  6. 32
    0
      l052-bldr.ld
  7. 1
    0
      libopencm3
  8. 294
    0
      libopencm3.rules.mk
  9. 26
    0
      usb_cdcacm/Makefile.f0
  10. 26
    0
      usb_cdcacm/Makefile.l0
  11. 27
    0
      usb_cdcacm/Makefile.l0btld
  12. 334
    0
      usb_cdcacm/cdcacm.c

+ 6
- 0
.gitignore View File

@@ -0,0 +1,6 @@
1
+*.o
2
+*.d
3
+*.elf
4
+*.hex
5
+*.bin
6
+*.map

+ 3
- 0
.gitmodules View File

@@ -0,0 +1,3 @@
1
+[submodule "libopencm3"]
2
+	path = libopencm3
3
+	url = https://github.com/libopencm3/libopencm3

+ 57
- 0
README.md View File

@@ -0,0 +1,57 @@
1
+A few examples of code for [the bat board], using [libopencm3].
2
+
3
+Most of them are just modified examples from the official [libopencm3 examples].
4
+
5
+They aren't too specific for the bat boards, except the usual pinout considerations. What's sometimes not so easy to change/adapt is the chip. These examples are for STM32 F072 and L052.
6
+
7
+## Short summary for the examples
8
+
9
+### usb_cdcacm
10
+
11
+The board presents itself as a serial port (CDC). It echoes back what it receives; toggling the LED after each received packet. Pressing the `PA1` button will print `hello, world` over this port.
12
+
13
+
14
+## General setup notes
15
+
16
+You are expected to a C compiler (for ARM) and some development tools (e.g. make and git) installed and ready to use. You can get a [toolchain from arm.com]; or use one provided by your system package manager (if you're on a normal system like some linux, bsd or mac). For the development tools, use your package manager.
17
+
18
+[libopencm3] is supposed to go into the `libopencm3` directory; it's git submodule if you're going the git way; otherwise just unpack it there. You'll need to run `make` in the `libopencm3` directory once, to compile the library. Any subsequent compilation of the examples here will just use these precompiled objects. This means that if you update, or make any changes to, libopencm3 sources, you'll need to recompile it explicitly like this. In other words, running `make` in any of the examples it not going to recompile the library.
19
+
20
+From time to time there are breaking changes in the library (e.g. L0 support is relatively new), so no guarantees that things compile (although they should with the commit referenced for the submodule). From time to time I pull in the new updates, but again, no guarantees. (Timestamp 2017-12-02T18:41:26).
21
+
22
+To compile an example, `cd` into its directory and run `make -f Makefile.l0btld` to compile. The three versions of the `Makefile`s are for STM32F072CBT6 (f0), STM32L052C8T6 (l0), STM32L052C8T6 with DFU bootloader occupying the first 8k of the flash (more about this setup on [the bat board] page). Cleaning up (important if you're switching to a different chip!) is done with the usual `make clean`.
23
+
24
+I didn't set up flashing to the board into the `Makefiles`, so flashing should be done manually. Here are the most common options:
25
+
26
+### DFU bootloader
27
+
28
+This requires [dfu-util] software. Put the board into DFU mode (on F072 by holding the `PA1` button during reset; on L052 by shorting `GND` and `PB3` during reset). The command is then
29
+```sh
30
+dfu-util -d 0483:df11  -a 0 -s 0x08002000 -D cdcacm.bin
31
+```
32
+where the adjustable parts are of course the name of the firmware (`cdcacm.bin` above) and importantly the address: it should be `0x08002000` for L052 with the 8k DFU bootloader, otherwise `0x08000000`).
33
+
34
+### built-in USART bootloader
35
+
36
+This requires a means of communicating over serial port (ideally 3.3V levels; although the required pins are 5V tolerant on L052 and F072). This usually means an external hardware, an USB-to-serial converter (there are loads on e.g. ebay; the most commonly used chips are FT231X, FT232RL, CP2102, CH340G). Although on boards like the Pi you can use the built-in UART.
37
+
38
+The built-in USART bootloader talks on PA9(TX) and PA10(RX) (and some others; but these are conveniently placed on the bat board). It is entered by holding the `PA1` button during a reset.
39
+
40
+On the software side, I prefer [stm32flash]. The command is then
41
+```sh
42
+stm32flash -e 255 -v -w cdcacm.bin /dev/ttyUSB0
43
+```
44
+where the adjustable parts are of course firmware filename and the serial port (`/dev/ttyUSB0` above).
45
+
46
+
47
+
48
+
49
+[the bat board]: https://flabbergast.github.io/bat-board
50
+[libopencm3]: https://github.com/libopencm3/libopencm3
51
+[libopencm3 examples]: https://github.com/libopencm3/libopencm3-examples
52
+[toolchain from arm.com]: https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
53
+[dfu-util]: http://dfu-util.sourceforge.net/
54
+
55
+
56
+License (for the original bits): CC-by-SA 2.0
57
+

+ 43
- 0
common.f0.mk View File

@@ -0,0 +1,43 @@
1
+##
2
+## This file is part of the libopencm3 project.
3
+##
4
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
6
+##
7
+## This library is free software: you can redistribute it and/or modify
8
+## it under the terms of the GNU Lesser General Public License as published by
9
+## the Free Software Foundation, either version 3 of the License, or
10
+## (at your option) any later version.
11
+##
12
+## This library is distributed in the hope that it will be useful,
13
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+## GNU Lesser General Public License for more details.
16
+##
17
+## You should have received a copy of the GNU Lesser General Public License
18
+## along with this library.  If not, see <http://www.gnu.org/licenses/>.
19
+##
20
+
21
+LIBNAME		= opencm3_stm32f0
22
+DEFS		+= -DSTM32F0
23
+
24
+FP_FLAGS	?= -msoft-float
25
+ARCH_FLAGS	= -mthumb -mcpu=cortex-m0 $(FP_FLAGS)
26
+
27
+################################################################################
28
+# OpenOCD specific variables
29
+
30
+OOCD		?= openocd
31
+OOCD_INTERFACE	?= stlink-v2-1
32
+OOCD_BOARD	?= st_nucleo_f0
33
+
34
+################################################################################
35
+# Black Magic Probe specific variables
36
+# Set the BMP_PORT to a serial port and then BMP is used for flashing
37
+BMP_PORT	?=
38
+
39
+################################################################################
40
+# texane/stlink specific variables
41
+#STLINK_PORT	?= :4242
42
+
43
+include ../libopencm3.rules.mk

+ 44
- 0
common.l0.mk View File

@@ -0,0 +1,44 @@
1
+##
2
+## This file is part of the libopencm3 project.
3
+##
4
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
6
+##
7
+## This library is free software: you can redistribute it and/or modify
8
+## it under the terms of the GNU Lesser General Public License as published by
9
+## the Free Software Foundation, either version 3 of the License, or
10
+## (at your option) any later version.
11
+##
12
+## This library is distributed in the hope that it will be useful,
13
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
+## GNU Lesser General Public License for more details.
16
+##
17
+## You should have received a copy of the GNU Lesser General Public License
18
+## along with this library.  If not, see <http://www.gnu.org/licenses/>.
19
+##
20
+
21
+LIBNAME		= opencm3_stm32l0
22
+DEFS		+= -DSTM32L0
23
+
24
+FP_FLAGS	?= -msoft-float
25
+ARCH_FLAGS	= -mthumb -mcpu=cortex-m0plus $(FP_FLAGS)
26
+
27
+################################################################################
28
+# OpenOCD specific variables
29
+
30
+OOCD		?= openocd
31
+OOCD_INTERFACE	?= stlink-v2-1
32
+OOCD_BOARD	?= stm32l0discovery
33
+
34
+################################################################################
35
+# Black Magic Probe specific variables
36
+# Set the BMP_PORT to a serial port and then BMP is used for flashing
37
+BMP_PORT	?=
38
+
39
+################################################################################
40
+# texane/stlink specific variables
41
+#STLINK_PORT	?= :4242
42
+
43
+
44
+include ../libopencm3.rules.mk

+ 32
- 0
l052-bldr.ld View File

@@ -0,0 +1,32 @@
1
+/*
2
+ * This file is part of the libopencm3 project.
3
+ *
4
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+ *
6
+ * This library is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU Lesser General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This library is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public License
17
+ * along with this library.  If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+/* Linker script for stm32duino (STM32F103RBT6, 128K flash, 20K RAM,
21
+ * minus 8k flash and 3k RAM for the DFU bootloader). */
22
+
23
+/* Define memory regions. */
24
+MEMORY
25
+{
26
+	rom (rx) : ORIGIN = 0x08002000, LENGTH = 64K-0x2000
27
+	ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K
28
+}
29
+
30
+/* Include the common ld script. */
31
+INCLUDE libopencm3_stm32l0.ld
32
+

+ 1
- 0
libopencm3

@@ -0,0 +1 @@
1
+Subproject commit 953bf531ea1c0b36a5b32b05ede8c6c77e480009

+ 294
- 0
libopencm3.rules.mk View File

@@ -0,0 +1,294 @@
1
+##
2
+## This file is part of the libopencm3 project.
3
+##
4
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
6
+## Copyright (C) 2013 Frantisek Burian <BuFran@seznam.cz>
7
+##
8
+## This library is free software: you can redistribute it and/or modify
9
+## it under the terms of the GNU Lesser General Public License as published by
10
+## the Free Software Foundation, either version 3 of the License, or
11
+## (at your option) any later version.
12
+##
13
+## This library is distributed in the hope that it will be useful,
14
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+## GNU Lesser General Public License for more details.
17
+##
18
+## You should have received a copy of the GNU Lesser General Public License
19
+## along with this library.  If not, see <http://www.gnu.org/licenses/>.
20
+##
21
+
22
+# Be silent per default, but 'make V=1' will show all compiler calls.
23
+ifneq ($(V),1)
24
+Q		:= @
25
+NULL		:= 2>/dev/null
26
+endif
27
+
28
+###############################################################################
29
+# Colour stuff
30
+NO_COLOR=\033[0m
31
+OK_COLOR=\033[32;01m
32
+ERROR_COLOR=\033[31;01m
33
+WARN_COLOR=\033[33;01m
34
+
35
+OK_STRING=$(OK_COLOR)[OK]$(NO_COLOR)
36
+ERROR_STRING=$(ERROR_COLOR)[ERRORS]$(NO_COLOR)
37
+WARN_STRING=$(WARN_COLOR)[WARNINGS]$(NO_COLOR)
38
+
39
+AWK_CMD = awk '{ printf "%-30s %-10s\n",$$1, $$2; }'
40
+PRINT_ERROR = printf "$@ $(ERROR_STRING)\n" | $(AWK_CMD) && printf "$(CMD)\n$$LOG\n" && false
41
+PRINT_WARNING = printf "$@ $(WARN_STRING)\n" | $(AWK_CMD) && printf "$(CMD)\n$$LOG\n"
42
+PRINT_OK = printf "$@ $(OK_STRING)\n" | $(AWK_CMD)
43
+BUILD_CMD = LOG=$$($(CMD) 2>&1) ; if [ $$? -eq 1 ]; then $(PRINT_ERROR); elif [ "$$LOG" != "" ] ; then $(PRINT_WARNING); else $(PRINT_OK); fi;
44
+## can use separately with '@$(PRINT_OK)'
45
+
46
+## can use with '$(call colorecho,<string>)'
47
+define colorecho
48
+      @tput setaf 6
49
+      @echo $1
50
+      @tput sgr0
51
+endef
52
+
53
+## can use as '$(call buildcmd,<command_to_run_as_string>)'
54
+define buildcmd
55
+	LOG=$$($1 2>&1) ; if [ $$? -eq 1 ]; then $(PRINT_ERROR); elif [ "$$LOG" != "" ] ; then $(PRINT_WARNING); else $(PRINT_OK); fi;
56
+endef
57
+
58
+###############################################################################
59
+# Executables
60
+
61
+PREFIX		?= arm-none-eabi
62
+
63
+CC		:= $(PREFIX)-gcc
64
+CXX		:= $(PREFIX)-g++
65
+LD		:= $(PREFIX)-gcc
66
+AR		:= $(PREFIX)-ar
67
+AS		:= $(PREFIX)-as
68
+OBJCOPY		:= $(PREFIX)-objcopy
69
+OBJDUMP		:= $(PREFIX)-objdump
70
+GDB		:= $(PREFIX)-gdb
71
+STFLASH		= $(shell which st-flash)
72
+STYLECHECK	:= /checkpatch.pl
73
+STYLECHECKFLAGS	:= --no-tree -f --terse --mailback
74
+STYLECHECKFILES	:= $(shell find . -name '*.[ch]')
75
+OPT		:= -Os
76
+CSTD		?= -std=c99
77
+
78
+
79
+###############################################################################
80
+# Source files
81
+
82
+LDSCRIPT	?= $(BINARY).ld
83
+
84
+OBJS		+= $(BINARY).o
85
+
86
+
87
+ifeq ($(strip $(OPENCM3_DIR)),)
88
+# user has not specified the library path, so we try to detect it
89
+
90
+# where we search for the library
91
+LIBPATHS := ./libopencm3 ../../../../libopencm3 ../../../../../libopencm3
92
+
93
+OPENCM3_DIR := $(wildcard $(LIBPATHS:=/locm3.sublime-project))
94
+OPENCM3_DIR := $(firstword $(dir $(OPENCM3_DIR)))
95
+
96
+ifeq ($(strip $(OPENCM3_DIR)),)
97
+$(warning Cannot find libopencm3 library in the standard search paths.)
98
+$(error Please specify it through OPENCM3_DIR variable!)
99
+endif
100
+endif
101
+
102
+ifeq ($(V),1)
103
+$(info Using $(OPENCM3_DIR) path to library)
104
+endif
105
+
106
+define ERR_DEVICE_LDSCRIPT_CONFLICT
107
+You can either specify DEVICE=blah, and have the LDSCRIPT generated,
108
+or you can provide LDSCRIPT, and ensure CPPFLAGS, LDFLAGS and LDLIBS
109
+all contain the correct values for the target you wish to use.
110
+You cannot provide both!
111
+endef
112
+
113
+ifeq ($(strip $(DEVICE)),)
114
+# Old style, assume LDSCRIPT exists
115
+DEFS		+= -I$(OPENCM3_DIR)/include
116
+LDFLAGS		+= -L$(OPENCM3_DIR)/lib
117
+LDLIBS		+= -l$(LIBNAME)
118
+LDSCRIPT	?= $(BINARY).ld
119
+else
120
+# New style, assume device is provided, and we're generating the rest.
121
+ifneq ($(strip $(LDSCRIPT)),)
122
+$(error $(ERR_DEVICE_LDSCRIPT_CONFLICT))
123
+endif
124
+include $(OPENCM3_DIR)/mk/genlink-config.mk
125
+endif
126
+
127
+OPENCM3_SCRIPT_DIR = $(OPENCM3_DIR)/scripts
128
+LOCAL_SCRIPT_DIR	?= ./scripts
129
+
130
+###############################################################################
131
+# C flags
132
+
133
+TGT_CFLAGS	+= $(OPT) $(CSTD) -g
134
+TGT_CFLAGS	+= $(ARCH_FLAGS)
135
+TGT_CFLAGS	+= -Wextra -Wshadow -Wimplicit-function-declaration
136
+TGT_CFLAGS	+= -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes
137
+TGT_CFLAGS	+= -fno-common -ffunction-sections -fdata-sections
138
+
139
+###############################################################################
140
+# C++ flags
141
+
142
+TGT_CXXFLAGS	+= $(OPT) $(CXXSTD) -g
143
+TGT_CXXFLAGS	+= $(ARCH_FLAGS)
144
+TGT_CXXFLAGS	+= -Wextra -Wshadow -Wredundant-decls  -Weffc++
145
+TGT_CXXFLAGS	+= -fno-common -ffunction-sections -fdata-sections
146
+
147
+###############################################################################
148
+# C & C++ preprocessor common flags
149
+
150
+TGT_CPPFLAGS	+= -MD
151
+TGT_CPPFLAGS	+= -Wall -Wundef
152
+TGT_CPPFLAGS	+= $(DEFS)
153
+
154
+###############################################################################
155
+# Linker flags
156
+
157
+TGT_LDFLAGS		+= --static -nostartfiles
158
+TGT_LDFLAGS		+= -T$(LDSCRIPT)
159
+TGT_LDFLAGS		+= $(ARCH_FLAGS)
160
+TGT_LDFLAGS		+= -Wl,-Map=$(*).map
161
+TGT_LDFLAGS		+= -Wl,--gc-sections
162
+ifeq ($(V),99)
163
+TGT_LDFLAGS		+= -Wl,--print-gc-sections
164
+endif
165
+
166
+###############################################################################
167
+# Used libraries
168
+
169
+LDLIBS		+= -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
170
+
171
+###############################################################################
172
+###############################################################################
173
+###############################################################################
174
+
175
+.SUFFIXES: .elf .bin .hex .srec .list .map .images
176
+.SECONDEXPANSION:
177
+.SECONDARY:
178
+
179
+all: elf hex bin
180
+
181
+elf: $(BINARY).elf
182
+bin: $(BINARY).bin
183
+hex: $(BINARY).hex
184
+srec: $(BINARY).srec
185
+list: $(BINARY).list
186
+
187
+images: $(BINARY).images
188
+flash: $(BINARY).flash
189
+
190
+# Either verify the user provided LDSCRIPT exists, or generate it.
191
+ifeq ($(strip $(DEVICE)),)
192
+$(LDSCRIPT):
193
+    ifeq (,$(wildcard $(LDSCRIPT)))
194
+        $(error Unable to find specified linker script: $(LDSCRIPT))
195
+    endif
196
+else
197
+include $(OPENCM3_DIR)/mk/genlink-rules.mk
198
+endif
199
+
200
+# Define a helper macro for debugging make errors online
201
+# you can type "make print-OPENCM3_DIR" and it will show you
202
+# how that ended up being resolved by all of the included
203
+# makefiles.
204
+print-%:
205
+	@echo $*=$($*)
206
+
207
+%.images: %.bin %.hex %.srec %.list %.map
208
+	@#printf "*** $* images generated ***\n"
209
+
210
+%.bin: %.elf
211
+	@#printf "  OBJCOPY $(*).bin\n"
212
+	$(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin
213
+
214
+%.hex: %.elf
215
+	@#printf "  OBJCOPY $(*).hex\n"
216
+	$(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex
217
+
218
+%.srec: %.elf
219
+	@#printf "  OBJCOPY $(*).srec\n"
220
+	$(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec
221
+
222
+%.list: %.elf
223
+	@#printf "  OBJDUMP $(*).list\n"
224
+	$(Q)$(OBJDUMP) -S $(*).elf > $(*).list
225
+
226
+%.elf %.map: $(OBJS) $(LDSCRIPT)
227
+	@#printf "  LD      $(*).elf\n"
228
+	$(Q)$(LD) $(TGT_LDFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(*).elf
229
+
230
+%.o: %.c
231
+	@#printf "  CC      $(*).c\n"
232
+	$(Q)$(CC) $(TGT_CFLAGS) $(CFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).c
233
+
234
+%.o: %.cxx
235
+	@#printf "  CXX     $(*).cxx\n"
236
+	$(Q)$(CXX) $(TGT_CXXFLAGS) $(CXXFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).cxx
237
+
238
+%.o: %.cpp
239
+	@#printf "  CXX     $(*).cpp\n"
240
+	$(Q)$(CXX) $(TGT_CXXFLAGS) $(CXXFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).cpp
241
+
242
+clean:
243
+	@#printf "  CLEAN\n"
244
+	$(Q)$(RM) *.o *.d *.elf *.bin *.hex *.srec *.list *.map generated.* ${OBJS} ${OBJS:%.o:%.d}
245
+
246
+stylecheck: $(STYLECHECKFILES:=.stylecheck)
247
+styleclean: $(STYLECHECKFILES:=.styleclean)
248
+
249
+# the cat is due to multithreaded nature - we like to have consistent chunks of text on the output
250
+%.stylecheck: %
251
+	$(Q)$(OPENCM3_SCRIPT_DIR)$(STYLECHECK) $(STYLECHECKFLAGS) $* > $*.stylecheck; \
252
+		if [ -s $*.stylecheck ]; then \
253
+			cat $*.stylecheck; \
254
+		else \
255
+			rm -f $*.stylecheck; \
256
+		fi;
257
+
258
+%.styleclean:
259
+	$(Q)rm -f $*.stylecheck;
260
+
261
+
262
+%.stlink-flash: %.bin
263
+	@printf "  FLASH  $<\n"
264
+	$(Q)$(STFLASH) write $(*).bin 0x8000000
265
+
266
+ifeq ($(BMP_PORT),)
267
+ifeq ($(OOCD_FILE),)
268
+%.flash: %.elf
269
+	@printf "  FLASH   $<\n"
270
+	$(Q)(echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \
271
+		$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \
272
+		-f target/$(OOCD_TARGET).cfg \
273
+		-c "program $(*).elf verify reset exit" \
274
+		$(NULL)
275
+else
276
+%.flash: %.elf
277
+	@printf "  FLASH   $<\n"
278
+	$(Q)(echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \
279
+		$(OOCD) -f $(OOCD_FILE) \
280
+		-c "program $(*).elf verify reset exit" \
281
+		$(NULL)
282
+endif
283
+else
284
+%.flash: %.elf
285
+	@printf "  GDB   $(*).elf (flash)\n"
286
+	$(GDB) --batch \
287
+		   -ex 'target extended-remote $(BMP_PORT)' \
288
+		   -x $(LOCAL_SCRIPT_DIR)/black_magic_probe_flash.scr \
289
+		   $(*).elf
290
+endif
291
+
292
+.PHONY: images clean stylecheck styleclean elf bin hex srec list
293
+
294
+-include $(OBJS:.o=.d)

+ 26
- 0
usb_cdcacm/Makefile.f0 View File

@@ -0,0 +1,26 @@
1
+##
2
+## This file is part of the libopencm3 project.
3
+##
4
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+##
6
+## This library is free software: you can redistribute it and/or modify
7
+## it under the terms of the GNU Lesser General Public License as published by
8
+## the Free Software Foundation, either version 3 of the License, or
9
+## (at your option) any later version.
10
+##
11
+## This library is distributed in the hope that it will be useful,
12
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+## GNU Lesser General Public License for more details.
15
+##
16
+## You should have received a copy of the GNU Lesser General Public License
17
+## along with this library.  If not, see <http://www.gnu.org/licenses/>.
18
+##
19
+
20
+BINARY = cdcacm
21
+
22
+OPENCM3_DIR=../libopencm3
23
+LDSCRIPT = $(OPENCM3_DIR)/lib/stm32/f0/stm32f07xzb.ld
24
+
25
+include ../common.f0.mk
26
+

+ 26
- 0
usb_cdcacm/Makefile.l0 View File

@@ -0,0 +1,26 @@
1
+##
2
+## This file is part of the libopencm3 project.
3
+##
4
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+##
6
+## This library is free software: you can redistribute it and/or modify
7
+## it under the terms of the GNU Lesser General Public License as published by
8
+## the Free Software Foundation, either version 3 of the License, or
9
+## (at your option) any later version.
10
+##
11
+## This library is distributed in the hope that it will be useful,
12
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+## GNU Lesser General Public License for more details.
15
+##
16
+## You should have received a copy of the GNU Lesser General Public License
17
+## along with this library.  If not, see <http://www.gnu.org/licenses/>.
18
+##
19
+
20
+BINARY = cdcacm
21
+
22
+OPENCM3_DIR=../libopencm3
23
+LDSCRIPT = $(OPENCM3_DIR)/lib/stm32/l0/stm32l0xx8.ld
24
+
25
+include ../common.l0.mk
26
+

+ 27
- 0
usb_cdcacm/Makefile.l0btld View File

@@ -0,0 +1,27 @@
1
+##
2
+## This file is part of the libopencm3 project.
3
+##
4
+## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
5
+##
6
+## This library is free software: you can redistribute it and/or modify
7
+## it under the terms of the GNU Lesser General Public License as published by
8
+## the Free Software Foundation, either version 3 of the License, or
9
+## (at your option) any later version.
10
+##
11
+## This library is distributed in the hope that it will be useful,
12
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+## GNU Lesser General Public License for more details.
15
+##
16
+## You should have received a copy of the GNU Lesser General Public License
17
+## along with this library.  If not, see <http://www.gnu.org/licenses/>.
18
+##
19
+
20
+BINARY = cdcacm
21
+
22
+OPENCM3_DIR=../libopencm3
23
+LDSCRIPT = ../l052-bldr.ld
24
+DEFS += -DBOOTLOADER8K
25
+
26
+include ../common.l0.mk
27
+

+ 334
- 0
usb_cdcacm/cdcacm.c View File

@@ -0,0 +1,334 @@
1
+/*
2
+ * This file is part of the libopencm3 project.
3
+ *
4
+ * Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
5
+ *
6
+ * This library is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU Lesser General Public License as published by
8
+ * the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This library is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public License
17
+ * along with this library.  If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+#include <stdlib.h>
21
+#include <libopencm3/stm32/rcc.h>
22
+#include <libopencm3/stm32/flash.h>
23
+#include <libopencm3/stm32/gpio.h>
24
+#include <libopencm3/stm32/syscfg.h>
25
+#include <libopencm3/stm32/crs.h>
26
+#include <libopencm3/usb/usbd.h>
27
+#include <libopencm3/usb/cdc.h>
28
+
29
+static const struct usb_device_descriptor dev = {
30
+    .bLength = USB_DT_DEVICE_SIZE,
31
+    .bDescriptorType = USB_DT_DEVICE,
32
+    .bcdUSB = 0x0200,
33
+    .bDeviceClass = USB_CLASS_CDC,
34
+    .bDeviceSubClass = 0,
35
+    .bDeviceProtocol = 0,
36
+    .bMaxPacketSize0 = 64,
37
+    .idVendor = 0x0483,
38
+    .idProduct = 0x5740,
39
+    .bcdDevice = 0x0200,
40
+    .iManufacturer = 1,
41
+    .iProduct = 2,
42
+    .iSerialNumber = 3,
43
+    .bNumConfigurations = 1,
44
+};
45
+
46
+/*
47
+ * This notification endpoint isn't implemented. According to CDC spec its
48
+ * optional, but its absence causes a NULL pointer dereference in Linux
49
+ * cdc_acm driver.
50
+ */
51
+static const struct usb_endpoint_descriptor comm_endp[] = {{
52
+    .bLength = USB_DT_ENDPOINT_SIZE,
53
+    .bDescriptorType = USB_DT_ENDPOINT,
54
+    .bEndpointAddress = 0x83,
55
+    .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
56
+    .wMaxPacketSize = 16,
57
+    .bInterval = 255,
58
+}};
59
+
60
+static const struct usb_endpoint_descriptor data_endp[] = {{
61
+    .bLength = USB_DT_ENDPOINT_SIZE,
62
+    .bDescriptorType = USB_DT_ENDPOINT,
63
+    .bEndpointAddress = 0x01,
64
+    .bmAttributes = USB_ENDPOINT_ATTR_BULK,
65
+    .wMaxPacketSize = 64,
66
+    .bInterval = 1,
67
+}, {
68
+    .bLength = USB_DT_ENDPOINT_SIZE,
69
+    .bDescriptorType = USB_DT_ENDPOINT,
70
+    .bEndpointAddress = 0x82,
71
+    .bmAttributes = USB_ENDPOINT_ATTR_BULK,
72
+    .wMaxPacketSize = 64,
73
+    .bInterval = 1,
74
+}};
75
+
76
+static const struct {
77
+    struct usb_cdc_header_descriptor header;
78
+    struct usb_cdc_call_management_descriptor call_mgmt;
79
+    struct usb_cdc_acm_descriptor acm;
80
+    struct usb_cdc_union_descriptor cdc_union;
81
+} __attribute__((packed)) cdcacm_functional_descriptors = {
82
+    .header = {
83
+        .bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
84
+        .bDescriptorType = CS_INTERFACE,
85
+        .bDescriptorSubtype = USB_CDC_TYPE_HEADER,
86
+        .bcdCDC = 0x0110,
87
+    },
88
+    .call_mgmt = {
89
+        .bFunctionLength =
90
+            sizeof(struct usb_cdc_call_management_descriptor),
91
+        .bDescriptorType = CS_INTERFACE,
92
+        .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
93
+        .bmCapabilities = 0,
94
+        .bDataInterface = 1,
95
+    },
96
+    .acm = {
97
+        .bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
98
+        .bDescriptorType = CS_INTERFACE,
99
+        .bDescriptorSubtype = USB_CDC_TYPE_ACM,
100
+        .bmCapabilities = 0,
101
+    },
102
+    .cdc_union = {
103
+        .bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
104
+        .bDescriptorType = CS_INTERFACE,
105
+        .bDescriptorSubtype = USB_CDC_TYPE_UNION,
106
+        .bControlInterface = 0,
107
+        .bSubordinateInterface0 = 1,
108
+     }
109
+};
110
+
111
+static const struct usb_interface_descriptor comm_iface[] = {{
112
+    .bLength = USB_DT_INTERFACE_SIZE,
113
+    .bDescriptorType = USB_DT_INTERFACE,
114
+    .bInterfaceNumber = 0,
115
+    .bAlternateSetting = 0,
116
+    .bNumEndpoints = 1,
117
+    .bInterfaceClass = USB_CLASS_CDC,
118
+    .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
119
+    .bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
120
+    .iInterface = 0,
121
+
122
+    .endpoint = comm_endp,
123
+
124
+    .extra = &cdcacm_functional_descriptors,
125
+    .extralen = sizeof(cdcacm_functional_descriptors)
126
+}};
127
+
128
+static const struct usb_interface_descriptor data_iface[] = {{
129
+    .bLength = USB_DT_INTERFACE_SIZE,
130
+    .bDescriptorType = USB_DT_INTERFACE,
131
+    .bInterfaceNumber = 1,
132
+    .bAlternateSetting = 0,
133
+    .bNumEndpoints = 2,
134
+    .bInterfaceClass = USB_CLASS_DATA,
135
+    .bInterfaceSubClass = 0,
136
+    .bInterfaceProtocol = 0,
137
+    .iInterface = 0,
138
+
139
+    .endpoint = data_endp,
140
+}};
141
+
142
+static const struct usb_interface ifaces[] = {{
143
+    .num_altsetting = 1,
144
+    .altsetting = comm_iface,
145
+}, {
146
+    .num_altsetting = 1,
147
+    .altsetting = data_iface,
148
+}};
149
+
150
+static const struct usb_config_descriptor config = {
151
+    .bLength = USB_DT_CONFIGURATION_SIZE,
152
+    .bDescriptorType = USB_DT_CONFIGURATION,
153
+    .wTotalLength = 0,
154
+    .bNumInterfaces = 2,
155
+    .bConfigurationValue = 1,
156
+    .iConfiguration = 0,
157
+    .bmAttributes = 0x80,
158
+    .bMaxPower = 0x32,
159
+
160
+    .interface = ifaces,
161
+};
162
+
163
+static const char *usb_strings[] = {
164
+    "flabbergast",
165
+    "CDC-ACM Test",
166
+    "DeMo",
167
+};
168
+
169
+/* Buffer to be used for control requests. */
170
+uint8_t usbd_control_buffer[128];
171
+
172
+/* Aux functions */
173
+static void led_flip(void) {
174
+  if(GPIOA_IDR & (1<<15)) {
175
+      GPIOA_BRR = GPIO15;
176
+  } else {
177
+      GPIOA_BSRR = GPIO15;
178
+  }
179
+}
180
+
181
+static int cdcacm_control_request(usbd_device *usbd_dev,
182
+    struct usb_setup_data *req, uint8_t **buf, uint16_t *len,
183
+    void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
184
+{
185
+    (void)complete;
186
+    (void)buf;
187
+    (void)usbd_dev;
188
+
189
+    switch(req->bRequest) {
190
+    case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
191
+        /*
192
+         * This Linux cdc_acm driver requires this to be implemented
193
+         * even though it's optional in the CDC spec, and we don't
194
+         * advertise it in the ACM functional descriptor.
195
+         */
196
+        char local_buf[10];
197
+        struct usb_cdc_notification *notif = (void *)local_buf;
198
+
199
+        /* We echo signals back to host as notification. */
200
+        notif->bmRequestType = 0xA1;
201
+        notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
202
+        notif->wValue = 0;
203
+        notif->wIndex = 0;
204
+        notif->wLength = 2;
205
+        local_buf[8] = req->wValue & 3;
206
+        local_buf[9] = 0;
207
+        // usbd_ep_write_packet(0x83, buf, 10);
208
+        return 1;
209
+        }
210
+    case USB_CDC_REQ_SET_LINE_CODING:
211
+        if(*len < sizeof(struct usb_cdc_line_coding))
212
+            return 0;
213
+
214
+        return 1;
215
+    }
216
+    return 0;
217
+}
218
+
219
+static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
220
+{
221
+    (void)ep;
222
+
223
+    char buf[64];
224
+    int len = usbd_ep_read_packet(usbd_dev, 0x01, buf, 64);
225
+
226
+    if (len) {
227
+        usbd_ep_write_packet(usbd_dev, 0x82, buf, len);
228
+        buf[len] = 0;
229
+    led_flip();
230
+    }
231
+}
232
+
233
+static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
234
+{
235
+    (void)wValue;
236
+
237
+    usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
238
+    usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
239
+    usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
240
+
241
+    usbd_register_control_callback(
242
+                usbd_dev,
243
+                USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
244
+                USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
245
+                cdcacm_control_request);
246
+}
247
+
248
+int main(void)
249
+{
250
+    usbd_device *usbd_dev;
251
+
252
+#if defined(BOOTLOADER8K)
253
+#   define SCB_VTOR MMIO32(0xE000ED08)
254
+    SCB_VTOR = (uint32_t) 0x08002000;
255
+#endif
256
+
257
+#if defined(STM32F0)
258
+    rcc_clock_setup_in_hsi_out_48mhz();
259
+    crs_autotrim_usb_enable();
260
+    rcc_set_usbclk_source(RCC_HSI48);
261
+
262
+    // this is needed for F042 in TSSOP-20 package; USB is on shared pins
263
+    //rcc_periph_clock_enable(RCC_SYSCFG_COMP);
264
+    //SYSCFG_CFGR1 |= SYSCFG_CFGR1_PA11_PA12_RMP;
265
+ 
266
+#elif defined(STM32L0)
267
+
268
+    // libopencm3 clock setup can be a bit ad-hoc, so let's configure manually
269
+    // 32MHz, PLL supplied by the internal HSI16 oscillator
270
+    /* Set the flash latency */
271
+    FLASH_ACR |= FLASH_ACR_LATENCY_1WS;
272
+    /* Turn on HSI16 */
273
+    RCC_CR |= RCC_CR_HSI16ON;
274
+	while ((RCC_CR & RCC_CR_HSI16RDY) == 0);
275
+    /* Make sure PLL is off (it should be after reset, but ...) */
276
+    RCC_CR &= ~RCC_CR_PLLON;
277
+	while (RCC_CR & RCC_CR_PLLRDY);
278
+    /* Set the PLL source to HSI16 */
279
+    RCC_CFGR &= ~(1<<16); // RCC_CFGR_PLLSRC
280
+    /* Set up the PLL */
281
+    uint32_t reg = RCC_CFGR
282
+                   & ~( (RCC_CFGR_PLLMUL_MASK << RCC_CFGR_PLLMUL_SHIFT)
283
+                      | (RCC_CFGR_PLLDIV_MASK << RCC_CFGR_PLLDIV_SHIFT));
284
+    RCC_CFGR = reg | (RCC_CFGR_PLLMUL_MUL4 << RCC_CFGR_PLLMUL_SHIFT)
285
+                   | (RCC_CFGR_PLLDIV_DIV2 << RCC_CFGR_PLLDIV_SHIFT);
286
+    /* Turn on PLL and switch to it */
287
+    RCC_CR |= RCC_CR_PLLON;
288
+    while ((RCC_CR & RCC_CR_PLLRDY) == 0);
289
+    RCC_CFGR |=  RCC_CFGR_SW_PLL;
290
+    /* Set the peripheral clock frequencies used. */
291
+    rcc_ahb_frequency  = 32000000; 
292
+    rcc_apb1_frequency = 32000000;
293
+    rcc_apb2_frequency = 32000000;
294
+    // end of manual clock configuration
295
+
296
+    // Enable VREFINT reference for HSI48
297
+    rcc_periph_clock_enable(RCC_SYSCFG);
298
+    SYSCFG_CFGR3 |= SYSCFG_CFGR3_ENREF_HSI48;
299
+
300
+    rcc_set_hsi48_source_rc48();
301
+    crs_autotrim_usb_enable();
302
+
303
+    rcc_osc_on(RCC_HSI48);
304
+    rcc_wait_for_osc_ready(RCC_HSI48);
305
+
306
+    /* MCO on PA9, to verify MCU speed with a scope */
307
+    gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9);
308
+    gpio_set_af(GPIOA, GPIO_AF0, GPIO9);
309
+    RCC_CFGR |= (RCC_CFGR_MCO_SYSCLK << RCC_CFGR_MCO_SHIFT) | (RCC_CFGR_MCOPRE_DIV16 << 28);
310
+
311
+#else
312
+    #error "Edit the sources and do the clock setup!"
313
+#endif
314
+
315
+    rcc_periph_clock_enable(RCC_GPIOA);
316
+    gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO15); // LED
317
+	gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO1);   // button, has external pull-down
318
+
319
+    usbd_dev = usbd_init(&st_usbfs_v2_usb_driver, &dev, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
320
+
321
+    usbd_register_set_config_callback(usbd_dev, cdcacm_set_config);
322
+
323
+    char greeting[16] = "hello, world\r\n";
324
+
325
+    while (1) {
326
+        usbd_poll(usbd_dev);
327
+		if (gpio_get(GPIOA, GPIO1)) {
328
+            usbd_ep_write_packet(usbd_dev, 0x82, greeting, 15);
329
+			for (uint32_t i = 0; i < 2000000; i++) {	/* Wait a bit, cheap "debounce" */
330
+				__asm__("nop");
331
+			}
332
+        }
333
+    }
334
+}

Loading…
Cancel
Save