├── .gitignore ├── README.md └── STM32F1 ├── CREDITS ├── Makefile ├── README ├── common.h ├── config.h ├── dfu.c ├── dfu.h ├── flash ├── debug.cfg ├── flash.cfg ├── openocd.cfg ├── stm32.cfg └── stm32loader.py ├── hardware.c ├── hardware.h ├── main.c ├── stm32_lib ├── c_only_md.ld ├── c_only_md_RAM.ld ├── c_only_md_high_density.ld ├── c_only_startup.s ├── c_only_startup_user.s ├── cortexm3_macro.h ├── cortexm3_macro.s └── stm32f10x_type.h ├── usb.c ├── usb.h ├── usb_descriptor.c ├── usb_descriptor.h ├── usb_lib ├── usb_conf.h ├── usb_core.c ├── usb_core.h ├── usb_def.h ├── usb_init.c ├── usb_init.h ├── usb_int.c ├── usb_int.h ├── usb_lib.h ├── usb_mem.c ├── usb_mem.h ├── usb_regs.c ├── usb_regs.h └── usb_type.h └── util ├── dfu-util.exe ├── maple_mini_bootloader_updater └── maple_mini_bootloader_updater.ino └── usb_descriptor_strings_util.html /.gitignore: -------------------------------------------------------------------------------- 1 | STM32F1/.dep 2 | STM32F1/TAGS 3 | STM32F1/tags 4 | STM32F1/cscope.out 5 | STM32F1/build 6 | STM32F1/*~ 7 | GD32F1/.dep 8 | GD32F1/TAGS 9 | GD32F1/tags 10 | GD32F1/cscope.out 11 | GD32F1/build 12 | GD32F1/*~ 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # STM32F103 DFU Bootloader 2 | 3 | This is a DFU bootloader for STM32F103 that fits in 8K of flash space, with several activation modes. I don't know how DFU-compliant it is, but it works with certain versions of dfu_util. The end goal is to provide a DFU-compliant bootloader that is both well written and has configurable entry options to cater to the target. This project is very far from the former and only has small amounts of the latter, but it does work today. 4 | 5 | Send code to AltID 2 for proper operation. 6 | 7 | The long term goal is to have a well written, well documented bootloader that works on other targets as well (particularly other STM32, and EFM32). I don't know if this goal will be achieved. 8 | 9 | *This fork has been tested to build and function with GCC4.8, GCC4.9 and GCC5.3.* 10 | 11 | Some useless information: 12 | 13 | - The bootloader has a DFU - AltID for RAM uploads, but the code for it has mostly been removed. The AltID will probably be removed in the future. 14 | - On "generic" boards, the USB reset (to force re-enumeration by the host) is triggered by reconfiguring USB line D+ (typically on PA12) into GPIO mode, and driving PA12 low for a short period, before setting the pin back to its USB operational mode. This is hacky as all hell, and this explanation may no longer be accurate, either. This system to reset the USB was written by @Victor_pv. 15 | - There are multiple build targets for "generic" STM32F103 boards, because each vendor seems to have the "LED" on a different port/pin, and the bootloader flashes the LED to indicate the current operation / state. Bootloader entry buttons are also on various pins, or sometimes are switches, or aren't present at all. 16 | -- You can add your own configurations in config.h. The Makefile sets the board name as a #define e.g. #define TARGET_GENERIC_F103_PD2, and config.h contains a block of config defines for each board. 17 | -- Boards which have the Maple USB reset hardware need to defined HAS_MAPLE_HARDWARE 18 | 19 | 20 | ##### Building on Linux 21 | 22 | You probably know how to do this. Just make sure you have your ARM toolchain working. 23 | 24 | 25 | ##### Building on Windows 26 | 27 | 1. Make sure MinGW is installed, and has make, bash (Makefile depends on non-Windows shell) 28 | 2. Make sure your ARM toolchain is in your path 29 | 3. Make like you would on Linux 30 | 31 | ##### Debugging on Windows 32 | 33 | I have found that using the ST-Link GDB server (stlink-20130324-win) works fine with gdb provided by MinGW, as for some reason the GDB provided with the Launchpad ARM toolchain wasn't working. 34 | 35 | ##### Problems with the bootloader 36 | 37 | If you have questions about or issues with the bootloader, please submit an Issue. 38 | -------------------------------------------------------------------------------- /STM32F1/CREDITS: -------------------------------------------------------------------------------- 1 | This is at least a partial credits-file of people that have 2 | contributed to the Maple bootloader. It is formatted the same way the 3 | Linux kernel CREDITS file is structured: sorted by name and formatted 4 | for easy processing. 5 | 6 | The fields are: name (N), email (E), web-address (W), description (D). 7 | 8 | ---------- 9 | 10 | N: Tormod Volden 11 | E: debian.tormod@gmail.com 12 | D: Fixes for DFU compliance 13 | -------------------------------------------------------------------------------- /STM32F1/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile skeleton adapted from Peter Harrison's - www.micromouse.com 2 | 3 | # MCU name and submodel 4 | MCU = cortex-m3 5 | SUBMDL = stm32f103 6 | 7 | # toolchain (using code sourcery now) 8 | TCHAIN = arm-none-eabi 9 | THUMB = -mthumb 10 | THUMB_IW = -mthumb-interwork 11 | 12 | # Target file name (without extension). 13 | BUILDDIR = build 14 | TARGET = $(BUILDDIR)/maple_boot 15 | 16 | ST_LIB = stm32_lib 17 | ST_USB = usb_lib 18 | 19 | # Optimization level [0,1,2,3,s] 20 | OPT ?= s 21 | DEBUG = 22 | #DEBUG = dwarf-2 23 | 24 | INCDIRS = ./$(ST_LIB) ./$(ST_USB) 25 | 26 | CFLAGS = $(DEBUG) 27 | CFLAGS += -O$(OPT) 28 | CFLAGS += -ffunction-sections -fdata-sections 29 | CFLAGS += -Wall -Wimplicit 30 | CFLAGS += -Wcast-align 31 | CFLAGS += -Wpointer-arith -Wswitch 32 | CFLAGS += -Wredundant-decls -Wreturn-type -Wshadow -Wunused 33 | CFLAGS += -Wa,-adhlns=$(BUILDDIR)/$(subst $(suffix $<),.lst,$<) 34 | CFLAGS += $(patsubst %,-I%,$(INCDIRS)) 35 | CFLAGS += -flto 36 | 37 | # Aeembler Flags 38 | ASFLAGS = -Wa,-adhlns=$(BUILDDIR)/$(<:.s=.lst)#,--g$(DEBUG) 39 | 40 | LDFLAGS = -nostartfiles -Wl,-Map=$(TARGET).map,--cref,--gc-sections 41 | LDFLAGS += -lc -lgcc 42 | 43 | 44 | 45 | # Define programs and commands. 46 | SHELL = sh 47 | CC = $(TCHAIN)-gcc 48 | CPP = $(TCHAIN)-g++ 49 | AR = $(TCHAIN)-ar 50 | OBJCOPY = $(TCHAIN)-objcopy 51 | OBJDUMP = $(TCHAIN)-objdump 52 | SIZE = $(TCHAIN)-size 53 | NM = $(TCHAIN)-nm 54 | REMOVE = rm -f 55 | REMOVEDIR = rm -r 56 | COPY = cp 57 | 58 | # Define Messages 59 | # English 60 | MSG_ERRORS_NONE = Errors: none 61 | MSG_BEGIN = "-------- begin --------" 62 | MSG_ETAGS = Created TAGS File 63 | MSG_END = -------- end -------- 64 | MSG_SIZE_BEFORE = Size before: 65 | MSG_SIZE_AFTER = Size after: 66 | MSG_FLASH = Creating load file for Flash: 67 | MSG_EXTENDED_LISTING = Creating Extended Listing: 68 | MSG_SYMBOL_TABLE = Creating Symbol Table: 69 | MSG_LINKING = Linking: 70 | MSG_COMPILING = Compiling C: 71 | MSG_ASSEMBLING = Assembling: 72 | MSG_CLEANING = Cleaning project: 73 | 74 | # Combine all necessary flags and optional flags. 75 | # Add target processor to flags. 76 | GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d 77 | ALL_CFLAGS = -g -mcpu=$(MCU) $(THUMB_IW) -I. $(CFLAGS) $(TARGETFLAGS) $(GENDEPFLAGS) 78 | ALL_ASFLAGS = -g -mcpu=$(MCU) $(THUMB_IW) -I. -x assembler-with-cpp $(ASFLAGS) 79 | 80 | # --------------------------------------------- # 81 | # file management 82 | ASRC = $(ST_LIB)/c_only_startup.s $(ST_LIB)/cortexm3_macro.s 83 | 84 | STM32SRCS = 85 | 86 | _STM32USBSRCS = usb_regs.c \ 87 | usb_int.c \ 88 | usb_init.c \ 89 | usb_core.c \ 90 | usb_mem.c 91 | 92 | STM32USBSRCS = $(patsubst %, $(ST_USB)/%,$(_STM32USBSRCS)) 93 | 94 | SRCS = usb.c usb_descriptor.c main.c hardware.c dfu.c 95 | 96 | 97 | SRC = $(SRCS) $(STM32SRCS) $(STM32USBSRCS) 98 | 99 | # Define all object files. 100 | _COBJ = $(SRC:.c=.o) 101 | _AOBJ = $(ASRC:.s=.o) 102 | COBJ = $(patsubst %, $(BUILDDIR)/%,$(_COBJ)) 103 | AOBJ = $(patsubst %, $(BUILDDIR)/%,$(_AOBJ)) 104 | 105 | # Define all listing files. 106 | _LST = $(ASRC:.s=.lst) 107 | _LST += $(SRC:.c=.lst) 108 | LST = $(patsubst %, $(BUILDDIR)/%,$(_LST)) 109 | 110 | # Display size of file. 111 | HEXSIZE = $(SIZE) --target=binary $(TARGET).hex 112 | ELFSIZE = $(SIZE) -A $(TARGET).elf 113 | 114 | # go! 115 | all: begin gccversion build sizeafter finished end 116 | maple-mini: begin gccversion build_maple-mini sizeafter finished copy_maple_mini end 117 | maple-rev3: begin gccversion build_maple-rev3 sizeafter finished copy_maple-rev3 end 118 | maple-rev5: begin gccversion build_maple-rev5 sizeafter finished copy_maple-rev5 end 119 | generic-pc13: begin gccversion build_generic-pc13 sizeafter finished copy_generic-pc13 end 120 | generic-pg15: begin gccversion build_generic-pg15 sizeafter finished copy_generic-pg15 end 121 | generic-pd2: begin gccversion build_generic-pd2 sizeafter finished copy_generic-pd2 end 122 | generic-pd1: begin gccversion build_generic-pd1 sizeafter finished copy_generic-pd1 end 123 | generic-pa1: begin gccversion build_generic-pa1 sizeafter finished copy_generic-pa1 end 124 | generic-pb9: begin gccversion build_generic-pb9 sizeafter finished copy_generic-pb9 end 125 | generic-pe2: begin gccversion build_generic-pe2 sizeafter finished copy_generic-pe2 end 126 | generic-pa9: begin gccversion build_generic-pa9 sizeafter finished copy_generic-pa9 end 127 | generic-pe5: begin gccversion build_generic-pe5 sizeafter finished copy_generic-pe5 end 128 | generic-pe5-button-pa0: begin gccversion build_generic-pe5-button-pa0 sizeafter finished copy_generic-pe5-button-pa0 end 129 | generic-pb7: begin gccversion build_generic-pb7 sizeafter finished copy_generic-pb7 end 130 | generic-pb0: begin gccversion build_generic-pb0 sizeafter finished copy_generic-pb0 end 131 | stbee : begin gccversion build_stbee sizeafter finished copy_stbee end 132 | naze32: begin gccversion build_naze32 sizeafter finished copy_naze32 end 133 | andnxor-dc24-bender: begin gccversion build_andnxor-dc24-bender sizeafter finished copy_andnxor-dc24-bender end 134 | tc-gripdaptor: begin gccversion build_tc-gripdaptor sizeafter finished copy_tc-gripdaptor end 135 | build: elf bin lss sym 136 | 137 | build_maple-mini: TARGETFLAGS= -DTARGET_MAPLE_MINI 138 | # Set the linker script 139 | build_maple-mini: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 140 | 141 | build_maple-mini: elf bin lss sym 142 | copy_maple_mini: 143 | @echo 144 | @echo "Copying to binaries folder" 145 | @echo 146 | cp $(TARGET).bin binaries/dfu_boot20_maple_mini.bin 147 | @echo 148 | 149 | build_maple-rev3: TARGETFLAGS= -DTARGET_MAPLE_REV3 150 | # Set the linker script 151 | build_maple-rev3: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 152 | 153 | build_maple-rev3: elf bin lss sym 154 | copy_maple-rev3: 155 | @echo 156 | @echo "Copying to binaries folder" 157 | @echo 158 | cp $(TARGET).bin binaries/dfu_boot20_maple_rev3.bin 159 | @echo 160 | 161 | build_maple-rev5: TARGETFLAGS= -DTARGET_MAPLE_REV5 162 | # Set the linker script 163 | build_maple-rev5: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 164 | build_maple-rev5: elf bin lss sym 165 | copy_maple-rev5: 166 | @echo 167 | @echo "Copying to binaries folder" 168 | @echo 169 | cp $(TARGET).bin binaries/dfu_boot20_maple_rev5.bin 170 | @echo 171 | 172 | 173 | build_generic-pc13: TARGETFLAGS= -DTARGET_GENERIC_F103_PC13 174 | # Set the linker script 175 | build_generic-pc13: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 176 | build_generic-pc13: elf bin lss sym 177 | copy_generic-pc13: 178 | @echo 179 | @echo "Copying to binaries folder" 180 | @echo 181 | cp $(TARGET).bin binaries/dfu_boot20_generic_pc13.bin 182 | @echo 183 | 184 | build_generic-pg15: TARGETFLAGS= -DTARGET_GENERIC_F103_PG15 185 | # Set the linker script 186 | build_generic-pg15: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 187 | build_generic-pg15: elf bin lss sym 188 | copy_generic-pg15: 189 | @echo 190 | @echo "Copying to binaries folder" 191 | @echo 192 | cp $(TARGET).bin binaries/dfu_boot20_generic_pg15.bin 193 | @echo 194 | 195 | 196 | build_generic-pd2: TARGETFLAGS= -DTARGET_GENERIC_F103_PD2 197 | # Set the linker script 198 | build_generic-pd2: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 199 | build_generic-pd2: elf bin lss sym 200 | copy_generic-pd2: 201 | @echo 202 | @echo "Copying to binaries folder" 203 | @echo 204 | cp $(TARGET).bin binaries/dfu_boot20_generic_pd2.bin 205 | @echo 206 | 207 | 208 | build_generic-pd1: TARGETFLAGS= -DTARGET_GENERIC_F103_PD1 209 | # Set the linker script 210 | build_generic-pd1: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 211 | build_generic-pd1: elf bin lss sym 212 | copy_generic-pd1: 213 | @echo 214 | @echo "Copying to binaries folder" 215 | @echo 216 | cp $(TARGET).bin binaries/dfu_boot20_generic_pd1.bin 217 | @echo 218 | 219 | build_generic-pa1: TARGETFLAGS= -DTARGET_GENERIC_F103_PA1 220 | # Set the linker script 221 | build_generic-pa1: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 222 | build_generic-pa1: elf bin lss sym 223 | copy_generic-pa1: 224 | @echo 225 | @echo "Copying to binaries folder" 226 | @echo 227 | cp $(TARGET).bin binaries/dfu_boot20_generic_pa1.bin 228 | @echo 229 | 230 | build_generic-pb9: TARGETFLAGS= -DTARGET_GENERIC_F103_PB9 231 | # Set the linker script 232 | build_generic-pb9: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 233 | build_generic-pb9: elf bin lss sym 234 | copy_generic-pb9: 235 | @echo 236 | @echo "Copying to binaries folder" 237 | @echo 238 | cp $(TARGET).bin binaries/dfu_boot20_generic_pb9.bin 239 | @echo 240 | 241 | 242 | build_generic-pe2: TARGETFLAGS= -DTARGET_GENERIC_F103_PE2 243 | # Set the linker script 244 | build_generic-pe2: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 245 | build_generic-pe2: elf bin lss sym 246 | copy_generic-pe2: 247 | @echo 248 | @echo "Copying to binaries folder" 249 | @echo 250 | cp $(TARGET).bin binaries/dfu_boot20_generic_pe2.bin 251 | @echo 252 | 253 | 254 | build_generic-pa9: TARGETFLAGS= -DTARGET_GENERIC_F103_PA9 255 | # Set the linker script 256 | build_generic-pa9: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 257 | build_generic-pa9: elf bin lss sym 258 | copy_generic-pa9: 259 | @echo 260 | @echo "Copying to binaries folder" 261 | @echo 262 | cp $(TARGET).bin binaries/dfu_boot20_generic_pa9.bin 263 | @echo 264 | 265 | 266 | build_generic-pe5: TARGETFLAGS= -DTARGET_GENERIC_F103_PE5 267 | # Set the linker script 268 | build_generic-pe5: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 269 | build_generic-pe5: elf bin lss sym 270 | copy_generic-pe5: 271 | @echo 272 | @echo "Copying to binaries folder" 273 | @echo 274 | cp $(TARGET).bin binaries/dfu_boot20_generic_pe5.bin 275 | @echo 276 | 277 | 278 | build_generic-pe5-button-pa0: TARGETFLAGS= -DTARGET_GENERIC_F103_PE5_BUTTON_PA0 279 | # Set the linker script 280 | build_generic-pe5-button-pa0: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 281 | build_generic-pe5-button-pa0: elf bin lss sym 282 | copy_generic-pe5-button-pa0: 283 | @echo 284 | @echo "Copying to binaries folder" 285 | @echo 286 | cp $(TARGET).bin binaries/dfu_boot20_generic_pe5_btn_pa0.bin 287 | @echo 288 | 289 | 290 | build_generic-pb7: TARGETFLAGS= -DTARGET_GENERIC_F103_PB7 291 | # Set the linker script 292 | build_generic-pb7: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 293 | build_generic-pb7: elf bin lss sym 294 | copy_generic-pb7: 295 | @echo 296 | @echo "Copying to binaries folder" 297 | @echo 298 | cp $(TARGET).bin binaries/dfu_boot20_generic_pb7.bin 299 | @echo 300 | build_generic-pb0: TARGETFLAGS= -DTARGET_GENERIC_F103_PB0 301 | # Set the linker script 302 | build_generic-pb0: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 303 | build_generic-pb0: elf bin lss sym 304 | copy_generic-pb0: 305 | @echo 306 | @echo "Copying to binaries folder" 307 | @echo 308 | cp $(TARGET).bin binaries/dfu_boot20_generic_pb0.bin 309 | @echo 310 | 311 | 312 | build_stbee: TARGETFLAGS= -DTARGET_STBEE 313 | # Set the linker script 314 | build_stbee: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 315 | build_stbee: elf bin lss sym 316 | copy_stbee: 317 | @echo 318 | @echo "Copying to binaries folder" 319 | @echo 320 | cp $(TARGET).bin binaries/dfu_boot20_stbee.bin 321 | @echo 322 | 323 | build_naze32: TARGETFLAGS= -DTARGET_NAZE32 324 | # Set the linker script 325 | build_naze32: LDFLAGS +=-T$(ST_LIB)/c_only_md_high_density.ld 326 | build_naze32: elf bin lss sym 327 | copy_naze32: 328 | @echo 329 | @echo "Copying to binaries folder" 330 | @echo 331 | cp $(TARGET).bin binaries/dfu_boot20_naze32.bin 332 | @echo 333 | 334 | build_andnxor-dc24-bender: TARGETFLAGS= -DTARGET_ANDNXOR_DC24_BENDER 335 | # Set the linker script 336 | build_andnxor-dc24-bender: LDFLAGS +=-T$(ST_LIB)/c_only_md.ld 337 | build_andnxor-dc24-bender: elf bin lss sym 338 | copy_andnxor-dc24-bender: 339 | @echo 340 | @echo "Copying to binaries folder" 341 | @echo 342 | cp $(TARGET).bin binaries/dfu_boot20_andnxor_dc24_bender.bin 343 | @echo 344 | 345 | build_tc-gripdaptor: TARGETFLAGS= -DTARGET_TC_GRIPDAPTOR 346 | # Set the linker script 347 | build_tc-gripdaptor: LDFLAGS +=-T$(ST_LIB)/c_only_md.ld 348 | build_tc-gripdaptor: elf bin lss sym 349 | copy_tc-gripdaptor: 350 | @echo 351 | @echo "Copying to binaries folder" 352 | @echo 353 | cp $(TARGET).bin binaries/dfu_boot20_tc_gripdaptor.bin 354 | @echo 355 | 356 | 357 | bin: $(TARGET).bin 358 | elf: $(TARGET).elf 359 | lss: $(TARGET).lss 360 | sym: $(TARGET).sym 361 | dfu: $(TARGET).bin 362 | sudo dfu-util -d 0110:1001 -a 0 -D $(TARGET).bin 363 | 364 | begin: 365 | # mkdir -p build\stm32_lib 366 | # mkdir -p build\usb_lib 367 | @echo -- 368 | @echo $(MSG_BEGIN) 369 | @echo $(COBJ) 370 | 371 | finished: 372 | @echo $(MSG_ERRORS_NONE) 373 | tags: 374 | etags `find . -name "*.c" -o -name "*.cpp" -o -name "*.h"` 375 | @echo $(MSG_ETAGS) 376 | end: 377 | @echo $(MSG_END) 378 | @echo 379 | sizeafter: 380 | @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi 381 | gccversion: 382 | @$(CC) --version 383 | 384 | program: 385 | @echo "Flash-programming with OpenOCD" 386 | cp $(TARGET).bin flash/tmpflash.bin 387 | cd flash && openocd -f flash.cfg 388 | 389 | program_serial: 390 | @echo "Flash-programming with stm32loader.py" 391 | ./flash/stm32loader.py -p /dev/ttyUSB0 -evw build/maple_boot.bin 392 | 393 | debug: $(TARGET).bin 394 | @echo "Flash-programming with OpenOCD - DEBUG" 395 | cp $(TARGET).bin flash/tmpflash.bin 396 | cd flash && openocd -f debug.cfg 397 | 398 | install: $(TARGET).bin 399 | cp $(TARGET).bin build/main.bin 400 | openocd -f flash/perry_flash.cfg 401 | 402 | run: $(TARGET).bin 403 | openocd -f flash/run.cfg 404 | 405 | # Create final output file (.hex) from ELF output file. 406 | %.hex: %.elf 407 | @echo 408 | @echo $(MSG_FLASH) $@ 409 | $(OBJCOPY) -O binary $< $@ 410 | 411 | # Create final output file (.bin) from ELF output file. 412 | %.bin: %.elf 413 | @echo 414 | @echo $(MSG_FLASH) $@ 415 | $(OBJCOPY) -O binary $< $@ 416 | 417 | 418 | # Create extended listing file from ELF output file. 419 | # testing: option -C 420 | %.lss: %.elf 421 | @echo 422 | @echo $(MSG_EXTENDED_LISTING) $@ 423 | $(OBJDUMP) -h -S -D $< > $@ 424 | 425 | 426 | # Create a symbol table from ELF output file. 427 | %.sym: %.elf 428 | @echo 429 | @echo $(MSG_SYMBOL_TABLE) $@ 430 | $(NM) -n $< > $@ 431 | 432 | 433 | # Link: create ELF output file from object files. 434 | .SECONDARY : $(TARGET).elf 435 | .PRECIOUS : $(COBJ) $(AOBJ) 436 | 437 | %.elf: $(COBJ) $(AOBJ) 438 | @echo 439 | @echo $(MSG_LINKING) $@ 440 | $(CC) $(THUMB) $(ALL_CFLAGS) $(AOBJ) $(COBJ) --output $@ $(LDFLAGS) 441 | 442 | # Compile: create object files from C source files. ARM/Thumb 443 | $(COBJ) : $(BUILDDIR)/%.o : %.c 444 | @echo 445 | @echo $(MSG_COMPILING) $< 446 | $(CC) -c $(THUMB) $(ALL_CFLAGS) $< -o $@ 447 | 448 | # Assemble: create object files from assembler source files. ARM/Thumb 449 | $(AOBJ) : $(BUILDDIR)/%.o : %.s 450 | @echo 451 | @echo $(MSG_ASSEMBLING) $< 452 | $(CC) -c $(THUMB) $(ALL_ASFLAGS) $< -o $@ 453 | 454 | clean: begin clean_list finished end 455 | 456 | clean_list : 457 | @echo 458 | @echo $(MSG_CLEANING) 459 | $(REMOVE) $(TARGET).hex 460 | $(REMOVE) $(TARGET).bin 461 | $(REMOVE) $(TARGET).obj 462 | $(REMOVE) $(TARGET).elf 463 | $(REMOVE) $(TARGET).map 464 | $(REMOVE) $(TARGET).obj 465 | $(REMOVE) $(TARGET).a90 466 | $(REMOVE) $(TARGET).sym 467 | $(REMOVE) $(TARGET).lnk 468 | $(REMOVE) $(TARGET).lss 469 | $(REMOVE) $(COBJ) 470 | $(REMOVE) $(AOBJ) 471 | $(REMOVE) $(LST) 472 | $(REMOVE) flash/tmpflash.bin 473 | # $(REMOVE) $(SRC:.c=.s) 474 | # $(REMOVE) $(SRC:.c=.d) 475 | $(REMOVE) .dep/* 476 | 477 | # Include the dependency files. 478 | -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) 479 | 480 | 481 | # Listing of phony targets. 482 | .PHONY : all begin finish tags end sizeafter gccversion \ 483 | build elf hex bin lss sym clean clean_list program cscope 484 | 485 | cscope: 486 | rm -rf *.cscope 487 | find . -iname "*.[hcs]" | grep -v examples | xargs cscope -R -b 488 | -------------------------------------------------------------------------------- /STM32F1/README: -------------------------------------------------------------------------------- 1 | 2 | FILES ------------------------------------------------------------------------- 3 | 4 | stm32_lib/* 5 | - all the (possibly consolidated) stm32 lib and usb example code 6 | 7 | usb.c 8 | - USB-specific hardware setup. Interrupts, clocks, etc. handling USB when 9 | not "Attached". some low-level callbacks (low power mode, init, reset, 10 | resume, etc). 11 | 12 | usb_descriptor.c 13 | - aka application descriptor; big static struct and callbacks for sending 14 | the descriptor. TODO: stop using unicode strings directly, generate 15 | with a function. will save a small amount of flash and everyone seems 16 | to give a big shit about that these days. Also makes it easier to add 17 | custom strings by an end-user adding a board. 18 | 19 | main.c 20 | - main loop and calling any hardware init stuff. timing hacks for EEPROM 21 | writes not to block usb interrupts. logic to handle 2 second timeout then 22 | jump to user code. 23 | 24 | hardware.c 25 | - init routines to setup clocks, interrupts, also destructor functions. 26 | does not include USB stuff. Flash read/write functions. 27 | 28 | dfu.c 29 | - mostly the giant FSM case switch, also some USB endpoint callbacks. 30 | also doesn't reset state correctly at the end so you've got one shot 31 | and you're done. probably not a bad idea but at least do it right... 32 | 33 | everything 34 | - mostly shit 35 | 36 | TODO -------------------------------------------------------------------------- 37 | 38 | * pack the structs 39 | * use sizeof() for usb application descriptor once structs are packed 40 | * configure POR detect to allow different BOOTLOADER_WAIT times? 41 | * actually know wtf are you doing when writing a bootloader -------------------------------------------------------------------------------- /STM32F1/common.h: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | 25 | /** 26 | * @file common.h 27 | * 28 | * @brief toplevel include for bootloader source files 29 | * 30 | * 31 | */ 32 | 33 | #ifndef __COMMON_H 34 | #define __COMMON_H 35 | 36 | 37 | #include "stm32_lib/stm32f10x_type.h" 38 | #include "stm32_lib/cortexm3_macro.h" 39 | 40 | #include "config.h" 41 | #include "hardware.h" 42 | #include "usb.h" 43 | 44 | // version 45 | #define VER_MAJOR '1' 46 | #define VER_MINOR '1' 47 | 48 | // reset types 49 | #define RESET_POR (1 << 27) // power-on reset 50 | #define RESET_EXT (1 << 26) // reset button via reset pin 51 | #define RESET_ANY 0xfe000000 // all reset types 52 | 53 | #ifndef RESET_ACTIVATION 54 | #define RESET_ACTIVATION (RESET_POR | RESET_EXT) 55 | #endif 56 | 57 | // user code entry 58 | typedef void (*FuncPtr)(void); 59 | 60 | 61 | #endif -------------------------------------------------------------------------------- /STM32F1/config.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | *****************************************************************************/ 24 | 25 | /** 26 | * @file config.h 27 | * 28 | * @brief bootloader settings and macro defines 29 | * 30 | * 31 | */ 32 | 33 | #ifndef __CONFIG_H 34 | #define __CONFIG_H 35 | 36 | 37 | #include "common.h" 38 | 39 | 40 | // Speed controls for strobing the LED pin 41 | #define BLINK_FAST 0x33000 42 | #define BLINK_SLOW 0x100000 43 | 44 | // default wait times in blink_slow periods if not explicitly defined 45 | #define WAIT_SHORT 4 46 | #define WAIT_LONG 15 47 | 48 | // how many blinks do we do at startup, and before checking user input? 49 | #define STARTUP_BLINKS 4 50 | // uncomment the next line to not do the fast blink at startup 51 | // #define DISABLE_STARTUP_FAST_BLINK 52 | 53 | // do we enter bootloader on certain reset methods only? 54 | #define RESET_ACTIVATION (RESET_POR | RESET_EXT) 55 | // how about the button? can it override this? uncomment if so 56 | #define BL_BUTTON_ALWAYS_WORKS 57 | 58 | // The USB clock bit is the same for all boards 59 | #define RCC_APB1ENR_USB_CLK 0x00800000 60 | 61 | // used by the bootloader for something 62 | #define LARGEST_FLASH_PAGE_SIZE 0x800 63 | 64 | // Jump locations for legacy (0x8005000) and new / smaller (0x8002000) bootloader 65 | #define USER_CODE_FLASH0X8005000 ((u32)0x08005000) 66 | #define USER_CODE_FLASH0X8002000 ((u32)0x08002000) 67 | 68 | // Upload to RAM has been removed / depreacted so these values a not used any more 69 | #define USER_CODE_RAM ((u32)0x20000C00) 70 | 71 | // RAM_END, set ram end to the end of ram on the device wth the least RAM (STM32F103C) 72 | // btw whoever did this, this is poor as shit practice, come on now 73 | #define RAM_END ((u32)0x20005000) 74 | 75 | 76 | /* Porting information Please read. 77 | The following defines are used to set up the hardware of your target board. 78 | See http://www.st.com/web/en/resource/technical/document/reference_manual/CD00171190.pdf 79 | 80 | Generally, two GPIO pins need to be defined; these are for the LED and the Button. 81 | 82 | The following is required: 83 | - LED_BANK - this is the GPIO port for the LED, e.g. GPIOA, GPIOB, ... 84 | - LED_PIN - this is the pin number e.g. for PB1, set the value to 1 85 | - LED_ON_STATE - the GPIO state to light the LED. 86 | if the GPIO is connected to cathode, set 0. if anode, set 1. 87 | 88 | - BUTTON_BANK - this is the GPIO port for the button, e.g. GPIOA, GPIOB, ... 89 | - BUTTON_PIN - this is the pin number e.g. for PBC14, set the value to 14 90 | - BUTTON_ON_STATE - set to the required value for button activation. a pull-up or 91 | pull-down will be set as appropriate to make the button work. 92 | set to 0 if your button shorts to GND on press, 1 if to VCC 93 | */ 94 | 95 | #if defined TARGET_MAPLE_MINI 96 | 97 | #define HAS_MAPLE_HARDWARE 1 98 | 99 | #define LED_BANK GPIOB 100 | #define LED_PIN 1 101 | #define LED_ON_STATE 1 102 | 103 | /* On the Mini, BUT is PB8 */ 104 | #define BUTTON_BANK GPIOB 105 | #define BUTTON_PIN 8 106 | #define BUTTON_ON_STATE 1 107 | 108 | /* USB Disc Pin Setup. USB DISC is PB9 */ 109 | #define USB_DISC_BANK GPIOB 110 | #define USB_DISC_PIN 9 111 | 112 | #elif defined TARGET_MAPLE_REV3 113 | 114 | #warning "Target MAPLE_REV3" 115 | 116 | // Flag that this type of board has the custom maple disconnect hardware 117 | #define HAS_MAPLE_HARDWARE 1 118 | 119 | #define LED_BANK GPIOB 120 | #define LED_PIN 1 121 | #define LED_ON_STATE 1 122 | 123 | #define BUTTON_BANK GPIOB 124 | #define BUTTON_PIN 8 125 | #define BUTTON_ON_STATE 1 126 | 127 | /* USB Disc Pin Setup. USB DISC is PB9 */ 128 | #define USB_DISC_BANK GPIOB 129 | #define USB_DISC_PIN 9 130 | 131 | #elif defined TARGET_MAPLE_REV5 132 | 133 | // Flag that this type of board has the custom maple disconnect hardware 134 | #define HAS_MAPLE_HARDWARE 1 135 | 136 | #define LED_BANK GPIOA 137 | #define LED_PIN 5 138 | #define LED_ON_STATE 0 139 | 140 | /* On the Mini, BUT is PB8 */ 141 | #define BUTTON_BANK GPIOC 142 | #define BUTTON_PIN 9 143 | 144 | /* USB Disc Pin Setup. USB DISC is PB9 */ 145 | #define USB_DISC_BANK GPIOB 146 | #define USB_DISC_PIN 9 147 | 148 | #elif defined TARGET_GENERIC_F103_PC13 149 | 150 | #define LED_BANK GPIOC 151 | #define LED_PIN 13 152 | #define LED_ON_STATE 0 153 | 154 | // Button (if you have one) 155 | #define BUTTON_BANK GPIOC 156 | #define BUTTON_PIN 14 157 | #define BUTTON_ON_STATE 1 158 | 159 | 160 | #elif defined TARGET_GENERIC_F103_PG15 161 | 162 | #define LED_BANK GPIOG 163 | #define LED_PIN 15 164 | #define LED_ON_STATE 1 165 | 166 | // Button (if you have one) 167 | #define BUTTON_BANK GPIOC 168 | #define BUTTON_PIN 14 169 | #define BUTTON_ON_STATE 1 170 | 171 | #elif defined TARGET_GENERIC_F103_PD2 172 | 173 | #define LED_BANK GPIOD 174 | #define LED_PIN 2 175 | #define LED_ON_STATE 1 176 | 177 | // Button (if you have one) 178 | #define BUTTON_BANK GPIOC 179 | #define BUTTON_PIN 14 180 | #define BUTTON_ON_STATE 1 181 | 182 | #elif defined TARGET_GENERIC_F103_PD1 183 | 184 | #define LED_BANK GPIOD 185 | #define LED_PIN 1 186 | #define LED_ON_STATE 1 187 | 188 | // Button (if you have one) 189 | #define BUTTON_BANK GPIOC 190 | #define BUTTON_PIN 14 191 | #define BUTTON_ON_STATE 1 192 | 193 | #elif defined TARGET_GENERIC_F103_PA1 194 | 195 | #define BOOTLOADER_WAIT WAIT_LONG 196 | 197 | #define LED_BANK GPIOA 198 | #define LED_PIN 1 199 | #define LED_ON_STATE 1 200 | 201 | // Button (if you have one) 202 | #define BUTTON_BANK GPIOC 203 | #define BUTTON_PIN 14 204 | #define BUTTON_ON_STATE 1 205 | 206 | #define USB_DISC_HARDWIRED 1 207 | 208 | #elif defined TARGET_GENERIC_F103_PB9 209 | 210 | #define LED_BANK GPIOB 211 | #define LED_PIN 9 212 | #define LED_ON_STATE 1 213 | 214 | // Button (if you have one) 215 | #define BUTTON_BANK GPIOC 216 | #define BUTTON_PIN 14 217 | #define BUTTON_ON_STATE 1 218 | 219 | #elif defined TARGET_GENERIC_F103_PE2 220 | 221 | #define LED_BANK GPIOE 222 | #define LED_PIN 2 223 | #define LED_ON_STATE 1 224 | 225 | #elif defined TARGET_GENERIC_F103_PA9 226 | 227 | #define LED_BANK GPIOA 228 | #define LED_PIN 9 229 | #define LED_ON_STATE 1 230 | 231 | #elif defined TARGET_GENERIC_F103_PE5 232 | 233 | #define LED_BANK GPIOE 234 | #define LED_PIN 5 235 | #define LED_ON_STATE 1 236 | 237 | #define BUTTON_BANK GPIOD 238 | #define BUTTON_PIN 2 239 | #define BUTTON_ON_STATE 1 240 | 241 | #elif defined TARGET_GENERIC_F103_PE5_BUTTON_PA0 242 | 243 | #define LED_BANK GPIOE 244 | #define LED_PIN 5 245 | #define LED_ON_STATE 1 246 | 247 | #define BUTTON_BANK GPIOA 248 | #define BUTTON_PIN 0 249 | #define BUTTON_ON_STATE 1 250 | 251 | #elif defined TARGET_GENERIC_F103_PB7 252 | 253 | #define LED_BANK GPIOB 254 | #define LED_PIN 7 255 | #define LED_ON_STATE 1 256 | 257 | #elif defined TARGET_GENERIC_F103_PB0 258 | 259 | #define LED_BANK GPIOB 260 | #define LED_PIN 0 261 | #define LED_ON_STATE 1 262 | #define BOOTLOADER_WAIT 30 263 | 264 | #elif defined TARGET_STBEE 265 | 266 | #define HAS_MAPLE_HARDWARE 1 267 | 268 | #define LED_BANK GPIOD 269 | #define LED_PIN 4 270 | #define LED_ON_STATE 0 271 | 272 | /* BUTTON is PA0 (pull down) */ 273 | #define BUTTON_BANK GPIOA 274 | #define BUTTON_PIN 0 275 | #define BUTTON_ON_STATE 1 276 | 277 | /* USB Disc Pin Setup. USB DISC is PD3 */ 278 | #define USB_DISC_BANK GPIOD 279 | #define USB_DISC_PIN 3 280 | 281 | /* CRISTAL 12MHz */ 282 | #define XTAL12M 283 | 284 | #elif defined TARGET_NAZE32 285 | 286 | #define LED_BANK GPIOB 287 | #define LED_PIN 3 288 | #define LED_ON_STATE 0 289 | 290 | #elif defined TARGET_ANDNXOR_DC24_BENDER 291 | 292 | #define BOOTLOADER_WAIT 0 293 | 294 | /* lightsense LED on PB0:K, PB1:A */ 295 | #define LED_BANK GPIOB 296 | #define LED_PIN 1 297 | #define LED_ON_STATE 1 298 | #define LED_PIN_K 0 // mcu-attached cathode 299 | 300 | /* SWITCH is */ 301 | #define BUTTON_BANK GPIOC 302 | #define BUTTON_PIN 14 303 | #define BUTTON_ON_STATE 0 304 | 305 | /* USB Disc Pin Setup. USB DISC is PA2 */ 306 | #define USB_DISC_BANK GPIOA 307 | #define USB_DISC_PIN 2 308 | 309 | #elif defined TARGET_TC_GRIPDAPTOR 310 | 311 | #define BOOTLOADER_WAIT 0 312 | 313 | /* P2 orange LED on PB3 */ 314 | #define LED_BANK GPIOB 315 | #define LED_PIN 3 316 | #define LED_ON_STATE 1 317 | 318 | /* SWITCH is PB2 (pull down) */ 319 | #define BUTTON_BANK GPIOB 320 | #define BUTTON_PIN 2 321 | #define BUTTON_ON_STATE 1 322 | 323 | /* USB Disc Pin Setup. USB DISC is PA8 */ 324 | #define USB_DISC_BANK GPIOA 325 | #define USB_DISC_PIN 8 326 | 327 | #define CUSTOM_VID_PID 328 | #define VEND_ID0 0xBA 329 | #define VEND_ID1 0xD5 330 | #define PROD_ID0 0xAD 331 | #define PROD_ID1 0xA3 332 | 333 | #define USB_VENDOR_STR_LEN 24 334 | #define USB_VENDOR_MSG_STR 't', 0, 'r', 0, 'u', 0, 'e', 0, 'C', 0, 'o', 0, 'n', 0, 't', 0,'r', 0, 'o', 0, 'l', 0 335 | 336 | #define USB_PRODUCT_STR_LEN 32 337 | #define USB_PRODUCT_MSG_STR 'G', 0, 'R', 0, 'i', 0, 'P', 0, ' ', 0, 'B', 0, 'o', 0, 'o', 0, 't', 0, 'l', 0, \ 338 | 'o', 0, 'a', 0, 'd', 0, 'e', 0, 'r', 0 339 | 340 | #define USB_SERIAL_STR_LEN 16 341 | #define USB_SERIAL_MSG_STR '1', 0, '2', 0, '3', 0, '4', 0, '3', 0, '2', 0, '1', 0 342 | 343 | #define CUSTOM_ALT_STRINGS 344 | #define ALT0_STR_LEN 0x64 345 | #define ALT0_MSG_STR 'G',0,'r',0,'I',0,'P',0,' ',0,'B',0,'o',0,'o',0,'t',0,'l',0,'o',0,'a',0,'d',0,'e',0,'r',0, \ 346 | ' ',0,'v',0,VER_MAJOR,0,'.',0,VER_MINOR,0,' ',0,' ',0,'U',0,'p',0,'l',0,'o',0,'a',0,'d',0, \ 347 | ' ',0,'t',0,'o',0,' ',0,'R',0,'A',0,'M',0,' ',0,'n',0,'o',0,'t',0,' ',0,'s',0,'u',0,'p',0, \ 348 | 'p',0,'o',0,'r',0,'t',0,'e',0,'d',0 349 | 350 | #define ALT1_STR_LEN 0x60 351 | #define ALT1_MSG_STR 'G',0,'r',0,'I',0,'P',0,' ',0,'B',0,'o',0,'o',0,'t',0,'l',0,'o',0,'a',0,'d',0,'e',0,'r',0, \ 352 | ' ',0,'v',0,VER_MAJOR,0,'.',0,VER_MINOR,0,' ',0,' ',0,'U',0,'p',0,'l',0,'o',0,'a',0,'d',0, \ 353 | ' ',0,'t',0,'o',0,' ',0,'F',0,'l',0,'a',0,'s',0,'h',0,' ',0,'0',0,'x',0,'8',0,'0',0,'0',0, \ 354 | '5',0,'0',0,'0',0,'0',0 355 | 356 | #define ALT2_STR_LEN 0x60 357 | #define ALT2_MSG_STR 'G',0,'r',0,'I',0,'P',0,' ',0,'B',0,'o',0,'o',0,'t',0,'l',0,'o',0,'a',0,'d',0,'e',0,'r',0, \ 358 | ' ',0,'v',0,VER_MAJOR,0,'.',0,VER_MINOR,0,' ',0,' ',0,'U',0,'p',0,'l',0,'o',0,'a',0,'d',0, \ 359 | ' ',0,'t',0,'o',0,' ',0,'F',0,'l',0,'a',0,'s',0,'h',0,' ',0,'0',0,'x',0,'8',0,'0',0,'0',0, \ 360 | '2',0,'0',0,'0',0,'0',0 361 | 362 | #else 363 | 364 | #error "No config for this target or no target specified" 365 | 366 | #endif 367 | 368 | 369 | /* some somewhat sensible defaults */ 370 | #ifndef BOOTLOADER_WAIT 371 | #ifdef BUTTON_BANK 372 | #define BOOTLOADER_WAIT WAIT_SHORT 373 | #else 374 | #define BOOTLOADER_WAIT WAIT_LONG 375 | #endif 376 | #endif 377 | 378 | #ifndef CUSTOM_VID_PID 379 | #define VEND_ID0 0x1E 380 | #define VEND_ID1 0xAF 381 | #define PROD_ID0 0x00 382 | #define PROD_ID1 0x03 383 | #endif 384 | 385 | #ifndef USB_VENDOR_STR_LEN 386 | #define USB_VENDOR_STR_LEN 0x12 387 | #define USB_VENDOR_MSG_STR 'L', 0, 'e', 0, 'a', 0, 'f', 0, 'L', 0, 'a', 0, 'b', 0, 's', 0 388 | #endif 389 | 390 | #ifndef USB_PRODUCT_STR_LEN 391 | #define USB_PRODUCT_STR_LEN 0x14 392 | #define USB_PRODUCT_MSG_STR 'M', 0, 'a', 0, 'p', 0, 'l', 0, 'e', 0, ' ', 0, '0', 0, '0', 0, '3', 0 393 | #endif 394 | 395 | #ifndef USB_SERIAL_STR_LEN 396 | #define USB_SERIAL_STR_LEN 0x10 397 | #define USB_SERIAL_MSG_STR 'L', 0, 'L', 0, 'M', 0, ' ', 0, '0', 0, '0', 0, '3', 0 398 | #endif 399 | 400 | #ifndef CUSTOM_ALT_STRINGS 401 | #define ALT0_STR_LEN 0x66 402 | #define ALT0_MSG_STR 'S',0,'T',0,'M',0,'3',0,'2',0,' ',0,'B',0,'o',0,'o',0,'t',0,'l',0,'o',0,'a',0,'d',0,'e',0, \ 403 | 'r',0,' ',0,'v',0,VER_MAJOR,0,'.',0,VER_MINOR,0,' ',0,' ',0,'U',0,'p',0,'l',0,'o',0,'a',0, \ 404 | 'd',0,' ',0,'t',0,'o',0,' ',0,'R',0,'A',0,'M',0,' ',0,'n',0,'o',0,'t',0,' ',0,'s',0,'u',0, \ 405 | 'p',0,'p',0,'o',0,'r',0,'t',0,'e',0,'d',0 406 | 407 | #define ALT1_STR_LEN 0x62 408 | #define ALT1_MSG_STR 'S',0,'T',0,'M',0,'3',0,'2',0,' ',0,'B',0,'o',0,'o',0,'t',0,'l',0,'o',0,'a',0,'d',0,'e',0, \ 409 | 'r',0,' ',0,'v',0,VER_MAJOR,0,'.',0,VER_MINOR,0,' ',0,' ',0,'U',0,'p',0,'l',0,'o',0,'a',0, \ 410 | 'd',0,' ',0,'t',0,'o',0,' ',0,'F',0,'l',0,'a',0,'s',0,'h',0,' ',0,'0',0,'x',0,'8',0,'0',0, \ 411 | '0',0,'5',0,'0',0,'0',0,'0',0 412 | 413 | #define ALT2_STR_LEN 0x62 414 | #define ALT2_MSG_STR 'S',0,'T',0,'M',0,'3',0,'2',0,' ',0,'B',0,'o',0,'o',0,'t',0,'l',0,'o',0,'a',0,'d',0,'e',0, \ 415 | 'r',0,' ',0,'v',0,VER_MAJOR,0,'.',0,VER_MINOR,0,' ',0,' ',0,'U',0,'p',0,'l',0,'o',0,'a',0, \ 416 | 'd',0,' ',0,'t',0,'o',0,' ',0,'F',0,'l',0,'a',0,'s',0,'h',0,' ',0,'0',0,'x',0,'8',0,'0',0, \ 417 | '0',0,'2',0,'0',0,'0',0,'0',0 418 | #endif 419 | 420 | #endif 421 | -------------------------------------------------------------------------------- /STM32F1/dfu.c: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | 25 | /** 26 | * @file dfu.c 27 | * 28 | * @brief The principle dfu state machine as well as the data 29 | * transfer callbacks accessed by the usb library 30 | * 31 | * 32 | */ 33 | 34 | #include "hardware.h" 35 | #include "dfu.h" 36 | #include "usb.h" 37 | 38 | 39 | /* DFU globals */ 40 | static volatile u32 userAppAddr = USER_CODE_RAM; /* default RAM user code location */ 41 | static volatile u32 userAppEnd = RAM_END; 42 | static volatile DFUStatus dfuAppStatus; /* includes state */ 43 | volatile dfuUploadTypes_t userUploadType = DFU_UPLOAD_NONE; 44 | volatile bool dfuBusy = FALSE; 45 | 46 | 47 | //static volatile u8 recvBuffer[wTransferSize] __attribute__((aligned(4))); 48 | static volatile u8 recvBuffer[LARGEST_FLASH_PAGE_SIZE] __attribute__((aligned(4))); 49 | 50 | static volatile u32 userFirmwareLen = 0; 51 | static volatile u16 thisBlockLen = 0; 52 | static volatile u16 uploadBlockLen = 0; 53 | 54 | 55 | volatile PLOT code_copy_lock; 56 | 57 | /* todo: force dfu globals to be singleton to avoid re-inits? */ 58 | void dfuInit(void) { 59 | dfuAppStatus.bStatus = OK; 60 | dfuAppStatus.bwPollTimeout0 = 0x00; 61 | dfuAppStatus.bwPollTimeout1 = 0x00; 62 | dfuAppStatus.bwPollTimeout2 = 0x00; 63 | dfuAppStatus.bState = dfuIDLE; 64 | dfuAppStatus.iString = 0x00; /* all strings must be 0x00 until we make them! */ 65 | userFirmwareLen = 0; 66 | thisBlockLen = 0;; 67 | userAppAddr = USER_CODE_RAM; /* default RAM user code location */ 68 | userAppEnd = RAM_END; 69 | userUploadType=DFU_UPLOAD_NONE; 70 | code_copy_lock = WAIT; 71 | dfuBusy = FALSE; 72 | } 73 | 74 | 75 | bool dfuUpdateByRequest(void) { 76 | /* were using the global pInformation struct from usb_lib here, 77 | see comment in maple_dfu.h around DFUEvent struct */ 78 | dfuBusy = TRUE; 79 | 80 | u8 startState = dfuAppStatus.bState; 81 | dfuAppStatus.bStatus = OK; 82 | 83 | /* often leaner to nest if's then embed a switch/case */ 84 | /* but who the fuck cares? use a better compiler. we have space */ 85 | if (startState == dfuIDLE) { 86 | /* device running inside DFU mode */ 87 | dfuBusy = TRUE; // signals the main loop to defer to the dfu write-loop 88 | 89 | if (pInformation->USBbRequest == DFU_DNLOAD) { 90 | if (pInformation->USBwLengths.w > 0) { 91 | userFirmwareLen = 0; 92 | dfuAppStatus.bState = dfuDNLOAD_SYNC; 93 | switch(pInformation->Current_AlternateSetting) { 94 | /* 95 | Roger Clark. removed upload to RAM option 96 | case 0: 97 | userAppAddr = USER_CODE_RAM; 98 | userUploadType = DFU_UPLOAD_RAM; 99 | break; 100 | */ 101 | 102 | case 1: 103 | userAppAddr = USER_CODE_FLASH0X8005000; 104 | userUploadType = DFU_UPLOAD_FLASH_0X8005000; 105 | 106 | /* make sure the flash is setup properly, unlock it */ 107 | setupFLASH(); 108 | flashUnlock(); 109 | 110 | /* Clear lower memory so that we can check on cold boot, whether 111 | the last upload was to 0x8002000 or 0x8005000 */ 112 | flashErasePage((u32)USER_CODE_FLASH0X8002000); 113 | 114 | break; 115 | 116 | case 2: 117 | userUploadType = DFU_UPLOAD_FLASH_0X8002000; 118 | userAppAddr = USER_CODE_FLASH0X8002000; 119 | 120 | /* make sure the flash is setup properly, unlock it */ 121 | setupFLASH(); 122 | flashUnlock(); 123 | 124 | break; 125 | 126 | default: 127 | // Roger Clark. Report error 128 | dfuAppStatus.bState = dfuERROR; 129 | dfuAppStatus.bStatus = errWRITE; 130 | 131 | break; 132 | } 133 | } else { 134 | dfuAppStatus.bState = dfuERROR; 135 | dfuAppStatus.bStatus = errNOTDONE; 136 | } 137 | } else if (pInformation->USBbRequest == DFU_UPLOAD) { 138 | dfuAppStatus.bState = dfuUPLOAD_IDLE; 139 | 140 | /* record length of first block for calculating target 141 | address from wValue in consecutive blocks */ 142 | uploadBlockLen = pInformation->USBwLengths.w; 143 | thisBlockLen = uploadBlockLen; /* for this first block as well */ 144 | 145 | /* calculate where the data should be copied from */ 146 | userFirmwareLen = uploadBlockLen * pInformation->USBwValue; 147 | 148 | switch(pInformation->Current_AlternateSetting) { 149 | /* 150 | case 0: 151 | userAppAddr = USER_CODE_RAM; 152 | userAppEnd = RAM_END; 153 | */ 154 | 155 | case 1: 156 | userAppAddr = USER_CODE_FLASH0X8005000; 157 | userAppEnd = getFlashEnd(); 158 | break; 159 | 160 | case 2: 161 | userAppAddr = USER_CODE_FLASH0X8002000; 162 | userAppEnd = getFlashEnd(); 163 | break; 164 | 165 | default: 166 | // Roger Clark. 167 | // Changed this to report error that its unable to write to this memory 168 | // However the code should never get here as only AlternateSetting 1 and 2 are allowed (see above) 169 | dfuAppStatus.bState = dfuERROR; 170 | dfuAppStatus.bStatus = errWRITE; 171 | break; 172 | } 173 | } else if (pInformation->USBbRequest == DFU_ABORT) { 174 | dfuAppStatus.bState = dfuIDLE; 175 | dfuAppStatus.bStatus = OK; /* are we really ok? we were just aborted */ 176 | } else if (pInformation->USBbRequest == DFU_GETSTATUS) { 177 | dfuAppStatus.bState = dfuIDLE; 178 | } else if (pInformation->USBbRequest == DFU_GETSTATE) { 179 | dfuAppStatus.bState = dfuIDLE; 180 | } else { 181 | dfuAppStatus.bState = dfuERROR; 182 | dfuAppStatus.bStatus = errSTALLEDPKT; 183 | } 184 | 185 | } else if (startState == dfuDNLOAD_SYNC) { 186 | /* device received block, waiting for DFU_GETSTATUS request */ 187 | if (pInformation->USBbRequest == DFU_GETSTATUS) { 188 | /* todo, add routine to wait for last block write to finish */ 189 | 190 | /* Roger Clark. Commented out code associated with RAM upload 191 | 192 | if (userUploadType == DFU_UPLOAD_RAM) 193 | { 194 | if (code_copy_lock == WAIT) { 195 | code_copy_lock = BEGINNING; 196 | dfuAppStatus.bwPollTimeout0 = 0x20; // 32 ms 197 | dfuAppStatus.bwPollTimeout1 = 0x00; 198 | dfuAppStatus.bState = dfuDNBUSY; 199 | 200 | } else if (code_copy_lock == BEGINNING) { 201 | dfuAppStatus.bState = dfuDNLOAD_SYNC; 202 | 203 | } else if (code_copy_lock == MIDDLE) { 204 | dfuAppStatus.bState = dfuDNLOAD_SYNC; 205 | 206 | } else if (code_copy_lock == END) { 207 | dfuAppStatus.bwPollTimeout0 = 0x00; 208 | code_copy_lock = WAIT; 209 | dfuAppStatus.bState = dfuDNLOAD_IDLE; 210 | } 211 | 212 | } 213 | else 214 | */ 215 | { 216 | dfuAppStatus.bState = dfuDNLOAD_IDLE; 217 | dfuCopyBufferToExec(); 218 | } 219 | 220 | } else if (pInformation->USBbRequest == DFU_GETSTATE) { 221 | dfuAppStatus.bState = dfuDNLOAD_SYNC; 222 | } else { 223 | dfuAppStatus.bState = dfuERROR; 224 | dfuAppStatus.bStatus = errSTALLEDPKT; 225 | } 226 | } else if (startState == dfuDNBUSY) { 227 | /* if were actually done writing, goto sync, else stay busy */ 228 | if (code_copy_lock == END) { 229 | dfuAppStatus.bwPollTimeout0 = 0x00; 230 | code_copy_lock = WAIT; 231 | dfuAppStatus.bState = dfuDNLOAD_IDLE; 232 | } else { 233 | dfuAppStatus.bState = dfuDNBUSY; 234 | } 235 | } else if (startState == dfuDNLOAD_IDLE) { 236 | /* device is expecting dfu_dnload requests */ 237 | if (pInformation->USBbRequest == DFU_DNLOAD) { 238 | if (pInformation->USBwLengths.w > 0) { 239 | dfuAppStatus.bState = dfuDNLOAD_SYNC; 240 | } else { 241 | /* todo, support "disagreement" if device expects more data than this */ 242 | dfuAppStatus.bState = dfuMANIFEST_SYNC; 243 | 244 | /* relock the flash */ 245 | flashLock(); 246 | } 247 | } else if (pInformation->USBbRequest == DFU_ABORT) { 248 | dfuAppStatus.bState = dfuIDLE; 249 | } else if (pInformation->USBbRequest == DFU_GETSTATUS) { 250 | dfuAppStatus.bState = dfuIDLE; 251 | } else if (pInformation->USBbRequest == DFU_GETSTATE) { 252 | dfuAppStatus.bState = dfuIDLE; 253 | } else { 254 | dfuAppStatus.bState = dfuERROR; 255 | dfuAppStatus.bStatus = errSTALLEDPKT; 256 | } 257 | 258 | } else if (startState == dfuMANIFEST_SYNC) { 259 | /* device has received last block, waiting DFU_GETSTATUS request */ 260 | if (pInformation->USBbRequest == DFU_GETSTATUS) { 261 | dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET; 262 | dfuAppStatus.bStatus = OK; 263 | } else if (pInformation->USBbRequest == DFU_GETSTATE) { 264 | dfuAppStatus.bState = dfuMANIFEST_SYNC; 265 | } else { 266 | dfuAppStatus.bState = dfuERROR; 267 | dfuAppStatus.bStatus = errSTALLEDPKT; 268 | } 269 | } else if (startState == dfuMANIFEST) { 270 | /* device is in manifestation phase */ 271 | 272 | /* should never receive request while in manifest! */ 273 | dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET; 274 | dfuAppStatus.bStatus = OK; 275 | } else if (startState == dfuMANIFEST_WAIT_RESET) { 276 | /* device has programmed new firmware but needs external 277 | usb reset or power on reset to run the new code */ 278 | 279 | /* consider timing out and self-resetting */ 280 | dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET; 281 | } else if (startState == dfuUPLOAD_IDLE) { 282 | /* device expecting further dfu_upload requests */ 283 | if (pInformation->USBbRequest == DFU_UPLOAD) { 284 | if (pInformation->USBwLengths.w > 0) { 285 | /* check that this is not the last possible block */ 286 | userFirmwareLen = uploadBlockLen * pInformation->USBwValue; 287 | if (userAppAddr + userFirmwareLen + uploadBlockLen <= userAppEnd) { 288 | thisBlockLen = uploadBlockLen; 289 | dfuAppStatus.bState = dfuUPLOAD_IDLE; 290 | } else { 291 | /* if above comparison was just equal, thisBlockLen becomes zero 292 | next time when USBWValue has been increased by one */ 293 | thisBlockLen = userAppEnd - userAppAddr - userFirmwareLen; 294 | 295 | /* check for overflow due to USBwValue out of range */ 296 | if (thisBlockLen >= pInformation->USBwLengths.w) { 297 | thisBlockLen = 0; 298 | } 299 | 300 | dfuAppStatus.bState = dfuIDLE; 301 | } 302 | } else { 303 | dfuAppStatus.bState = dfuERROR; 304 | dfuAppStatus.bStatus = errNOTDONE; 305 | } 306 | } else if (pInformation->USBbRequest == DFU_ABORT) { 307 | dfuAppStatus.bState = dfuIDLE; 308 | } else if (pInformation->USBbRequest == DFU_GETSTATUS) { 309 | dfuAppStatus.bState = dfuUPLOAD_IDLE; 310 | } else if (pInformation->USBbRequest == DFU_GETSTATE) { 311 | dfuAppStatus.bState = dfuUPLOAD_IDLE; 312 | } else { 313 | dfuAppStatus.bState = dfuERROR; 314 | dfuAppStatus.bStatus = errSTALLEDPKT; 315 | } 316 | } else if (startState == dfuERROR) { 317 | /* status is in error, awaiting DFU_CLRSTATUS request */ 318 | if (pInformation->USBbRequest == DFU_GETSTATUS) { 319 | /* todo, add routine to wait for last block write to finish */ 320 | dfuAppStatus.bState = dfuERROR; 321 | } else if (pInformation->USBbRequest == DFU_GETSTATE) { 322 | dfuAppStatus.bState = dfuERROR; 323 | } else if (pInformation->USBbRequest == DFU_CLRSTATUS) { 324 | /* todo handle any cleanup we need here */ 325 | dfuAppStatus.bState = dfuIDLE; 326 | dfuAppStatus.bStatus = OK; 327 | } else { 328 | dfuAppStatus.bState = dfuERROR; 329 | dfuAppStatus.bStatus = errSTALLEDPKT; 330 | } 331 | } else { 332 | /* some kind of error... */ 333 | dfuAppStatus.bState = dfuERROR; 334 | dfuAppStatus.bStatus = errSTALLEDPKT; 335 | } 336 | 337 | return (dfuAppStatus.bStatus == OK) ? TRUE : FALSE; 338 | } 339 | 340 | void dfuUpdateByReset(void) { 341 | u8 startState = dfuAppStatus.bState; 342 | userFirmwareLen = 0; 343 | 344 | if (startState == appDETACH) { 345 | dfuAppStatus.bState = dfuIDLE; 346 | dfuAppStatus.bStatus = OK; 347 | 348 | nvicDisableInterrupts(); 349 | usbEnbISR(); 350 | } else if (startState == appIDLE || startState == dfuIDLE) { 351 | /* do nothing...might be normal usb bus activity */ 352 | } else { 353 | /* we reset from the dfu, reset everything and startover, 354 | which is the correct operation if this is an erroneous 355 | event or properly following a MANIFEST */ 356 | dfuAppStatus.bState = dfuIDLE; 357 | dfuAppStatus.bStatus = OK; 358 | 359 | systemHardReset(); 360 | } 361 | } 362 | 363 | void dfuUpdateByTimeout(void) { 364 | } 365 | 366 | u8 *dfuCopyState(u16 length) { 367 | if (length == 0) { 368 | pInformation->Ctrl_Info.Usb_wLength = 1; 369 | return NULL; 370 | } else { 371 | return (u8 *)(&(dfuAppStatus.bState)); 372 | } 373 | } 374 | 375 | u8 *dfuCopyStatus(u16 length) { 376 | if (length == 0) { 377 | pInformation->Ctrl_Info.Usb_wLength = 6; 378 | return NULL; 379 | } else { 380 | return (u8*)(&dfuAppStatus); 381 | } 382 | } 383 | 384 | 385 | u8 *dfuCopyDNLOAD(u16 length) { 386 | if (length == 0) { 387 | pInformation->Ctrl_Info.Usb_wLength = pInformation->USBwLengths.w - pInformation->Ctrl_Info.Usb_wOffset; 388 | thisBlockLen = pInformation->USBwLengths.w; 389 | return NULL; 390 | } else { 391 | return ((u8 *)recvBuffer + pInformation->Ctrl_Info.Usb_wOffset); 392 | } 393 | } 394 | 395 | u8 *dfuCopyUPLOAD(u16 length) { 396 | if (length == 0) { 397 | pInformation->Ctrl_Info.Usb_wLength = thisBlockLen - pInformation->Ctrl_Info.Usb_wOffset; 398 | return NULL; 399 | } else { 400 | return((u8*) userAppAddr + userFirmwareLen + pInformation->Ctrl_Info.Usb_wOffset); 401 | } 402 | } 403 | 404 | void dfuCopyBufferToExec() { 405 | int i; 406 | u32 *userSpace; 407 | 408 | /* Roger Clark. 409 | Commented out code associated with upload to RAM 410 | 411 | if (userUploadType == DFU_UPLOAD_RAM) 412 | { 413 | userSpace = (u32 *)(USER_CODE_RAM + userFirmwareLen); 414 | // we dont need to handle when thisBlock len is not divisible by 4, 415 | // since the linker will align everything to 4B anyway 416 | for (i = 0; i < thisBlockLen; i = i + 4) { 417 | *userSpace++ = *(u32 *)(recvBuffer + i); 418 | } 419 | } 420 | else 421 | */ 422 | { 423 | if (userUploadType == DFU_UPLOAD_FLASH_0X8005000) { 424 | userSpace = (u32 *)(USER_CODE_FLASH0X8005000 + userFirmwareLen); 425 | } 426 | else { 427 | userSpace = (u32 *)(USER_CODE_FLASH0X8002000 + userFirmwareLen); 428 | } 429 | 430 | flashErasePage((u32)(userSpace)); 431 | 432 | for (i = 0; i < thisBlockLen; i = i + 4) { 433 | flashWriteWord((u32)(userSpace++), *(u32 *)(recvBuffer +i)); 434 | } 435 | 436 | } 437 | 438 | userFirmwareLen += thisBlockLen; 439 | thisBlockLen = 0; 440 | } 441 | 442 | u8 dfuGetState(void) 443 | { 444 | return dfuAppStatus.bState; 445 | } 446 | 447 | void dfuSetState(u8 newState) 448 | { 449 | dfuAppStatus.bState = newState; 450 | } 451 | 452 | bool dfuUploadStarted() 453 | { 454 | return dfuBusy; 455 | } 456 | 457 | bool dfuUploadDone() 458 | { 459 | return (dfuAppStatus.bState == dfuMANIFEST_WAIT_RESET 460 | && dfuAppStatus.bStatus == OK) ? TRUE : FALSE; 461 | } 462 | 463 | void dfuFinishUpload() { 464 | while (1) 465 | { 466 | __asm__ __volatile__ (""); 467 | 468 | /* Roger Clark. 469 | Commented out code associated with upload to RAM 470 | 471 | if (userUploadType==DFU_UPLOAD_RAM) 472 | { 473 | if (code_copy_lock == BEGINNING) { 474 | code_copy_lock = MIDDLE; 475 | strobePin(LED_BANK, LED, 2, 0x1000); 476 | dfuCopyBufferToExec(); 477 | strobePin(LED_BANK, LED, 2, 0x500); 478 | code_copy_lock = END; 479 | } 480 | } 481 | 482 | */ 483 | 484 | /* otherwise do nothing, dfu state machine resets itself */ 485 | } 486 | } 487 | 488 | -------------------------------------------------------------------------------- /STM32F1/dfu.h: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | 25 | #ifndef __DFU_H 26 | #define __DFU_H 27 | 28 | #include "common.h" 29 | /* 30 | #define DFU_UPLOAD_NONE 0 31 | #define DFU_UPLOAD_RAM 1 32 | #define DFU_UPLOAD_FLASH_0X8005000 2 33 | #define DFU_UPLOAD_FLASH_0X8002000 3 34 | */ 35 | typedef enum {DFU_UPLOAD_NONE, DFU_UPLOAD_RAM, DFU_UPLOAD_FLASH_0X8005000,DFU_UPLOAD_FLASH_0X8002000} dfuUploadTypes_t; 36 | 37 | /* exposed types */ 38 | typedef u8 *(*ClassReqCB)(u16); 39 | 40 | /* exposed structs */ 41 | typedef struct _DFUStatus { 42 | u8 bStatus; 43 | u8 bwPollTimeout0; 44 | u8 bwPollTimeout1; 45 | u8 bwPollTimeout2; 46 | u8 bState; /* state of device at the time the host receives the message! */ 47 | u8 iString; 48 | } DFUStatus; 49 | 50 | typedef enum _PLOT { 51 | BEGINNING, 52 | MIDDLE, 53 | END, 54 | WAIT 55 | } PLOT; 56 | 57 | 58 | /*** DFU bRequest Values ******/ 59 | /* bmRequestType, wValue, wIndex, wLength, Data */ 60 | #define DFU_DETACH 0x00 /* 0x21, wTimeout, Interface, Zero, None */ 61 | #define DFU_DNLOAD 0x01 /* 0x21, wBlockNum, Interface, Length, Firmware */ 62 | #define DFU_UPLOAD 0x02 /* 0xA1, Zero, Interface, Length, Firmware */ 63 | #define DFU_GETSTATUS 0x03 /* 0xA1, Zero, Interface, 6, Status */ 64 | #define DFU_CLRSTATUS 0x04 /* 0x21, Zero, Interface, Zero, None */ 65 | #define DFU_GETSTATE 0x05 /* 0xA1, Zero, Interface, 1, State */ 66 | #define DFU_ABORT 0x06 /* 0x21, Zero, Interface, Zero, None */ 67 | 68 | /*** DFU Status Values ******/ 69 | #define OK 0x00 /* No error */ 70 | #define errTARGET 0x01 /* File is not appropriate for this device */ 71 | #define errFILE 0x02 /* File fails some vendor tests */ 72 | #define errWRITE 0x03 /* Device is unable to write memory */ 73 | #define errERASE 0x04 /* Memory erase failed */ 74 | #define errCHECK_ERASED 0x05 /* Memory erase check failed */ 75 | #define errPROG 0x06 /* Program memory function failed */ 76 | #define errVERIFY 0x07 /* Written program failed verification */ 77 | #define errADDRESS 0x08 /* address out of range */ 78 | #define errNOTDONE 0x09 /* received DNLOAD with wLength=0, but firmware seems incomplete */ 79 | #define errFIRMWARE 0x0A /* Runtime firmware corrupt, cannot return to non-dfu operations! */ 80 | #define errVENDOR 0x0B /* vendor specific error */ 81 | #define errUSBR 0x0C /* Unexpected usb reset! */ 82 | #define errPOR 0x0D /* Unexpected power on reset */ 83 | #define errUNKNOWN 0x0E /* Unknown error */ 84 | #define errSTALLEDPKT 0x0F /* device stalled unexpected request */ 85 | /***************************/ 86 | 87 | /*** DFU State Values **************/ 88 | #define appIDLE 0x00 89 | #define appDETACH 0x01 90 | #define dfuIDLE 0x02 91 | #define dfuDNLOAD_SYNC 0x03 92 | #define dfuDNBUSY 0x04 93 | #define dfuDNLOAD_IDLE 0x05 94 | #define dfuMANIFEST_SYNC 0x06 95 | #define dfuMANIFEST 0x07 96 | #define dfuMANIFEST_WAIT_RESET 0x08 97 | #define dfuUPLOAD_IDLE 0x09 98 | #define dfuERROR 0x0A 99 | /***********************************/ 100 | 101 | 102 | 103 | extern volatile bool dfuBusy; 104 | 105 | /* exposed functions */ 106 | void dfuInit(void); /* singleton dfu initializer */ 107 | 108 | /* should consume dfuEvent type, but for now we can use pInfo (see comment above) */ 109 | bool dfuUpdateByRequest(void); /* returns if new status is OK */ 110 | void dfuUpdateByReset(void); 111 | void dfuUpdateByTimeout(void); 112 | 113 | /* usb callbacks */ 114 | u8 *dfuCopyState(u16); 115 | u8 *dfuCopyStatus(u16); 116 | u8 *dfuCopyDNLOAD(u16); 117 | u8 *dfuCopyUPLOAD(u16); 118 | 119 | void dfuCopyBufferToExec(void); 120 | bool checkTestFile(void); 121 | 122 | u8 dfuGetState(void); 123 | void dfuSetState(u8); 124 | bool dfuUploadStarted(); 125 | bool dfuUploadDone(); 126 | void dfuFinishUpload(); 127 | 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /STM32F1/flash/debug.cfg: -------------------------------------------------------------------------------- 1 | # script for stm32 2 | 3 | interface ft2232 4 | ft2232_device_desc "Olimex OpenOCD JTAG" 5 | ft2232_layout olimex-jtag 6 | ft2232_vid_pid 0x15ba 0x0003 7 | 8 | if { [info exists CHIPNAME] } { 9 | set _CHIPNAME $CHIPNAME 10 | } else { 11 | set _CHIPNAME stm32 12 | } 13 | 14 | if { [info exists ENDIAN] } { 15 | set _ENDIAN $ENDIAN 16 | } else { 17 | set _ENDIAN little 18 | } 19 | 20 | # jtag speed 21 | jtag_khz 600 22 | 23 | #use combined on interfaces or targets that can't set TRST/SRST separately 24 | reset_config trst_and_srst 25 | 26 | #jtag scan chain 27 | if { [info exists CPUTAPID ] } { 28 | set _CPUTAPID $CPUTAPID 29 | } else { 30 | # See STM Document RM0008 31 | # Section 26.6.3 32 | set _CPUTAPID 0x3ba00477 33 | } 34 | jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID 35 | 36 | if { [info exists BSTAPID ] } { 37 | set _BSTAPID $BSTAPID 38 | } else { 39 | # See STM Document RM0008 40 | # Section 26.6.2 41 | # Medium Density RevA 42 | set _BSTAPID 0x06410041 43 | # Rev B and Rev Z 44 | set _BSTAPID 0x16410041 45 | # High Density Devices, Rev A 46 | #set _BSTAPID 0x06414041 47 | } 48 | jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID 49 | 50 | set _TARGETNAME [format "%s.cpu" $_CHIPNAME] 51 | target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME 52 | 53 | $_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 54 | #$_TARGETNAME configure -event halted halt_handle 55 | 56 | #flash bank stm32x 0 0 0 0 0 57 | 58 | 59 | #target create cortex_m3 -endian little 60 | #run_and_halt_time 0 30 61 | 62 | #working_area 0 0x20000000 0x4000 nobackup 63 | 64 | flash bank stm32x 0x08000000 0x00010000 0 0 0 65 | 66 | # For more information about the configuration files, take a look at: 67 | # openocd.texi 68 | 69 | #script flash.script 70 | 71 | proc halt_handle {} { 72 | resume 73 | } 74 | 75 | proc flash_test {} { 76 | puts "Entering DEBUG wait" 77 | sleep 100 78 | # reset run 79 | # sleep 500 80 | } 81 | 82 | init 83 | flash_test 84 | -------------------------------------------------------------------------------- /STM32F1/flash/flash.cfg: -------------------------------------------------------------------------------- 1 | # script for stm32 2 | 3 | interface ft2232 4 | ft2232_device_desc "Olimex OpenOCD JTAG" 5 | ft2232_layout olimex-jtag 6 | ft2232_vid_pid 0x15ba 0x0003 7 | 8 | if { [info exists CHIPNAME] } { 9 | set _CHIPNAME $CHIPNAME 10 | } else { 11 | set _CHIPNAME stm32 12 | } 13 | 14 | if { [info exists ENDIAN] } { 15 | set _ENDIAN $ENDIAN 16 | } else { 17 | set _ENDIAN little 18 | } 19 | 20 | # jtag speed 21 | jtag_khz 600 22 | 23 | #use combined on interfaces or targets that can't set TRST/SRST separately 24 | reset_config trst_and_srst 25 | 26 | #jtag scan chain 27 | if { [info exists CPUTAPID ] } { 28 | set _CPUTAPID $CPUTAPID 29 | } else { 30 | # See STM Document RM0008 31 | # Section 26.6.3 32 | set _CPUTAPID 0x3ba00477 33 | } 34 | jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID 35 | 36 | if { [info exists BSTAPID ] } { 37 | set _BSTAPID $BSTAPID 38 | } else { 39 | # See STM Document RM0008 40 | # Section 26.6.2 41 | # Medium Density RevA 42 | set _BSTAPID 0x06410041 43 | # Rev B and Rev Z 44 | set _BSTAPID 0x16410041 45 | # High Density Devices, Rev A 46 | #set _BSTAPID 0x06414041 47 | } 48 | jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID 49 | 50 | set _TARGETNAME [format "%s.cpu" $_CHIPNAME] 51 | target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME 52 | 53 | $_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 54 | #$_TARGETNAME configure -event halted halt_handle 55 | 56 | #flash bank stm32x 0 0 0 0 0 57 | 58 | 59 | #target create cortex_m3 -endian little 60 | #run_and_halt_time 0 30 61 | 62 | #working_area 0 0x20000000 0x4000 nobackup 63 | 64 | flash bank stm32x 0x08000000 0x00010000 0 0 0 65 | 66 | # For more information about the configuration files, take a look at: 67 | # openocd.texi 68 | 69 | #script flash.script 70 | 71 | proc halt_handle {} { 72 | resume 73 | } 74 | 75 | proc flash_test {} { 76 | puts "Trying to flash" 77 | sleep 100 78 | halt 79 | sleep 300 80 | stm32x mass_erase 0 81 | sleep 20 82 | flash write_bank 0 tmpflash.bin 0 83 | sleep 50 84 | # reset run 85 | # sleep 500 86 | reset run 87 | shutdown 88 | } 89 | 90 | init 91 | flash_test 92 | -------------------------------------------------------------------------------- /STM32F1/flash/openocd.cfg: -------------------------------------------------------------------------------- 1 | # script for stm32 2 | 3 | interface ft2232 4 | ft2232_device_desc "Olimex OpenOCD JTAG" 5 | ft2232_layout olimex-jtag 6 | ft2232_vid_pid 0x15ba 0x0003 7 | 8 | if { [info exists CHIPNAME] } { 9 | set _CHIPNAME $CHIPNAME 10 | } else { 11 | set _CHIPNAME stm32 12 | } 13 | 14 | if { [info exists ENDIAN] } { 15 | set _ENDIAN $ENDIAN 16 | } else { 17 | set _ENDIAN little 18 | } 19 | 20 | # jtag speed 21 | jtag_khz 500 22 | 23 | jtag_nsrst_delay 200 24 | jtag_ntrst_delay 200 25 | 26 | #use combined on interfaces or targets that can't set TRST/SRST separately 27 | reset_config trst_and_srst 28 | 29 | #jtag scan chain 30 | if { [info exists CPUTAPID ] } { 31 | set _CPUTAPID $CPUTAPID 32 | } else { 33 | # See STM Document RM0008 34 | # Section 26.6.3 35 | set _CPUTAPID 0x3ba00477 36 | } 37 | 38 | jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID 39 | 40 | if { [info exists BSTAPID ] } { 41 | set _BSTAPID $BSTAPID 42 | } else { 43 | # See STM Document RM0008 44 | # Section 26.6.2 45 | # Medium Density RevA 46 | set _BSTAPID 0x06410041 47 | # Rev B and Rev Z 48 | set _BSTAPID 0x16410041 49 | # High Density Devices, Rev A 50 | #set _BSTAPID 0x06414041 51 | } 52 | 53 | jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID 54 | 55 | set _TARGETNAME [format "%s.cpu" $_CHIPNAME] 56 | target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME 57 | 58 | $_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0 59 | 60 | flash bank stm32x 0x08000000 0x00010000 0 0 0 61 | 62 | init 63 | 64 | halt 65 | sleep 1000 66 | stm32x unlock 0 67 | flash erase_sector 0 0 0 68 | sleep 1000 69 | flash write_bank 0 tmpflash.bin 0 70 | sleep 3000 71 | reset 72 | sleep 3000 73 | shutdown 74 | -------------------------------------------------------------------------------- /STM32F1/flash/stm32.cfg: -------------------------------------------------------------------------------- 1 | # script for stm32 2 | 3 | interface ft2232 4 | ft2232_device_desc "Olimex OpenOCD JTAG" 5 | ft2232_layout olimex-jtag 6 | ft2232_vid_pid 0x15ba 0x0003 7 | 8 | if { [info exists CHIPNAME] } { 9 | set _CHIPNAME $CHIPNAME 10 | } else { 11 | set _CHIPNAME stm32 12 | } 13 | 14 | if { [info exists ENDIAN] } { 15 | set _ENDIAN $ENDIAN 16 | } else { 17 | set _ENDIAN little 18 | } 19 | 20 | # jtag speed 21 | jtag_khz 500 22 | 23 | jtag_nsrst_delay 100 24 | jtag_ntrst_delay 100 25 | 26 | #use combined on interfaces or targets that can't set TRST/SRST separately 27 | reset_config trst_and_srst 28 | 29 | #jtag scan chain 30 | if { [info exists CPUTAPID ] } { 31 | set _CPUTAPID $CPUTAPID 32 | } else { 33 | # See STM Document RM0008 34 | # Section 26.6.3 35 | set _CPUTAPID 0x3ba00477 36 | } 37 | jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID 38 | 39 | if { [info exists BSTAPID ] } { 40 | set _BSTAPID $BSTAPID 41 | } else { 42 | # See STM Document RM0008 43 | # Section 26.6.2 44 | # Medium Density RevA 45 | set _BSTAPID 0x06410041 46 | # Rev B and Rev Z 47 | set _BSTAPID 0x16410041 48 | # High Density Devices, Rev A 49 | #set _BSTAPID 0x06414041 50 | } 51 | jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID 52 | 53 | set _TARGETNAME [format "%s.cpu" $_CHIPNAME] 54 | target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME 55 | 56 | $_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0 57 | 58 | #flash bank stm32x 0 0 0 0 0 59 | 60 | 61 | target create cortex_m3 -endian little 62 | #run_and_halt_time 0 30 63 | 64 | #working_area 0 0x20000000 0x4000 nobackup 65 | 66 | #flash bank stm32x 0x08000000 0x00010000 0 0 0 67 | reset 68 | sleep 3000 69 | shutdown 70 | # For more information about the configuration files, take a look at: 71 | # openocd.texi 72 | 73 | -------------------------------------------------------------------------------- /STM32F1/flash/stm32loader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # -*- coding: utf-8 -*- 4 | # vim: sw=4:ts=4:si:et:enc=utf-8 5 | 6 | # Author: Ivan A-R 7 | # Project page: http://tuxotronic.org/wiki/projects/stm32loader 8 | # 9 | # This file is part of stm32loader. 10 | # 11 | # stm32loader is free software; you can redistribute it and/or modify it under 12 | # the terms of the GNU General Public License as published by the Free 13 | # Software Foundation; either version 3, or (at your option) any later 14 | # version. 15 | # 16 | # stm32loader is distributed in the hope that it will be useful, but WITHOUT ANY 17 | # WARRANTY; without even the implied warranty of MERCHANTABILITY or 18 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19 | # for more details. 20 | # 21 | # You should have received a copy of the GNU General Public License 22 | # along with stm32loader; see the file COPYING3. If not see 23 | # . 24 | 25 | import sys, getopt 26 | import serial 27 | import time 28 | 29 | try: 30 | from progressbar import * 31 | usepbar = 1 32 | except: 33 | usepbar = 0 34 | 35 | # Verbose level 36 | QUIET = 20 37 | 38 | def mdebug(level, message): 39 | if(QUIET >= level): 40 | print >> sys.stderr , message 41 | 42 | 43 | class CmdException(Exception): 44 | pass 45 | 46 | class CommandInterface: 47 | def open(self, aport='/dev/tty.usbserial-FTD3TMCH', abaudrate=115200) : 48 | self.sp = serial.Serial( 49 | port=aport, 50 | baudrate=abaudrate, # baudrate 51 | bytesize=8, # number of databits 52 | parity=serial.PARITY_EVEN, 53 | stopbits=1, 54 | xonxoff=0, # enable software flow control 55 | rtscts=0, # disable RTS/CTS flow control 56 | timeout=5 # set a timeout value, None for waiting forever 57 | ) 58 | 59 | 60 | def _wait_for_ask(self, info = ""): 61 | # wait for ask 62 | try: 63 | ask = ord(self.sp.read()) 64 | except: 65 | raise CmdException("Can't read port or timeout") 66 | else: 67 | if ask == 0x79: 68 | # ACK 69 | return 1 70 | else: 71 | if ask == 0x1F: 72 | # NACK 73 | raise CmdException("NACK "+info) 74 | else: 75 | # Unknown response 76 | raise CmdException("Unknown response. "+info+": "+hex(ask)) 77 | 78 | 79 | def reset(self): 80 | self.sp.setDTR(0) 81 | time.sleep(0.1) 82 | self.sp.setDTR(1) 83 | time.sleep(0.5) 84 | 85 | def initChip(self): 86 | # Set boot 87 | self.sp.setRTS(0) 88 | self.reset() 89 | 90 | self.sp.write("\x7F") # Syncro 91 | return self._wait_for_ask("Syncro") 92 | 93 | def releaseChip(self): 94 | self.sp.setRTS(1) 95 | self.reset() 96 | 97 | def cmdGeneric(self, cmd): 98 | self.sp.write(chr(cmd)) 99 | self.sp.write(chr(cmd ^ 0xFF)) # Control byte 100 | return self._wait_for_ask(hex(cmd)) 101 | 102 | def cmdGet(self): 103 | if self.cmdGeneric(0x00): 104 | mdebug(10, "*** Get command"); 105 | len = ord(self.sp.read()) 106 | version = ord(self.sp.read()) 107 | mdebug(10, " Bootloader version: "+hex(version)) 108 | dat = map(lambda c: hex(ord(c)), self.sp.read(len)) 109 | mdebug(10, " Available commands: "+str(dat)) 110 | self._wait_for_ask("0x00 end") 111 | return version 112 | else: 113 | raise CmdException("Get (0x00) failed") 114 | 115 | def cmdGetVersion(self): 116 | if self.cmdGeneric(0x01): 117 | mdebug(10, "*** GetVersion command") 118 | version = ord(self.sp.read()) 119 | self.sp.read(2) 120 | self._wait_for_ask("0x01 end") 121 | mdebug(10, " Bootloader version: "+hex(version)) 122 | return version 123 | else: 124 | raise CmdException("GetVersion (0x01) failed") 125 | 126 | def cmdGetID(self): 127 | if self.cmdGeneric(0x02): 128 | mdebug(10, "*** GetID command") 129 | len = ord(self.sp.read()) 130 | id = self.sp.read(len+1) 131 | self._wait_for_ask("0x02 end") 132 | return id 133 | else: 134 | raise CmdException("GetID (0x02) failed") 135 | 136 | 137 | def _encode_addr(self, addr): 138 | byte3 = (addr >> 0) & 0xFF 139 | byte2 = (addr >> 8) & 0xFF 140 | byte1 = (addr >> 16) & 0xFF 141 | byte0 = (addr >> 24) & 0xFF 142 | crc = byte0 ^ byte1 ^ byte2 ^ byte3 143 | return (chr(byte0) + chr(byte1) + chr(byte2) + chr(byte3) + chr(crc)) 144 | 145 | 146 | def cmdReadMemory(self, addr, lng): 147 | assert(lng <= 256) 148 | if self.cmdGeneric(0x11): 149 | mdebug(10, "*** ReadMemory command") 150 | self.sp.write(self._encode_addr(addr)) 151 | self._wait_for_ask("0x11 address failed") 152 | N = (lng - 1) & 0xFF 153 | crc = N ^ 0xFF 154 | self.sp.write(chr(N) + chr(crc)) 155 | self._wait_for_ask("0x11 length failed") 156 | return map(lambda c: ord(c), self.sp.read(lng)) 157 | else: 158 | raise CmdException("ReadMemory (0x11) failed") 159 | 160 | 161 | def cmdGo(self, addr): 162 | if self.cmdGeneric(0x21): 163 | mdebug(10, "*** Go command") 164 | self.sp.write(self._encode_addr(addr)) 165 | self._wait_for_ask("0x21 go failed") 166 | else: 167 | raise CmdException("Go (0x21) failed") 168 | 169 | 170 | def cmdWriteMemory(self, addr, data): 171 | assert(len(data) <= 256) 172 | if self.cmdGeneric(0x31): 173 | mdebug(10, "*** Write memory command") 174 | self.sp.write(self._encode_addr(addr)) 175 | self._wait_for_ask("0x31 address failed") 176 | #map(lambda c: hex(ord(c)), data) 177 | lng = (len(data)-1) & 0xFF 178 | mdebug(10, " %s bytes to write" % [lng+1]); 179 | self.sp.write(chr(lng)) # len really 180 | crc = 0xFF 181 | for c in data: 182 | crc = crc ^ c 183 | self.sp.write(chr(c)) 184 | self.sp.write(chr(crc)) 185 | self._wait_for_ask("0x31 programming failed") 186 | mdebug(10, " Write memory done") 187 | else: 188 | raise CmdException("Write memory (0x31) failed") 189 | 190 | 191 | def cmdEraseMemory(self, sectors = None): 192 | if self.cmdGeneric(0x43): 193 | mdebug(10, "*** Erase memory command") 194 | if sectors is None: 195 | # Global erase 196 | self.sp.write(chr(0xFF)) 197 | self.sp.write(chr(0x00)) 198 | else: 199 | # Sectors erase 200 | self.sp.write(chr((len(sectors)-1) & 0xFF)) 201 | crc = 0xFF 202 | for c in sectors: 203 | crc = crc ^ c 204 | self.sp.write(chr(c)) 205 | self.sp.write(chr(crc)) 206 | self._wait_for_ask("0x43 erasing failed") 207 | mdebug(10, " Erase memory done") 208 | else: 209 | raise CmdException("Erase memory (0x43) failed") 210 | 211 | def cmdWriteProtect(self, sectors): 212 | if self.cmdGeneric(0x63): 213 | mdebug(10, "*** Write protect command") 214 | self.sp.write(chr((len(sectors)-1) & 0xFF)) 215 | crc = 0xFF 216 | for c in sectors: 217 | crc = crc ^ c 218 | self.sp.write(chr(c)) 219 | self.sp.write(chr(crc)) 220 | self._wait_for_ask("0x63 write protect failed") 221 | mdebug(10, " Write protect done") 222 | else: 223 | raise CmdException("Write Protect memory (0x63) failed") 224 | 225 | def cmdWriteUnprotect(self): 226 | if self.cmdGeneric(0x73): 227 | mdebug(10, "*** Write Unprotect command") 228 | self._wait_for_ask("0x73 write unprotect failed") 229 | self._wait_for_ask("0x73 write unprotect 2 failed") 230 | mdebug(10, " Write Unprotect done") 231 | else: 232 | raise CmdException("Write Unprotect (0x73) failed") 233 | 234 | def cmdReadoutProtect(self): 235 | if self.cmdGeneric(0x82): 236 | mdebug(10, "*** Readout protect command") 237 | self._wait_for_ask("0x82 readout protect failed") 238 | self._wait_for_ask("0x82 readout protect 2 failed") 239 | mdebug(10, " Read protect done") 240 | else: 241 | raise CmdException("Readout protect (0x82) failed") 242 | 243 | def cmdReadoutUnprotect(self): 244 | if self.cmdGeneric(0x92): 245 | mdebug(10, "*** Readout Unprotect command") 246 | self._wait_for_ask("0x92 readout unprotect failed") 247 | self._wait_for_ask("0x92 readout unprotect 2 failed") 248 | mdebug(10, " Read Unprotect done") 249 | else: 250 | raise CmdException("Readout unprotect (0x92) failed") 251 | 252 | 253 | # Complex commands section 254 | 255 | def readMemory(self, addr, lng): 256 | data = [] 257 | if usepbar: 258 | widgets = ['Reading: ', Percentage(),', ', ETA(), ' ', Bar()] 259 | pbar = ProgressBar(widgets=widgets,maxval=lng, term_width=79).start() 260 | 261 | while lng > 256: 262 | if usepbar: 263 | pbar.update(pbar.maxval-lng) 264 | else: 265 | mdebug(5, "Read %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256}) 266 | data = data + self.cmdReadMemory(addr, 256) 267 | addr = addr + 256 268 | lng = lng - 256 269 | if usepbar: 270 | pbar.update(pbar.maxval-lng) 271 | pbar.finish() 272 | else: 273 | mdebug(5, "Read %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256}) 274 | data = data + self.cmdReadMemory(addr, lng) 275 | return data 276 | 277 | def writeMemory(self, addr, data): 278 | lng = len(data) 279 | if usepbar: 280 | widgets = ['Writing: ', Percentage(),' ', ETA(), ' ', Bar()] 281 | pbar = ProgressBar(widgets=widgets, maxval=lng, term_width=79).start() 282 | 283 | offs = 0 284 | while lng > 256: 285 | if usepbar: 286 | pbar.update(pbar.maxval-lng) 287 | else: 288 | mdebug(5, "Write %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256}) 289 | self.cmdWriteMemory(addr, data[offs:offs+256]) 290 | offs = offs + 256 291 | addr = addr + 256 292 | lng = lng - 256 293 | if usepbar: 294 | pbar.update(pbar.maxval-lng) 295 | pbar.finish() 296 | else: 297 | mdebug(5, "Write %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256}) 298 | self.cmdWriteMemory(addr, data[offs:offs+lng] + ([0xFF] * (256-lng)) ) 299 | 300 | 301 | 302 | 303 | def __init__(self) : 304 | pass 305 | 306 | 307 | def usage(): 308 | print """Usage: %s [-hqVewvr] [-l length] [-p port] [-b baud] [-a addr] [file.bin] 309 | -h This help 310 | -q Quiet 311 | -V Verbose 312 | -e Erase 313 | -w Write 314 | -v Verify 315 | -r Read 316 | -l length Length of read 317 | -p port Serial port (default: /dev/tty.usbserial-ftCYPMYJ) 318 | -b baud Baud speed (default: 115200) 319 | -a addr Target address 320 | 321 | ./stm32loader.py -e -w -v example/main.bin 322 | 323 | """ % sys.argv[0] 324 | 325 | 326 | if __name__ == "__main__": 327 | 328 | # Import Psyco if available 329 | try: 330 | import psyco 331 | psyco.full() 332 | print "Using Psyco..." 333 | except ImportError: 334 | pass 335 | 336 | conf = { 337 | 'port': '/dev/tty.usbserial-FTD3TMCH', 338 | 'baud': 115200, 339 | 'address': 0x08000000, 340 | 'erase': 0, 341 | 'write': 0, 342 | 'verify': 0, 343 | 'read': 0, 344 | 'len': 1000, 345 | 'fname':'', 346 | } 347 | 348 | # http://www.python.org/doc/2.5.2/lib/module-getopt.html 349 | 350 | try: 351 | opts, args = getopt.getopt(sys.argv[1:], "hqVewvrp:b:a:l:") 352 | except getopt.GetoptError, err: 353 | # print help information and exit: 354 | print str(err) # will print something like "option -a not recognized" 355 | usage() 356 | sys.exit(2) 357 | 358 | QUIET = 5 359 | 360 | for o, a in opts: 361 | if o == '-V': 362 | QUIET = 10 363 | elif o == '-q': 364 | QUIET = 0 365 | elif o == '-h': 366 | usage() 367 | sys.exit(0) 368 | elif o == '-e': 369 | conf['erase'] = 1 370 | elif o == '-w': 371 | conf['write'] = 1 372 | elif o == '-v': 373 | conf['verify'] = 1 374 | elif o == '-r': 375 | conf['read'] = 1 376 | elif o == '-p': 377 | conf['port'] = a 378 | elif o == '-b': 379 | conf['baud'] = eval(a) 380 | elif o == '-a': 381 | conf['address'] = eval(a) 382 | elif o == '-l': 383 | conf['len'] = eval(a) 384 | # elif o == '-f': 385 | # conf['fname'] = a 386 | else: 387 | assert False, "unhandled option" 388 | 389 | cmd = CommandInterface() 390 | cmd.open(conf['port'], conf['baud']) 391 | mdebug(10, "Open port %(port)s, baud %(baud)d" % {'port':conf['port'], 'baud':conf['baud']}) 392 | try: 393 | try: 394 | cmd.initChip() 395 | except: 396 | print "Can't init. Ensure that BOOT0 is enabled and reset device" 397 | 398 | bootversion = cmd.cmdGet() 399 | mdebug(0, "Bootloader version %X" % bootversion) 400 | mdebug(0, "Chip id `%s'" % str(map(lambda c: hex(ord(c)), cmd.cmdGetID()))) 401 | # cmd.cmdGetVersion() 402 | # cmd.cmdGetID() 403 | # cmd.cmdReadoutUnprotect() 404 | # cmd.cmdWriteUnprotect() 405 | # cmd.cmdWriteProtect([0, 1]) 406 | 407 | if (conf['write'] or conf['verify']): 408 | data = map(lambda c: ord(c), file(args[0]).read()) 409 | 410 | if conf['erase']: 411 | cmd.cmdEraseMemory() 412 | 413 | if conf['write']: 414 | cmd.writeMemory(conf['address'], data) 415 | 416 | if conf['verify']: 417 | verify = cmd.readMemory(conf['address'], len(data)) 418 | if(data == verify): 419 | print "Verification OK" 420 | else: 421 | print "Verification FAILED" 422 | print str(len(data)) + ' vs ' + str(len(verify)) 423 | for i in xrange(0, len(data)): 424 | if data[i] != verify[i]: 425 | print hex(i) + ': ' + hex(data[i]) + ' vs ' + hex(verify[i]) 426 | 427 | if not conf['write'] and conf['read']: 428 | rdata = cmd.readMemory(conf['address'], conf['len']) 429 | # file(conf['fname'], 'wb').write(rdata) 430 | file(args[0], 'wb').write(''.join(map(chr,rdata))) 431 | 432 | # cmd.cmdGo(addr + 0x04) 433 | finally: 434 | cmd.releaseChip() 435 | 436 | -------------------------------------------------------------------------------- /STM32F1/hardware.c: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | 25 | /** 26 | * @file hardware.c 27 | * 28 | * @brief init routines to setup clocks, interrupts, also destructor functions. 29 | * does not include USB stuff. EEPROM read/write functions. 30 | * 31 | */ 32 | #include "common.h" 33 | #include "hardware.h" 34 | 35 | 36 | static RCC_TypeDef *RCC = (RCC_TypeDef *)RCC_BASE; 37 | static FLASH_TypeDef *FLASH = (FLASH_TypeDef *)FLASH_BASE; 38 | static SCB_TypeDef *SCB = (SCB_TypeDef *)SCB_BASE; 39 | static NVIC_TypeDef *NVIC = (NVIC_TypeDef *)NVIC_BASE; 40 | 41 | 42 | /* system init shit */ 43 | void systemReset(void) 44 | { 45 | /* TODO: say what this does */ 46 | RCC->CR |= 0x00000001; 47 | RCC->CFGR &= 0xF8FF0000; 48 | RCC->CR &= 0xFEF6FFFF; 49 | RCC->CR &= 0xFFFBFFFF; 50 | RCC->CFGR &= 0xFF80FFFF; 51 | 52 | /* disable all RCC interrupts */ 53 | RCC->CIR = 0x00000000; 54 | } 55 | 56 | void setupCLK(void) 57 | { 58 | unsigned int StartUpCounter=0; 59 | 60 | // enable HSE 61 | RCC->CR |= 0x00010001; 62 | 63 | // and wait for it to come on 64 | while ((RCC->CR & 0x00020000) == 0); 65 | 66 | // enable flash prefetch buffer 67 | FLASH->ACR = 0x00000012; 68 | 69 | // Configure PLL 70 | #ifdef XTAL12M 71 | RCC->CFGR |= 0x00110400; /* pll=72Mhz(x6),APB1=36Mhz,AHB=72Mhz */ 72 | #else 73 | RCC->CFGR |= 0x001D0400; /* pll=72Mhz(x9),APB1=36Mhz,AHB=72Mhz */ 74 | #endif 75 | 76 | // enable the pll 77 | RCC->CR |= 0x01000000; 78 | 79 | #ifndef HSE_STARTUP_TIMEOUT 80 | #define HSE_STARTUP_TIMEOUT ((unsigned int)0x0500) /*!< Time out for HSE start up */ 81 | #endif /* HSE_STARTUP_TIMEOUT */ 82 | 83 | StartUpCounter = HSE_STARTUP_TIMEOUT; 84 | while (((RCC->CR & 0x03000000) == 0) && --StartUpCounter); 85 | 86 | if (!StartUpCounter) { 87 | // HSE has not started. Try restarting the processor 88 | systemHardReset(); 89 | } 90 | 91 | // Set SYSCLK as PLL 92 | RCC->CFGR |= 0x00000002; 93 | // and wait for it to come on 94 | while ((RCC->CFGR & 0x00000008) == 0); 95 | 96 | // Enable All GPIO channels (A to E), AFIO clock; disable any other clocks 97 | RCC->APB2ENR = 0x0000007d; 98 | // disable JTAG pins 99 | REG_SET(AFIO_MAPR, AFIO_MAPR_SWJ_CFG_NO_JTAG_SW); 100 | } 101 | 102 | 103 | void setupLEDAndButton (void) 104 | { 105 | // clear PA15, which is a now-disabled JTAG pin that is otherwise on because of JTAG hardware 106 | REG_SET(GPIO_CR(GPIOA, 15), 107 | (REG_GET(GPIO_CR(GPIOA, 15)) & crMask(15)) | CR_INPUT << CR_SHIFT(15)); 108 | gpio_write_bit(GPIOA, 15, 0); 109 | 110 | #if defined(BUTTON_BANK) && defined(BUTTON_PIN) && defined(BUTTON_ON_STATE) 111 | // configure activation button 112 | REG_SET(GPIO_CR(BUTTON_BANK, BUTTON_PIN), 113 | (GPIO_CR(BUTTON_BANK, BUTTON_PIN) & crMask(BUTTON_PIN)) | CR_INPUT_PU_PD << CR_SHIFT(BUTTON_PIN)); 114 | gpio_write_bit(BUTTON_BANK, BUTTON_PIN, 1-BUTTON_ON_STATE);// set pulldown resistor in case there is no button. 115 | #endif 116 | 117 | #if defined(LED_PIN_K) 118 | // LED is connected to two pins, so set cathode side low 119 | REG_SET(GPIO_CR(LED_BANK, LED_PIN_K), 120 | (REG_GET(GPIO_CR(LED_BANK, LED_PIN_K)) & crMask(LED_PIN_K)) | CR_OUTPUT_PP << CR_SHIFT(LED_PIN_K)); 121 | gpio_write_bit(LED_BANK, LED_PIN_K, 0); 122 | #endif 123 | 124 | // configure LED 125 | REG_SET(GPIO_CR(LED_BANK, LED_PIN), 126 | (REG_GET(GPIO_CR(LED_BANK, LED_PIN)) & crMask(LED_PIN)) | CR_OUTPUT_PP << CR_SHIFT(LED_PIN)); 127 | } 128 | 129 | void setupFLASH() 130 | { 131 | // configure the HSI oscillator 132 | if ((RCC->CR & 0x01) == 0) { 133 | RCC->CR |= 0x01; 134 | } 135 | 136 | // wait for it to come on 137 | while ((RCC->CR & 0x02) == 0); 138 | } 139 | 140 | bool checkUserCode(u32 usrAddr) 141 | { 142 | u32 sp = *(vu32 *) usrAddr; 143 | 144 | if ((sp & 0x2FFE0000) == 0x20000000) return (TRUE); 145 | 146 | return (FALSE); 147 | } 148 | 149 | void jumpToUser(u32 userAddr) 150 | { 151 | // bootloaded reset vector 152 | u32 jumpAddr = *(vu32 *)(userAddr + 0x04); /* reset ptr in vector table */ 153 | FuncPtr userMain = (FuncPtr)jumpAddr; 154 | 155 | // tear down all the dfu related setup 156 | // disable usb interrupts, clear them, turn off usb, set the disc pin 157 | // todo pick exactly what we want to do here, now its just a conservative 158 | flashLock(); 159 | usbDsbISR(); 160 | nvicDisableInterrupts(); 161 | 162 | #ifndef HAS_MAPLE_HARDWARE 163 | usbDsbBus(); 164 | #endif 165 | 166 | // resets clocks and periphs, not core regs 167 | systemReset(); 168 | 169 | // set user stack pointer 170 | __MSR_MSP(*(vu32 *)userAddr); 171 | 172 | // let's go 173 | userMain(); 174 | } 175 | 176 | void nvicInit(NVIC_InitTypeDef *NVIC_InitStruct) 177 | { 178 | u32 tmppriority = 0x00; 179 | u32 tmpreg = 0x00; 180 | u32 tmpmask = 0x00; 181 | u32 tmppre = 0; 182 | u32 tmpsub = 0x0F; 183 | 184 | /* Compute the Corresponding IRQ Priority --------------------------------*/ 185 | tmppriority = (0x700 - (SCB->AIRCR & (u32)0x700)) >> 0x08; 186 | tmppre = (0x4 - tmppriority); 187 | tmpsub = tmpsub >> tmppriority; 188 | 189 | tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre; 190 | tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub; 191 | 192 | tmppriority = tmppriority << 0x04; 193 | tmppriority = ((u32)tmppriority) << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); 194 | 195 | tmpreg = NVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)]; 196 | tmpmask = (u32)0xFF << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08); 197 | tmpreg &= ~tmpmask; 198 | tmppriority &= tmpmask; 199 | tmpreg |= tmppriority; 200 | 201 | NVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg; 202 | 203 | /* Enable the Selected IRQ Channels --------------------------------------*/ 204 | NVIC->ISER[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] = 205 | (u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F); 206 | } 207 | 208 | void nvicDisableInterrupts() 209 | { 210 | NVIC->ICER[0] = 0xFFFFFFFF; 211 | NVIC->ICER[1] = 0xFFFFFFFF; 212 | NVIC->ICPR[0] = 0xFFFFFFFF; 213 | NVIC->ICPR[1] = 0xFFFFFFFF; 214 | 215 | REG_SET(STK_CTRL, 0x04); /* disable the systick, which operates separately from nvic */ 216 | } 217 | 218 | void systemHardReset(void) 219 | { 220 | 221 | 222 | /* Reset */ 223 | SCB->AIRCR = (u32)AIRCR_RESET_REQ; 224 | 225 | /* should never get here */ 226 | while (1) { 227 | asm volatile("nop"); 228 | } 229 | } 230 | 231 | /* flash functions */ 232 | bool flashErasePage(u32 pageAddr) 233 | { 234 | FLASH->CR = FLASH_CR_PER; 235 | 236 | while (FLASH->SR & FLASH_SR_BSY); 237 | FLASH->AR = pageAddr; 238 | FLASH->CR = FLASH_CR_START | FLASH_CR_PER; 239 | while (FLASH->SR & FLASH_SR_BSY); 240 | 241 | /* todo: verify the page was erased */ 242 | FLASH->CR = 0; 243 | 244 | return TRUE; 245 | } 246 | 247 | bool flashErasePages(u32 pageAddr, u16 n) 248 | { 249 | while (n-- > 0) { 250 | if (!flashErasePage(pageAddr + wTransferSize * n)) { 251 | return FALSE; 252 | } 253 | } 254 | 255 | return TRUE; 256 | } 257 | 258 | bool flashWriteWord(u32 addr, u32 word) 259 | { 260 | vu16 *flashAddr = (vu16 *)addr; 261 | vu32 lhWord = (vu32)word & 0x0000FFFF; 262 | vu32 hhWord = ((vu32)word & 0xFFFF0000) >> 16; 263 | 264 | FLASH->CR = FLASH_CR_PG; 265 | 266 | /* apparently we need not write to FLASH_AR and can 267 | simply do a native write of a half word */ 268 | while (FLASH->SR & FLASH_SR_BSY); 269 | *(flashAddr + 0x01) = (vu16)hhWord; 270 | while (FLASH->SR & FLASH_SR_BSY); 271 | *(flashAddr) = (vu16)lhWord; 272 | while (FLASH->SR & FLASH_SR_BSY); 273 | 274 | FLASH->CR &= 0xFFFFFFFE; 275 | 276 | /* verify the write */ 277 | if (*(vu32 *)addr != word) { 278 | return FALSE; 279 | } 280 | 281 | return TRUE; 282 | } 283 | 284 | void flashLock() 285 | { 286 | /* take down the HSI oscillator? it may be in use elsewhere */ 287 | 288 | /* ensure all FPEC functions disabled and lock the FPEC */ 289 | FLASH->CR = 0x00000080; 290 | } 291 | 292 | void flashUnlock() 293 | { 294 | /* unlock the flash */ 295 | FLASH->KEYR = FLASH_KEY1; 296 | FLASH->KEYR = FLASH_KEY2; 297 | } 298 | 299 | #define FLASH_SIZE_REG 0x1FFFF7E0 300 | int getFlashEnd(void) 301 | { 302 | unsigned short *flashSize = (unsigned short *)FLASH_SIZE_REG;// Address register 303 | return ((int)(*flashSize & 0xffff) * 1024) + 0x08000000; 304 | } 305 | 306 | int getFlashPageSize(void) 307 | { 308 | 309 | unsigned short *flashSize = (unsigned short *)FLASH_SIZE_REG;// Address register 310 | if ((*flashSize & 0xffff) > 128) { 311 | return 0x800; 312 | } else { 313 | return 0x400; 314 | } 315 | } 316 | 317 | 318 | /* gpio functions */ 319 | /** 320 | * Used to create the control register masking pattern, when setting control register mode. 321 | */ 322 | unsigned int crMask(int pin) 323 | { 324 | unsigned int mask; 325 | if (pin>=8) { 326 | pin-=8; 327 | } 328 | 329 | mask = 0x0F << (pin << 2); 330 | return ~mask; 331 | } 332 | 333 | void gpio_write_bit(u32 bank, u8 pin, u8 val) { 334 | val = !val; // "set" bits are lower than "reset" bits 335 | REG_SET(GPIO_BSRR(bank), (1U << pin) << (16 * val)); 336 | } 337 | 338 | bool readPin(u32 bank, u8 pin) { 339 | // todo, implement read 340 | if (REG_GET(GPIO_IDR(bank)) & (0x01 << pin)) { 341 | return TRUE; 342 | } else { 343 | return FALSE; 344 | } 345 | } 346 | 347 | bool readButtonState() 348 | { 349 | bool state = FALSE; 350 | 351 | #if defined(BUTTON_BANK) && defined (BUTTON_PIN) && defined (BUTTON_ON_STATE) 352 | if (REG_GET(GPIO_IDR(BUTTON_BANK)) & (0x01 << BUTTON_PIN)) { 353 | state = TRUE; 354 | } 355 | 356 | if (BUTTON_ON_STATE==0) { 357 | state = !state; 358 | } 359 | #endif 360 | 361 | return state; 362 | } 363 | 364 | void strobePin(u32 bank, u8 pin, u8 count, u32 rate,u8 onState) 365 | { 366 | gpio_write_bit(bank, pin, 1-onState); 367 | 368 | u32 c; 369 | while (count-- > 0) { 370 | for (c = rate; c > 0; c--) { 371 | asm volatile("nop"); 372 | } 373 | 374 | gpio_write_bit(bank, pin, onState); 375 | 376 | for (c = rate; c > 0; c--) { 377 | asm volatile("nop"); 378 | } 379 | 380 | gpio_write_bit(bank, pin, 1 - onState); 381 | } 382 | } -------------------------------------------------------------------------------- /STM32F1/hardware.h: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | 25 | #ifndef __HARDWARE_H 26 | #define __HARDWARE_H 27 | 28 | 29 | #include "stm32f10x_type.h" 30 | #include "cortexm3_macro.h" 31 | #include "common.h" 32 | 33 | /* macro'd register and peripheral definitions */ 34 | #define PERIPH_BASE ((u32)0x40000000) 35 | 36 | #define APB1_BASE PERIPH_BASE 37 | #define APB2_BASE (PERIPH_BASE + 0x10000) 38 | 39 | #define RCC_BASE (PERIPH_BASE + 0x21000) 40 | #define FLASH_BASE (PERIPH_BASE + 0x22000) 41 | 42 | #define GPIOA (PERIPH_BASE + 0x10800) 43 | #define GPIOB (PERIPH_BASE + 0x10C00) 44 | #define GPIOC (PERIPH_BASE + 0x11000) 45 | #define GPIOD (PERIPH_BASE + 0x11400) 46 | 47 | #define AFIO_BASE (APB2_BASE + 0x0000) 48 | #define AFIO_MAPR (AFIO_BASE + 0x04) 49 | 50 | #define FLASH_KEY1 0x45670123 51 | #define FLASH_KEY2 0xCDEF89AB 52 | #define FLASH_RDPRT 0x00A5 53 | #define FLASH_SR_BSY 0x01 54 | #define FLASH_CR_PER 0x02 55 | #define FLASH_CR_PG 0x01 56 | #define FLASH_CR_START 0x40 57 | 58 | #define GPIO_CRL(port) port 59 | #define GPIO_CRH(port) (port+0x04) 60 | #define GPIO_IDR(port) (port+0x08) 61 | #define GPIO_ODR(port) (port+0x0c) 62 | #define GPIO_BSRR(port) (port+0x10) 63 | #define GPIO_CR(port,pin) (port + (0x04*(pin>7))) 64 | 65 | #define CR_OUTPUT_OD 0x05 66 | #define CR_OUTPUT_PP 0x01 67 | #define CR_INPUT 0x04 68 | #define CR_INPUT_PU_PD 0x08 69 | 70 | #define SCS_BASE ((u32)0xE000E000) 71 | #define NVIC_BASE (SCS_BASE + 0x0100) 72 | #define SCB_BASE (SCS_BASE + 0x0D00) 73 | 74 | #define STK_BASE (SCS_BASE + 0x0010) 75 | #define STK_CTRL (STK_BASE + 0x0000) 76 | 77 | #define TIM1_APB2_ENB ((u32)0x00000800) 78 | #define TIM1 ((u32)0x40012C00) 79 | #define TIM1_PSC (TIM1+0x28) 80 | #define TIM1_ARR (TIM1+0x2C) 81 | #define TIM1_RCR (TIM1+0x30) 82 | #define TIM1_CR1 (TIM1+0x00) 83 | #define TIM1_CR2 (TIM1+0x04) 84 | #define TIM1_DIER (TIM1+0x0C) 85 | #define TIM1_UP_IRQ_Channel ((u8)0x19) 86 | 87 | #define USB_HP_IRQ ((u8)0x13) 88 | #define USB_LP_IRQ ((u8)0x14) 89 | #define TIM2_IRQ ((u8)0x1C) 90 | 91 | 92 | /* AIRCR */ 93 | #define AIRCR_RESET 0x05FA0000 94 | #define AIRCR_RESET_REQ (AIRCR_RESET | (u32)0x04); 95 | 96 | /* temporary copyage of example from kiel */ 97 | #define __VAL(__TIMCLK, __PERIOD) ((__TIMCLK/1000000UL)*__PERIOD) 98 | #define __PSC(__TIMCLK, __PERIOD) (((__VAL(__TIMCLK, __PERIOD)+49999UL)/50000UL) - 1) 99 | #define __ARR(__TIMCLK, __PERIOD) ((__VAL(__TIMCLK, __PERIOD)/(__PSC(__TIMCLK, __PERIOD)+1)) - 1) 100 | 101 | // SWD and JTAG DEBUGGING 102 | #define AFIO_MAPR_SWJ_CFG (0x7 << 24) 103 | #define AFIO_MAPR_SWJ_CFG_FULL_SWJ (0x0 << 24) 104 | #define AFIO_MAPR_SWJ_CFG_FULL_SWJ_NO_NJRST (0x1 << 24) 105 | #define AFIO_MAPR_SWJ_CFG_NO_JTAG_SW (0x2 << 24) 106 | #define AFIO_MAPR_SWJ_CFG_NO_JTAG_NO_SW (0x4 << 24) 107 | 108 | // more bit twiddling to set Control register bits 109 | #define CR_SHIFT(pin) ((pin - 8*(pin>7))<<2) 110 | 111 | #define REG_GET(addr) (*(vu32*)(addr)) 112 | 113 | #define REG_SET(addr,val) do { *(vu32*)(addr) = val; } while(0) 114 | #define REG_BOR(addr,val) do { *(vu32*)(addr) |= val; } while(0) 115 | #define REG_BAND(addr,val) do { *(vu32*)(addr) &= val; } while(0) 116 | 117 | 118 | 119 | typedef struct { 120 | vu32 ISER[2]; 121 | u32 RESERVED0[30]; 122 | vu32 ICER[2]; 123 | u32 RSERVED1[30]; 124 | vu32 ISPR[2]; 125 | u32 RESERVED2[30]; 126 | vu32 ICPR[2]; 127 | u32 RESERVED3[30]; 128 | vu32 IABR[2]; 129 | u32 RESERVED4[62]; 130 | vu32 IPR[15]; 131 | } NVIC_TypeDef; 132 | 133 | typedef struct { 134 | u8 NVIC_IRQChannel; 135 | u8 NVIC_IRQChannelPreemptionPriority; 136 | u8 NVIC_IRQChannelSubPriority; 137 | bool NVIC_IRQChannelCmd; /* TRUE for enable */ 138 | } NVIC_InitTypeDef; 139 | 140 | typedef struct { 141 | vuc32 CPUID; 142 | vu32 ICSR; 143 | vu32 VTOR; 144 | vu32 AIRCR; 145 | vu32 SCR; 146 | vu32 CCR; 147 | vu32 SHPR[3]; 148 | vu32 SHCSR; 149 | vu32 CFSR; 150 | vu32 HFSR; 151 | vu32 DFSR; 152 | vu32 MMFAR; 153 | vu32 BFAR; 154 | vu32 AFSR; 155 | } SCB_TypeDef; 156 | 157 | typedef struct { 158 | vu32 CR; 159 | vu32 CFGR; 160 | vu32 CIR; 161 | vu32 APB2RSTR; 162 | vu32 ABP1RSTR; 163 | vu32 AHBENR; 164 | vu32 APB2ENR; 165 | vu32 APB1ENR; 166 | vu32 RCC_BDCR; 167 | vu32 CSR; 168 | } RCC_TypeDef; 169 | 170 | typedef struct { 171 | vu32 ACR; 172 | vu32 KEYR; 173 | vu32 OPTKEYR; 174 | vu32 SR; 175 | vu32 CR; 176 | vu32 AR; 177 | vu32 RESERVED0; 178 | vu32 OBR; 179 | vu32 WRPR; 180 | } FLASH_TypeDef; 181 | 182 | 183 | //void setPin(u32 bank, u8 pin); 184 | //void resetPin(u32 bank, u8 pin); 185 | void gpio_write_bit(u32 bank, u8 pin, u8 val); 186 | unsigned int crMask(int pin); 187 | 188 | bool readPin(u32 bank, u8 pin); 189 | void strobePin(u32 bank, u8 pin, u8 count, u32 rate,u8 onState); 190 | bool readButtonState(); 191 | 192 | void systemHardReset(void); 193 | void systemReset(void); 194 | void setupCLK(void); 195 | void setupLEDAndButton(void); 196 | void setupFLASH(void); 197 | bool checkUserCode(u32 usrAddr); 198 | void jumpToUser(u32 usrAddr); 199 | 200 | bool flashWriteWord(u32 addr, u32 word); 201 | bool flashErasePage(u32 addr); 202 | bool flashErasePages(u32 addr, u16 n); 203 | void flashLock(void); 204 | void flashUnlock(void); 205 | void nvicInit(NVIC_InitTypeDef *); 206 | void nvicDisableInterrupts(void); 207 | 208 | int getFlashEnd(void); 209 | int getFlashPageSize(void); 210 | 211 | 212 | #endif 213 | -------------------------------------------------------------------------------- /STM32F1/main.c: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | 25 | /** 26 | * @file main.c 27 | * 28 | * @brief main loop and calling any hardware init stuff. 29 | * logic to handle bootloader entry and jumping to user code. 30 | */ 31 | 32 | #include "common.h" 33 | #include "dfu.h" 34 | 35 | 36 | #define SW_ONLY 1 37 | #define FLASH_ONLY 2 38 | #define SW_OR_FLASH 0 39 | 40 | 41 | static RCC_TypeDef *RCC = (RCC_TypeDef *)RCC_BASE; 42 | 43 | 44 | static int checkUserJump(u8 sw) 45 | { 46 | switch (sw) { 47 | case SW_ONLY: return readButtonState(); 48 | case FLASH_ONLY: { 49 | return (!(checkUserCode(USER_CODE_FLASH0X8005000) 50 | || checkUserCode(USER_CODE_FLASH0X8002000)) 51 | ); 52 | } 53 | } 54 | 55 | return (readButtonState() || 56 | (!(checkUserCode(USER_CODE_FLASH0X8005000) 57 | || checkUserCode(USER_CODE_FLASH0X8002000))) 58 | ); 59 | } 60 | 61 | static u32 checkReset() 62 | { 63 | #ifdef BL_BUTTON_ALWAYS_WORKS 64 | return checkUserJump(SW_ONLY) | (RCC->CSR & (RESET_ACTIVATION)); 65 | #else 66 | return ((RCC->CSR) & (RESET_ACTIVATION)); 67 | #endif 68 | } 69 | 70 | int main() 71 | { 72 | int bl_start = 0; 73 | int bl_active = 0; 74 | 75 | systemReset(); // peripherals but not PC 76 | setupCLK(); // not USB, that is handled by USB portion 77 | setupLEDAndButton(); 78 | 79 | // determine our reset method to see if we should even use the bootloader 80 | // NOTE: user must set RCC->CSR bit 24, otherwise this may always succeed 81 | if (checkReset()) { 82 | // do the startup LED quickflash 83 | #ifndef DISABLE_STARTUP_FAST_BLINK 84 | strobePin(LED_BANK, LED_PIN, STARTUP_BLINKS, BLINK_FAST, LED_ON_STATE); 85 | #endif 86 | 87 | // see if we should enter the bootloader.... 88 | #if (BOOTLOADER_WAIT == 0) 89 | // as there is no wait defined, there must a switch or other method to get 90 | // into the bootloader. we don't even want to activate it for a brief moment, 91 | // so only activate if the button is held high or no code is in user flash 92 | bl_start = checkUserJump(SW_OR_FLASH); 93 | #else 94 | // load the bootloader for the specified bootloader wait time 95 | // this is specified in config.h for the selected platform 96 | bl_start = 1; 97 | #endif 98 | } else { 99 | // even if invalid reset, if for some reason the flash is corrupted, 100 | // we need to enter the bootloader. in this case, we get no quickflash =) 101 | bl_start = checkUserJump(FLASH_ONLY); 102 | } 103 | 104 | if (bl_start) { 105 | // for some reason we've entered the bootloader 106 | // if a button is pushed, or we don't have valid code in flash, 107 | // we want to stay in the bootloader 108 | bl_active = checkUserJump(SW_OR_FLASH); 109 | 110 | // only set up USB and flash if in the bootloader (as we are now) 111 | setupUSB(); 112 | setupFLASH(); 113 | 114 | // stay in the bootloader if we're waiting, or if we're forced active 115 | int bl_wait = BOOTLOADER_WAIT; 116 | while (bl_wait || bl_active) { 117 | if (bl_wait) bl_wait--; 118 | 119 | // is DFU in progress? 120 | if (dfuUploadStarted()) { 121 | // wait until we're done 122 | while (!dfuUploadDone()); 123 | // success flash, we also need to wait a little longer for manifest to be sent 124 | // otherwise it will be successful but we'll get "unable to read DFU status" error 125 | 126 | // flashing faster once we're done takes time, this serves as our wait 127 | strobePin(LED_BANK, LED_PIN, STARTUP_BLINKS, BLINK_FAST, LED_ON_STATE); 128 | 129 | // uncomment the following line if you always want to execute code after completion 130 | // break; 131 | 132 | // uncomment the following line if you only want to stay in the bootloader if 133 | // the switch is still pressed (used for toggle switches). deactivating the 134 | // switch will then start the program. used for user-initiated code start 135 | bl_active = checkUserJump(SW_ONLY); 136 | 137 | // uncomment no lines if you want to stay in the bootloader after loading code 138 | // keep in mind that the DFU state machine is broken so there's no point, really 139 | } else { 140 | // while in bootloader, flash the LED slowly 141 | strobePin(LED_BANK, LED_PIN, 1, BLINK_SLOW, LED_ON_STATE); 142 | } 143 | } 144 | } 145 | 146 | if (checkUserCode(USER_CODE_FLASH0X8002000)) { 147 | jumpToUser(USER_CODE_FLASH0X8002000); 148 | } else { 149 | if (checkUserCode(USER_CODE_FLASH0X8005000)) { 150 | jumpToUser(USER_CODE_FLASH0X8005000); 151 | } else { 152 | // Nothing to execute in either Flash or RAM 153 | strobePin(LED_BANK, LED_PIN, 10, BLINK_FAST, LED_ON_STATE); 154 | systemHardReset(); 155 | } 156 | } 157 | 158 | return 0; 159 | } -------------------------------------------------------------------------------- /STM32F1/stm32_lib/c_only_md.ld: -------------------------------------------------------------------------------- 1 | /* 2 | Default linker script for STM32F10x_128K_20K 3 | Original Copyright RAISONANCE S.A.S. 2008 4 | Modified P Harrison May 2009 5 | */ 6 | 7 | /* 8 | * Default stack sizes. 9 | * 10 | * These are used by the startup in order to allocate stacks for the different modes. 11 | * PROVIDE" allows to easily override these values from an object file or the commmand line. 12 | */ 13 | 14 | __Stack_Size = 1024 ; 15 | PROVIDE ( _Stack_Size = __Stack_Size ) ; 16 | __Stack_Init = _estack - __Stack_Size ; 17 | PROVIDE ( _Stack_Init = __Stack_Init ) ; 18 | 19 | /* 20 | *There will be a link error if there is not this amount of RAM free at the end. 21 | */ 22 | _Minimum_Stack_Size = 0x100 ; 23 | 24 | 25 | MEMORY 26 | { 27 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K 28 | FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 8K 29 | } 30 | 31 | /* higher address of the user mode stack */ 32 | _estack = 0x20005000; 33 | 34 | SECTIONS 35 | { 36 | /* 37 | * for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, 38 | * which goes to FLASH 39 | */ 40 | .isr_vector : 41 | { 42 | . = ALIGN(4); 43 | KEEP(*(.isr_vector)) /* Startup code */ 44 | . = ALIGN(4); 45 | } >FLASH 46 | 47 | /* 48 | * for some STRx devices, the beginning of the startup code is stored in the .flashtext section, 49 | * which goes to FLASH 50 | */ 51 | .flashtext : 52 | { 53 | . = ALIGN(4); 54 | KEEP (*(.flashtext)) /* Startup code */ 55 | . = ALIGN(4); 56 | } >FLASH 57 | 58 | /* 59 | * the program code is stored in the .text section, which goes to Flash 60 | */ 61 | .text : 62 | { 63 | . = ALIGN(4); 64 | *(.text) /* remaining code */ 65 | *(.text.*) /* remaining code */ 66 | *(.rodata) /* read-only data (constants) */ 67 | *(.rodata*) 68 | *(.glue_7) 69 | *(.glue_7t) 70 | . = ALIGN(4); 71 | _etext = .; 72 | _sidata = _etext; 73 | } >FLASH 74 | 75 | /* 76 | * This is the initialized data section. It is stored in RAM but the initial values 77 | * are held in flash and copied to RAM by the startup code 78 | */ 79 | 80 | /* we copy the important program globals vector in RAM as well, so that users can fool with it */ 81 | .data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */ 82 | { 83 | . = ALIGN(4); 84 | _sdata = . ; /* Used by the startup in order to initialize the .data section */ 85 | KEEP( *(.data) ) 86 | KEEP( *(.data.*) ) 87 | . = ALIGN(4); 88 | _edata = . ; /* Used by the startup in order to initialize the .data section */ 89 | } >RAM 90 | 91 | 92 | 93 | /* 94 | * This is the uninitialized data section. Date here is stored in RAM and will be 95 | * set to zero by the startup code. 96 | */ 97 | .bss : 98 | { 99 | . = ALIGN(4); 100 | _sbss = .; /* Used by the startup in order to initialize the .bss section */ 101 | *(.bss) 102 | *(COMMON) 103 | . = ALIGN(4); 104 | _ebss = . ; /* Used by the startup in order to initialize the .bss section */ 105 | } >RAM 106 | 107 | PROVIDE ( end = _ebss ); 108 | PROVIDE ( _end = _ebss ); 109 | 110 | /* 111 | * This is the user stack section 112 | * This is just to check that there is enough RAM left for the User mode stack 113 | * It should generate an error if it's full. 114 | */ 115 | ._usrstack : 116 | { 117 | . = ALIGN(4); 118 | _susrstack = . ; 119 | . = . + _Minimum_Stack_Size ; 120 | . = ALIGN(4); 121 | _eusrstack = . ; 122 | } >RAM 123 | 124 | /* 125 | * after that it's only debugging information. 126 | */ 127 | 128 | /* remove the debugging information from the standard libraries */ 129 | DISCARD : 130 | { 131 | libc.a ( * ) 132 | libm.a ( * ) 133 | libgcc.a ( * ) 134 | } 135 | 136 | /* Stabs debugging sections. */ 137 | .stab 0 : { *(.stab) } 138 | .stabstr 0 : { *(.stabstr) } 139 | .stab.excl 0 : { *(.stab.excl) } 140 | .stab.exclstr 0 : { *(.stab.exclstr) } 141 | .stab.index 0 : { *(.stab.index) } 142 | .stab.indexstr 0 : { *(.stab.indexstr) } 143 | .comment 0 : { *(.comment) } 144 | /* 145 | * DWARF debug sections. 146 | * Symbols in the DWARF debugging sections are relative to the beginning 147 | * of the section so we begin them at 0. 148 | */ 149 | 150 | /* DWARF 1 */ 151 | .debug 0 : { *(.debug) } 152 | .line 0 : { *(.line) } 153 | /* GNU DWARF 1 extensions */ 154 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 155 | .debug_sfnames 0 : { *(.debug_sfnames) } 156 | /* DWARF 1.1 and DWARF 2 */ 157 | .debug_aranges 0 : { *(.debug_aranges) } 158 | .debug_pubnames 0 : { *(.debug_pubnames) } 159 | /* DWARF 2 */ 160 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 161 | .debug_abbrev 0 : { *(.debug_abbrev) } 162 | .debug_line 0 : { *(.debug_line) } 163 | .debug_frame 0 : { *(.debug_frame) } 164 | .debug_str 0 : { *(.debug_str) } 165 | .debug_loc 0 : { *(.debug_loc) } 166 | .debug_macinfo 0 : { *(.debug_macinfo) } 167 | /* SGI/MIPS DWARF 2 extensions */ 168 | .debug_weaknames 0 : { *(.debug_weaknames) } 169 | .debug_funcnames 0 : { *(.debug_funcnames) } 170 | .debug_typenames 0 : { *(.debug_typenames) } 171 | .debug_varnames 0 : { *(.debug_varnames) } 172 | } 173 | -------------------------------------------------------------------------------- /STM32F1/stm32_lib/c_only_md_RAM.ld: -------------------------------------------------------------------------------- 1 | /* 2 | Default linker script for STM32F10x_128K_20K 3 | Original Copyright RAISONANCE S.A.S. 2008 4 | Modified P Harrison May 2009 5 | */ 6 | 7 | /* 8 | * Default stack sizes. 9 | * 10 | * These are used by the startup in order to allocate stacks for the different modes. 11 | * PROVIDE" allows to easily override these values from an object file or the commmand line. 12 | */ 13 | 14 | __Stack_Size = 1024 ; 15 | PROVIDE ( _Stack_Size = __Stack_Size ) ; 16 | __Stack_Init = _estack - __Stack_Size ; 17 | PROVIDE ( _Stack_Init = __Stack_Init ) ; 18 | 19 | /* 20 | *There will be a link error if there is not this amount of RAM free at the end. 21 | */ 22 | _Minimum_Stack_Size = 0x100 ; 23 | 24 | 25 | MEMORY 26 | { 27 | RAM (xrw) : ORIGIN = 0x20000C00, LENGTH = 17K 28 | } 29 | 30 | /* higher address of the user mode stack */ 31 | _estack = 0x20005000; 32 | _magicRate = 0x5000; 33 | SECTIONS 34 | { 35 | /* 36 | * for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, 37 | * which goes to FLASH 38 | */ 39 | .isr_vector : 40 | { 41 | . = ALIGN(4); 42 | KEEP(*(.isr_vector)) /* Startup code */ 43 | . = ALIGN(4); 44 | } >RAM 45 | 46 | /* 47 | * for some STRx devices, the beginning of the startup code is stored in the .flashtext section, 48 | * which goes to FLASH 49 | */ 50 | .flashtext : 51 | { 52 | . = ALIGN(4); 53 | KEEP (*(.flashtext)) /* Startup code */ 54 | . = ALIGN(4); 55 | } >RAM 56 | 57 | /* 58 | * the program code is stored in the .text section, which goes to Flash 59 | */ 60 | .text : 61 | { 62 | . = ALIGN(4); 63 | *(.text) /* remaining code */ 64 | *(.text.*) /* remaining code */ 65 | *(.rodata) /* read-only data (constants) */ 66 | *(.rodata*) 67 | *(.glue_7) 68 | *(.glue_7t) 69 | . = ALIGN(4); 70 | _etext = .; 71 | _sidata = _etext; /* Uused by the startup in order to initialize the .data secion */ 72 | } >RAM 73 | 74 | /* 75 | * This is the initialized data section. It is stored in RAM but the initial values 76 | * are held in flash and copied to RAM by the startup code 77 | */ 78 | .data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */ 79 | { 80 | . = ALIGN(4); 81 | _sdata = . ; /* Used by the startup in order to initialize the .data section */ 82 | KEEP( *(.data) ) 83 | KEEP( *(.data.*) ) 84 | . = ALIGN(4); 85 | _edata = . ; /* Used by the startup in order to initialize the .data section */ 86 | } >RAM 87 | 88 | 89 | 90 | /* 91 | * This is the uninitialized data section. Date here is stored in RAM and will be 92 | * set to zero by the startup code. 93 | */ 94 | .bss : 95 | { 96 | . = ALIGN(4); 97 | _sbss = .; /* Used by the startup in order to initialize the .bss section */ 98 | *(.bss) 99 | *(COMMON) 100 | . = ALIGN(4); 101 | _ebss = . ; /* Used by the startup in order to initialize the .bss section */ 102 | } >RAM 103 | 104 | PROVIDE ( end = _ebss ); 105 | PROVIDE ( _end = _ebss ); 106 | 107 | /* 108 | * This is the user stack section 109 | * This is just to check that there is enough RAM left for the User mode stack 110 | * It should generate an error if it's full. 111 | */ 112 | ._usrstack : 113 | { 114 | . = ALIGN(4); 115 | _susrstack = . ; 116 | . = . + _Minimum_Stack_Size ; 117 | . = ALIGN(4); 118 | _eusrstack = . ; 119 | } >RAM 120 | 121 | /* 122 | * after that it's only debugging information. 123 | */ 124 | 125 | /* remove the debugging information from the standard libraries */ 126 | DISCARD : 127 | { 128 | libc.a ( * ) 129 | libm.a ( * ) 130 | libgcc.a ( * ) 131 | } 132 | 133 | /* Stabs debugging sections. */ 134 | .stab 0 : { *(.stab) } 135 | .stabstr 0 : { *(.stabstr) } 136 | .stab.excl 0 : { *(.stab.excl) } 137 | .stab.exclstr 0 : { *(.stab.exclstr) } 138 | .stab.index 0 : { *(.stab.index) } 139 | .stab.indexstr 0 : { *(.stab.indexstr) } 140 | .comment 0 : { *(.comment) } 141 | /* 142 | * DWARF debug sections. 143 | * Symbols in the DWARF debugging sections are relative to the beginning 144 | * of the section so we begin them at 0. 145 | */ 146 | 147 | /* DWARF 1 */ 148 | .debug 0 : { *(.debug) } 149 | .line 0 : { *(.line) } 150 | /* GNU DWARF 1 extensions */ 151 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 152 | .debug_sfnames 0 : { *(.debug_sfnames) } 153 | /* DWARF 1.1 and DWARF 2 */ 154 | .debug_aranges 0 : { *(.debug_aranges) } 155 | .debug_pubnames 0 : { *(.debug_pubnames) } 156 | /* DWARF 2 */ 157 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 158 | .debug_abbrev 0 : { *(.debug_abbrev) } 159 | .debug_line 0 : { *(.debug_line) } 160 | .debug_frame 0 : { *(.debug_frame) } 161 | .debug_str 0 : { *(.debug_str) } 162 | .debug_loc 0 : { *(.debug_loc) } 163 | .debug_macinfo 0 : { *(.debug_macinfo) } 164 | /* SGI/MIPS DWARF 2 extensions */ 165 | .debug_weaknames 0 : { *(.debug_weaknames) } 166 | .debug_funcnames 0 : { *(.debug_funcnames) } 167 | .debug_typenames 0 : { *(.debug_typenames) } 168 | .debug_varnames 0 : { *(.debug_varnames) } 169 | } 170 | -------------------------------------------------------------------------------- /STM32F1/stm32_lib/c_only_md_high_density.ld: -------------------------------------------------------------------------------- 1 | /* 2 | Default linker script for STM32F10x_128K_20K 3 | Original Copyright RAISONANCE S.A.S. 2008 4 | Modified P Harrison May 2009 5 | */ 6 | 7 | /* 8 | * Default stack sizes. 9 | * 10 | * These are used by the startup in order to allocate stacks for the different modes. 11 | * PROVIDE" allows to easily override these values from an object file or the commmand line. 12 | */ 13 | 14 | __Stack_Size = 1024 ; 15 | PROVIDE ( _Stack_Size = __Stack_Size ) ; 16 | __Stack_Init = _estack - __Stack_Size ; 17 | PROVIDE ( _Stack_Init = __Stack_Init ) ; 18 | 19 | /* 20 | *There will be a link error if there is not this amount of RAM free at the end. 21 | */ 22 | _Minimum_Stack_Size = 0x100 ; 23 | 24 | 25 | MEMORY 26 | { 27 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K 28 | FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 8K 29 | } 30 | 31 | /* higher address of the user mode stack */ 32 | _estack = 0x20005000; 33 | 34 | SECTIONS 35 | { 36 | /* 37 | * for Cortex devices, the beginning of the startup code is stored in the .isr_vector section, 38 | * which goes to FLASH 39 | */ 40 | .isr_vector : 41 | { 42 | . = ALIGN(4); 43 | KEEP(*(.isr_vector)) /* Startup code */ 44 | . = ALIGN(4); 45 | } >FLASH 46 | 47 | /* 48 | * for some STRx devices, the beginning of the startup code is stored in the .flashtext section, 49 | * which goes to FLASH 50 | */ 51 | .flashtext : 52 | { 53 | . = ALIGN(4); 54 | KEEP (*(.flashtext)) /* Startup code */ 55 | . = ALIGN(4); 56 | } >FLASH 57 | 58 | /* 59 | * the program code is stored in the .text section, which goes to Flash 60 | */ 61 | .text : 62 | { 63 | . = ALIGN(4); 64 | *(.text) /* remaining code */ 65 | *(.text.*) /* remaining code */ 66 | *(.rodata) /* read-only data (constants) */ 67 | *(.rodata*) 68 | *(.glue_7) 69 | *(.glue_7t) 70 | . = ALIGN(4); 71 | _etext = .; 72 | _sidata = _etext; 73 | } >FLASH 74 | 75 | /* 76 | * This is the initialized data section. It is stored in RAM but the initial values 77 | * are held in flash and copied to RAM by the startup code 78 | */ 79 | 80 | /* we copy the important program globals vector in RAM as well, so that users can fool with it */ 81 | .data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */ 82 | { 83 | . = ALIGN(4); 84 | _sdata = . ; /* Used by the startup in order to initialize the .data section */ 85 | KEEP( *(.data) ) 86 | KEEP( *(.data.*) ) 87 | . = ALIGN(4); 88 | _edata = . ; /* Used by the startup in order to initialize the .data section */ 89 | } >RAM 90 | 91 | 92 | 93 | /* 94 | * This is the uninitialized data section. Date here is stored in RAM and will be 95 | * set to zero by the startup code. 96 | */ 97 | .bss : 98 | { 99 | . = ALIGN(4); 100 | _sbss = .; /* Used by the startup in order to initialize the .bss section */ 101 | *(.bss) 102 | *(COMMON) 103 | . = ALIGN(4); 104 | _ebss = . ; /* Used by the startup in order to initialize the .bss section */ 105 | } >RAM 106 | 107 | PROVIDE ( end = _ebss ); 108 | PROVIDE ( _end = _ebss ); 109 | 110 | /* 111 | * This is the user stack section 112 | * This is just to check that there is enough RAM left for the User mode stack 113 | * It should generate an error if it's full. 114 | */ 115 | ._usrstack : 116 | { 117 | . = ALIGN(4); 118 | _susrstack = . ; 119 | . = . + _Minimum_Stack_Size ; 120 | . = ALIGN(4); 121 | _eusrstack = . ; 122 | } >RAM 123 | 124 | /* 125 | * after that it's only debugging information. 126 | */ 127 | 128 | /* remove the debugging information from the standard libraries */ 129 | DISCARD : 130 | { 131 | libc.a ( * ) 132 | libm.a ( * ) 133 | libgcc.a ( * ) 134 | } 135 | 136 | /* Stabs debugging sections. */ 137 | .stab 0 : { *(.stab) } 138 | .stabstr 0 : { *(.stabstr) } 139 | .stab.excl 0 : { *(.stab.excl) } 140 | .stab.exclstr 0 : { *(.stab.exclstr) } 141 | .stab.index 0 : { *(.stab.index) } 142 | .stab.indexstr 0 : { *(.stab.indexstr) } 143 | .comment 0 : { *(.comment) } 144 | /* 145 | * DWARF debug sections. 146 | * Symbols in the DWARF debugging sections are relative to the beginning 147 | * of the section so we begin them at 0. 148 | */ 149 | 150 | /* DWARF 1 */ 151 | .debug 0 : { *(.debug) } 152 | .line 0 : { *(.line) } 153 | /* GNU DWARF 1 extensions */ 154 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 155 | .debug_sfnames 0 : { *(.debug_sfnames) } 156 | /* DWARF 1.1 and DWARF 2 */ 157 | .debug_aranges 0 : { *(.debug_aranges) } 158 | .debug_pubnames 0 : { *(.debug_pubnames) } 159 | /* DWARF 2 */ 160 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 161 | .debug_abbrev 0 : { *(.debug_abbrev) } 162 | .debug_line 0 : { *(.debug_line) } 163 | .debug_frame 0 : { *(.debug_frame) } 164 | .debug_str 0 : { *(.debug_str) } 165 | .debug_loc 0 : { *(.debug_loc) } 166 | .debug_macinfo 0 : { *(.debug_macinfo) } 167 | /* SGI/MIPS DWARF 2 extensions */ 168 | .debug_weaknames 0 : { *(.debug_weaknames) } 169 | .debug_funcnames 0 : { *(.debug_funcnames) } 170 | .debug_typenames 0 : { *(.debug_typenames) } 171 | .debug_varnames 0 : { *(.debug_varnames) } 172 | } 173 | -------------------------------------------------------------------------------- /STM32F1/stm32_lib/c_only_startup.s: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file startup_stm32f10x_md.s 4 | * @author MCD Application Team 5 | * @version V3.1.0 6 | * @date 06/19/2009 7 | * @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain. 8 | * This module performs: 9 | * - Set the initial SP 10 | * - Set the initial PC == Reset_Handler, 11 | * - Set the vector table entries with the exceptions ISR address 12 | * - Branches to main in the C library (which eventually 13 | * calls main()). 14 | * After Reset the Cortex-M3 processor is in Thread mode, 15 | * priority is Privileged, and the Stack is set to Main. 16 | ******************************************************************************* 17 | * @copy 18 | * 19 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 20 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 21 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 22 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 23 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 24 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 25 | * 26 | *

