aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUwe Hermann2011-04-28 19:42:35 +0200
committerUwe Hermann2011-04-28 19:42:35 +0200
commit089bb73018517701284b47d3801bf8bc6ad03cdd (patch)
tree1fe3c6fdbbd8a75c7748b59d64a2d073a3d46cd1
parent149c0c7dc0aeeda92b83c0c0e7c1a169d45e3d0b (diff)
parent3ac0ae839d710de6552f617934bed2f5f9629bec (diff)
Merge remote-tracking branch 'gsmcmullin/master'.
-rw-r--r--Makefile41
-rw-r--r--examples/lm3s/Makefile38
-rw-r--r--examples/lm3s/Makefile.include7
-rw-r--r--examples/lm3s/lm3s3748-evb/Makefile38
-rw-r--r--examples/lpc13xx/Makefile38
-rw-r--r--examples/lpc13xx/Makefile.include7
-rw-r--r--examples/lpc13xx/lpc-p1343/Makefile38
-rw-r--r--examples/stm32/Makefile74
-rw-r--r--examples/stm32/Makefile.include7
-rw-r--r--examples/stm32/lisa-m/Makefile43
-rw-r--r--examples/stm32/lisa-m/usb_dfu/usbdfu.c64
-rw-r--r--examples/stm32/mb525/Makefile44
-rw-r--r--examples/stm32/obldc/Makefile56
-rw-r--r--examples/stm32/obldc/usart_irq/usart_irq.c4
-rw-r--r--examples/stm32/other/Makefile92
-rw-r--r--examples/stm32/stm32-discovery/Makefile62
-rw-r--r--examples/stm32/stm32-h103/Makefile114
-rw-r--r--examples/stm32/stm32-h103/usb_dfu/usbdfu.c64
-rw-r--r--examples/stm32/stm32-h103/usb_iap/Makefile2
-rw-r--r--examples/stm32/stm32-h103/usb_iap/usbiap.c64
-rw-r--r--examples/stm32/stm32-h107/usb_simple/Makefile (renamed from examples/stm32/stm32-h107/Makefile)19
-rw-r--r--examples/stm32/stm32-h107/usb_simple/README10
-rw-r--r--examples/stm32/stm32-h107/usb_simple/usb_simple.c118
-rw-r--r--examples/stm32/stm32-h107/usb_simple/usb_simple.ld31
-rw-r--r--include/libopencm3/stm32/nvic.h8
-rw-r--r--include/libopencm3/stm32/otg_fs.h12
-rw-r--r--include/libopencm3/usb/usbd.h2
-rw-r--r--lib/lm3s/Makefile5
-rw-r--r--lib/lpc13xx/Makefile6
-rw-r--r--lib/stm32/Makefile6
-rw-r--r--lib/stm32/can.c10
-rw-r--r--lib/stm32/vector.c26
-rw-r--r--lib/usb/usb.c6
-rw-r--r--lib/usb/usb_f103.c21
-rw-r--r--lib/usb/usb_f107.c132
-rw-r--r--lib/usb/usb_private.h1
-rw-r--r--lib/usb/usb_standard.c11
37 files changed, 442 insertions, 879 deletions
diff --git a/Makefile b/Makefile
index 718ecd4..fe8db6a 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,8 @@ INCDIR = $(DESTDIR)/$(PREFIX)/include
LIBDIR = $(DESTDIR)/$(PREFIX)/lib
INSTALL = install
+TARGETS = stm32 lpc13xx lm3s
+
# Be silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
Q := @
@@ -36,20 +38,20 @@ all: build
build: lib examples
lib:
- @printf " BUILD lib/stm32\n"
- $(Q)$(MAKE) -C lib/stm32 all
- @printf " BUILD lib/lpc13xx\n"
- $(Q)$(MAKE) -C lib/lpc13xx all
- @printf " BUILD lib/lm3s\n"
- $(Q)$(MAKE) -C lib/lm3s all
+ $(Q)for i in $(addprefix $@/,$(TARGETS)); do \
+ if [ -d $$i ]; then \
+ printf " BUILD $$i\n"; \
+ $(MAKE) -C $$i || exit $?; \
+ fi; \
+ done
-examples: lib
- @printf " BUILD examples/stm32\n"
- $(Q)$(MAKE) -C examples/stm32 all
- @printf " BUILD examples/lpc13xx\n"
- $(Q)$(MAKE) -C examples/lpc13xx all
- @printf " BUILD examples/lm3s\n"
- $(Q)$(MAKE) -C examples/lm3s all
+examples:
+ $(Q)for i in $(addsuffix /*/*,$(addprefix $@/,$(TARGETS))); do \
+ if [ -d $$i ]; then \
+ printf " BUILD $$i\n"; \
+ $(MAKE) -C $$i || exit $?; \
+ fi; \
+ done
install: lib
@printf " INSTALL headers\n"
@@ -62,12 +64,13 @@ install: lib
$(Q)$(INSTALL) -m 0644 lib/*/*.ld $(LIBDIR)
clean:
- $(Q)$(MAKE) -C examples/stm32 clean
- $(Q)$(MAKE) -C lib/stm32 clean
- $(Q)$(MAKE) -C examples/lpc13xx clean
- $(Q)$(MAKE) -C lib/lpc13xx clean
- $(Q)$(MAKE) -C examples/lm3s clean
- $(Q)$(MAKE) -C lib/lm3s clean
+ $(Q)for i in $(addprefix lib/,$(TARGETS)) \
+ $(addsuffix /*/*,$(addprefix examples/,$(TARGETS))); do \
+ if [ -d $$i ]; then \
+ printf " CLEAN $$i\n"; \
+ $(MAKE) -C $$i clean || exit $?; \
+ fi; \
+ done
.PHONY: build lib examples install clean
diff --git a/examples/lm3s/Makefile b/examples/lm3s/Makefile
deleted file mode 100644
index 4f1704b..0000000
--- a/examples/lm3s/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: lm3s3748-evb
-
-lm3s3748-evb:
- @printf " BUILD examples/lm3s/lm3s3748-evb\n"
- $(Q)$(MAKE) -C lm3s3748-evb
-
-clean:
- @printf " CLEAN examples/lm3s/lm3s3748-evb\n"
- $(Q)$(MAKE) -C lm3s3748-evb clean
-
-.PHONY: lm3s3748-evb clean
-
diff --git a/examples/lm3s/Makefile.include b/examples/lm3s/Makefile.include
index 3420d1a..764a145 100644
--- a/examples/lm3s/Makefile.include
+++ b/examples/lm3s/Makefile.include
@@ -28,7 +28,7 @@ OBJDUMP = $(PREFIX)-objdump
# TOOLCHAIN_DIR = `dirname \`which $(CC)\``/../$(PREFIX)
TOOLCHAIN_DIR = ../../../..
CFLAGS += -O0 -g3 -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \
- -mcpu=cortex-m3 -mthumb
+ -mcpu=cortex-m3 -mthumb -MD
LDSCRIPT = $(BINARY).ld
LDFLAGS += -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/lm3s \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections
@@ -75,7 +75,7 @@ flash: $(BINARY).flash
@#printf " OBJDUMP $(*).list\n"
$(Q)$(OBJDUMP) -S $(*).elf > $(*).list
-%.elf: $(OBJS) $(LDSCRIPT)
+%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/lm3s/libopencm3_lm3s.a
@#printf " LD $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(LD) $(LDFLAGS) -o $(*).elf $(OBJS) -lopencm3_lm3s
@@ -85,6 +85,7 @@ flash: $(BINARY).flash
clean:
$(Q)rm -f *.o
+ $(Q)rm -f *.d
$(Q)rm -f *.elf
$(Q)rm -f *.bin
$(Q)rm -f *.hex
@@ -119,3 +120,5 @@ endif
.PHONY: images clean
+-include $(OBJS:.o=.d)
+
diff --git a/examples/lm3s/lm3s3748-evb/Makefile b/examples/lm3s/lm3s3748-evb/Makefile
deleted file mode 100644
index 5750afd..0000000
--- a/examples/lm3s/lm3s3748-evb/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: miniblink
-
-miniblink:
- @printf " BUILD examples/lm3s/lm3s3748-evb/miniblink\n"
- $(Q)$(MAKE) -C miniblink
-
-clean:
- @printf " CLEAN examples/lm3s/lm3s3748-evb/miniblink\n"
- $(Q)$(MAKE) -C miniblink clean
-
-.PHONY: miniblink clean
-
diff --git a/examples/lpc13xx/Makefile b/examples/lpc13xx/Makefile
deleted file mode 100644
index 486b4ba..0000000
--- a/examples/lpc13xx/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: lpc-p1343
-
-lpc-p1343:
- @printf " BUILD examples/lpc13xx/lpc-p1343\n"
- $(Q)$(MAKE) -C lpc-p1343
-
-clean:
- @printf " CLEAN examples/lpc13xx/lpc-p1343\n"
- $(Q)$(MAKE) -C lpc-p1343 clean
-
-.PHONY: lpc-p1343 clean
-
diff --git a/examples/lpc13xx/Makefile.include b/examples/lpc13xx/Makefile.include
index 6e80fd5..c9ae180 100644
--- a/examples/lpc13xx/Makefile.include
+++ b/examples/lpc13xx/Makefile.include
@@ -28,7 +28,7 @@ OBJDUMP = $(PREFIX)-objdump
# TOOLCHAIN_DIR = `dirname \`which $(CC)\``/../$(PREFIX)
TOOLCHAIN_DIR = ../../../..
CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include -fno-common \
- -mcpu=cortex-m3 -mthumb
+ -mcpu=cortex-m3 -mthumb -MD
LDSCRIPT = $(BINARY).ld
LDFLAGS += -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/lpc13xx \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections
@@ -75,7 +75,7 @@ flash: $(BINARY).flash
@#printf " OBJDUMP $(*).list\n"
$(Q)$(OBJDUMP) -S $(*).elf > $(*).list
-%.elf: $(OBJS) $(LDSCRIPT)
+%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/lpc13xx/libopencm3_lpc13xx.a
@#printf " LD $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(LD) $(LDFLAGS) -o $(*).elf $(OBJS) -lopencm3_lpc13xx
@@ -85,6 +85,7 @@ flash: $(BINARY).flash
clean:
$(Q)rm -f *.o
+ $(Q)rm -f *.d
$(Q)rm -f *.elf
$(Q)rm -f *.bin
$(Q)rm -f *.hex
@@ -119,3 +120,5 @@ endif
.PHONY: images clean
+-include $(OBJS:.o=.d)
+
diff --git a/examples/lpc13xx/lpc-p1343/Makefile b/examples/lpc13xx/lpc-p1343/Makefile
deleted file mode 100644
index e1745ac..0000000
--- a/examples/lpc13xx/lpc-p1343/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: miniblink
-
-miniblink:
- @printf " BUILD examples/lpc13xx/lpc-p1343/miniblink\n"
- $(Q)$(MAKE) -C miniblink
-
-clean:
- @printf " CLEAN examples/lpc13xx/lpc-p1343/miniblink\n"
- $(Q)$(MAKE) -C miniblink clean
-
-.PHONY: miniblink clean
-
diff --git a/examples/stm32/Makefile b/examples/stm32/Makefile
deleted file mode 100644
index 6a218fc..0000000
--- a/examples/stm32/Makefile
+++ /dev/null
@@ -1,74 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: stm32-discovery stm32-h103 stm32-h107 mb525 lisa-m obldc other
-
-stm32-discovery:
- @printf " BUILD examples/stm32/stm32-discovery\n"
- $(Q)$(MAKE) -C stm32-discovery
-
-stm32-h103:
- @printf " BUILD examples/stm32/stm32-h103\n"
- $(Q)$(MAKE) -C stm32-h103
-
-stm32-h107:
- @printf " BUILD examples/stm32/stm32-h107\n"
- $(Q)$(MAKE) -C stm32-h107
-
-mb525:
- @printf " BUILD examples/stm32/mb525\n"
- $(Q)$(MAKE) -C mb525
-
-lisa-m:
- @printf " BUILD examples/stm32/lisa-m\n"
- $(Q)$(MAKE) -C lisa-m
-
-other:
- @printf " BUILD examples/stm32/other\n"
- $(Q)$(MAKE) -C other
-
-obldc:
- @printf " BUILD examples/stm32/obldc\n"
- $(Q)$(MAKE) -C obldc
-
-clean:
- @printf " CLEAN examples/stm32/stm32-discovery\n"
- $(Q)$(MAKE) -C stm32-discovery clean
- @printf " CLEAN examples/stm32/stm32-h103\n"
- $(Q)$(MAKE) -C stm32-h103 clean
- @printf " CLEAN examples/stm32/stm32-h107\n"
- $(Q)$(MAKE) -C stm32-h107 clean
- @printf " CLEAN examples/stm32/mb525\n"
- $(Q)$(MAKE) -C mb525 clean
- @printf " CLEAN examples/stm32/lisa-m\n"
- $(Q)$(MAKE) -C lisa-m clean
- @printf " CLEAN examples/stm32/other\n"
- $(Q)$(MAKE) -C other clean
- @printf " CLEAN examples/stm32/obldc\n"
- $(Q)$(MAKE) -C obldc clean
-
-.PHONY: stm32-discovery stm32-h103 stm32-h107 mb525 lisa-m other obldc clean
-
diff --git a/examples/stm32/Makefile.include b/examples/stm32/Makefile.include
index 3eb3d35..acb78e8 100644
--- a/examples/stm32/Makefile.include
+++ b/examples/stm32/Makefile.include
@@ -28,7 +28,7 @@ OBJDUMP = $(PREFIX)-objdump
# TOOLCHAIN_DIR = `dirname \`which $(CC)\``/../$(PREFIX)
TOOLCHAIN_DIR = ../../../..
CFLAGS += -Os -g -Wall -Wextra -I$(TOOLCHAIN_DIR)/include \
- -fno-common -mcpu=cortex-m3 -mthumb -msoft-float
+ -fno-common -mcpu=cortex-m3 -mthumb -msoft-float -MD
LDSCRIPT = $(BINARY).ld
LDFLAGS += -lc -lnosys -L$(TOOLCHAIN_DIR)/lib -L$(TOOLCHAIN_DIR)/lib/stm32 \
-T$(LDSCRIPT) -nostartfiles -Wl,--gc-sections \
@@ -75,7 +75,7 @@ flash: $(BINARY).flash
@#printf " OBJDUMP $(*).list\n"
$(Q)$(OBJDUMP) -S $(*).elf > $(*).list
-%.elf: $(OBJS) $(LDSCRIPT)
+%.elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/stm32/libopencm3_stm32.a
@#printf " LD $(subst $(shell pwd)/,,$(@))\n"
$(Q)$(LD) -o $(*).elf $(OBJS) -lopencm3_stm32 $(LDFLAGS)
@@ -85,6 +85,7 @@ flash: $(BINARY).flash
clean:
$(Q)rm -f *.o
+ $(Q)rm -f *.d
$(Q)rm -f *.elf
$(Q)rm -f *.bin
$(Q)rm -f *.hex
@@ -118,3 +119,5 @@ endif
.PHONY: images clean
+-include $(OBJS:.o=.d)
+
diff --git a/examples/stm32/lisa-m/Makefile b/examples/stm32/lisa-m/Makefile
deleted file mode 100644
index fa554bc..0000000
--- a/examples/stm32/lisa-m/Makefile
+++ /dev/null
@@ -1,43 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-# TODO: Add usb_dfu later, doesn't build at the moment.
-all: fancyblink usb_hid
-
-fancyblink:
- @printf " BUILD examples/stm32/lisa-m/fancyblink\n"
- $(Q)$(MAKE) -C usb_hid
-
-usb_hid:
- @printf " BUILD examples/stm32/lisa-m/usb_hid\n"
- $(Q)$(MAKE) -C usb_hid
-
-clean:
- @printf " CLEAN examples/stm32/lisa-m/usb_hid\n"
- $(Q)$(MAKE) -C usb_hid clean
-
-.PHONY: fancyblink usb_hid clean
-
diff --git a/examples/stm32/lisa-m/usb_dfu/usbdfu.c b/examples/stm32/lisa-m/usb_dfu/usbdfu.c
index 2ae8374..4e83ce0 100644
--- a/examples/stm32/lisa-m/usb_dfu/usbdfu.c
+++ b/examples/stm32/lisa-m/usb_dfu/usbdfu.c
@@ -173,18 +173,26 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req)
}
}
-static int usbdfu_control_command(struct usb_setup_data *req,
- void (**complete)(struct usb_setup_data *req))
+static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(struct usb_setup_data *req))
{
- (void)complete;
- if(req->bmRequestType != 0x21)
+ if((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request */
-
+
switch(req->bRequest) {
case DFU_DNLOAD:
- usbdfu_state = STATE_DFU_MANIFEST_SYNC;
- return 1;
+ if((len == NULL) || (*len == 0)) {
+ usbdfu_state = STATE_DFU_MANIFEST_SYNC;
+ return 1;
+ } else {
+ /* Copy download data for use on GET_STATUS */
+ prog.blocknum = req->wValue;
+ prog.len = *len;
+ memcpy(prog.buf, *buf, *len);
+ usbdfu_state = STATE_DFU_DNLOAD_SYNC;
+ return 1;
+ }
case DFU_CLRSTATUS:
/* Clear error and return to dfuIDLE */
if(usbdfu_state == STATE_DFU_ERROR)
@@ -194,19 +202,6 @@ static int usbdfu_control_command(struct usb_setup_data *req,
/* Abort returns to dfuIDLE state */
usbdfu_state = STATE_DFU_IDLE;
return 1;
- }
-
- return 0;
-}
-
-static int usbdfu_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
- void (**complete)(struct usb_setup_data *req))
-{
-
- if(req->bmRequestType != 0xA1)
- return 0; /* Only accept class request */
-
- switch(req->bRequest) {
case DFU_UPLOAD:
/* Upload not supported for now */
return 0;
@@ -235,26 +230,6 @@ static int usbdfu_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
return 0;
}
-static int usbdfu_control_write(struct usb_setup_data *req, u8 *buf, u16 len,
- void (**complete)(struct usb_setup_data *req))
-{
- (void)complete;
-
- if(req->bmRequestType != 0x21)
- return 0; /* Only accept class request */
-
- if(req->bRequest != DFU_DNLOAD)
- return 0;
-
- /* Copy download data for use on GET_STATUS */
- prog.blocknum = req->wValue;
- prog.len = len;
- memcpy(prog.buf, buf, len);
- usbdfu_state = STATE_DFU_DNLOAD_SYNC;
-
- return 1;
-}
-
int main(void)
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
@@ -280,11 +255,12 @@ int main(void)
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
- usbd_init(&dev, &config, usb_strings);
+ usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
- usbd_register_control_command_callback(usbdfu_control_command);
- usbd_register_control_write_callback(usbdfu_control_write);
- usbd_register_control_read_callback(usbdfu_control_read);
+ usbd_register_control_callback(
+ USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
+ USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
+ usbdfu_control_request);
gpio_set(GPIOA, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
diff --git a/examples/stm32/mb525/Makefile b/examples/stm32/mb525/Makefile
deleted file mode 100644
index 78181e0..0000000
--- a/examples/stm32/mb525/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: fancyblink pwmleds
-
-fancyblink:
- @printf " BUILD examples/stm32/mb525/fancyblink\n"
- $(Q)$(MAKE) -C fancyblink
-
-pwmleds:
- @printf " BUILD examples/stm32/mb525/pwmleds\n"
- $(Q)$(MAKE) -C pwmleds
-
-clean:
- @printf " CLEAN examples/stm32/mb525/fancyblink\n"
- $(Q)$(MAKE) -C fancyblink clean
- @printf " CLEAN examples/stm32/mb525/pwmleds\n"
- $(Q)$(MAKE) -C pwmleds clean
-
-.PHONY: fancyblink pwmleds clean
-
diff --git a/examples/stm32/obldc/Makefile b/examples/stm32/obldc/Makefile
deleted file mode 100644
index 626d889..0000000
--- a/examples/stm32/obldc/Makefile
+++ /dev/null
@@ -1,56 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: led systick usart can
-
-led:
- @printf " BUILD examples/stm32/obldc/led\n"
- $(Q)$(MAKE) -C led
-
-systick:
- @printf " BUILD examples/stm32/obldc/systick\n"
- $(Q)$(MAKE) -C systick
-
-usart:
- @printf " BUILD examples/stm32/obldc/usart\n"
- $(Q)$(MAKE) -C usart
-
-can:
- @printf " BUILD examples/stm32/obldc/can\n"
- $(Q)$(MAKE) -C can
-
-clean:
- @printf " CLEAN examples/stm32/obldc/led\n"
- $(Q)$(MAKE) -C led clean
- @printf " CLEAN examples/stm32/obldc/systick\n"
- $(Q)$(MAKE) -C systick clean
- @printf " CLEAN examples/stm32/obldc/usart\n"
- $(Q)$(MAKE) -C usart clean
- @printf " CLEAN examples/stm32/obldc/can\n"
- $(Q)$(MAKE) -C can clean
-
-.PHONY: led systick usart can
-
diff --git a/examples/stm32/obldc/usart_irq/usart_irq.c b/examples/stm32/obldc/usart_irq/usart_irq.c
index 7e5f971..82320c1 100644
--- a/examples/stm32/obldc/usart_irq/usart_irq.c
+++ b/examples/stm32/obldc/usart_irq/usart_irq.c
@@ -80,7 +80,7 @@ void usart1_isr(void)
static u8 data = 'A';
/* Check if we were called because of RXNE. */
- if (((USART_CR1(USART1) & USART_SR_RXNEIE) != 0) &&
+ if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
((USART_SR(USART1) & USART_SR_RXNE) != 0)) {
/* Indicate that we got data. */
gpio_toggle(GPIOA, GPIO6);
@@ -93,7 +93,7 @@ void usart1_isr(void)
}
/* Check if we were called because of TXE. */
- if ((USART_CR1(USART1) & USART_SR_TXEIE) != 0) &&
+ if (((USART_CR1(USART1) & USART_CR1_TXEIE) != 0) &&
((USART_SR(USART1) & USART_SR_TXE) != 0)) {
/* Indicate that we are sending out data. */
gpio_toggle(GPIOA, GPIO7);
diff --git a/examples/stm32/other/Makefile b/examples/stm32/other/Makefile
deleted file mode 100644
index 995bec8..0000000
--- a/examples/stm32/other/Makefile
+++ /dev/null
@@ -1,92 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: i2c_stts75_sensor adc_temperature_sensor dma_mem2mem timer_interrupt systick dogm128 rtc usb_cdcacm usb_dfu usb_hid
-
-i2c_stts75_sensor:
- @printf " BUILD examples/stm32/other/i2c_stts75_sensor\n"
- $(Q)$(MAKE) -C i2c_stts75_sensor
-
-adc_temperature_sensor:
- @printf " BUILD examples/stm32/other/adc_temperature_sensor\n"
- $(Q)$(MAKE) -C adc_temperature_sensor
-
-dma_mem2mem:
- @printf " BUILD examples/stm32/other/dma_mem2mem\n"
- $(Q)$(MAKE) -C dma_mem2mem
-
-timer_interrupt:
- @printf " BUILD examples/stm32/other/timer_interrupt\n"
- $(Q)$(MAKE) -C timer_interrupt
-
-systick:
- @printf " BUILD examples/stm32/other/systick\n"
- $(Q)$(MAKE) -C systick
-
-dogm128:
- @printf " BUILD examples/stm32/other/dogm128\n"
- $(Q)$(MAKE) -C dogm128
-
-rtc:
- @printf " BUILD examples/stm32/other/rtc\n"
- $(Q)$(MAKE) -C rtc
-
-usb_cdcacm:
- @printf " BUILD examples/stm32/other/usb_cdcacm\n"
- $(Q)$(MAKE) -C usb_cdcacm
-
-usb_dfu:
- @printf " BUILD examples/stm32/other/usb_dfu\n"
- $(Q)$(MAKE) -C usb_dfu
-
-usb_hid:
- @printf " BUILD examples/stm32/other/usb_hid\n"
- $(Q)$(MAKE) -C usb_hid
-
-clean:
- @printf " CLEAN examples/stm32/other/i2c_stts75_sensor\n"
- $(Q)$(MAKE) -C i2c_stts75_sensor clean
- @printf " CLEAN examples/stm32/other/adc_temperature_sensor\n"
- $(Q)$(MAKE) -C adc_temperature_sensor clean
- @printf " CLEAN examples/stm32/other/dma_mem2mem\n"
- $(Q)$(MAKE) -C dma_mem2mem clean
- @printf " CLEAN examples/stm32/other/timer_interrupt\n"
- $(Q)$(MAKE) -C timer_interrupt clean
- @printf " CLEAN examples/stm32/other/systick\n"
- $(Q)$(MAKE) -C systick clean
- @printf " CLEAN examples/stm32/other/dogm128\n"
- $(Q)$(MAKE) -C dogm128 clean
- @printf " CLEAN examples/stm32/other/rtc\n"
- $(Q)$(MAKE) -C rtc clean
- @printf " CLEAN examples/stm32/other/usb_cdcacm\n"
- $(Q)$(MAKE) -C usb_cdcacm clean
- @printf " CLEAN examples/stm32/other/usb_dfu\n"
- $(Q)$(MAKE) -C usb_dfu clean
- @printf " CLEAN examples/stm32/other/usb_hid\n"
- $(Q)$(MAKE) -C usb_hid clean
-
-.PHONY: i2c_stts75_sensor adc_temperature_sensor dma_mem2mem timer_interrupt systick dogm128 rtc clean usb_cdcacm usb_dfu usb_hid
-
diff --git a/examples/stm32/stm32-discovery/Makefile b/examples/stm32/stm32-discovery/Makefile
deleted file mode 100644
index bbf96d8..0000000
--- a/examples/stm32/stm32-discovery/Makefile
+++ /dev/null
@@ -1,62 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: miniblink fancyblink usart button rtc
-
-miniblink:
- @printf " BUILD examples/stm32/stm32-discovery/miniblink\n"
- $(Q)$(MAKE) -C miniblink
-
-fancyblink:
- @printf " BUILD examples/stm32/stm32-discovery/fancyblink\n"
- $(Q)$(MAKE) -C fancyblink
-
-usart:
- @printf " BUILD examples/stm32/stm32-discovery/usart\n"
- $(Q)$(MAKE) -C usart
-
-button:
- @printf " BUILD examples/stm32/stm32-discovery/button\n"
- $(Q)$(MAKE) -C button
-
-rtc:
- @printf " BUILD examples/stm32/stm32-discovery/rtc\n"
- $(Q)$(MAKE) -C rtc
-
-clean:
- @printf " CLEAN examples/stm32/stm32-discovery/miniblink\n"
- $(Q)$(MAKE) -C miniblink clean
- @printf " CLEAN examples/stm32/stm32-discovery/fancyblink\n"
- $(Q)$(MAKE) -C fancyblink clean
- @printf " CLEAN examples/stm32/stm32-discovery/usart\n"
- $(Q)$(MAKE) -C usart clean
- @printf " CLEAN examples/stm32/stm32-discovery/button\n"
- $(Q)$(MAKE) -C button clean
- @printf " CLEAN examples/stm32/stm32-discovery/rtc\n"
- $(Q)$(MAKE) -C rtc clean
-
-.PHONY: miniblink fancyblink usart button rtc clean
-
diff --git a/examples/stm32/stm32-h103/Makefile b/examples/stm32/stm32-h103/Makefile
deleted file mode 100644
index d9423f2..0000000
--- a/examples/stm32/stm32-h103/Makefile
+++ /dev/null
@@ -1,114 +0,0 @@
-##
-## This file is part of the libopencm3 project.
-##
-## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
-##
-## This program is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
-
-all: miniblink fancyblink usart usart_irq usart_printf usart_irq_printf timer usb_cdcacm usb_hid button exti_both traceswo led_stripe
-
-miniblink:
- @printf " BUILD examples/stm32/stm32-h103/miniblink\n"
- $(Q)$(MAKE) -C miniblink
-
-fancyblink:
- @printf " BUILD examples/stm32/stm32-h103/fancyblink\n"
- $(Q)$(MAKE) -C fancyblink
-
-usart:
- @printf " BUILD examples/stm32/stm32-h103/usart\n"
- $(Q)$(MAKE) -C usart
-
-usart_irq:
- @printf " BUILD examples/stm32/stm32-h103/usart_irq\n"
- $(Q)$(MAKE) -C usart_irq
-
-usart_printf:
- @printf " BUILD examples/stm32/stm32-h103/usart_printf\n"
- $(Q)$(MAKE) -C usart_printf
-
-usart_irq_printf:
- @printf " BUILD examples/stm32/stm32-h103/usart_irq_printf\n"
- $(Q)$(MAKE) -C usart_irq_printf
-
-timer:
- @printf " BUILD examples/stm32/stm32-h103/timer\n"
- $(Q)$(MAKE) -C timer
-
-spi:
- @printf " BUILD examples/stm32/stm32-h103/spi\n"
- $(Q)$(MAKE) -C spi
-
-usb_cdcacm:
- @printf " BUILD examples/stm32/stm32-h103/usb_cdcacm\n"
- $(Q)$(MAKE) -C usb_cdcacm
-
-usb_hid:
- @printf " BUILD examples/stm32/stm32-h103/usb_hid\n"
- $(Q)$(MAKE) -C usb_hid
-
-button:
- @printf " BUILD examples/stm32/stm32-h103/button\n"
- $(Q)$(MAKE) -C button
-
-exti_both:
- @printf " BUILD examples/stm32/stm32-h103/exti_both\n"
- $(Q)$(MAKE) -C exti_both
-
-traceswo:
- @printf " BUILD examples/stm32/stm32-h103/traceswo\n"
- $(Q)$(MAKE) -C traceswo
-
-led_stripe:
- @printf " BUILD examples/stm32/stm32-h103/led_stripe\n"
- $(Q)$(MAKE) -C led_stripe
-
-clean:
- @printf " CLEAN examples/stm32/stm32-h103/miniblink\n"
- $(Q)$(MAKE) -C miniblink clean
- @printf " CLEAN examples/stm32/stm32-h103/fancyblink\n"
- $(Q)$(MAKE) -C fancyblink clean
- @printf " CLEAN examples/stm32/stm32-h103/usart\n"
- $(Q)$(MAKE) -C usart clean
- @printf " CLEAN examples/stm32/stm32-h103/usart_irq\n"
- $(Q)$(MAKE) -C usart_irq clean
- @printf " CLEAN examples/stm32/stm32-h103/usart_printf\n"
- $(Q)$(MAKE) -C usart_printf clean
- @printf " CLEAN examples/stm32/stm32-h103/usart_irq_printf\n"
- $(Q)$(MAKE) -C usart_irq_printf clean
- @printf " CLEAN examples/stm32/stm32-h103/spi\n"
- $(Q)$(MAKE) -C spi clean
- @printf " CLEAN examples/stm32/stm32-h103/usb_cdcacm\n"
- $(Q)$(MAKE) -C usb_cdcacm clean
- @printf " CLEAN examples/stm32/stm32-h103/usb_hid\n"
- $(Q)$(MAKE) -C usb_hid clean
- @printf " CLEAN examples/stm32/stm32-h103/button\n"
- $(Q)$(MAKE) -C button clean
- @printf " CLEAN examples/stm32/stm32-h103/exti_both\n"
- $(Q)$(MAKE) -C exti_both clean
- @printf " CLEAN examples/stm32/stm32-h103/traceswo\n"
- $(Q)$(MAKE) -C traceswo clean
- @printf " CLEAN examples/stm32/stm32-h103/led_stripe\n"
- $(Q)$(MAKE) -C led_stripe clean
-
-.PHONY: miniblink fancyblink usart usart_irq usart_printf usart_irq_printf timer spi usb_cdcacm usb_hid button exti_both traceswo led_stripe clean
-
diff --git a/examples/stm32/stm32-h103/usb_dfu/usbdfu.c b/examples/stm32/stm32-h103/usb_dfu/usbdfu.c
index 2ae8374..4e83ce0 100644
--- a/examples/stm32/stm32-h103/usb_dfu/usbdfu.c
+++ b/examples/stm32/stm32-h103/usb_dfu/usbdfu.c
@@ -173,18 +173,26 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req)
}
}
-static int usbdfu_control_command(struct usb_setup_data *req,
- void (**complete)(struct usb_setup_data *req))
+static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(struct usb_setup_data *req))
{
- (void)complete;
- if(req->bmRequestType != 0x21)
+ if((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request */
-
+
switch(req->bRequest) {
case DFU_DNLOAD:
- usbdfu_state = STATE_DFU_MANIFEST_SYNC;
- return 1;
+ if((len == NULL) || (*len == 0)) {
+ usbdfu_state = STATE_DFU_MANIFEST_SYNC;
+ return 1;
+ } else {
+ /* Copy download data for use on GET_STATUS */
+ prog.blocknum = req->wValue;
+ prog.len = *len;
+ memcpy(prog.buf, *buf, *len);
+ usbdfu_state = STATE_DFU_DNLOAD_SYNC;
+ return 1;
+ }
case DFU_CLRSTATUS:
/* Clear error and return to dfuIDLE */
if(usbdfu_state == STATE_DFU_ERROR)
@@ -194,19 +202,6 @@ static int usbdfu_control_command(struct usb_setup_data *req,
/* Abort returns to dfuIDLE state */
usbdfu_state = STATE_DFU_IDLE;
return 1;
- }
-
- return 0;
-}
-
-static int usbdfu_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
- void (**complete)(struct usb_setup_data *req))
-{
-
- if(req->bmRequestType != 0xA1)
- return 0; /* Only accept class request */
-
- switch(req->bRequest) {
case DFU_UPLOAD:
/* Upload not supported for now */
return 0;
@@ -235,26 +230,6 @@ static int usbdfu_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
return 0;
}
-static int usbdfu_control_write(struct usb_setup_data *req, u8 *buf, u16 len,
- void (**complete)(struct usb_setup_data *req))
-{
- (void)complete;
-
- if(req->bmRequestType != 0x21)
- return 0; /* Only accept class request */
-
- if(req->bRequest != DFU_DNLOAD)
- return 0;
-
- /* Copy download data for use on GET_STATUS */
- prog.blocknum = req->wValue;
- prog.len = len;
- memcpy(prog.buf, buf, len);
- usbdfu_state = STATE_DFU_DNLOAD_SYNC;
-
- return 1;
-}
-
int main(void)
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
@@ -280,11 +255,12 @@ int main(void)
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
- usbd_init(&dev, &config, usb_strings);
+ usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
- usbd_register_control_command_callback(usbdfu_control_command);
- usbd_register_control_write_callback(usbdfu_control_write);
- usbd_register_control_read_callback(usbdfu_control_read);
+ usbd_register_control_callback(
+ USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
+ USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
+ usbdfu_control_request);
gpio_set(GPIOA, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
diff --git a/examples/stm32/stm32-h103/usb_iap/Makefile b/examples/stm32/stm32-h103/usb_iap/Makefile
index 0b51782..bed9908 100644
--- a/examples/stm32/stm32-h103/usb_iap/Makefile
+++ b/examples/stm32/stm32-h103/usb_iap/Makefile
@@ -19,5 +19,5 @@
BINARY = usbiap
-include ../../Makefile.includes
+include ../../Makefile.include
diff --git a/examples/stm32/stm32-h103/usb_iap/usbiap.c b/examples/stm32/stm32-h103/usb_iap/usbiap.c
index 2ae8374..4e83ce0 100644
--- a/examples/stm32/stm32-h103/usb_iap/usbiap.c
+++ b/examples/stm32/stm32-h103/usb_iap/usbiap.c
@@ -173,18 +173,26 @@ static void usbdfu_getstatus_complete(struct usb_setup_data *req)
}
}
-static int usbdfu_control_command(struct usb_setup_data *req,
- void (**complete)(struct usb_setup_data *req))
+static int usbdfu_control_request(struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(struct usb_setup_data *req))
{
- (void)complete;
- if(req->bmRequestType != 0x21)
+ if((req->bmRequestType & 0x7F) != 0x21)
return 0; /* Only accept class request */
-
+
switch(req->bRequest) {
case DFU_DNLOAD:
- usbdfu_state = STATE_DFU_MANIFEST_SYNC;
- return 1;
+ if((len == NULL) || (*len == 0)) {
+ usbdfu_state = STATE_DFU_MANIFEST_SYNC;
+ return 1;
+ } else {
+ /* Copy download data for use on GET_STATUS */
+ prog.blocknum = req->wValue;
+ prog.len = *len;
+ memcpy(prog.buf, *buf, *len);
+ usbdfu_state = STATE_DFU_DNLOAD_SYNC;
+ return 1;
+ }
case DFU_CLRSTATUS:
/* Clear error and return to dfuIDLE */
if(usbdfu_state == STATE_DFU_ERROR)
@@ -194,19 +202,6 @@ static int usbdfu_control_command(struct usb_setup_data *req,
/* Abort returns to dfuIDLE state */
usbdfu_state = STATE_DFU_IDLE;
return 1;
- }
-
- return 0;
-}
-
-static int usbdfu_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
- void (**complete)(struct usb_setup_data *req))
-{
-
- if(req->bmRequestType != 0xA1)
- return 0; /* Only accept class request */
-
- switch(req->bRequest) {
case DFU_UPLOAD:
/* Upload not supported for now */
return 0;
@@ -235,26 +230,6 @@ static int usbdfu_control_read(struct usb_setup_data *req, u8 **buf, u16 *len,
return 0;
}
-static int usbdfu_control_write(struct usb_setup_data *req, u8 *buf, u16 len,
- void (**complete)(struct usb_setup_data *req))
-{
- (void)complete;
-
- if(req->bmRequestType != 0x21)
- return 0; /* Only accept class request */
-
- if(req->bRequest != DFU_DNLOAD)
- return 0;
-
- /* Copy download data for use on GET_STATUS */
- prog.blocknum = req->wValue;
- prog.len = len;
- memcpy(prog.buf, buf, len);
- usbdfu_state = STATE_DFU_DNLOAD_SYNC;
-
- return 1;
-}
-
int main(void)
{
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
@@ -280,11 +255,12 @@ int main(void)
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
- usbd_init(&dev, &config, usb_strings);
+ usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings);
usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
- usbd_register_control_command_callback(usbdfu_control_command);
- usbd_register_control_write_callback(usbdfu_control_write);
- usbd_register_control_read_callback(usbdfu_control_read);
+ usbd_register_control_callback(
+ USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
+ USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
+ usbdfu_control_request);
gpio_set(GPIOA, GPIO15);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
diff --git a/examples/stm32/stm32-h107/Makefile b/examples/stm32/stm32-h107/usb_simple/Makefile
index a6d797d..2d954e2 100644
--- a/examples/stm32/stm32-h107/Makefile
+++ b/examples/stm32/stm32-h107/usb_simple/Makefile
@@ -17,22 +17,7 @@
## along with this program. If not, see <http://www.gnu.org/licenses/>.
##
-# Be silent per default, but 'make V=1' will show all compiler calls.
-ifneq ($(V),1)
-Q := @
-# Do not print "Entering directory ...".
-MAKEFLAGS += --no-print-directory
-endif
+BINARY = usb_simple
-all: fancyblink
-
-fancyblink:
- @printf " BUILD examples/stm32/stm32-h107/fancyblink\n"
- $(Q)$(MAKE) -C fancyblink
-
-clean:
- @printf " CLEAN examples/stm32/stm32-h107/fancyblink\n"
- $(Q)$(MAKE) -C fancyblink clean
-
-.PHONY: fancyblink
+include ../../Makefile.include
diff --git a/examples/stm32/stm32-h107/usb_simple/README b/examples/stm32/stm32-h107/usb_simple/README
new file mode 100644
index 0000000..93d4f03
--- /dev/null
+++ b/examples/stm32/stm32-h107/usb_simple/README
@@ -0,0 +1,10 @@
+------------------------------------------------------------------------------
+README
+------------------------------------------------------------------------------
+
+This is small USB controlled LED blinking example program using libopencm3.
+
+It's intended for the ST STM32-based Olimex STM32-H107 eval board (see
+http://olimex.com/dev/stm32-h107.html for details). The usbtest.py
+script in this directory maybe used to control the LED.
+
diff --git a/examples/stm32/stm32-h107/usb_simple/usb_simple.c b/examples/stm32/stm32-h107/usb_simple/usb_simple.c
new file mode 100644
index 0000000..517f37e
--- /dev/null
+++ b/examples/stm32/stm32-h107/usb_simple/usb_simple.c
@@ -0,0 +1,118 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libopencm3/stm32/rcc.h>
+#include <libopencm3/stm32/gpio.h>
+
+#include <libopencm3/usb/usbd.h>
+
+const struct usb_device_descriptor dev = {
+ .bLength = USB_DT_DEVICE_SIZE,
+ .bDescriptorType = USB_DT_DEVICE,
+ .bcdUSB = 0x0200,
+ .bDeviceClass = 0xFF,
+ .bDeviceSubClass = 0,
+ .bDeviceProtocol = 0,
+ .bMaxPacketSize0 = 64,
+ .idVendor = 0xCAFE,
+ .idProduct = 0xCAFE,
+ .bcdDevice = 0x0200,
+ .iManufacturer = 1,
+ .iProduct = 2,
+ .iSerialNumber = 3,
+ .bNumConfigurations = 1,
+};
+
+const struct usb_interface_descriptor iface = {
+ .bLength = USB_DT_INTERFACE_SIZE,
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = 0xFF,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = 0,
+};
+
+const struct usb_interface ifaces[] = {{
+ .num_altsetting = 1,
+ .altsetting = &iface,
+}};
+
+const struct usb_config_descriptor config = {
+ .bLength = USB_DT_CONFIGURATION_SIZE,
+ .bDescriptorType = USB_DT_CONFIGURATION,
+ .wTotalLength = 0,
+ .bNumInterfaces = 1,
+ .bConfigurationValue = 1,
+ .iConfiguration = 0,
+ .bmAttributes = 0x80,
+ .bMaxPower = 0x32,
+
+ .interface = ifaces,
+};
+
+const char *usb_strings[] = {
+ "x",
+ "Black Sphere Technologies",
+ "Simple Device",
+ "1001"
+};
+
+static int simple_control_callback(struct usb_setup_data *req, u8 **buf,
+ u16 *len, void (**complete)(struct usb_setup_data *req))
+{
+ (void)buf;
+ (void)len;
+ (void)complete;
+
+ if(req->bmRequestType != 0x40)
+ return 0; /* Only accept vendor request */
+
+ if(req->wValue & 1)
+ gpio_set(GPIOC, GPIO6);
+ else
+ gpio_clear(GPIOC, GPIO6);
+
+ return 1;
+}
+
+int main(void)
+{
+ rcc_clock_setup_in_hse_8mhz_out_72mhz();
+
+ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPAEN);
+ rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN);
+
+ /* LED output */
+ gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
+ GPIO_CNF_OUTPUT_PUSHPULL, GPIO6);
+
+ usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
+ usbd_register_control_callback(
+ USB_REQ_TYPE_VENDOR,
+ USB_REQ_TYPE_TYPE,
+ simple_control_callback);
+
+ while (1)
+ usbd_poll();
+}
+
diff --git a/examples/stm32/stm32-h107/usb_simple/usb_simple.ld b/examples/stm32/stm32-h107/usb_simple/usb_simple.ld
new file mode 100644
index 0000000..6c9c766
--- /dev/null
+++ b/examples/stm32/stm32-h107/usb_simple/usb_simple.ld
@@ -0,0 +1,31 @@
+/*
+ * This file is part of the libopencm3 project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Linker script for Olimex STM32-H107 (STM32F107VCT6, 256K flash, 64K RAM). */
+
+/* Define memory regions. */
+MEMORY
+{
+ rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
+ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
+}
+
+/* Include the common ld script. */
+INCLUDE libopencm3_stm32.ld
+
diff --git a/include/libopencm3/stm32/nvic.h b/include/libopencm3/stm32/nvic.h
index ce8132f..d29c425 100644
--- a/include/libopencm3/stm32/nvic.h
+++ b/include/libopencm3/stm32/nvic.h
@@ -138,6 +138,14 @@
#define NVIC_DMA2_CHANNEL2_IRQ 57
#define NVIC_DMA2_CHANNEL3_IRQ 58
#define NVIC_DMA2_CHANNEL4_5_IRQ 59
+#define NVIC_DMA2_CHANNEL5_IRQ 60
+#define NVIC_ETH_IRQ 61
+#define NVIC_ETH_WKUP_IRQ 62
+#define NVIC_CAN2_TX_IRQ 63
+#define NVIC_CAN2_RX0_IRQ 64
+#define NVIC_CAN2_RX1_IRQ 65
+#define NVIC_CAN2_SCE_IRQ 66
+#define NVIC_OTG_FS_IRQ 67
/* --- NVIC functions ------------------------------------------------------ */
diff --git a/include/libopencm3/stm32/otg_fs.h b/include/libopencm3/stm32/otg_fs.h
index d39593e..e1d7a6a 100644
--- a/include/libopencm3/stm32/otg_fs.h
+++ b/include/libopencm3/stm32/otg_fs.h
@@ -250,6 +250,7 @@
#define OTG_FS_DIEPCTL0_EPENA (1 << 31)
#define OTG_FS_DIEPCTL0_EPDIS (1 << 30)
/* Bits 29:28 - Reserved */
+#define OTG_FS_DIEPCTLX_SD0PID (1 << 28)
#define OTG_FS_DIEPCTL0_SNAK (1 << 27)
#define OTG_FS_DIEPCTL0_CNAK (1 << 26)
#define OTG_FS_DIEPCTL0_TXFNUM_MASK (0xf << 22)
@@ -270,6 +271,7 @@
#define OTG_FS_DOEPCTL0_EPENA (1 << 31)
#define OTG_FS_DOEPCTL0_EPDIS (1 << 30)
/* Bits 29:28 - Reserved */
+#define OTG_FS_DOEPCTLX_SD0PID (1 << 28)
#define OTG_FS_DOEPCTL0_SNAK (1 << 27)
#define OTG_FS_DOEPCTL0_CNAK (1 << 26)
/* Bits 25:22 - Reserved */
@@ -297,6 +299,16 @@
#define OTG_FS_DIEPINTX_EPDISD (1 << 1)
#define OTG_FS_DIEPINTX_XFRC (1 << 0)
+/* OTG_FS Device IN Endpoint Interrupt Register (OTG_FS_DOEPINTx) */
+/* Bits 31:7 - Reserved */
+#define OTG_FS_DOEPINTX_B2BSTUP (1 << 6)
+/* Bit 5 - Reserved */
+#define OTG_FS_DOEPINTX_OTEPDIS (1 << 4)
+#define OTG_FS_DOEPINTX_STUP (1 << 3)
+/* Bit 2 - Reserved */
+#define OTG_FS_DOEPINTX_EPDISD (1 << 1)
+#define OTG_FS_DOEPINTX_XFRC (1 << 0)
+
/* OTG_FS Device OUT Endpoint 0 Transfer Size Regsiter (OTG_FS_DOEPTSIZ0) */
/* Bit 31 - Reserved */
#define OTG_FS_DIEPSIZ0_STUPCNT_1 (0x1 << 29)
diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h
index fab6304..c73de07 100644
--- a/include/libopencm3/usb/usbd.h
+++ b/include/libopencm3/usb/usbd.h
@@ -65,6 +65,8 @@ extern u16 usbd_ep_read_packet(u8 addr, void *buf, u16 len);
extern void usbd_ep_stall_set(u8 addr, u8 stall);
extern u8 usbd_ep_stall_get(u8 addr);
+extern void usbd_ep_nak_set(u8 addr, u8 nak);
+
/* Optional */
extern void usbd_cable_connect(u8 on);
diff --git a/lib/lm3s/Makefile b/lib/lm3s/Makefile
index 25c57ec..2bdbd72 100644
--- a/lib/lm3s/Makefile
+++ b/lib/lm3s/Makefile
@@ -25,7 +25,7 @@ CC = $(PREFIX)-gcc
AR = $(PREFIX)-ar
CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \
-mcpu=cortex-m3 -mthumb -Wstrict-prototypes \
- -ffunction-sections -fdata-sections
+ -ffunction-sections -fdata-sections -MD
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = gpio.o vector.o
@@ -49,8 +49,9 @@ $(LIBNAME).a: $(OBJS)
clean:
@printf " CLEAN lib/lpc13xx\n"
- $(Q)rm -f *.o
+ $(Q)rm -f *.o *.d
$(Q)rm -f $(LIBNAME).a
.PHONY: clean
+-include $(OBJS:.o=.d)
diff --git a/lib/lpc13xx/Makefile b/lib/lpc13xx/Makefile
index 37889e6..7181a08 100644
--- a/lib/lpc13xx/Makefile
+++ b/lib/lpc13xx/Makefile
@@ -25,7 +25,7 @@ CC = $(PREFIX)-gcc
AR = $(PREFIX)-ar
CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \
-mcpu=cortex-m3 -mthumb -Wstrict-prototypes \
- -ffunction-sections -fdata-sections
+ -ffunction-sections -fdata-sections -MD
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = gpio.o
@@ -49,8 +49,10 @@ $(LIBNAME).a: $(OBJS)
clean:
@printf " CLEAN lib/lpc13xx\n"
- $(Q)rm -f *.o
+ $(Q)rm -f *.o *.d
$(Q)rm -f $(LIBNAME).a
.PHONY: clean
+-include $(OBJS:.o=.d)
+
diff --git a/lib/stm32/Makefile b/lib/stm32/Makefile
index 6ffcc4a..095f524 100644
--- a/lib/stm32/Makefile
+++ b/lib/stm32/Makefile
@@ -25,7 +25,7 @@ CC = $(PREFIX)-gcc
AR = $(PREFIX)-ar
CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \
-mcpu=cortex-m3 -mthumb -Wstrict-prototypes \
- -ffunction-sections -fdata-sections
+ -ffunction-sections -fdata-sections -MD
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = vector.o rcc.o gpio.o usart.o adc.o spi.o flash.o nvic.o \
@@ -52,8 +52,10 @@ $(LIBNAME).a: $(OBJS)
clean:
@printf " CLEAN lib/stm32\n"
- $(Q)rm -f *.o
+ $(Q)rm -f *.o *.d
$(Q)rm -f $(LIBNAME).a
.PHONY: clean
+-include $(OBJS:.o=.d)
+
diff --git a/lib/stm32/can.c b/lib/stm32/can.c
index 3266133..e571f8a 100644
--- a/lib/stm32/can.c
+++ b/lib/stm32/can.c
@@ -211,6 +211,8 @@ int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data)
if (ret == -1)
return ret;
+ /* Clear stale register bits */
+ CAN_TIxR(canport, mailbox) = 0;
if (ext) {
/* Set extended ID. */
CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_EXID_SHIFT;
@@ -219,15 +221,11 @@ int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data)
} else {
/* Set standard ID. */
CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_STID_SHIFT;
- /* Unset extended ID indicator bit. */
- CAN_TIxR(canport, mailbox) &= ~CAN_TIxR_IDE;
}
/* Set/clear remote transmission request bit. */
if (rtr)
CAN_TIxR(canport, mailbox) |= CAN_TIxR_RTR; /* Set */
- else
- CAN_TIxR(canport, mailbox) &= ~CAN_TIxR_RTR; /* Clear */
/* Set the DLC. */
CAN_TDTxR(canport, mailbox) &= 0xFFFFFFFF0;
@@ -270,12 +268,12 @@ void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext,
if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_IDE) {
*ext = true;
/* Get extended CAN ID. */
- *id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_EXID_MASK) >
+ *id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_EXID_MASK) >>
CAN_RIxR_EXID_SHIFT);
} else {
*ext = false;
/* Get standard CAN ID. */
- *id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_STID_MASK) >
+ *id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_STID_MASK) >>
CAN_RIxR_STID_SHIFT);
}
diff --git a/lib/stm32/vector.c b/lib/stm32/vector.c
index 4d3d510..39bd9a1 100644
--- a/lib/stm32/vector.c
+++ b/lib/stm32/vector.c
@@ -96,6 +96,15 @@ void WEAK dma2_channel1_isr(void);
void WEAK dma2_channel2_isr(void);
void WEAK dma2_channel3_isr(void);
void WEAK dma2_channel4_5_isr(void);
+void WEAK dma2_channel5_isr(void);
+void WEAK eth_isr(void);
+void WEAK eth_wkup_isr(void);
+void WEAK can2_tx_isr(void);
+void WEAK can2_rx0_isr(void);
+void WEAK can2_rx1_isr(void);
+void WEAK can2_sce_isr(void);
+void WEAK otg_fs_isr(void);
+
__attribute__ ((section(".vectors")))
void (*const vector_table[]) (void) = {
@@ -172,6 +181,14 @@ void (*const vector_table[]) (void) = {
dma2_channel2_isr,
dma2_channel3_isr,
dma2_channel4_5_isr,
+ dma2_channel5_isr,
+ eth_isr,
+ eth_wkup_isr,
+ can2_tx_isr,
+ can2_rx0_isr,
+ can2_rx1_isr,
+ can2_sce_isr,
+ otg_fs_isr,
};
void reset_handler(void)
@@ -268,3 +285,12 @@ void null_handler(void)
#pragma weak dma2_channel2_isr = null_handler
#pragma weak dma2_channel3_isr = null_handler
#pragma weak dma2_channel4_5_isr = null_handler
+#pragma weak dma2_channel5_isr
+#pragma weak eth_isr = null_handler
+#pragma weak eth_wkup_isr = null_handler
+#pragma weak can2_tx_isr = null_handler
+#pragma weak can2_rx0_isr = null_handler
+#pragma weak can2_rx1_isr = null_handler
+#pragma weak can2_sce_isr = null_handler
+#pragma weak otg_fs_isr = null_handler
+
diff --git a/lib/usb/usb.c b/lib/usb/usb.c
index eb8e6d8..59c526d 100644
--- a/lib/usb/usb.c
+++ b/lib/usb/usb.c
@@ -127,3 +127,9 @@ u8 usbd_ep_stall_get(u8 addr)
{
return _usbd_device.driver->ep_stall_get(addr);
}
+
+void usbd_ep_nak_set(u8 addr, u8 nak)
+{
+ _usbd_device.driver->ep_nak_set(addr, nak);
+}
+
diff --git a/lib/usb/usb_f103.c b/lib/usb/usb_f103.c
index ef97670..19f645d 100644
--- a/lib/usb/usb_f103.c
+++ b/lib/usb/usb_f103.c
@@ -30,10 +30,13 @@ static void stm32f103_ep_setup(u8 addr, u8 type, u16 max_size,
static void stm32f103_endpoints_reset(void);
static void stm32f103_ep_stall_set(u8 addr, u8 stall);
static u8 stm32f103_ep_stall_get(u8 addr);
+static void stm32f103_ep_nak_set(u8 addr, u8 nak);
static u16 stm32f103_ep_write_packet(u8 addr, const void *buf, u16 len);
static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len);
static void stm32f103_poll(void);
+static u8 force_nak[8];
+
const struct _usbd_driver stm32f103_usb_driver = {
.init = stm32f103_usbd_init,
.set_address = stm32f103_set_address,
@@ -41,6 +44,7 @@ const struct _usbd_driver stm32f103_usb_driver = {
.ep_reset = stm32f103_endpoints_reset,
.ep_stall_set = stm32f103_ep_stall_set,
.ep_stall_get = stm32f103_ep_stall_get,
+ .ep_nak_set = stm32f103_ep_nak_set,
.ep_write_packet = stm32f103_ep_write_packet,
.ep_read_packet = stm32f103_ep_read_packet,
.poll = stm32f103_poll,
@@ -177,6 +181,20 @@ static u8 stm32f103_ep_stall_get(u8 addr)
return 0;
}
+static void stm32f103_ep_nak_set(u8 addr, u8 nak)
+{
+ /* It does not make sence to force NAK on IN endpoints */
+ if(addr & 0x80)
+ return;
+
+ force_nak[addr] = nak;
+
+ if(nak)
+ USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_NAK);
+ else
+ USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID);
+}
+
/**
* Copy a data buffer to packet memory.
*
@@ -236,7 +254,8 @@ static u16 stm32f103_ep_read_packet(u8 addr, void *buf, u16 len)
usb_copy_from_pm(buf, USB_GET_EP_RX_BUFF(addr), len);
USB_CLR_EP_RX_CTR(addr);
- USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID);
+ if(!force_nak[addr])
+ USB_SET_EP_RX_STAT(addr, USB_EP_RX_STAT_VALID);
return len;
}
diff --git a/lib/usb/usb_f107.c b/lib/usb/usb_f107.c
index a681b60..ee83b65 100644
--- a/lib/usb/usb_f107.c
+++ b/lib/usb/usb_f107.c
@@ -25,6 +25,12 @@
#include <string.h>
+/* Receive FIFO size in 32-bit words */
+#define RX_FIFO_SIZE 128
+static uint16_t fifo_mem_top;
+
+static u8 force_nak[4];
+
static void stm32f107_usbd_init(void);
static void stm32f107_set_address(u8 addr);
static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
@@ -32,6 +38,7 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
static void stm32f107_endpoints_reset(void);
static void stm32f107_ep_stall_set(u8 addr, u8 stall);
static u8 stm32f107_ep_stall_get(u8 addr);
+static void stm32f107_ep_nak_set(u8 addr, u8 nak);
static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len);
static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len);
static void stm32f107_poll(void);
@@ -47,6 +54,7 @@ const struct _usbd_driver stm32f107_usb_driver = {
.ep_reset = stm32f107_endpoints_reset,
.ep_stall_set = stm32f107_ep_stall_set,
.ep_stall_get = stm32f107_ep_stall_get,
+ .ep_nak_set = stm32f107_ep_nak_set,
.ep_write_packet = stm32f107_ep_write_packet,
.ep_read_packet = stm32f107_ep_read_packet,
.poll = stm32f107_poll,
@@ -55,15 +63,13 @@ const struct _usbd_driver stm32f107_usb_driver = {
/** Initialize the USB device controller hardware of the STM32. */
static void stm32f107_usbd_init(void)
{
- int i;
- /* TODO: Enable interrupts on Reset, Transfer, Suspend and Resume */
+ OTG_FS_GINTSTS = OTG_FS_GINTSTS_MMIS;
/* WARNING: Undocumented! Select internal PHY */
OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_PHYSEL;
/* Enable VBUS sensing in device mode and power down the phy */
OTG_FS_GCCFG |= OTG_FS_GCCFG_VBUSBSEN | OTG_FS_GCCFG_PWRDWN;
- for(i = 0; i < 800000; i++) __asm__("nop");
/* Wait for AHB idle */
while(!(OTG_FS_GRSTCTL & OTG_FS_GRSTCTL_AHBIDL));
@@ -71,7 +77,6 @@ static void stm32f107_usbd_init(void)
OTG_FS_GRSTCTL |= OTG_FS_GRSTCTL_CSRST;
while(OTG_FS_GRSTCTL & OTG_FS_GRSTCTL_CSRST);
- for(i = 0; i < 800000; i++) __asm__("nop");
/* Force peripheral only mode. */
OTG_FS_GUSBCFG |= OTG_FS_GUSBCFG_FDMOD;
@@ -82,28 +87,30 @@ static void stm32f107_usbd_init(void)
/* Restart the phy clock */
OTG_FS_PCGCCTL = 0;
+ OTG_FS_GRXFSIZ = RX_FIFO_SIZE;
+ fifo_mem_top = RX_FIFO_SIZE;
/* Unmask interrupts for TX and RX */
- OTG_FS_GINTMSK &= OTG_FS_GINTMSK_RXFLVLM;
+ OTG_FS_GAHBCFG |= OTG_FS_GAHBCFG_GINT;
+ OTG_FS_GINTMSK = OTG_FS_GINTMSK_ENUMDNEM |
+ OTG_FS_GINTMSK_RXFLVLM |
+ OTG_FS_GINTMSK_IEPINT |
+ OTG_FS_GINTMSK_USBSUSPM |
+ OTG_FS_GINTMSK_WUIM |
+ OTG_FS_GINTMSK_SOFM;
+ OTG_FS_DAINTMSK = 0xF;
+ OTG_FS_DIEPMSK = OTG_FS_DIEPMSK_XFRCM;
}
static void stm32f107_set_address(u8 addr)
{
- /* There is something badly wrong gere! */
-
- /* TODO: Set device address and enable. */
-
- /* This I think is correct, but doesn't work at all... */
- //OTG_FS_DCFG = (OTG_FS_DCFG & ~OTG_FS_DCFG_DAD) | (addr << 4);
-
- /* This is obviously incorrect, but sometimes works... */
- OTG_FS_DCFG |= addr << 4;
+ OTG_FS_DCFG = (OTG_FS_DCFG & ~OTG_FS_DCFG_DAD) | (addr << 4);
}
static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
void (*callback) (u8 ep))
{
- /* TODO: Configure endpoint address and type.
+ /* Configure endpoint address and type.
* Allocate FIFO memory for endpoint.
* Install callback funciton.
*/
@@ -130,14 +137,20 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
OTG_FS_DOEPTSIZ(0) = doeptsiz[0];
OTG_FS_DOEPCTL(0) |= OTG_FS_DOEPCTL0_EPENA | OTG_FS_DIEPCTL0_SNAK;
+ OTG_FS_GNPTXFSIZ = ((max_size / 4) << 16) | RX_FIFO_SIZE;
+ fifo_mem_top += max_size / 4;
+
return;
}
- /* TODO: Configuration for other endpoints */
if (dir) {
+ OTG_FS_DIEPTXF(addr) = ((max_size / 4) << 16) | fifo_mem_top;
+ fifo_mem_top += max_size / 4;
+
OTG_FS_DIEPTSIZ(addr) = (max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_EPENA |
OTG_FS_DIEPCTL0_SNAK | (type << 18) |
+ OTG_FS_DIEPCTL0_USBAEP |
(addr << 22) | max_size;
if (callback) {
@@ -152,7 +165,8 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
(max_size & OTG_FS_DIEPSIZ0_XFRSIZ_MASK);
OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
- OTG_FS_DIEPCTL0_CNAK | (type << 18) | max_size;
+ OTG_FS_DOEPCTL0_USBAEP | OTG_FS_DIEPCTL0_CNAK |
+ (type << 18) | max_size;
if (callback) {
_usbd_device.
@@ -164,41 +178,59 @@ static void stm32f107_ep_setup(u8 addr, u8 type, u16 max_size,
static void stm32f107_endpoints_reset(void)
{
- /* TODO: Reset all endpoints. */
+ /* The core resets the endpoints automatically on reset */
+ fifo_mem_top = RX_FIFO_SIZE;
}
static void stm32f107_ep_stall_set(u8 addr, u8 stall)
{
if(addr == 0) {
if(stall)
- OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_STALL;
+ OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL;
else
- OTG_FS_DOEPCTL(addr) &= ~OTG_FS_DOEPCTL0_STALL;
+ OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL;
}
if(addr & 0x80) {
addr &= 0x7F;
- if(stall)
+ if(stall) {
OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTL0_STALL;
- else
+ } else {
OTG_FS_DIEPCTL(addr) &= ~OTG_FS_DIEPCTL0_STALL;
- /* TODO: Reset to DATA0 */
+ OTG_FS_DIEPCTL(addr) |= OTG_FS_DIEPCTLX_SD0PID;
+ }
} else {
- if(stall)
+ if(stall) {
OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_STALL;
- else
+ } else {
OTG_FS_DOEPCTL(addr) &= ~OTG_FS_DOEPCTL0_STALL;
- /* TODO: Reset to DATA0 */
+ OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTLX_SD0PID;
+ }
}
}
static u8 stm32f107_ep_stall_get(u8 addr)
{
- /* TODO: return 1 if STALL set. */
- (void)addr;
+ /* return non-zero if STALL set. */
+ if(addr & 0x80)
+ return (OTG_FS_DIEPCTL(addr&0x7f) & OTG_FS_DIEPCTL0_STALL)?1:0;
+ else
+ return (OTG_FS_DOEPCTL(addr) & OTG_FS_DOEPCTL0_STALL)?1:0;
+}
+
+static void stm32f107_ep_nak_set(u8 addr, u8 nak)
+{
+ /* It does not make sence to force NAK on IN endpoints */
+ if(addr & 0x80)
+ return;
+
+ force_nak[addr] = nak;
- return 0;
+ if(nak)
+ OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_SNAK;
+ else
+ OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_CNAK;
}
static u16 stm32f107_ep_write_packet(u8 addr, const void *buf, u16 len)
@@ -247,31 +279,33 @@ static u16 stm32f107_ep_read_packet(u8 addr, void *buf, u16 len)
}
OTG_FS_DOEPTSIZ(addr) = doeptsiz[addr];
- OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA | OTG_FS_DOEPCTL0_CNAK;
+ OTG_FS_DOEPCTL(addr) |= OTG_FS_DOEPCTL0_EPENA |
+ (force_nak[addr] ? OTG_FS_DOEPCTL0_SNAK : OTG_FS_DOEPCTL0_CNAK);
return len;
}
static void stm32f107_poll(void)
{
- /* TODO: Read interrupt status register */
+ /* Read interrupt status register */
u32 intsts = OTG_FS_GINTSTS;
+ int i;
if (intsts & OTG_FS_GINTSTS_ENUMDNE) {
- /* TODO: Handle USB RESET condition */
+ /* Handle USB RESET condition */
OTG_FS_GINTSTS = OTG_FS_GINTSTS_ENUMDNE;
_usbd_reset();
return;
}
- /* TODO: Handle transfer complete condition */
/* Note: RX and TX handled differently in this device. */
if (intsts & OTG_FS_GINTSTS_RXFLVL) {
/* Receive FIFO non-empty */
u32 rxstsp = OTG_FS_GRXSTSP;
u32 pktsts = rxstsp & OTG_FS_GRXSTSP_PKTSTS_MASK;
if((pktsts != OTG_FS_GRXSTSP_PKTSTS_OUT) &&
- (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP)) return;
+ (pktsts != OTG_FS_GRXSTSP_PKTSTS_SETUP))
+ return;
u8 ep = rxstsp & OTG_FS_GRXSTSP_EPNUM_MASK;
u8 type;
@@ -285,39 +319,33 @@ static void stm32f107_poll(void)
if (_usbd_device.user_callback_ctr[ep][type])
_usbd_device.user_callback_ctr[ep][type] (ep);
- /* TODO: clear any interrupt flag */
}
/* There is no global interrupt flag for transmit complete.
* the XFRC bit must be checked in each OTG_FS_DIEPINT(x)
*/
- /* TODO: Check on endpoint interrupt... */
- {
- int i;
- for (i = 0; i < 4; i++) { /* Iterate over endpoints */
- if(OTG_FS_DIEPINT(i) & OTG_FS_DIEPINTX_XFRC) {
- /* Transfer complete */
- if (_usbd_device.user_callback_ctr[i][USB_TRANSACTION_IN])
- _usbd_device.user_callback_ctr[i][USB_TRANSACTION_IN] (i);
- OTG_FS_DIEPINT(i) = OTG_FS_DIEPINTX_XFRC;
- }
+ for (i = 0; i < 4; i++) { /* Iterate over endpoints */
+ if(OTG_FS_DIEPINT(i) & OTG_FS_DIEPINTX_XFRC) {
+ /* Transfer complete */
+ if (_usbd_device.user_callback_ctr[i][USB_TRANSACTION_IN])
+ _usbd_device.user_callback_ctr[i][USB_TRANSACTION_IN] (i);
+ OTG_FS_DIEPINT(i) = OTG_FS_DIEPINTX_XFRC;
}
}
- /* TODO: Handle suspend condition */
- if (0) {
- /* TODO: Clear suspend interrupt flag */
+ if (intsts & OTG_FS_GINTSTS_USBSUSP) {
if (_usbd_device.user_callback_suspend)
_usbd_device.user_callback_suspend();
+ OTG_FS_GINTSTS = OTG_FS_GINTSTS_USBSUSP;
}
- /* TODO: Handle wakeup condition */
- if (0) {
- /* TODO: Clear wakeup interrupt flag */
+ if (intsts & OTG_FS_GINTSTS_WKUPINT) {
if (_usbd_device.user_callback_resume)
_usbd_device.user_callback_resume();
+ OTG_FS_GINTSTS = OTG_FS_GINTSTS_WKUPINT;
}
- /* TODO: Handle SOF condition */
+ if (intsts & OTG_FS_GINTSTS_SOF)
+ OTG_FS_GINTSTS = OTG_FS_GINTSTS_SOF;
}
diff --git a/lib/usb/usb_private.h b/lib/usb/usb_private.h
index 1bc6b3f..40d59a1 100644
--- a/lib/usb/usb_private.h
+++ b/lib/usb/usb_private.h
@@ -78,6 +78,7 @@ struct _usbd_driver {
void (*ep_setup)(u8 addr, u8 type, u16 max_size, void (*cb)(u8 ep));
void (*ep_reset)(void);
void (*ep_stall_set)(u8 addr, u8 stall);
+ void (*ep_nak_set)(u8 addr, u8 nak);
u8 (*ep_stall_get)(u8 addr);
u16 (*ep_write_packet)(u8 addr, const void *buf, u16 len);
u16 (*ep_read_packet)(u8 addr, void *buf, u16 len);
diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c
index 5995387..aa92010 100644
--- a/lib/usb/usb_standard.c
+++ b/lib/usb/usb_standard.c
@@ -98,6 +98,11 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req,
if (!_usbd_device.strings)
return 0; /* Device doesn't support strings. */
+ /* Check that string index is in range */
+ for(i = 0; i <= (req->wValue & 0xff); i++)
+ if(_usbd_device.strings[i] == NULL)
+ return 0;
+
sd->bLength = strlen(_usbd_device.strings[req->wValue & 0xff])
* 2 + 2;
sd->bDescriptorType = USB_DT_STRING;
@@ -131,6 +136,12 @@ static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf,
_usbd_device.current_address = req->wValue;
+ /* Special workaround for STM32F10[57] that require the address
+ * to be set here. This is undocumented!
+ */
+ if(_usbd_device.driver == &stm32f107_usb_driver)
+ _usbd_device.driver->set_address(req->wValue);
+
return 1;
}