© COPYRIGHT 2009 STMicroelectronics

27 | */ 28 | 29 | .syntax unified 30 | .cpu cortex-m3 31 | .fpu softvfp 32 | .thumb 33 | 34 | .global g_pfnVectors 35 | .global SystemInit_ExtMemCtl_Dummy 36 | .global Default_Handler 37 | 38 | /* start address for the initialization values of the .data section. 39 | defined in linker script */ 40 | .word _sidata 41 | /* start address for the .data section. defined in linker script */ 42 | .word _sdata 43 | /* end address for the .data section. defined in linker script */ 44 | .word _edata 45 | /* start address for the .bss section. defined in linker script */ 46 | .word _sbss 47 | /* end address for the .bss section. defined in linker script */ 48 | .word _ebss 49 | 50 | .equ BootRAM, 0xF108F85F 51 | /** 52 | * @brief This is the code that gets called when the processor first 53 | * starts execution following a reset event. Only the absolutely 54 | * necessary set is performed, after which the application 55 | * supplied main() routine is called. 56 | * @param None 57 | * @retval : None 58 | */ 59 | 60 | .section .text.Reset_Handler 61 | .weak Reset_Handler 62 | .type Reset_Handler, %function 63 | Reset_Handler: 64 | 65 | /* Copy the data segment initializers from flash to SRAM */ 66 | movs r1, #0 67 | b LoopCopyDataInit 68 | 69 | CopyDataInit: 70 | ldr r3, =_sidata 71 | ldr r3, [r3, r1] 72 | str r3, [r0, r1] 73 | adds r1, r1, #4 74 | 75 | LoopCopyDataInit: 76 | ldr r0, =_sdata 77 | ldr r3, =_edata 78 | adds r2, r0, r1 79 | cmp r2, r3 80 | bcc CopyDataInit 81 | ldr r2, =_sbss 82 | b LoopFillZerobss 83 | /* Zero fill the bss segment. */ 84 | FillZerobss: 85 | movs r3, #0 86 | str r3, [r2], #4 87 | 88 | LoopFillZerobss: 89 | ldr r3, = _ebss 90 | cmp r2, r3 91 | bcc FillZerobss 92 | /* Call the application's entry point.*/ 93 | bl main 94 | bx lr 95 | .size Reset_Handler, .-Reset_Handler 96 | 97 | /** 98 | * @brief This is the code that gets called when the processor receives an 99 | * unexpected interrupt. This simply enters an infinite loop, preserving 100 | * the system state for examination by a debugger. 101 | * 102 | * @param None 103 | * @retval : None 104 | */ 105 | .section .text.Default_Handler,"ax",%progbits 106 | Default_Handler: 107 | Infinite_Loop: 108 | b Infinite_Loop 109 | .size Default_Handler, .-Default_Handler 110 | /****************************************************************************** 111 | * 112 | * The minimal vector table for a Cortex M3. Note that the proper constructs 113 | * must be placed on this to ensure that it ends up at physical address 114 | * 0x0000.0000. 115 | * 116 | ******************************************************************************/ 117 | .section .isr_vector,"a",%progbits 118 | .type g_pfnVectors, %object 119 | .size g_pfnVectors, .-g_pfnVectors 120 | 121 | 122 | g_pfnVectors: 123 | .word _estack 124 | .word Reset_Handler 125 | .word NMI_Handler 126 | .word HardFault_Handler 127 | .word MemManage_Handler 128 | .word BusFault_Handler 129 | .word UsageFault_Handler 130 | .word 0 131 | .word 0 132 | .word 0 133 | .word 0 134 | .word SVC_Handler 135 | .word DebugMon_Handler 136 | .word 0 137 | .word PendSV_Handler 138 | .word SysTick_Handler 139 | .word WWDG_IRQHandler 140 | .word PVD_IRQHandler 141 | .word TAMPER_IRQHandler 142 | .word RTC_IRQHandler 143 | .word FLASH_IRQHandler 144 | .word RCC_IRQHandler 145 | .word EXTI0_IRQHandler 146 | .word EXTI1_IRQHandler 147 | .word EXTI2_IRQHandler 148 | .word EXTI3_IRQHandler 149 | .word EXTI4_IRQHandler 150 | .word DMA1_Channel1_IRQHandler 151 | .word DMA1_Channel2_IRQHandler 152 | .word DMA1_Channel3_IRQHandler 153 | .word DMA1_Channel4_IRQHandler 154 | .word DMA1_Channel5_IRQHandler 155 | .word DMA1_Channel6_IRQHandler 156 | .word DMA1_Channel7_IRQHandler 157 | .word ADC1_2_IRQHandler 158 | .word USB_HP_CAN1_TX_IRQHandler 159 | .word USB_LP_CAN1_RX0_IRQHandler 160 | .word CAN1_RX1_IRQHandler 161 | .word CAN1_SCE_IRQHandler 162 | .word EXTI9_5_IRQHandler 163 | .word TIM1_BRK_IRQHandler 164 | .word TIM1_UP_IRQHandler 165 | .word TIM1_TRG_COM_IRQHandler 166 | .word TIM1_CC_IRQHandler 167 | .word TIM2_IRQHandler 168 | .word TIM3_IRQHandler 169 | .word TIM4_IRQHandler 170 | .word I2C1_EV_IRQHandler 171 | .word I2C1_ER_IRQHandler 172 | .word I2C2_EV_IRQHandler 173 | .word I2C2_ER_IRQHandler 174 | .word SPI1_IRQHandler 175 | .word SPI2_IRQHandler 176 | .word USART1_IRQHandler 177 | .word USART2_IRQHandler 178 | .word USART3_IRQHandler 179 | .word EXTI15_10_IRQHandler 180 | .word RTCAlarm_IRQHandler 181 | .word USBWakeUp_IRQHandler 182 | /* 183 | .word TIM8_BRK 184 | .word TIM8_UP 185 | .word TIM8_TRG_COM 186 | .word TIM8_CC 187 | .word ADC3 188 | .word FSMC 189 | .word SDIO 190 | .word TIM5 191 | .word SPI3 192 | .word UART4 193 | .word UART5 194 | .word TIM6 195 | .word TIM7 196 | .word DMA2_Channel1 197 | .word DMA2_Channel2 198 | .word DMA2_Channel3 199 | .word DMA2_Channel5 200 | */ 201 | .word BootRAM /* @0x108. This is for boot in RAM mode for 202 | STM32F10x Medium Density devices. */ 203 | 204 | /******************************************************************************* 205 | * 206 | * Provide weak aliases for each Exception handler to the Default_Handler. 207 | * As they are weak aliases, any function with the same name will override 208 | * this definition. 209 | * 210 | *******************************************************************************/ 211 | 212 | .weak NMI_Handler 213 | .thumb_set NMI_Handler,Default_Handler 214 | 215 | .weak HardFault_Handler 216 | .thumb_set HardFault_Handler,Default_Handler 217 | 218 | .weak MemManage_Handler 219 | .thumb_set MemManage_Handler,Default_Handler 220 | 221 | .weak BusFault_Handler 222 | .thumb_set BusFault_Handler,Default_Handler 223 | 224 | .weak UsageFault_Handler 225 | .thumb_set UsageFault_Handler,Default_Handler 226 | 227 | .weak SVC_Handler 228 | .thumb_set SVC_Handler,Default_Handler 229 | 230 | .weak DebugMon_Handler 231 | .thumb_set DebugMon_Handler,Default_Handler 232 | 233 | .weak PendSV_Handler 234 | .thumb_set PendSV_Handler,Default_Handler 235 | 236 | .weak SysTick_Handler 237 | .thumb_set SysTick_Handler,Default_Handler 238 | 239 | .weak WWDG_IRQHandler 240 | .thumb_set WWDG_IRQHandler,Default_Handler 241 | 242 | .weak PVD_IRQHandler 243 | .thumb_set PVD_IRQHandler,Default_Handler 244 | 245 | .weak TAMPER_IRQHandler 246 | .thumb_set TAMPER_IRQHandler,Default_Handler 247 | 248 | .weak RTC_IRQHandler 249 | .thumb_set RTC_IRQHandler,Default_Handler 250 | 251 | .weak FLASH_IRQHandler 252 | .thumb_set FLASH_IRQHandler,Default_Handler 253 | 254 | .weak RCC_IRQHandler 255 | .thumb_set RCC_IRQHandler,Default_Handler 256 | 257 | .weak EXTI0_IRQHandler 258 | .thumb_set EXTI0_IRQHandler,Default_Handler 259 | 260 | .weak EXTI1_IRQHandler 261 | .thumb_set EXTI1_IRQHandler,Default_Handler 262 | 263 | .weak EXTI2_IRQHandler 264 | .thumb_set EXTI2_IRQHandler,Default_Handler 265 | 266 | .weak EXTI3_IRQHandler 267 | .thumb_set EXTI3_IRQHandler,Default_Handler 268 | 269 | .weak EXTI4_IRQHandler 270 | .thumb_set EXTI4_IRQHandler,Default_Handler 271 | 272 | .weak DMA1_Channel1_IRQHandler 273 | .thumb_set DMA1_Channel1_IRQHandler,Default_Handler 274 | 275 | .weak DMA1_Channel2_IRQHandler 276 | .thumb_set DMA1_Channel2_IRQHandler,Default_Handler 277 | 278 | .weak DMA1_Channel3_IRQHandler 279 | .thumb_set DMA1_Channel3_IRQHandler,Default_Handler 280 | 281 | .weak DMA1_Channel4_IRQHandler 282 | .thumb_set DMA1_Channel4_IRQHandler,Default_Handler 283 | 284 | .weak DMA1_Channel5_IRQHandler 285 | .thumb_set DMA1_Channel5_IRQHandler,Default_Handler 286 | 287 | .weak DMA1_Channel6_IRQHandler 288 | .thumb_set DMA1_Channel6_IRQHandler,Default_Handler 289 | 290 | .weak DMA1_Channel7_IRQHandler 291 | .thumb_set DMA1_Channel7_IRQHandler,Default_Handler 292 | 293 | .weak ADC1_2_IRQHandler 294 | .thumb_set ADC1_2_IRQHandler,Default_Handler 295 | 296 | .weak USB_HP_CAN1_TX_IRQHandler 297 | .thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler 298 | 299 | .weak USB_LP_CAN1_RX0_IRQHandler 300 | .thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler 301 | 302 | .weak CAN1_RX1_IRQHandler 303 | .thumb_set CAN1_RX1_IRQHandler,Default_Handler 304 | 305 | .weak CAN1_SCE_IRQHandler 306 | .thumb_set CAN1_SCE_IRQHandler,Default_Handler 307 | 308 | .weak EXTI9_5_IRQHandler 309 | .thumb_set EXTI9_5_IRQHandler,Default_Handler 310 | 311 | .weak TIM1_BRK_IRQHandler 312 | .thumb_set TIM1_BRK_IRQHandler,Default_Handler 313 | 314 | .weak TIM1_UP_IRQHandler 315 | .thumb_set TIM1_UP_IRQHandler,Default_Handler 316 | 317 | .weak TIM1_TRG_COM_IRQHandler 318 | .thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler 319 | 320 | .weak TIM1_CC_IRQHandler 321 | .thumb_set TIM1_CC_IRQHandler,Default_Handler 322 | 323 | .weak TIM2_IRQHandler 324 | .thumb_set TIM2_IRQHandler,Default_Handler 325 | 326 | .weak TIM3_IRQHandler 327 | .thumb_set TIM3_IRQHandler,Default_Handler 328 | 329 | .weak TIM4_IRQHandler 330 | .thumb_set TIM4_IRQHandler,Default_Handler 331 | 332 | .weak I2C1_EV_IRQHandler 333 | .thumb_set I2C1_EV_IRQHandler,Default_Handler 334 | 335 | .weak I2C1_ER_IRQHandler 336 | .thumb_set I2C1_ER_IRQHandler,Default_Handler 337 | 338 | .weak I2C2_EV_IRQHandler 339 | .thumb_set I2C2_EV_IRQHandler,Default_Handler 340 | 341 | .weak I2C2_ER_IRQHandler 342 | .thumb_set I2C2_ER_IRQHandler,Default_Handler 343 | 344 | .weak SPI1_IRQHandler 345 | .thumb_set SPI1_IRQHandler,Default_Handler 346 | 347 | .weak SPI2_IRQHandler 348 | .thumb_set SPI2_IRQHandler,Default_Handler 349 | 350 | .weak USART1_IRQHandler 351 | .thumb_set USART1_IRQHandler,Default_Handler 352 | 353 | .weak USART2_IRQHandler 354 | .thumb_set USART2_IRQHandler,Default_Handler 355 | 356 | .weak USART3_IRQHandler 357 | .thumb_set USART3_IRQHandler,Default_Handler 358 | 359 | .weak EXTI15_10_IRQHandler 360 | .thumb_set EXTI15_10_IRQHandler,Default_Handler 361 | 362 | .weak RTCAlarm_IRQHandler 363 | .thumb_set RTCAlarm_IRQHandler,Default_Handler 364 | 365 | .weak USBWakeUp_IRQHandler 366 | .thumb_set USBWakeUp_IRQHandler,Default_Handler 367 | 368 | -------------------------------------------------------------------------------- /STM32F1/stm32_lib/c_only_startup_user.s: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file startup_stm32f10x_md.s 4 | * @author MCD Application Team 5 | * @version V3.1.0 6 | * @date 06/19/2009 7 | * @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain. 8 | * This module performs: 9 | * - Set the initial SP 10 | * - Set the initial PC == Reset_Handler, 11 | * - Set the vector table entries with the exceptions ISR address 12 | * - Branches to main in the C library (which eventually 13 | * calls main()). 14 | * After Reset the Cortex-M3 processor is in Thread mode, 15 | * priority is Privileged, and the Stack is set to Main. 16 | ******************************************************************************* 17 | * @copy 18 | * 19 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 20 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 21 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 22 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 23 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 24 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 25 | * 26 | *

© COPYRIGHT 2009 STMicroelectronics

27 | */ 28 | 29 | .syntax unified 30 | .cpu cortex-m3 31 | .fpu softvfp 32 | .thumb 33 | 34 | .global g_pfnVectors 35 | .global SystemInit_ExtMemCtl_Dummy 36 | .global Default_Handler 37 | 38 | /* start address for the initialization values of the .data section. 39 | defined in linker script */ 40 | .word _sidata 41 | /* start address for the .data section. defined in linker script */ 42 | .word _sdata 43 | /* end address for the .data section. defined in linker script */ 44 | .word _edata 45 | /* start address for the .bss section. defined in linker script */ 46 | .word _sbss 47 | /* end address for the .bss section. defined in linker script */ 48 | .word _ebss 49 | .word _magicRate 50 | 51 | .equ BootRAM, 0xF108F85F 52 | /** 53 | * @brief This is the code that gets called when the processor first 54 | * starts execution following a reset event. Only the absolutely 55 | * necessary set is performed, after which the application 56 | * supplied main() routine is called. 57 | * @param None 58 | * @retval : None 59 | */ 60 | 61 | .section .text.Reset_Handler 62 | .weak Reset_Handler 63 | .type Reset_Handler, %function 64 | Reset_Handler: 65 | 66 | /* Copy the data segment initializers from flash to SRAM */ 67 | movs r1, #0 68 | b LoopCopyDataInit 69 | 70 | CopyDataInit: 71 | ldr r3, =_sidata 72 | ldr r3, [r3, r1] 73 | str r3, [r0, r1] 74 | adds r1, r1, #4 75 | 76 | LoopCopyDataInit: 77 | ldr r0, =_sdata 78 | ldr r3, =_edata 79 | adds r2, r0, r1 80 | cmp r2, r3 81 | bcc CopyDataInit 82 | ldr r2, =_sbss 83 | b LoopFillZerobss 84 | /* Zero fill the bss segment. */ 85 | FillZerobss: 86 | movs r3, #0 87 | str r3, [r2], #4 88 | 89 | LoopFillZerobss: 90 | ldr r3, = _ebss 91 | cmp r2, r3 92 | bcc FillZerobss 93 | /* Call the application's entry point.*/ 94 | bl main 95 | bx lr 96 | .size Reset_Handler, .-Reset_Handler 97 | 98 | /** 99 | * @brief This is the code that gets called when the processor receives an 100 | * unexpected interrupt. This simply enters an infinite loop, preserving 101 | * the system state for examination by a debugger. 102 | * 103 | * @param None 104 | * @retval : None 105 | */ 106 | .section .text.Default_Handler,"ax",%progbits 107 | Default_Handler: 108 | Infinite_Loop: 109 | b Infinite_Loop 110 | .size Default_Handler, .-Default_Handler 111 | /****************************************************************************** 112 | * 113 | * The minimal vector table for a Cortex M3. Note that the proper constructs 114 | * must be placed on this to ensure that it ends up at physical address 115 | * 0x0000.0000. 116 | * 117 | ******************************************************************************/ 118 | .section .isr_vector,"a",%progbits 119 | .type g_pfnVectors, %object 120 | .size g_pfnVectors, .-g_pfnVectors 121 | 122 | 123 | g_pfnVectors: 124 | .word _estack 125 | .word Reset_Handler 126 | .word _magicRate 127 | 128 | 129 | -------------------------------------------------------------------------------- /STM32F1/stm32_lib/cortexm3_macro.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : cortexm3_macro.h 3 | * Author : MCD Application Team 4 | * Version : V2.0.3 5 | * Date : 09/22/2008 6 | * Description : Header file for cortexm3_macro.s. 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Define to prevent recursive inclusion -------------------------------------*/ 17 | #ifndef __CORTEXM3_MACRO_H 18 | #define __CORTEXM3_MACRO_H 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "stm32f10x_type.h" 22 | 23 | /* Exported types ------------------------------------------------------------*/ 24 | /* Exported constants --------------------------------------------------------*/ 25 | /* Exported macro ------------------------------------------------------------*/ 26 | /* Exported functions ------------------------------------------------------- */ 27 | void __WFI(void); 28 | void __WFE(void); 29 | void __SEV(void); 30 | void __ISB(void); 31 | void __DSB(void); 32 | void __DMB(void); 33 | void __SVC(void); 34 | u32 __MRS_CONTROL(void); 35 | void __MSR_CONTROL(u32 Control); 36 | u32 __MRS_PSP(void); 37 | void __MSR_PSP(u32 TopOfProcessStack); 38 | u32 __MRS_MSP(void); 39 | void __MSR_MSP(u32 TopOfMainStack); 40 | void __RESETPRIMASK(void); 41 | void __SETPRIMASK(void); 42 | u32 __READ_PRIMASK(void); 43 | void __RESETFAULTMASK(void); 44 | void __SETFAULTMASK(void); 45 | u32 __READ_FAULTMASK(void); 46 | void __BASEPRICONFIG(u32 NewPriority); 47 | u32 __GetBASEPRI(void); 48 | u16 __REV_HalfWord(u16 Data); 49 | u32 __REV_Word(u32 Data); 50 | 51 | #endif /* __CORTEXM3_MACRO_H */ 52 | 53 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 54 | -------------------------------------------------------------------------------- /STM32F1/stm32_lib/cortexm3_macro.s: -------------------------------------------------------------------------------- 1 | # 1 "./stm32_lib/cortexm3_macro.S" 2 | # 1 "" 3 | # 1 "" 4 | # 1 "./stm32_lib/cortexm3_macro.S" 5 | # 16 "./stm32_lib/cortexm3_macro.S" 6 | .cpu cortex-m3 7 | .fpu softvfp 8 | .syntax unified 9 | .thumb 10 | .text 11 | 12 | 13 | .globl __WFI 14 | .globl __WFE 15 | .globl __SEV 16 | .globl __ISB 17 | .globl __DSB 18 | .globl __DMB 19 | .globl __SVC 20 | .globl __MRS_CONTROL 21 | .globl __MSR_CONTROL 22 | .globl __MRS_PSP 23 | .globl __MSR_PSP 24 | .globl __MRS_MSP 25 | .globl __MSR_MSP 26 | .globl __RESETPRIMASK 27 | .globl __SETPRIMASK 28 | .globl __READ_PRIMASK 29 | .globl __RESETFAULTMASK 30 | .globl __SETFAULTMASK 31 | .globl __READ_FAULTMASK 32 | .globl __BASEPRICONFIG 33 | .globl __GetBASEPRI 34 | .globl __REV_HalfWord 35 | .globl __REV_Word 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | .thumb_func 44 | __WFI: 45 | 46 | WFI 47 | BX r14 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | .thumb_func 56 | __WFE: 57 | 58 | WFE 59 | BX r14 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | .thumb_func 68 | __SEV: 69 | 70 | SEV 71 | BX r14 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | .thumb_func 80 | __ISB: 81 | 82 | ISB 83 | BX r14 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | .thumb_func 92 | __DSB: 93 | 94 | DSB 95 | BX r14 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | .thumb_func 104 | __DMB: 105 | 106 | DMB 107 | BX r14 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | .thumb_func 116 | __SVC: 117 | 118 | SVC 0x01 119 | BX r14 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | .thumb_func 128 | __MRS_CONTROL: 129 | 130 | MRS r0,control 131 | BX r14 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | .thumb_func 140 | __MSR_CONTROL: 141 | 142 | MSR control, r0 143 | ISB 144 | BX r14 145 | 146 | 147 | 148 | 149 | 150 | 151 | .thumb_func 152 | __MRS_PSP: 153 | 154 | MRS r0, psp 155 | BX r14 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | .thumb_func 164 | __MSR_PSP: 165 | 166 | MSR psp, r0 167 | BX r14 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | .thumb_func 176 | __MRS_MSP: 177 | 178 | MRS r0, msp 179 | BX r14 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | .thumb_func 188 | __MSR_MSP: 189 | 190 | MSR msp, r0 191 | BX r14 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | .thumb_func 200 | __RESETPRIMASK: 201 | 202 | CPSIE i 203 | BX r14 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | .thumb_func 212 | __SETPRIMASK: 213 | 214 | CPSID i 215 | BX r14 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | .thumb_func 224 | __READ_PRIMASK: 225 | 226 | MRS r0, PRIMASK 227 | BX r14 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | .thumb_func 236 | __RESETFAULTMASK: 237 | 238 | CPSIE f 239 | BX r14 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | .thumb_func 248 | __SETFAULTMASK: 249 | 250 | CPSID f 251 | BX r14 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | .thumb_func 260 | __READ_FAULTMASK: 261 | 262 | MRS r0, FAULTMASK 263 | BX r14 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | .thumb_func 272 | __BASEPRICONFIG: 273 | 274 | MSR basepri, r0 275 | BX r14 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | .thumb_func 284 | __GetBASEPRI: 285 | 286 | MRS r0, basepri_max 287 | BX r14 288 | 289 | 290 | 291 | 292 | 293 | 294 | .thumb_func 295 | __REV_HalfWord: 296 | 297 | REV16 r0, r0 298 | BX r14 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | .thumb_func 307 | __REV_Word: 308 | 309 | REV r0, r0 310 | BX r14 311 | 312 | .end 313 | -------------------------------------------------------------------------------- /STM32F1/stm32_lib/stm32f10x_type.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : stm32f10x_type.h 3 | * Author : MCD Application Team 4 | * Version : V2.0.3 5 | * Date : 09/22/2008 6 | * Description : This file contains all the common data types used for the 7 | * STM32F10x firmware library. 8 | ******************************************************************************** 9 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 10 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 11 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 12 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 13 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 14 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 15 | *******************************************************************************/ 16 | 17 | /* Define to prevent recursive inclusion -------------------------------------*/ 18 | #ifndef __STM32F10x_TYPE_H 19 | #define __STM32F10x_TYPE_H 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | /* Exported types ------------------------------------------------------------*/ 23 | typedef signed long s32; 24 | typedef signed short s16; 25 | typedef signed char s8; 26 | 27 | typedef signed long const sc32; /* Read Only */ 28 | typedef signed short const sc16; /* Read Only */ 29 | typedef signed char const sc8; /* Read Only */ 30 | 31 | typedef volatile signed long vs32; 32 | typedef volatile signed short vs16; 33 | typedef volatile signed char vs8; 34 | 35 | typedef volatile signed long const vsc32; /* Read Only */ 36 | typedef volatile signed short const vsc16; /* Read Only */ 37 | typedef volatile signed char const vsc8; /* Read Only */ 38 | 39 | typedef unsigned long u32; 40 | typedef unsigned short u16; 41 | typedef unsigned char u8; 42 | 43 | typedef unsigned long const uc32; /* Read Only */ 44 | typedef unsigned short const uc16; /* Read Only */ 45 | typedef unsigned char const uc8; /* Read Only */ 46 | 47 | typedef volatile unsigned long vu32; 48 | typedef volatile unsigned short vu16; 49 | typedef volatile unsigned char vu8; 50 | 51 | typedef volatile unsigned long const vuc32; /* Read Only */ 52 | typedef volatile unsigned short const vuc16; /* Read Only */ 53 | typedef volatile unsigned char const vuc8; /* Read Only */ 54 | 55 | typedef enum {FALSE = 0, TRUE = !FALSE} bool; 56 | 57 | typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; 58 | 59 | typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; 60 | #define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE)) 61 | 62 | typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; 63 | 64 | #define U8_MAX ((u8)255) 65 | #define S8_MAX ((s8)127) 66 | #define S8_MIN ((s8)-128) 67 | #define U16_MAX ((u16)65535u) 68 | #define S16_MAX ((s16)32767) 69 | #define S16_MIN ((s16)-32768) 70 | #define U32_MAX ((u32)4294967295uL) 71 | #define S32_MAX ((s32)2147483647) 72 | #define S32_MIN ((s32)-2147483648) 73 | 74 | /* Exported constants --------------------------------------------------------*/ 75 | /* Exported macro ------------------------------------------------------------*/ 76 | /* Exported functions ------------------------------------------------------- */ 77 | 78 | #endif /* __STM32F10x_TYPE_H */ 79 | 80 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 81 | -------------------------------------------------------------------------------- /STM32F1/usb.c: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | 25 | /** 26 | * @file usb.c 27 | * 28 | * @brief usb-specific hardware setup, NVIC, clocks, and usb activities 29 | * in the pre-attached state. includes some of the lower level callbacks 30 | * needed by the usb library, like suspend,resume,init,etc 31 | */ 32 | 33 | #include "usb.h" 34 | #include "dfu.h" 35 | 36 | 37 | extern u8 u8_usbConfigDescriptorDFU[]; 38 | extern u8 u8_usbFunctionalDescriptor[]; 39 | 40 | vu32 bDeviceState = UNCONNECTED; 41 | 42 | /* tracks sequential behavior of the ISTR */ 43 | vu16 wIstr; 44 | vu8 bIntPackSOF = 0; 45 | 46 | DEVICE Device_Table = { 47 | NUM_ENDPTS, 48 | 1 49 | }; 50 | 51 | DEVICE_PROP Device_Property = { 52 | usbInit, 53 | usbReset, 54 | usbStatusIn, 55 | usbStatusOut, 56 | usbDataSetup, 57 | usbNoDataSetup, 58 | usbGetInterfaceSetting, 59 | usbGetDeviceDescriptor, 60 | usbGetConfigDescriptor, 61 | usbGetStringDescriptor, 62 | usbGetFunctionalDescriptor, 63 | 0, 64 | bMaxPacketSize 65 | }; 66 | 67 | USER_STANDARD_REQUESTS User_Standard_Requests = { 68 | usbGetConfiguration, 69 | usbSetConfiguration, 70 | usbGetInterface, 71 | usbSetInterface, 72 | usbGetStatus, 73 | usbClearFeature, 74 | usbSetEndpointFeature, 75 | usbSetDeviceFeature, 76 | usbSetDeviceAddress 77 | }; 78 | 79 | void (*pEpInt_IN[7])(void) = { 80 | nothingProc, 81 | nothingProc, 82 | nothingProc, 83 | nothingProc, 84 | nothingProc, 85 | nothingProc, 86 | nothingProc, 87 | }; 88 | 89 | void (*pEpInt_OUT[7])(void) = { 90 | nothingProc, 91 | nothingProc, 92 | nothingProc, 93 | nothingProc, 94 | nothingProc, 95 | nothingProc, 96 | nothingProc, 97 | }; 98 | 99 | struct { 100 | volatile RESUME_STATE eState; 101 | volatile u8 bESOFcnt; 102 | } ResumeS; 103 | 104 | 105 | static RCC_TypeDef *RCC = (RCC_TypeDef *)RCC_BASE; 106 | 107 | 108 | void setupUSB (void) 109 | { 110 | #ifndef USB_DISC_HARDWIRED 111 | #ifdef HAS_MAPLE_HARDWARE 112 | // set up USB DISC pin as output open drain 113 | gpio_write_bit(USB_DISC_BANK, USB_DISC_PIN, 1); 114 | REG_SET(GPIO_CR(USB_DISC_BANK, USB_DISC_PIN), 115 | (REG_GET( 116 | GPIO_CR(USB_DISC_BANK,USB_DISC_PIN)) & crMask(USB_DISC_PIN)) 117 | | CR_OUTPUT_OD << CR_SHIFT(USB_DISC_PIN) 118 | ); 119 | #else 120 | #ifndef USB_DISC_HARDWIRED 121 | 122 | // Generic boards don't have disconnect hardware, so we drive PA12 (or defined pin) high. 123 | // this is connected to the usb D+ line. driving high will signal usb full speed to host 124 | #ifndef USB_DISC_BANK 125 | #define USB_DISC_BANK GPIOA 126 | #endif 127 | 128 | #ifndef USB_DISC_PIN 129 | #define USB_DISC_PIN 12 130 | #endif 131 | 132 | // set up pin in host disconnected state 133 | gpio_write_bit(USB_DISC_BANK, USB_DISC_PIN, 0); 134 | REG_SET(GPIO_CR(USB_DISC_BANK, USB_DISC_PIN), 135 | (REG_GET( 136 | GPIO_CR(USB_DISC_BANK, USB_DISC_PIN)) & crMask(USB_DISC_PIN)) 137 | | CR_OUTPUT_PP << CR_SHIFT(USB_DISC_PIN) 138 | ); 139 | 140 | // wait a while to make sure host disconnects us 141 | volatile u32 delay; 142 | for(delay = 256; delay; delay--); 143 | 144 | #endif 145 | #endif 146 | #endif 147 | 148 | // initialize the usb application 149 | wTransferSize = getFlashPageSize(); 150 | u8_usbConfigDescriptorDFU[41] = (wTransferSize & 0x00FF); 151 | u8_usbConfigDescriptorDFU[42] = (wTransferSize & 0xFF00) >> 8; 152 | 153 | u8_usbFunctionalDescriptor[5] = (wTransferSize & 0x00FF); 154 | u8_usbFunctionalDescriptor[6] = (wTransferSize & 0xFF00) >> 8; 155 | 156 | usbAppInit(); 157 | } 158 | 159 | 160 | void usbDsbBus(void) 161 | { 162 | usbPowerOff(); 163 | } 164 | 165 | 166 | /* dummy proc */ 167 | void nothingProc(void) 168 | { 169 | return; 170 | } 171 | 172 | /* application function definitions */ 173 | void usbAppInit(void) 174 | { 175 | // hook in to usb_core, depends on all those damn non encapsulated externs! 176 | USB_Init(); 177 | } 178 | 179 | void usbSuspend(void) 180 | { 181 | u16 wCNTR; 182 | wCNTR = _GetCNTR(); 183 | wCNTR |= CNTR_FSUSP | CNTR_LPMODE; 184 | _SetCNTR(wCNTR); 185 | 186 | // run any power reduction handlers 187 | bDeviceState = SUSPENDED; 188 | } 189 | 190 | void usbResumeInit(void) 191 | { 192 | u16 wCNTR; 193 | 194 | // restart any clocks that had been stopped 195 | wCNTR = _GetCNTR(); 196 | wCNTR &= (~CNTR_LPMODE); 197 | _SetCNTR(wCNTR); 198 | 199 | // undo power reduction handlers here 200 | _SetCNTR(ISR_MSK); 201 | } 202 | 203 | void usbResume(RESUME_STATE eResumeSetVal) 204 | { 205 | u16 wCNTR; 206 | 207 | if (eResumeSetVal != RESUME_ESOF) 208 | ResumeS.eState = eResumeSetVal; 209 | 210 | switch (ResumeS.eState) { 211 | case RESUME_EXTERNAL: 212 | usbResumeInit(); 213 | ResumeS.eState = RESUME_OFF; 214 | break; 215 | case RESUME_INTERNAL: 216 | usbResumeInit(); 217 | ResumeS.eState = RESUME_START; 218 | break; 219 | case RESUME_LATER: 220 | ResumeS.bESOFcnt = 2; 221 | ResumeS.eState = RESUME_WAIT; 222 | break; 223 | case RESUME_WAIT: 224 | ResumeS.bESOFcnt--; 225 | if (ResumeS.bESOFcnt == 0) 226 | ResumeS.eState = RESUME_START; 227 | break; 228 | case RESUME_START: 229 | wCNTR = _GetCNTR(); 230 | wCNTR |= CNTR_RESUME; 231 | _SetCNTR(wCNTR); 232 | ResumeS.eState = RESUME_ON; 233 | ResumeS.bESOFcnt = 10; 234 | break; 235 | case RESUME_ON: 236 | ResumeS.bESOFcnt--; 237 | if (ResumeS.bESOFcnt == 0) { 238 | wCNTR = _GetCNTR(); 239 | wCNTR &= (~CNTR_RESUME); 240 | _SetCNTR(wCNTR); 241 | ResumeS.eState = RESUME_OFF; 242 | } 243 | break; 244 | case RESUME_OFF: 245 | case RESUME_ESOF: 246 | default: 247 | ResumeS.eState = RESUME_OFF; 248 | break; 249 | } 250 | } 251 | 252 | RESULT usbPowerOn(void) 253 | { 254 | // Enable USB clock 255 | RCC->APB1ENR |= RCC_APB1ENR_USB_CLK; 256 | 257 | _SetCNTR(CNTR_FRES); 258 | _SetCNTR(0); 259 | _SetISTR(0); 260 | 261 | wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM; /* the bare minimum */ 262 | _SetCNTR(wInterrupt_Mask); 263 | 264 | // present to host 265 | #ifndef USB_DISC_HARDWIRED 266 | #ifdef HAS_MAPLE_HARDWARE 267 | gpio_write_bit(USB_DISC_BANK, USB_DISC_PIN, 0); 268 | #else 269 | gpio_write_bit(USB_DISC_BANK, USB_DISC_PIN, 1); 270 | #endif 271 | #endif 272 | 273 | return USB_SUCCESS; 274 | } 275 | 276 | RESULT usbPowerOff(void) { 277 | _SetCNTR(CNTR_FRES); 278 | _SetISTR(0); 279 | _SetCNTR(CNTR_FRES + CNTR_PDWN); 280 | 281 | /* note that all weve done here is powerdown the 282 | usb peripheral, set USB_DISC_PIN to signal 283 | disconnect, and stopped USB clocks. 284 | we have not reset the application state machines */ 285 | 286 | // act unplugged to host 287 | #ifndef USB_DISC_HARDWIRED 288 | #ifdef HAS_MAPLE_HARDWARE 289 | gpio_write_bit(USB_DISC_BANK, USB_DISC_PIN, 1); 290 | #else 291 | gpio_write_bit(USB_DISC_BANK, USB_DISC_PIN, 0); 292 | #endif 293 | #endif 294 | 295 | // Disable USB clock 296 | RCC->APB1ENR &= ~RCC_APB1ENR_USB_CLK; 297 | 298 | return USB_SUCCESS; 299 | } 300 | 301 | void usbInit(void) 302 | { 303 | dfuInit(); 304 | 305 | pInformation->Current_Configuration = 0; 306 | usbPowerOn(); 307 | 308 | _SetISTR(0); 309 | wInterrupt_Mask = ISR_MSK; 310 | _SetCNTR(wInterrupt_Mask); 311 | 312 | // configure the cortex M3 private peripheral NVIC 313 | usbEnbISR(); 314 | bDeviceState = UNCONNECTED; 315 | } 316 | 317 | void usbReset(void) 318 | { 319 | dfuUpdateByReset(); 320 | 321 | pInformation->Current_Configuration = 0; 322 | pInformation->Current_Feature = usbConfigDescriptorDFU.Descriptor[7]; 323 | 324 | _SetBTABLE(BTABLE_ADDRESS); 325 | 326 | // set up the ctrl endpoint 327 | _SetEPType(ENDP0, EP_CONTROL); 328 | _SetEPTxStatus(ENDP0, EP_TX_STALL); 329 | 330 | _SetEPRxAddr(ENDP0, ENDP0_RXADDR); 331 | _SetEPTxAddr(ENDP0, ENDP0_TXADDR); 332 | 333 | Clear_Status_Out(ENDP0); 334 | 335 | SetEPRxCount(ENDP0, pProperty->MaxPacketSize); 336 | // SetEPTxCount(ENDP0, pProperty->MaxPacketSize); 337 | SetEPRxValid(ENDP0); 338 | 339 | bDeviceState = ATTACHED; 340 | SetDeviceAddress(0); /* different than usbSetDeviceAddr! comes from usb_core */ 341 | } 342 | 343 | void usbStatusIn(void) 344 | { 345 | return; 346 | } 347 | 348 | void usbStatusOut(void) 349 | { 350 | return; 351 | } 352 | 353 | RESULT usbDataSetup(u8 request) { 354 | u8 *(*CopyRoutine)(u16); 355 | CopyRoutine = NULL; 356 | 357 | // handle dfu class requests 358 | if ((pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { 359 | if (dfuUpdateByRequest()) { 360 | // successfull state transition, handle the request 361 | switch (request) { 362 | case(DFU_GETSTATUS): 363 | CopyRoutine = dfuCopyStatus; 364 | break; 365 | case(DFU_GETSTATE): 366 | CopyRoutine = dfuCopyState; 367 | break; 368 | case(DFU_DNLOAD): 369 | CopyRoutine = dfuCopyDNLOAD; 370 | break; 371 | case(DFU_UPLOAD): 372 | CopyRoutine = dfuCopyUPLOAD; 373 | break; 374 | default: 375 | // leave copy routine null 376 | break; 377 | } 378 | } 379 | } 380 | 381 | if (CopyRoutine != NULL) { 382 | pInformation->Ctrl_Info.CopyData = CopyRoutine; 383 | pInformation->Ctrl_Info.Usb_wOffset = 0; 384 | (*CopyRoutine)(0); 385 | 386 | return USB_SUCCESS; 387 | } 388 | 389 | return USB_UNSUPPORT; 390 | } 391 | 392 | RESULT usbNoDataSetup(u8 request) 393 | { 394 | if ((pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) { 395 | // todo, keep track of the destination interface, often stored in wIndex 396 | if (dfuUpdateByRequest()) { 397 | return USB_SUCCESS; 398 | } 399 | } 400 | return USB_UNSUPPORT; 401 | } 402 | 403 | RESULT usbGetInterfaceSetting(u8 interface, u8 altSetting) 404 | { 405 | // alt setting 0 -> program RAM, alt setting 1 or higher -> FLASH 406 | if (interface > NUM_ALT_SETTINGS) { 407 | return USB_UNSUPPORT; 408 | } 409 | 410 | return USB_SUCCESS; 411 | } 412 | 413 | u8 *usbGetDeviceDescriptor(u16 len) 414 | { 415 | return Standard_GetDescriptorData(len, &usbDeviceDescriptorDFU); 416 | } 417 | 418 | u8 *usbGetConfigDescriptor(u16 len) 419 | { 420 | return Standard_GetDescriptorData(len, &usbConfigDescriptorDFU); 421 | } 422 | 423 | u8 *usbGetStringDescriptor(u16 len) 424 | { 425 | u8 strIndex = pInformation->USBwValue0; 426 | if (strIndex > STR_DESC_LEN) { 427 | return NULL; 428 | } else { 429 | return Standard_GetDescriptorData(len, &usbStringDescriptor[strIndex]); 430 | } 431 | } 432 | 433 | u8 *usbGetFunctionalDescriptor(u16 len) 434 | { 435 | return Standard_GetDescriptorData(len, &usbFunctionalDescriptor); 436 | } 437 | 438 | 439 | 440 | /***** start of USER STANDARD REQUESTS ****** 441 | * 442 | * These are the USER STANDARD REQUESTS, they are handled 443 | * in the core but we are given these callbacks at the 444 | * application level 445 | *******************************************/ 446 | 447 | void usbGetConfiguration(void) 448 | { 449 | /* nothing process */ 450 | } 451 | 452 | void usbSetConfiguration(void) 453 | { 454 | if (pInformation->Current_Configuration != 0) { 455 | bDeviceState = CONFIGURED; 456 | } 457 | } 458 | 459 | void usbGetInterface(void) 460 | { 461 | /* nothing process */ 462 | } 463 | 464 | void usbSetInterface(void) 465 | { 466 | /* nothing process */ 467 | } 468 | 469 | void usbGetStatus(void) 470 | { 471 | /* nothing process */ 472 | } 473 | 474 | void usbClearFeature(void) 475 | { 476 | /* nothing process */ 477 | } 478 | 479 | void usbSetEndpointFeature(void) 480 | { 481 | /* nothing process */ 482 | } 483 | 484 | void usbSetDeviceFeature(void) 485 | { 486 | /* nothing process */ 487 | } 488 | 489 | void usbSetDeviceAddress(void) 490 | { 491 | bDeviceState = ADDRESSED; 492 | } 493 | /***** end of USER STANDARD REQUESTS *****/ 494 | 495 | 496 | void usbEnbISR(void) 497 | { 498 | NVIC_InitTypeDef NVIC_InitStructure; 499 | 500 | NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; 501 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 502 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 503 | NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE; 504 | nvicInit(&NVIC_InitStructure); 505 | } 506 | 507 | void usbDsbISR(void) 508 | { 509 | NVIC_InitTypeDef NVIC_InitStructure; 510 | NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ; 511 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 512 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 513 | NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE; 514 | nvicInit(&NVIC_InitStructure); 515 | } 516 | 517 | void USB_LP_CAN1_RX0_IRQHandler(void) 518 | { 519 | wIstr = _GetISTR(); 520 | 521 | /* go nuts with the preproc switches since this is an ISTR and must be FAST */ 522 | /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ 523 | #if (ISR_MSK & ISTR_CTR) 524 | if (wIstr & ISTR_CTR & wInterrupt_Mask) { 525 | /* servicing of the endpoint correct transfer interrupt */ 526 | /* clear of the CTR flag into the sub */ 527 | CTR_LP(); /* low priority ISR defined in the usb core lib */ 528 | } 529 | #endif 530 | 531 | #if (ISR_MSK & ISTR_RESET) 532 | if (wIstr & ISTR_RESET & wInterrupt_Mask) { 533 | _SetISTR((u16)CLR_RESET); 534 | Device_Property.Reset(); 535 | } 536 | #endif 537 | 538 | 539 | #if (ISR_MSK & ISTR_DOVR) 540 | if (wIstr & ISTR_DOVR & wInterrupt_Mask) { 541 | _SetISTR((u16)CLR_DOVR); 542 | } 543 | #endif 544 | 545 | 546 | #if (ISR_MSK & ISTR_ERR) 547 | if (wIstr & ISTR_ERR & wInterrupt_Mask) { 548 | _SetISTR((u16)CLR_ERR); 549 | } 550 | #endif 551 | 552 | 553 | #if (ISR_MSK & ISTR_WKUP) 554 | if (wIstr & ISTR_WKUP & wInterrupt_Mask) { 555 | _SetISTR((u16)CLR_WKUP); 556 | usbResume(RESUME_EXTERNAL); 557 | } 558 | #endif 559 | 560 | /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/ 561 | #if (ISR_MSK & ISTR_SUSP) 562 | if (wIstr & ISTR_SUSP & wInterrupt_Mask) { 563 | 564 | // check if SUSPEND is possible 565 | if (F_SUSPEND_ENABLED) { 566 | usbSuspend(); 567 | } else { 568 | // if not possible then resume after xx ms 569 | usbResume(RESUME_LATER); 570 | } 571 | // clear of the ISTR bit must be done after setting of CNTR_FSUSP 572 | _SetISTR((u16)CLR_SUSP); 573 | } 574 | #endif 575 | 576 | 577 | #if (ISR_MSK & ISTR_SOF) 578 | if (wIstr & ISTR_SOF & wInterrupt_Mask) { 579 | _SetISTR((u16)CLR_SOF); 580 | bIntPackSOF++; 581 | } 582 | #endif 583 | 584 | 585 | #if (ISR_MSK & ISTR_ESOF) 586 | if (wIstr & ISTR_ESOF & wInterrupt_Mask) { 587 | _SetISTR((u16)CLR_ESOF); 588 | // resume handling timing is made with ESOFs 589 | // request without change of the machine state 590 | usbResume(RESUME_ESOF); 591 | } 592 | #endif 593 | 594 | } 595 | 596 | 597 | DEVICE_STATE usbGetState() 598 | { 599 | return bDeviceState; 600 | } 601 | -------------------------------------------------------------------------------- /STM32F1/usb.h: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | #ifndef __USB_H 25 | #define __USB_H 26 | 27 | #include "common.h" 28 | #include "usb_lib.h" 29 | #include "usb_descriptor.h" 30 | #include "config.h" 31 | 32 | 33 | /* USB configuration params */ 34 | #define BTABLE_ADDRESS 0x00 35 | #define ENDP0_RXADDR 0x40 36 | #define ENDP0_TXADDR 0x80 /* gives 64 bytes i/o buflen */ 37 | #define ENDP1_TXADDR 0xC0 38 | #define ENDP2_TXADDR 0x100 39 | #define ENDP3_RXADDR 0x110 40 | 41 | #define bMaxPacketSize 0x40 /* 64b, maximum for usb FS devices */ 42 | //#define wTransferSize FLASH_PAGE_SIZE /* This is important, because transfers have to match with the flash page size, otherwise it erases a page before its finished copying to that page */ 43 | #define dummyTransferSize 0x800 44 | int wTransferSize; 45 | 46 | #define NUM_ENDPTS 0x01 47 | 48 | /* do we gracefully implement usb suspend? */ 49 | #define F_SUSPEND_ENABLED 1 50 | 51 | /* defines which interrupts are handled */ 52 | #define ISR_MSK (ISTR_CTR | \ 53 | ISTR_WKUP | \ 54 | ISTR_SUSP | \ 55 | ISTR_ERR | \ 56 | ISTR_SOF | \ 57 | ISTR_ESOF | \ 58 | ISTR_RESET \ 59 | ) 60 | 61 | typedef enum _RESUME_STATE { 62 | RESUME_EXTERNAL, 63 | RESUME_INTERNAL, 64 | RESUME_LATER, 65 | RESUME_WAIT, 66 | RESUME_START, 67 | RESUME_ON, 68 | RESUME_OFF, 69 | RESUME_ESOF 70 | } RESUME_STATE; 71 | 72 | typedef enum _DEVICE_STATE { 73 | UNCONNECTED, 74 | ATTACHED, 75 | POWERED, 76 | SUSPENDED, 77 | ADDRESSED, 78 | CONFIGURED 79 | } DEVICE_STATE; 80 | 81 | void setupUSB(void); 82 | void usbDsbBus(void); 83 | void usbAppInit(void); /* singleton usb initializer */ 84 | 85 | void usbSuspend(void); 86 | void usbResumeInit(void); 87 | void usbResume(RESUME_STATE state); 88 | RESULT usbPowerOn(void); 89 | RESULT usbPowerOff(void); 90 | 91 | /* internal functions (as per the usb_core pProperty structure) */ 92 | void usbInit(void); 93 | void usbReset(void); 94 | void usbStatusIn(void); 95 | void usbStatusOut(void); 96 | 97 | DEVICE_STATE usbGetState(); 98 | 99 | RESULT usbDataSetup(u8 request); 100 | RESULT usbNoDataSetup(u8 request); 101 | RESULT usbGetInterfaceSetting(u8, u8); 102 | 103 | u8 *usbGetDeviceDescriptor(u16 length); 104 | u8 *usbGetConfigDescriptor(u16 length); 105 | u8 *usbGetStringDescriptor(u16 length); 106 | u8 *usbGetFunctionalDescriptor(u16 length); 107 | 108 | /* internal callbacks to respond to standard requests */ 109 | void usbGetConfiguration(void); 110 | void usbSetConfiguration(void); 111 | void usbGetInterface(void); 112 | void usbSetInterface(void); 113 | void usbGetStatus(void); 114 | void usbClearFeature(void); 115 | void usbSetEndpointFeature(void); 116 | void usbSetDeviceFeature(void); 117 | void usbSetDeviceAddress(void); 118 | 119 | /* the small number of comm emulator functions to 120 | eventually be migrated into their own usart sources 121 | */ 122 | u8 *vcomGetLineCoding(u16 length); 123 | u8 *vcomSetLineCoding(u16 length); 124 | void vcomEp1In(void); 125 | void vcomEp3Out(void); 126 | 127 | /* Interrupt setup/handling exposed only so that 128 | its obvious from main what interrupts are overloaded 129 | from c_only_startup.s (see the top of main.c) */ 130 | void usbDsbISR(void); 131 | void usbEnbISR(void); 132 | 133 | /* override the weakly defined isr in linker */ 134 | void USB_LP_CAN1_RX0_IRQHandler(void); 135 | 136 | 137 | void nothingProc(void); 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /STM32F1/usb_descriptor.c: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | 25 | 26 | /** 27 | * @file usb_descriptor.c 28 | * 29 | * @brief aka application descriptor; big static struct and callbacks for sending 30 | * the descriptor. 31 | * 32 | */ 33 | 34 | 35 | #include "usb_descriptor.h" 36 | 37 | u8 u8_usbDeviceDescriptorDFU[18] = { 38 | 18, /* bLength */ 39 | 0x01, /* bDescriptorType */ 40 | 0x00, /* bcdUSB, version 2.00 */ 41 | 0x02, 42 | 0x00, /* bDeviceClass : See interface */ 43 | 0x00, /* bDeviceSubClass : See interface*/ 44 | 0x00, /* bDeviceProtocol : See interface */ 45 | bMaxPacketSize, /* bMaxPacketSize0 0x40 = 64 */ 46 | VEND_ID1, /* idVendor (0110) */ 47 | VEND_ID0, 48 | PROD_ID1, /* idProduct (0x1001 or 1002) */ 49 | PROD_ID0, 50 | 0x00, /* bcdDevice*/ 51 | 0x01, 52 | 0x01, /* iManufacturer : index of string Manufacturer */ 53 | 0x02, /* iProduct : index of string descriptor of product*/ 54 | 0x03, /* iSerialNumber : index of string serial number*/ 55 | 0x01 /*bNumConfigurations */ 56 | }; 57 | 58 | ONE_DESCRIPTOR usbDeviceDescriptorDFU = { 59 | u8_usbDeviceDescriptorDFU, 60 | 18 61 | }; 62 | 63 | u8 u8_usbFunctionalDescriptor[9] = { 64 | /******************** DFU Functional Descriptor********************/ 65 | 9, /*blength = 9 Bytes*/ 66 | 0x21, /* DFU Functional Descriptor*/ 67 | 0x03, /*bmAttributes, bitCanDnload | bitCanUpload */ 68 | 0xFF, /*DetachTimeOut= 255 ms*/ 69 | 0x00, 70 | (dummyTransferSize & 0x00FF), 71 | (dummyTransferSize & 0xFF00) >> 8, /* TransferSize = 1024 Byte*/ 72 | 0x10, /* bcdDFUVersion = 1.1 */ 73 | 0x01 74 | }; 75 | 76 | ONE_DESCRIPTOR usbFunctionalDescriptor = { 77 | u8_usbFunctionalDescriptor, 78 | 9 79 | }; 80 | 81 | #define u8_usbConfigDescriptorDFU_LENGTH 45 82 | u8 u8_usbConfigDescriptorDFU[u8_usbConfigDescriptorDFU_LENGTH] = { 83 | 0x09, /* bLength: Configuation Descriptor size */ 84 | 0x02, /* bDescriptorType: Configuration */ 85 | u8_usbConfigDescriptorDFU_LENGTH, /* wTotalLength: Bytes returned */ 86 | 0x00, 87 | 0x01, /* bNumInterfaces: 1 interface */ 88 | 0x01, /* bConfigurationValue: */ 89 | 0x00, /* iConfiguration: */ 90 | 0x80, /* bmAttributes: */ 91 | 0x32, /* MaxPower 100 mA */ 92 | /* 09 */ 93 | 94 | /************ Descriptor of DFU interface 0 Alternate setting 0 *********/ 95 | 0x09, /* bLength: Interface Descriptor size */ 96 | 0x04, /* bDescriptorType: */ 97 | 0x00, /* bInterfaceNumber: Number of Interface */ 98 | 0x00, /* bAlternateSetting: Alternate setting */ 99 | 0x00, /* bNumEndpoints*/ 100 | 0xFE, /* bInterfaceClass: DFU */ 101 | 0x01, /* bInterfaceSubClass */ 102 | 0x02, /* nInterfaceProtocol, switched to 0x02 while in dfu_mode */ 103 | 0x04, /* iInterface: */ 104 | 105 | /************ Descriptor of DFU interface 0 Alternate setting 1 *********/ 106 | 0x09, /* bLength: Interface Descriptor size */ 107 | 0x04, /* bDescriptorType: */ 108 | 0x00, /* bInterfaceNumber: Number of Interface */ 109 | 0x01, /* bAlternateSetting: Alternate setting */ 110 | 0x00, /* bNumEndpoints*/ 111 | 0xFE, /* bInterfaceClass: DFU */ 112 | 0x01, /* bInterfaceSubClass */ 113 | 0x02, /* nInterfaceProtocol, switched to 0x02 while in dfu_mode */ 114 | 0x05, /* iInterface: */ 115 | 116 | /************ Descriptor of DFU interface 0 Alternate setting 2 *********/ 117 | 0x09, /* bLength: Interface Descriptor size */ 118 | 0x04, /* bDescriptorType: */ 119 | 0x00, /* bInterfaceNumber: Number of Interface */ 120 | 0x02, /* bAlternateSetting: Alternate setting */ 121 | 0x00, /* bNumEndpoints*/ 122 | 0xFE, /* bInterfaceClass: DFU */ 123 | 0x01, /* bInterfaceSubClass */ 124 | 0x02, /* nInterfaceProtocol, switched to 0x02 while in dfu_mode */ 125 | 0x06, /* iInterface: */ 126 | 127 | /******************** DFU Functional Descriptor********************/ 128 | 0x09, /*blength = 7 Bytes*/ 129 | 0x21, /* DFU Functional Descriptor*/ 130 | 0x03, /*bmAttributes, bitCanDnload | bitCanUpload */ 131 | 0xFF, /*DetachTimeOut= 255 ms*/ 132 | 0x00, 133 | (dummyTransferSize & 0x00FF), 134 | (dummyTransferSize & 0xFF00) >> 8, /* TransferSize = 1024 Byte*/ 135 | 0x10, /* bcdDFUVersion = 1.1 */ 136 | 0x01 137 | /***********************************************************/ 138 | /*45*/ 139 | }; 140 | 141 | ONE_DESCRIPTOR usbConfigDescriptorDFU = { 142 | u8_usbConfigDescriptorDFU, 143 | u8_usbConfigDescriptorDFU_LENGTH 144 | }; 145 | 146 | #define USB_STR_LANG_ID_LEN 4 147 | u8 u8_usbStringLangId[USB_STR_LANG_ID_LEN] = { 148 | USB_STR_LANG_ID_LEN, 149 | 0x03, 150 | 0x09, 151 | 0x04 /* LangID = 0x0409: U.S. English */ 152 | }; 153 | 154 | static const u8 u8_usbStringVendor[USB_VENDOR_STR_LEN] = { 155 | USB_VENDOR_STR_LEN, 156 | 0x03, 157 | USB_VENDOR_MSG_STR 158 | }; 159 | 160 | static const u8 u8_usbStringProduct[USB_PRODUCT_STR_LEN] = { 161 | USB_PRODUCT_STR_LEN, 162 | 0x03, 163 | USB_PRODUCT_MSG_STR 164 | }; 165 | 166 | static const u8 u8_usbStringSerial[USB_SERIAL_STR_LEN] = { 167 | USB_SERIAL_STR_LEN, 168 | 0x03, 169 | USB_SERIAL_MSG_STR 170 | }; 171 | 172 | static const u8 u8_usbStringAlt0[ALT0_STR_LEN] = { 173 | ALT0_STR_LEN, 174 | 0x03, 175 | ALT0_MSG_STR 176 | }; 177 | 178 | 179 | static const u8 u8_usbStringAlt1[ALT1_STR_LEN] = { 180 | ALT1_STR_LEN, 181 | 0x03, 182 | ALT1_MSG_STR 183 | }; 184 | 185 | 186 | static const u8 u8_usbStringAlt2[ALT2_STR_LEN] = { 187 | ALT2_STR_LEN, 188 | 0x03, 189 | ALT2_MSG_STR 190 | }; 191 | 192 | u8 u8_usbStringInterface = 0; 193 | 194 | ONE_DESCRIPTOR usbStringDescriptor[STR_DESC_LEN] = { 195 | { (u8 *)u8_usbStringLangId, USB_STR_LANG_ID_LEN }, 196 | { (u8 *)u8_usbStringVendor, USB_VENDOR_STR_LEN }, 197 | { (u8 *)u8_usbStringProduct, USB_PRODUCT_STR_LEN }, 198 | { (u8 *)u8_usbStringSerial, USB_SERIAL_STR_LEN }, 199 | { (u8 *)u8_usbStringAlt0, ALT0_STR_LEN }, 200 | { (u8 *)u8_usbStringAlt1, ALT1_STR_LEN }, 201 | { (u8 *)u8_usbStringAlt2, ALT2_STR_LEN } 202 | }; 203 | 204 | -------------------------------------------------------------------------------- /STM32F1/usb_descriptor.h: -------------------------------------------------------------------------------- 1 | /* ***************************************************************************** 2 | * The MIT License 3 | * 4 | * Copyright (c) 2010 LeafLabs LLC. 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | * ****************************************************************************/ 24 | 25 | #ifndef __MAPLE_USB_DESC_H 26 | #define __MAPLE_USB_DESC_H 27 | 28 | #include "common.h" 29 | #include "usb_lib.h" 30 | #include "usb.h" 31 | 32 | #define NUM_ALT_SETTINGS 3 33 | #define STR_DESC_LEN 7 34 | 35 | extern ONE_DESCRIPTOR usbDeviceDescriptorDFU; 36 | extern ONE_DESCRIPTOR usbConfigDescriptorDFU; 37 | extern ONE_DESCRIPTOR usbStringDescriptor[STR_DESC_LEN]; 38 | extern ONE_DESCRIPTOR usbFunctionalDescriptor; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_conf.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_conf.h 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Device Firmware Upgrade (DFU) configuration file 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Define to prevent recursive inclusion -------------------------------------*/ 17 | #ifndef __USB_CONF_H 18 | #define __USB_CONF_H 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | /* Exported types ------------------------------------------------------------*/ 22 | /* Exported constants --------------------------------------------------------*/ 23 | /* Exported macro ------------------------------------------------------------*/ 24 | /* Exported functions ------------------------------------------------------- */ 25 | /* External variables --------------------------------------------------------*/ 26 | /*-------------------------------------------------------------*/ 27 | /* EP_NUM */ 28 | /* defines how many endpoints are used by the device */ 29 | /*-------------------------------------------------------------*/ 30 | #define EP_NUM (1) 31 | 32 | /*-------------------------------------------------------------*/ 33 | /* -------------- Buffer Description Table -----------------*/ 34 | /*-------------------------------------------------------------*/ 35 | /* buffer table base address */ 36 | /* buffer table base address */ 37 | #define BTABLE_ADDRESS (0x00) 38 | 39 | /* EP0 */ 40 | /* rx/tx buffer base address */ 41 | #define ENDP0_RXADDR (0x10) 42 | #define ENDP0_TXADDR (0x50) 43 | 44 | 45 | /*-------------------------------------------------------------*/ 46 | /* ------------------- ISTR events -------------------------*/ 47 | /*-------------------------------------------------------------*/ 48 | /* IMR_MSK */ 49 | /* mask defining which events has to be handled */ 50 | /* by the device application software */ 51 | #define IMR_MSK (CNTR_CTRM | \ 52 | CNTR_WKUPM | \ 53 | CNTR_SUSPM | \ 54 | CNTR_ERRM | \ 55 | CNTR_SOFM | \ 56 | CNTR_ESOFM | \ 57 | CNTR_RESETM \ 58 | ) 59 | 60 | /* CTR service routines */ 61 | /* associated to defined endpoints */ 62 | #define EP1_IN_Callback NOP_Process 63 | #define EP2_IN_Callback NOP_Process 64 | #define EP3_IN_Callback NOP_Process 65 | #define EP4_IN_Callback NOP_Process 66 | #define EP5_IN_Callback NOP_Process 67 | #define EP6_IN_Callback NOP_Process 68 | #define EP7_IN_Callback NOP_Process 69 | 70 | 71 | #define EP1_OUT_Callback NOP_Process 72 | #define EP2_OUT_Callback NOP_Process 73 | #define EP3_OUT_Callback NOP_Process 74 | #define EP4_OUT_Callback NOP_Process 75 | #define EP5_OUT_Callback NOP_Process 76 | #define EP6_OUT_Callback NOP_Process 77 | #define EP7_OUT_Callback NOP_Process 78 | 79 | 80 | #endif /*__USB_CONF_H*/ 81 | 82 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_core.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_core.h 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Standard protocol processing functions prototypes 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Define to prevent recursive inclusion -------------------------------------*/ 17 | #ifndef __USB_CORE_H 18 | #define __USB_CORE_H 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | /* Exported types ------------------------------------------------------------*/ 22 | typedef enum _CONTROL_STATE { 23 | WAIT_SETUP, /* 0 */ 24 | SETTING_UP, /* 1 */ 25 | IN_DATA, /* 2 */ 26 | OUT_DATA, /* 3 */ 27 | LAST_IN_DATA, /* 4 */ 28 | LAST_OUT_DATA, /* 5 */ 29 | WAIT_STATUS_IN, /* 7 */ 30 | WAIT_STATUS_OUT, /* 8 */ 31 | STALLED, /* 9 */ 32 | PAUSE /* 10 */ 33 | } CONTROL_STATE; /* The state machine states of a control pipe */ 34 | 35 | typedef struct OneDescriptor { 36 | u8 *Descriptor; 37 | u16 Descriptor_Size; 38 | } ONE_DESCRIPTOR, *PONE_DESCRIPTOR; 39 | /* All the request process routines return a value of this type 40 | If the return value is not SUCCESS or NOT_READY, 41 | the software will STALL the correspond endpoint */ 42 | typedef enum _RESULT { 43 | USB_SUCCESS = 0, /* Process sucessfully */ 44 | USB_ERROR, 45 | USB_UNSUPPORT, 46 | USB_NOT_READY /* The process has not been finished, endpoint will be 47 | NAK to further rquest */ 48 | } RESULT; 49 | 50 | 51 | /*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/ 52 | typedef struct _ENDPOINT_INFO { 53 | /* When send data out of the device, 54 | CopyData() is used to get data buffer 'Length' bytes data 55 | if Length is 0, 56 | CopyData() returns the total length of the data 57 | if the request is not supported, returns 0 58 | (NEW Feature ) 59 | if CopyData() returns -1, the calling routine should not proceed 60 | further and will resume the SETUP process by the class device 61 | if Length is not 0, 62 | CopyData() returns a pointer to indicate the data location 63 | Usb_wLength is the data remain to be sent, 64 | Usb_wOffset is the Offset of original data 65 | When receive data from the host, 66 | CopyData() is used to get user data buffer which is capable 67 | of Length bytes data to copy data from the endpoint buffer. 68 | if Length is 0, 69 | CopyData() returns the available data length, 70 | if Length is not 0, 71 | CopyData() returns user buffer address 72 | Usb_rLength is the data remain to be received, 73 | Usb_rPointer is the Offset of data buffer 74 | */ 75 | u16 Usb_wLength; 76 | u16 Usb_wOffset; 77 | u16 PacketSize; 78 | u8 *(*CopyData)(u16 Length); 79 | } ENDPOINT_INFO; 80 | 81 | /*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/ 82 | 83 | typedef struct _DEVICE { 84 | u8 Total_Endpoint; /* Number of endpoints that are used */ 85 | u8 Total_Configuration;/* Number of configuration available */ 86 | } DEVICE; 87 | 88 | typedef union { 89 | u16 w; 90 | struct BW { 91 | /* Little Endian */ 92 | u8 bb0; 93 | u8 bb1; 94 | } bw; 95 | } u16_u8; 96 | 97 | typedef struct _DEVICE_INFO { 98 | u8 USBbmRequestType; /* bmRequestType */ 99 | u8 USBbRequest; /* bRequest */ 100 | u16_u8 USBwValues; /* wValue */ 101 | u16_u8 USBwIndexs; /* wIndex */ 102 | u16_u8 USBwLengths; /* wLength */ 103 | 104 | u8 ControlState; /* of type CONTROL_STATE */ 105 | u8 Current_Feature; 106 | u8 Current_Configuration; /* Selected configuration */ 107 | u8 Current_Interface; /* Selected interface of current configuration */ 108 | u8 Current_AlternateSetting;/* Selected Alternate Setting of current 109 | interface*/ 110 | 111 | ENDPOINT_INFO Ctrl_Info; 112 | } DEVICE_INFO; 113 | 114 | typedef struct _DEVICE_PROP { 115 | void (*Init)(void); /* Initialize the device */ 116 | void (*Reset)(void); /* Reset routine of this device */ 117 | 118 | /* Device dependent process after the status stage */ 119 | void (*Process_Status_IN)(void); 120 | void (*Process_Status_OUT)(void); 121 | 122 | /* Procedure of process on setup stage of a class specified request with data stage */ 123 | /* All class specified requests with data stage are processed in Class_Data_Setup 124 | Class_Data_Setup() 125 | responses to check all special requests and fills ENDPOINT_INFO 126 | according to the request 127 | If IN tokens are expected, then wLength & wOffset will be filled 128 | with the total transferring bytes and the starting position 129 | If OUT tokens are expected, then rLength & rOffset will be filled 130 | with the total expected bytes and the starting position in the buffer 131 | 132 | If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT 133 | 134 | CAUTION: 135 | Since GET_CONFIGURATION & GET_INTERFACE are highly related to 136 | the individual classes, they will be checked and processed here. 137 | */ 138 | RESULT (*Class_Data_Setup)(u8 RequestNo); 139 | 140 | /* Procedure of process on setup stage of a class specified request without data stage */ 141 | /* All class specified requests without data stage are processed in Class_NoData_Setup 142 | Class_NoData_Setup 143 | responses to check all special requests and perform the request 144 | 145 | CAUTION: 146 | Since SET_CONFIGURATION & SET_INTERFACE are highly related to 147 | the individual classes, they will be checked and processed here. 148 | */ 149 | RESULT (*Class_NoData_Setup)(u8 RequestNo); 150 | 151 | /*Class_Get_Interface_Setting 152 | This function is used by the file usb_core.c to test if the selected Interface 153 | and Alternate Setting (u8 Interface, u8 AlternateSetting) are supported by 154 | the application. 155 | This function is writing by user. It should return "SUCCESS" if the Interface 156 | and Alternate Setting are supported by the application or "UNSUPPORT" if they 157 | are not supported. */ 158 | 159 | RESULT (*Class_Get_Interface_Setting)(u8 Interface, u8 AlternateSetting); 160 | 161 | u8* (*GetDeviceDescriptor)(u16 Length); 162 | u8* (*GetConfigDescriptor)(u16 Length); 163 | u8* (*GetStringDescriptor)(u16 Length); 164 | u8* (*GetFunctionalDescriptor)(u16 Length); 165 | 166 | u8* RxEP_buffer; 167 | u8 MaxPacketSize; 168 | 169 | } DEVICE_PROP; 170 | 171 | typedef struct _USER_STANDARD_REQUESTS { 172 | void (*User_GetConfiguration)(void); /* Get Configuration */ 173 | void (*User_SetConfiguration)(void); /* Set Configuration */ 174 | void (*User_GetInterface)(void); /* Get Interface */ 175 | void (*User_SetInterface)(void); /* Set Interface */ 176 | void (*User_GetStatus)(void); /* Get Status */ 177 | void (*User_ClearFeature)(void); /* Clear Feature */ 178 | void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */ 179 | void (*User_SetDeviceFeature)(void); /* Set Device Feature */ 180 | void (*User_SetDeviceAddress)(void); /* Set Device Address */ 181 | } USER_STANDARD_REQUESTS; 182 | 183 | /* Exported constants --------------------------------------------------------*/ 184 | #define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) 185 | 186 | #define Usb_rLength Usb_wLength 187 | #define Usb_rOffset Usb_wOffset 188 | 189 | #define USBwValue USBwValues.w 190 | #define USBwValue0 USBwValues.bw.bb0 191 | #define USBwValue1 USBwValues.bw.bb1 192 | #define USBwIndex USBwIndexs.w 193 | #define USBwIndex0 USBwIndexs.bw.bb0 194 | #define USBwIndex1 USBwIndexs.bw.bb1 195 | #define USBwLength USBwLengths.w 196 | #define USBwLength0 USBwLengths.bw.bb0 197 | #define USBwLength1 USBwLengths.bw.bb1 198 | #define StatusInfo0 StatusInfo.bw.bb0 199 | #define StatusInfo1 StatusInfo.bw.bb1 200 | 201 | /* Exported macro ------------------------------------------------------------*/ 202 | /* Exported functions ------------------------------------------------------- */ 203 | u8 Setup0_Process(void); 204 | u8 Post0_Process(void); 205 | u8 Out0_Process(void); 206 | u8 In0_Process(void); 207 | 208 | RESULT Standard_SetEndPointFeature(void); 209 | RESULT Standard_SetDeviceFeature(void); 210 | 211 | u8 *Standard_GetConfiguration(u16 Length); 212 | RESULT Standard_SetConfiguration(void); 213 | u8 *Standard_GetInterface(u16 Length); 214 | RESULT Standard_SetInterface(void); 215 | u8 *Standard_GetDescriptorData(u16 Length, PONE_DESCRIPTOR pDesc); 216 | 217 | u8 *Standard_GetStatus(u16 Length); 218 | RESULT Standard_ClearFeature(void); 219 | void SetDeviceAddress(u8); 220 | void NOP_Process(void); 221 | 222 | extern DEVICE_PROP Device_Property; 223 | extern USER_STANDARD_REQUESTS User_Standard_Requests; 224 | extern DEVICE Device_Table; 225 | extern DEVICE_INFO Device_Info; 226 | 227 | /* cells saving status during interrupt servicing */ 228 | extern u16 SaveRState; 229 | extern u16 SaveTState; 230 | 231 | #endif /* __USB_CORE_H */ 232 | 233 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 234 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_def.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_def.h 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Definitions related to USB Core 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Define to prevent recursive inclusion -------------------------------------*/ 17 | #ifndef __USB_DEF_H 18 | #define __USB_DEF_H 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | /* Exported types ------------------------------------------------------------*/ 22 | typedef enum _RECIPIENT_TYPE { 23 | DEVICE_RECIPIENT, /* Recipient device */ 24 | INTERFACE_RECIPIENT, /* Recipient interface */ 25 | ENDPOINT_RECIPIENT, /* Recipient endpoint */ 26 | OTHER_RECIPIENT 27 | } RECIPIENT_TYPE; 28 | 29 | 30 | typedef enum _STANDARD_REQUESTS { 31 | GET_STATUS = 0, 32 | CLEAR_FEATURE, 33 | RESERVED1, 34 | SET_FEATURE, 35 | RESERVED2, 36 | SET_ADDRESS, 37 | GET_DESCRIPTOR, 38 | SET_DESCRIPTOR, 39 | GET_CONFIGURATION, 40 | SET_CONFIGURATION, 41 | GET_INTERFACE, 42 | SET_INTERFACE, 43 | TOTAL_sREQUEST, /* Total number of Standard request */ 44 | SYNCH_FRAME = 12 45 | } STANDARD_REQUESTS; 46 | 47 | /* Definition of "USBwValue" */ 48 | typedef enum _DESCRIPTOR_TYPE { 49 | DEVICE_DESCRIPTOR = 1, 50 | CONFIG_DESCRIPTOR, 51 | STRING_DESCRIPTOR, 52 | INTERFACE_DESCRIPTOR, 53 | ENDPOINT_DESCRIPTOR 54 | } DESCRIPTOR_TYPE; 55 | 56 | /* Feature selector of a SET_FEATURE or CLEAR_FEATURE */ 57 | typedef enum _FEATURE_SELECTOR { 58 | ENDPOINT_STALL, 59 | DEVICE_REMOTE_WAKEUP 60 | } FEATURE_SELECTOR; 61 | 62 | /* Exported constants --------------------------------------------------------*/ 63 | /* Definition of "USBbmRequestType" */ 64 | #define REQUEST_TYPE 0x60 /* Mask to get request type */ 65 | #define STANDARD_REQUEST 0x00 /* Standard request */ 66 | #define CLASS_REQUEST 0x20 /* Class request */ 67 | #define VENDOR_REQUEST 0x40 /* Vendor request */ 68 | 69 | #define RECIPIENT 0x1F /* Mask to get recipient */ 70 | 71 | /* Exported macro ------------------------------------------------------------*/ 72 | /* Exported functions ------------------------------------------------------- */ 73 | 74 | #endif /* __USB_DEF_H */ 75 | 76 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 77 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_init.c: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_init.c 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Initialization routines & global variables 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Includes ------------------------------------------------------------------*/ 17 | #include "usb_lib.h" 18 | 19 | /* Private typedef -----------------------------------------------------------*/ 20 | /* Private define ------------------------------------------------------------*/ 21 | /* Private macro -------------------------------------------------------------*/ 22 | /* Private variables ---------------------------------------------------------*/ 23 | /* The number of current endpoint, it will be used to specify an endpoint */ 24 | u8 EPindex; 25 | /* The number of current device, it is an index to the Device_Table */ 26 | /* u8 Device_no; */ 27 | /* Points to the DEVICE_INFO structure of current device */ 28 | /* The purpose of this register is to speed up the execution */ 29 | DEVICE_INFO *pInformation; 30 | /* Points to the DEVICE_PROP structure of current device */ 31 | /* The purpose of this register is to speed up the execution */ 32 | DEVICE_PROP *pProperty; 33 | /* Temporary save the state of Rx & Tx status. */ 34 | /* Whenever the Rx or Tx state is changed, its value is saved */ 35 | /* in this variable first and will be set to the EPRB or EPRA */ 36 | /* at the end of interrupt process */ 37 | u16 SaveState ; 38 | volatile u16 wInterrupt_Mask; 39 | DEVICE_INFO Device_Info; 40 | USER_STANDARD_REQUESTS *pUser_Standard_Requests; 41 | 42 | /* Extern variables ----------------------------------------------------------*/ 43 | /* Private function prototypes -----------------------------------------------*/ 44 | /* Private functions ---------------------------------------------------------*/ 45 | 46 | /******************************************************************************* 47 | * Function Name : USB_Init 48 | * Description : USB system initialization 49 | * Input : None. 50 | * Output : None. 51 | * Return : None. 52 | *******************************************************************************/ 53 | void USB_Init(void) 54 | { 55 | pInformation = &Device_Info; 56 | pInformation->ControlState = 2; 57 | pProperty = &Device_Property; 58 | pUser_Standard_Requests = &User_Standard_Requests; 59 | /* Initialize devices one by one */ 60 | 61 | pProperty->Init(); 62 | } 63 | 64 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 65 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_init.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_init.h 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Initialization routines & global variables 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Define to prevent recursive inclusion -------------------------------------*/ 17 | #ifndef __USB_INIT_H 18 | #define __USB_INIT_H 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | /* Exported types ------------------------------------------------------------*/ 22 | /* Exported constants --------------------------------------------------------*/ 23 | /* Exported macro ------------------------------------------------------------*/ 24 | /* Exported functions ------------------------------------------------------- */ 25 | void USB_Init(void); 26 | 27 | /* External variables --------------------------------------------------------*/ 28 | /* The number of current endpoint, it will be used to specify an endpoint */ 29 | extern u8 EPindex; 30 | /* The number of current device, it is an index to the Device_Table */ 31 | /*extern u8 Device_no; */ 32 | /* Points to the DEVICE_INFO structure of current device */ 33 | /* The purpose of this register is to speed up the execution */ 34 | extern DEVICE_INFO *pInformation; 35 | /* Points to the DEVICE_PROP structure of current device */ 36 | /* The purpose of this register is to speed up the execution */ 37 | extern DEVICE_PROP *pProperty; 38 | /* Temporary save the state of Rx & Tx status. */ 39 | /* Whenever the Rx or Tx state is changed, its value is saved */ 40 | /* in this variable first and will be set to the EPRB or EPRA */ 41 | /* at the end of interrupt process */ 42 | extern USER_STANDARD_REQUESTS *pUser_Standard_Requests; 43 | 44 | extern u16 SaveState ; 45 | extern volatile u16 wInterrupt_Mask; 46 | 47 | #endif /* __USB_INIT_H */ 48 | 49 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 50 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_int.c: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_int.c 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Endpoint CTR (Low and High) interrupt's service routines 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Includes ------------------------------------------------------------------*/ 17 | #include "usb_lib.h" 18 | 19 | /* Private typedef -----------------------------------------------------------*/ 20 | /* Private define ------------------------------------------------------------*/ 21 | /* Private macro -------------------------------------------------------------*/ 22 | /* Private variables ---------------------------------------------------------*/ 23 | u16 SaveRState; 24 | u16 SaveTState; 25 | 26 | /* Extern variables ----------------------------------------------------------*/ 27 | extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */ 28 | extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */ 29 | 30 | /* Private function prototypes -----------------------------------------------*/ 31 | /* Private functions ---------------------------------------------------------*/ 32 | 33 | /******************************************************************************* 34 | * Function Name : CTR_LP. 35 | * Description : Low priority Endpoint Correct Transfer interrupt's service 36 | * routine. 37 | * Input : None. 38 | * Output : None. 39 | * Return : None. 40 | *******************************************************************************/ 41 | void CTR_LP(void) 42 | { 43 | u32 wEPVal = 0; 44 | /* stay in loop while pending ints */ 45 | while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) { 46 | _SetISTR((u16)CLR_CTR); /* clear CTR flag */ 47 | /* extract highest priority endpoint number */ 48 | EPindex = (u8)(wIstr & ISTR_EP_ID); 49 | if (EPindex == 0) { 50 | /* Decode and service control endpoint interrupt */ 51 | /* calling related service routine */ 52 | /* (Setup0_Process, In0_Process, Out0_Process) */ 53 | 54 | /* save RX & TX status */ 55 | /* and set both to NAK */ 56 | SaveRState = _GetEPRxStatus(ENDP0); 57 | SaveTState = _GetEPTxStatus(ENDP0); 58 | _SetEPRxStatus(ENDP0, EP_RX_NAK); 59 | _SetEPTxStatus(ENDP0, EP_TX_NAK); 60 | 61 | 62 | /* DIR bit = origin of the interrupt */ 63 | 64 | if ((wIstr & ISTR_DIR) == 0) { 65 | /* DIR = 0 */ 66 | 67 | /* DIR = 0 => IN int */ 68 | /* DIR = 0 implies that (EP_CTR_TX = 1) always */ 69 | 70 | 71 | _ClearEP_CTR_TX(ENDP0); 72 | In0_Process(); 73 | 74 | /* before terminate set Tx & Rx status */ 75 | _SetEPRxStatus(ENDP0, SaveRState); 76 | _SetEPTxStatus(ENDP0, SaveTState); 77 | return; 78 | } else { 79 | /* DIR = 1 */ 80 | 81 | /* DIR = 1 & CTR_RX => SETUP or OUT int */ 82 | /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ 83 | 84 | wEPVal = _GetENDPOINT(ENDP0); 85 | if ((wEPVal & EP_CTR_TX) != 0) { 86 | _ClearEP_CTR_TX(ENDP0); 87 | In0_Process(); 88 | /* before terminate set Tx & Rx status */ 89 | _SetEPRxStatus(ENDP0, SaveRState); 90 | _SetEPTxStatus(ENDP0, SaveTState); 91 | return; 92 | } else if ((wEPVal &EP_SETUP) != 0) { 93 | _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */ 94 | Setup0_Process(); 95 | /* before terminate set Tx & Rx status */ 96 | _SetEPRxStatus(ENDP0, SaveRState); 97 | _SetEPTxStatus(ENDP0, SaveTState); 98 | return; 99 | } 100 | 101 | else if ((wEPVal & EP_CTR_RX) != 0) { 102 | _ClearEP_CTR_RX(ENDP0); 103 | Out0_Process(); 104 | /* before terminate set Tx & Rx status */ 105 | _SetEPRxStatus(ENDP0, SaveRState); 106 | _SetEPTxStatus(ENDP0, SaveTState); 107 | return; 108 | } 109 | } 110 | }/* if(EPindex == 0) */ 111 | else { 112 | /* Decode and service non control endpoints interrupt */ 113 | 114 | /* process related endpoint register */ 115 | wEPVal = _GetENDPOINT(EPindex); 116 | if ((wEPVal & EP_CTR_RX) != 0) { 117 | /* clear int flag */ 118 | _ClearEP_CTR_RX(EPindex); 119 | 120 | /* call OUT service function */ 121 | (*pEpInt_OUT[EPindex-1])(); 122 | 123 | } /* if((wEPVal & EP_CTR_RX) */ 124 | 125 | if ((wEPVal & EP_CTR_TX) != 0) { 126 | /* clear int flag */ 127 | _ClearEP_CTR_TX(EPindex); 128 | 129 | /* call IN service function */ 130 | (*pEpInt_IN[EPindex-1])(); 131 | } /* if((wEPVal & EP_CTR_TX) != 0) */ 132 | 133 | }/* if(EPindex == 0) else */ 134 | 135 | }/* while(...) */ 136 | } 137 | 138 | /******************************************************************************* 139 | * Function Name : CTR_HP. 140 | * Description : High Priority Endpoint Correct Transfer interrupt's service 141 | * routine. 142 | * Input : None. 143 | * Output : None. 144 | * Return : None. 145 | *******************************************************************************/ 146 | void CTR_HP(void) 147 | { 148 | u32 wEPVal = 0; 149 | 150 | while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) { 151 | _SetISTR((u16)CLR_CTR); /* clear CTR flag */ 152 | /* extract highest priority endpoint number */ 153 | EPindex = (u8)(wIstr & ISTR_EP_ID); 154 | /* process related endpoint register */ 155 | wEPVal = _GetENDPOINT(EPindex); 156 | if ((wEPVal & EP_CTR_RX) != 0) { 157 | /* clear int flag */ 158 | _ClearEP_CTR_RX(EPindex); 159 | 160 | /* call OUT service function */ 161 | (*pEpInt_OUT[EPindex-1])(); 162 | 163 | } /* if((wEPVal & EP_CTR_RX) */ 164 | else if ((wEPVal & EP_CTR_TX) != 0) { 165 | /* clear int flag */ 166 | _ClearEP_CTR_TX(EPindex); 167 | 168 | /* call IN service function */ 169 | (*pEpInt_IN[EPindex-1])(); 170 | 171 | 172 | } /* if((wEPVal & EP_CTR_TX) != 0) */ 173 | 174 | }/* while(...) */ 175 | } 176 | 177 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 178 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_int.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_int.h 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Endpoint CTR (Low and High) interrupt's service routines 7 | * prototypes 8 | ******************************************************************************** 9 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 10 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 11 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 12 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 13 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 14 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 15 | *******************************************************************************/ 16 | 17 | /* Define to prevent recursive inclusion -------------------------------------*/ 18 | #ifndef __USB_INT_H 19 | #define __USB_INT_H 20 | 21 | /* Includes ------------------------------------------------------------------*/ 22 | /* Exported types ------------------------------------------------------------*/ 23 | /* Exported constants --------------------------------------------------------*/ 24 | /* Exported macro ------------------------------------------------------------*/ 25 | /* Exported functions ------------------------------------------------------- */ 26 | void CTR_LP(void); 27 | void CTR_HP(void); 28 | 29 | /* External variables --------------------------------------------------------*/ 30 | 31 | #endif /* __USB_INT_H */ 32 | 33 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 34 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_lib.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_lib.h 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : USB library include files 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Define to prevent recursive inclusion -------------------------------------*/ 17 | #ifndef __USB_LIB_H 18 | #define __USB_LIB_H 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "usb_type.h" 22 | #include "usb_regs.h" 23 | #include "usb_def.h" 24 | #include "usb_core.h" 25 | #include "usb_init.h" 26 | #include "usb_mem.h" 27 | #include "usb_int.h" 28 | 29 | /* Exported types ------------------------------------------------------------*/ 30 | /* Exported constants --------------------------------------------------------*/ 31 | /* Exported macro ------------------------------------------------------------*/ 32 | /* Exported functions ------------------------------------------------------- */ 33 | /* External variables --------------------------------------------------------*/ 34 | 35 | #endif /* __USB_LIB_H */ 36 | 37 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 38 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_mem.c: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_mem.c 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Utility functions for memory transfers to/from PMA 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Includes ------------------------------------------------------------------*/ 17 | #include "usb_lib.h" 18 | 19 | /* Private typedef -----------------------------------------------------------*/ 20 | /* Private define ------------------------------------------------------------*/ 21 | /* Private macro -------------------------------------------------------------*/ 22 | /* Private variables ---------------------------------------------------------*/ 23 | /* Extern variables ----------------------------------------------------------*/ 24 | /* Private function prototypes -----------------------------------------------*/ 25 | /* Private functions ---------------------------------------------------------*/ 26 | /******************************************************************************* 27 | * Function Name : UserToPMABufferCopy 28 | * Description : Copy a buffer from user memory area to packet memory area (PMA) 29 | * Input : - pbUsrBuf: pointer to user memory area. 30 | * - wPMABufAddr: address into PMA. 31 | * - wNBytes: no. of bytes to be copied. 32 | * Output : None. 33 | * Return : None . 34 | *******************************************************************************/ 35 | void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) 36 | { 37 | u32 n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */ 38 | u32 i, temp1, temp2; 39 | u16 *pdwVal; 40 | pdwVal = (u16 *)(wPMABufAddr * 2 + PMAAddr); 41 | for (i = n; i != 0; i--) { 42 | temp1 = (u16) * pbUsrBuf; 43 | pbUsrBuf++; 44 | temp2 = temp1 | (u16) * pbUsrBuf << 8; 45 | *pdwVal++ = temp2; 46 | pdwVal++; 47 | pbUsrBuf++; 48 | } 49 | } 50 | /******************************************************************************* 51 | * Function Name : PMAToUserBufferCopy 52 | * Description : Copy a buffer from user memory area to packet memory area (PMA) 53 | * Input : - pbUsrBuf = pointer to user memory area. 54 | * - wPMABufAddr = address into PMA. 55 | * - wNBytes = no. of bytes to be copied. 56 | * Output : None. 57 | * Return : None. 58 | *******************************************************************************/ 59 | void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes) 60 | { 61 | u32 n = (wNBytes + 1) >> 1;/* /2*/ 62 | u32 i; 63 | u32 *pdwVal; 64 | pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr); 65 | for (i = n; i != 0; i--) { 66 | *(u16*)pbUsrBuf++ = *pdwVal++; 67 | pbUsrBuf++; 68 | } 69 | } 70 | 71 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 72 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_mem.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_mem.h 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Utility prototypes functions for memory/PMA transfers 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Define to prevent recursive inclusion -------------------------------------*/ 17 | #ifndef __USB_MEM_H 18 | #define __USB_MEM_H 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | /* Exported types ------------------------------------------------------------*/ 22 | /* Exported constants --------------------------------------------------------*/ 23 | /* Exported macro ------------------------------------------------------------*/ 24 | /* Exported functions ------------------------------------------------------- */ 25 | void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); 26 | void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes); 27 | 28 | /* External variables --------------------------------------------------------*/ 29 | 30 | #endif /*__USB_MEM_H*/ 31 | 32 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 33 | -------------------------------------------------------------------------------- /STM32F1/usb_lib/usb_type.h: -------------------------------------------------------------------------------- 1 | /******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** 2 | * File Name : usb_type.h 3 | * Author : MCD Application Team 4 | * Version : V2.2.1 5 | * Date : 09/22/2008 6 | * Description : Type definitions used by the USB Library 7 | ******************************************************************************** 8 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 9 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. 10 | * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, 11 | * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE 12 | * CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING 13 | * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 14 | *******************************************************************************/ 15 | 16 | /* Define to prevent recursive inclusion -------------------------------------*/ 17 | #ifndef __USB_TYPE_H 18 | #define __USB_TYPE_H 19 | 20 | /* Exported types ------------------------------------------------------------*/ 21 | /* Exported constants --------------------------------------------------------*/ 22 | #ifndef NULL 23 | #define NULL ((void *)0) 24 | #endif 25 | 26 | #ifndef __STM32F10x_TYPE_H 27 | 28 | typedef signed long s32; 29 | typedef signed short s16; 30 | typedef signed char s8; 31 | 32 | typedef volatile signed long vs32; 33 | typedef volatile signed short vs16; 34 | typedef volatile signed char vs8; 35 | 36 | typedef unsigned long u32; 37 | typedef unsigned short u16; 38 | typedef unsigned char u8; 39 | 40 | typedef unsigned long const uc32; /* Read Only */ 41 | typedef unsigned short const uc16; /* Read Only */ 42 | typedef unsigned char const uc8; /* Read Only */ 43 | 44 | typedef volatile unsigned long vu32; 45 | typedef volatile unsigned short vu16; 46 | typedef volatile unsigned char vu8; 47 | 48 | typedef volatile unsigned long const vuc32; /* Read Only */ 49 | typedef volatile unsigned short const vuc16; /* Read Only */ 50 | typedef volatile unsigned char const vuc8; /* Read Only */ 51 | 52 | 53 | typedef enum { 54 | FALSE = 0, TRUE = !FALSE 55 | } 56 | bool; 57 | 58 | typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus; 59 | 60 | typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState; 61 | 62 | typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus; 63 | #endif 64 | 65 | /* Exported macro ------------------------------------------------------------*/ 66 | /* Exported functions ------------------------------------------------------- */ 67 | /* External variables --------------------------------------------------------*/ 68 | 69 | #endif /* __USB_TYPE_H */ 70 | 71 | /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/ 72 | -------------------------------------------------------------------------------- /STM32F1/util/dfu-util.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trueserve/stm32f103-bootloader/98347bf7b9bf6f9e9ee43547a50e668051a3e87d/STM32F1/util/dfu-util.exe -------------------------------------------------------------------------------- /STM32F1/util/usb_descriptor_strings_util.html: -------------------------------------------------------------------------------- 1 | 2 | 22 | --------------------------------------------------------------------------------