From ed70a1efa3335b6bf64c8c6a6f5be4dc25bdd9b7 Mon Sep 17 00:00:00 2001 From: Amir Hammad Date: Fri, 9 Sep 2016 18:36:38 +0200 Subject: Switch to cmake build system * use tinyprintf * ability to configure project via ccmake Signed-off-by: Amir Hammad --- CMakeLists.txt | 94 +++++++ DEVICE_DRIVER_HOWTO | 3 - Makefile | 267 ------------------ README.md | 159 ++++++----- build/.gitignore | 1 + cmake/doc.cmake | 6 + cmake/openocd_flash.cmake | 18 ++ cmake/toolchain.cmake | 15 ++ compileDemo.sh | 2 - config.mk | 4 - include/driver/usbh_device_driver.h | 1 - include/usbh_config.h | 6 - libopencm3_stm32f4.ld | 32 --- libusbhost_stm32f4.ld | 32 +++ src/CMakeLists.txt | 61 +++++ src/demo.c | 7 +- src/tinyprintf.c | 521 ++++++++++++++++++++++++++++++++++++ src/tinyprintf.h | 186 +++++++++++++ src/usart_helpers.c | 39 +-- src/usart_helpers.h | 1 - 20 files changed, 1043 insertions(+), 412 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 DEVICE_DRIVER_HOWTO delete mode 100644 Makefile create mode 100644 cmake/doc.cmake create mode 100644 cmake/openocd_flash.cmake create mode 100644 cmake/toolchain.cmake delete mode 100755 compileDemo.sh delete mode 100644 config.mk delete mode 100644 libopencm3_stm32f4.ld create mode 100644 libusbhost_stm32f4.ld create mode 100644 src/CMakeLists.txt create mode 100644 src/tinyprintf.c create mode 100644 src/tinyprintf.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b97355d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,94 @@ +cmake_minimum_required (VERSION 2.6) + +# initialize compiler +include (cmake/toolchain.cmake) + +# initialize flashing +include (cmake/openocd_flash.cmake) + +# initilize doc +include (cmake/doc.cmake) + +project (libusbhost C) + +# Declare cached variables + +set (USE_STM32F4_FS TRUE CACHE BOOL "Use USB full speed (FS) host periphery") +set (USE_STM32F4_HS TRUE CACHE BOOL "Use USB high speed (HS) host periphery") +set (USE_USART_DEBUG TRUE CACHE BOOL "Use debug uart output") + +# Set compiler and linker flags + +set (FP_FLAGS + "-mfloat-abi=hard -mfpu=fpv4-sp-d16 -mfp16-format=alternative" +) + +set (ARCH_FLAGS + "-mthumb -mcpu=cortex-m4 ${FP_FLAGS}" +) +set (COMMON_FLAGS + "-O2 -g -Wextra -Wshadow -Wredundant-decls -fno-common -ffunction-sections -fdata-sections" +) + +set (CMAKE_C_FLAGS + "${COMMON_FLAGS} ${ARCH_FLAGS} -Wstrict-prototypes -Wmissing-prototypes -Wimplicit-function-declaration" +) + +set (CMAKE_CXX_FLAGS + "${COMMON_FLAGS} ${ARCH_FLAGS} -Weffc++" +) + +# C preprocessor flags +set (CPP_FLAGS + " -MD -Wall -Wundef" +) + +add_definitions (${CPP_FLAGS}) + +# set platform +add_definitions (-DSTM32F4) + +set (CMAKE_EXE_LINKER_FLAGS + "--static -nostartfiles -T${CMAKE_SOURCE_DIR}/libusbhost_stm32f4.ld -Wl,-Map=FIXME_ONE.map -Wl,--gc-sections -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group" +) + +include_directories (${CMAKE_SOURCE_DIR}/include) + +function (init_libopencm3) + include_directories (${CMAKE_SOURCE_DIR}/libopencm3/include) + link_directories (${CMAKE_SOURCE_DIR}/libopencm3/lib) + set (LIBOPENCM3_LIB opencm3_stm32f4 PARENT_SCOPE) + execute_process ( + COMMAND sh "${CMAKE_SOURCE_DIR}/initRepo.sh" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_QUIET + ) +endfunction (init_libopencm3) + +message (STATUS "Initializing repository") +init_libopencm3 () +message (STATUS "Repository initialized") + +# Process cached varibles +message (STATUS "Setuping build") +if (USE_STM32F4_FS) + message (STATUS "... Using USB full speed (FS) host periphery") + add_definitions (-DUSE_STM32F4_USBH_DRIVER_FS) +endif (USE_STM32F4_FS) + +if (USE_STM32F4_HS) + message (STATUS "... Using USB high speed (HS) host periphery") + add_definitions (-DUSE_STM32F4_USBH_DRIVER_HS) +endif (USE_STM32F4_HS) + +if (USE_USART_DEBUG) + message (STATUS "... Using debug uart output") + add_definitions (-DUSART_DEBUG) +endif (USE_USART_DEBUG) +message (STATUS "Setup done") + +add_custom_target (README.md + SOURCES README.md +) + +add_subdirectory (src) diff --git a/DEVICE_DRIVER_HOWTO b/DEVICE_DRIVER_HOWTO deleted file mode 100644 index e26c9f1..0000000 --- a/DEVICE_DRIVER_HOWTO +++ /dev/null @@ -1,3 +0,0 @@ -TODO - -See usbh_driver*.c in src directory for example of device drivers. diff --git a/Makefile b/Makefile deleted file mode 100644 index 350e42a..0000000 --- a/Makefile +++ /dev/null @@ -1,267 +0,0 @@ -## -## This file is part of the libusbhost project. -## Imported and adopted from libopencm3 project. -## -## Copyright (C) 2009 Uwe Hermann -## Copyright (C) 2010 Piotr Esden-Tempski -## Copyright (C) 2013 Frantisek Burian -## Copyright (C) 2014 Amir Hammad -## -## This library is free software: you can redistribute it and/or modify -## it under the terms of the GNU Lesser General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## This library 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 Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public License -## along with this library. If not, see . -## - -BINARY = demo -BINARY := $(addprefix build/, demo) -LIBUSBHOSTNAME = usbhost - -LIBUSBHOST := $(addprefix build/lib, $(LIBUSBHOSTNAME)) -LIBNAME = opencm3_stm32f4 -DEFS = -DSTM32F4 - -# load user config -include config.mk -DEFS += $(USER_CONFIG) - -ifdef USART_DEBUG -DEFS += -DUSART_DEBUG -endif - -DEFS += -Iinclude -LDSCRIPT = lib$(LIBNAME).ld - -SRCDIR = src -OPENCM3_DIR ?= ./libopencm3 -FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mfp16-format=alternative -ARCH_FLAGS = -mthumb -mcpu=cortex-m4 $(FP_FLAGS) - -################################################################################ -# OpenOCD specific variables - -OOCD ?= openocd -OOCD_INTERFACE ?= stlink-v2 -OOCD_BOARD ?= stm32f4discovery - -################################################################################ -# Black Magic Probe specific variables -# Set the BMP_PORT to a serial port and then BMP is used for flashing -BMP_PORT ?= - -################################################################################ -# texane/stlink specific variables -#STLINK_PORT ?= :4242 - -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -NULL := 2>/dev/null -endif - -############################################################################### -# Executables - -PREFIX ?= arm-none-eabi - -CC := $(PREFIX)-gcc -CXX := $(PREFIX)-g++ -LD := $(PREFIX)-gcc -AR := $(PREFIX)-ar -AS := $(PREFIX)-as -OBJCOPY := $(PREFIX)-objcopy -OBJDUMP := $(PREFIX)-objdump -GDB := $(PREFIX)-gdb -STFLASH = $(shell which st-flash) -STYLECHECK := /checkpatch.pl -STYLECHECKFLAGS := --no-tree -f --terse --mailback -STYLECHECKFILES := $(shell find . -name '*.[ch]') - - -############################################################################### -# Source files - -LDSCRIPT ?= $(BINARY).ld - - -SRCS := $(sort $(notdir $(wildcard $(SRCDIR)/*.c))) -OBJSDEMO := $(patsubst %.c, build/%.o ,$(SRCS)) -SRCS := $(sort $(notdir $(wildcard $(SRCDIR)/*.cpp))) -OBJSDEMO += $(patsubst %.cpp, build/%.o ,$(SRCS)) -OBJS = $(filter-out $(BINARY).o, $(OBJSDEMO)) - -ifndef USART_DEBUG -OBJS := $(filter-out build/usart_helpers.o, $(OBJS)) -OBJSDEMO := $(filter-out build/usart_helpers.o, $(OBJSDEMO)) -else -$(info compiling with DEBUG functions) -endif - - -INCLUDE_DIR = $(OPENCM3_DIR)/include -LIB_DIR = $(OPENCM3_DIR)/lib -SCRIPT_DIR = $(OPENCM3_DIR)/scripts - -############################################################################### -# C flags - -CFLAGS += -Ofast -g -CFLAGS += -Wextra -Wshadow -Wimplicit-function-declaration -CFLAGS += -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes -CFLAGS += -fno-common -ffunction-sections -fdata-sections - -############################################################################### -# C++ flags - -CXXFLAGS += -Ofast -g -CXXFLAGS += -Wextra -Wshadow -Wredundant-decls -Weffc++ -CXXFLAGS += -fno-common -ffunction-sections -fdata-sections - -############################################################################### -# C & C++ preprocessor common flags - -CPPFLAGS += -MD -CPPFLAGS += -Wall -Wundef -CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS) - -############################################################################### -# Linker flags - -LDFLAGS += --static -nostartfiles -LDFLAGS += -L$(LIB_DIR) -LDFLAGS += -T$(LDSCRIPT) -LDFLAGS += -Wl,-Map=build/$*.map -LDFLAGS += -Wl,--gc-sections -ifeq ($(V),99) -LDFLAGS += -Wl,--print-gc-sections -endif - -############################################################################### -# Used libraries - -LDLIBS += -l$(LIBNAME) -LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group - -############################################################################### -############################################################################### -############################################################################### - -.SUFFIXES: .elf .bin .hex .srec .list .map .images -.SECONDEXPANSION: -.SECONDARY: - - -all: elf bin lib -doc: - doxygen - -elf: $(BINARY).elf -bin: $(BINARY).bin -hex: $(BINARY).hex -srec: $(BINARY).srec -list: $(BINARY).list -lib: $(LIBUSBHOST).a -images: $(BINARY).images -flash: $(BINARY).flash - -%.images: %.bin %.hex %.srec %.list %.map - @#printf "*** $* images generated ***\n" - -%.bin: %.elf - @printf " OBJCOPY $(*).bin\n" - $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin - -%.hex: %.elf - @#printf " OBJCOPY $(*).hex\n" - $(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex - -%.srec: %.elf - @#printf " OBJCOPY $(*).srec\n" - $(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec - -%.list: %.elf - @#printf " OBJDUMP $(*).list\n" - $(Q)$(OBJDUMP) -S $(*).elf > $(*).list - --include $(OBJSDEMO:.o=.d) -build/%.elf build/%.map: $(OBJSDEMO) $(LDSCRIPT) - @printf " LD $(*).elf\n" - $(Q)$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJSDEMO) $(LDLIBS) -o build/$*.elf - -build/%.o:$(SRCDIR)/%.c - @printf " CC $(*).c\n" - $(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $(SRCDIR)/$*.c - -build/%.o: $(SRCDIR)/%.cxx - @printf " CXX $(*).cxx\n" - $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $(SRCDIR)/$(*).cxx - -build/%.o: $(SRCDIR)/%.cpp - @printf " CXX $(*).cpp\n" - $(Q)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $(SRCDIR)/$(*).cpp -$(LIB_DIR)/lib$(LIBNAME).a: - -clean: - @#printf " CLEAN\n" - @rm -f build/* - - -%.stlink-flash: %.bin - @printf " FLASH $<\n" - $(Q)$(STFLASH) write $(*).bin 0x8000000 - -ifeq ($(STLINK_PORT),) -ifeq ($(BMP_PORT),) -ifeq ($(OOCD_SERIAL),) -%.flash: %.hex - @printf " FLASH $<\n" - @# IMPORTANT: Don't use "resume", only "reset" will work correctly! - $(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \ - -f board/$(OOCD_BOARD).cfg \ - -c "init" -c "reset init" \ - -c "flash write_image erase $(*).hex" \ - -c "reset" \ - -c "shutdown" $(NULL) -else -%.flash: %.hex - @printf " FLASH $<\n" - @# IMPORTANT: Don't use "resume", only "reset" will work correctly! - $(Q)$(OOCD) -f interface/$(OOCD_INTERFACE).cfg \ - -f board/$(OOCD_BOARD).cfg \ - -c "ft2232_serial $(OOCD_SERIAL)" \ - -c "init" -c "reset init" \ - -c "flash write_image erase $(*).hex" \ - -c "reset" \ - -c "shutdown" $(NULL) -endif -else -%.flash: %.elf - @printf " GDB $(*).elf (flash)\n" - $(Q)$(GDB) --batch \ - -ex 'target extended-remote $(BMP_PORT)' \ - -x $(SCRIPT_DIR)/black_magic_probe_flash.scr \ - $(*).elf -endif -else -%.flash: %.elf - @printf " GDB $(*).elf (flash)\n" - $(Q)$(GDB) --batch \ - -ex 'target extended-remote $(STLINK_PORT)' \ - -x $(SCRIPT_DIR)/stlink_flash.scr \ - $(*).elf -endif - -.PHONY: images clean stylecheck styleclean elf bin hex srec list testing doc - --include $(OBJS:.o=.d) -build/lib$(LIBUSBHOSTNAME).a: $(OBJS) - @printf " LIB $@\n" - $(Q)$(AR) rcs $@ $(OBJS) diff --git a/README.md b/README.md index 3d5df3f..d23b425 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,104 @@ -###General Information +##General Information +[Link to the official repository](http://github.com/libusbhost/libusbhost) -**This library is in an active development.** -**WARNING**: None of its features are considered stable ! +###Objectives -This library implement usb host driver allowing users use -or write device drivers, which functionality -is abstracted of low level implementation. - -Main objectives are: - provide open-source(Lesser GPL3) usb host library for embedded devices -- execution speed: This library doesn't use blocking sleep, +- execution speed. This library doesn't use blocking sleep, making low overhead on runtime performance -- uses static allocation for all its buffers, -so no allocation and reallocation is affecting performance -(possibility of memory fragmentation. execution time indeterminism), -so no malloc(), realloc(), free(). -- written in C, with the support to use it with C++. -- does not depend on any Operating System. Library libopencm3 is used for testing purposes and to get proper defines. -So no runtime dependency is on this library. +- use static allocation for all of its buffers. +This means no allocation and reallocation is affecting performance +(possibility of memory fragmentation. execution time indeterminism). No malloc(), realloc(), free() +- do not depend on any operating system +### Supported hardware +- stm32f4discovery -Currently supported devices (yet tested) are: -* stm32f407 (stm32f4 Discovery) +### Supported device drivers -Native device drivers (mostly for demonstration purposes): - HUB - Gamepad - XBox compatible Controller - mouse (draft: only displays raw data) - USB MIDI devices (raw data + note on/off) -###Practical info - -!!! Do not forget to invoke "make clean" before new build when defines change(_TODO: remove this warning and fix the Makefile_) - - -**How to initialize repository** - -> ./initRepo.sh - -fetch libopencm3 submodule and compile needed libraries - -**How to generate documentation** - -> make doc - -**How to compile demo** - -Edit usbh_config.h to configure the library (By default Full speed OTG periphery on stm32f4 is supported) - - -> ./compileDemo.sh - -compiles demo, that can be flashed into stm32f4 Discovery platform and debug by USART - - -**How to upload firmware (FLASH) to stm32f4 Discovery** - -> sudo make flash - - -**How to view debug data** - -connect uart to USART6 pins on gpios: GPIOC6(TX - data), GPIOC7(RX - not used) -configure uart baud on PC side to 921600 with 1 stop bit, no parity, 8bit data, no handshake - - -**How to compile library only** - -> make lib - -**libusbhost.a** is built without usart debug support -(check compileDemo.sh for hint on how to compile with debug) - - -###Contact -Amir Hammad - *amir.hammad@hotmail.com* - -**Library is maintained there** -> http://github.com/libusbhost/libusbhost - +## Steps to compile library and demo +### Prerequisities +Make sure the following prerequisities are installed to be able to compile this library +- **git** for libopencm3 submodule fetch +- **gcc-arm-none-eabi** toolchain for cross compilation +- **cmake** +- **ccmake** (optional) +- **openocd** (optional) + +### Basic setup +1. go to build directory located in the root of the project +> cd build + +2. compile demo and the library with the default options set +> cmake .. && make + +Executable demo is placed into `build/demo.hex`. +Library is placed into `build/src/libusbhost.a`. + +### Advanced setup +*cmake* initial cache variables + + + + + + + + + + + + + + + + + + + +
Cache variableValueDescription
USE_STM32F4_FSTRUEEnable STM32F4 Full Speed USB host peripheral
USE_STM32F4_HSTRUEEnable STM32F4 High Speed USB host peripheral
USE_USART_DEBUGTRUEEnable writing of the debug information to USART6
OOCD_INTERFACE"stlink-v2"Interface configuration file used by the openocd
OOCD_BOARD"stm32f4discovery"Board configuration file used by the openocd
+You can alter these by issuing the following commands in the build directory + +- Graphical user interface +> ccmake .. + +- Command line interface +> cmake .. -D{VARIABLE}={VALUE} + +### Flashing +If the *openocd* is installed, `make flash` executed in the build directory +flashes the `build/demo.hex` to the stm32f4discovery board. + +### Reading debug output +The following table represents the configuration of the debug output + + + + + + + + + + + + + + + + +
GPIOGPIOC6
USART peripheryUSART6
FunctionUART TX
Baud rate921600
Uart mode8N1
+ +## License + +The libusbhost code is released under the terms of the GNU Lesser General +Public License (LGPL), version 3 or later. + +See COPYING.GPL3 and COPYING.LGPL3 for details. diff --git a/build/.gitignore b/build/.gitignore index e69de29..72e8ffc 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -0,0 +1 @@ +* diff --git a/cmake/doc.cmake b/cmake/doc.cmake new file mode 100644 index 0000000..76336a8 --- /dev/null +++ b/cmake/doc.cmake @@ -0,0 +1,6 @@ +add_custom_target (doc + COMMAND doxygen + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMENT "output is generted in the ${CMAKE_SOURCE_DIR}/doc" + SOURCES Doxyfile +) diff --git a/cmake/openocd_flash.cmake b/cmake/openocd_flash.cmake new file mode 100644 index 0000000..5c92c49 --- /dev/null +++ b/cmake/openocd_flash.cmake @@ -0,0 +1,18 @@ +find_program (OOCD openocd DOC "openocd executable") + +set (OOCD_INTERFACE stlink-v2 CACHE STRING "interface config file used for openocd flashing") +set (OOCD_BOARD stm32f4discovery CACHE STRING "board config file used for openocd flashing") +if (OOCD) + message (STATUS "OpenOCD found: ${OOCD}") + message (STATUS "... interface: ${OOCD_INTERFACE}") + message (STATUS "... board: ${OOCD_BOARD}") + add_custom_target (flash + COMMAND sh -c '${OOCD} -f interface/${OOCD_INTERFACE}.cfg + -f board/${OOCD_BOARD}.cfg + -c "init" -c "reset init" + -c "flash write_image erase $" + -c "reset" + -c "shutdown" ' + DEPENDS demo + ) +endif (OOCD) diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake new file mode 100644 index 0000000..b6e2af7 --- /dev/null +++ b/cmake/toolchain.cmake @@ -0,0 +1,15 @@ +set (_CMAKE_TOOLCHAIN_PREFIX "arm-none-eabi-" CACHE STRING "toolchain prefix") +set (_CMAKE_TOOLCHAIN_LOCATION "" CACHE STRING "toolchain location hint") + +set (CMAKE_SYSTEM_NAME Generic) +set (CMAKE_C_COMPILER_WORKS 1) +set (CMAKE_CXX_COMPILER_WORKS 1) +set (CMAKE_C_FLAGS "") +set (CMAKE_CXX_FLAGS "") +set (BUILD_SHARED_LIBS OFF) +find_program (CMAKE_C_COMPILER NAMES ${_CMAKE_TOOLCHAIN_PREFIX}gcc HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) +find_program (CMAKE_C_COMPILER NAMES ${_CMAKE_TOOLCHAIN_PREFIX}g++ HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) +find_program (CMAKE_OBJCOPY NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objcopy HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) +find_program (CMAKE_SIZE NAMES ${_CMAKE_TOOLCHAIN_PREFIX}size HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) + + diff --git a/compileDemo.sh b/compileDemo.sh deleted file mode 100755 index 7731473..0000000 --- a/compileDemo.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -USART_DEBUG=1 OPENCM3_DIR=libopencm3 make all diff --git a/config.mk b/config.mk deleted file mode 100644 index 3ba462b..0000000 --- a/config.mk +++ /dev/null @@ -1,4 +0,0 @@ - - -USER_CONFIG = - diff --git a/include/driver/usbh_device_driver.h b/include/driver/usbh_device_driver.h index 76e2619..eca8928 100644 --- a/include/driver/usbh_device_driver.h +++ b/include/driver/usbh_device_driver.h @@ -240,7 +240,6 @@ void device_xfer_control_read(void *data, uint16_t datalen, usbh_packet_callback void device_xfer_control_write_setup(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); void device_xfer_control_write_data(const void *data, uint16_t datalen, usbh_packet_callback_t callback, usbh_device_t *dev); - END_DECLS #endif diff --git a/include/usbh_config.h b/include/usbh_config.h index 7bf800b..4fa38cb 100644 --- a/include/usbh_config.h +++ b/include/usbh_config.h @@ -59,10 +59,4 @@ #error USBH_MAX_DEVICES > 127 #endif -// Uncomment to enable OTG_HS support - low level driver -// #define USE_STM32F4_USBH_DRIVER_HS - -// Uncomment to enable OTG_FS support - low level driver -#define USE_STM32F4_USBH_DRIVER_FS - #endif diff --git a/libopencm3_stm32f4.ld b/libopencm3_stm32f4.ld deleted file mode 100644 index 46a80f2..0000000 --- a/libopencm3_stm32f4.ld +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * Copyright (C) 2011 Stephen Caudle - * - * This library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This library 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library. If not, see . - */ - -/* Linker script for ST STM32F4DISCOVERY (STM32F407VG, 1024K flash, 128K RAM). */ - -/* Define memory regions. */ -MEMORY -{ - rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K -} - -/* Include the common ld script. */ -INCLUDE ./libopencm3/lib/libopencm3_stm32f4.ld - diff --git a/libusbhost_stm32f4.ld b/libusbhost_stm32f4.ld new file mode 100644 index 0000000..b814cc2 --- /dev/null +++ b/libusbhost_stm32f4.ld @@ -0,0 +1,32 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2011 Stephen Caudle + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Linker script for ST STM32F4DISCOVERY (STM32F407VG, 1024K flash, 128K RAM). */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f4.ld + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..3165b51 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,61 @@ +if (USE_USART_DEBUG) + set (USART_HELPERS + usart_helpers.c + tinyprintf.c + ) +else (USE_USART_DEBUG) + set (USART_HELPERS "") +endif (USE_USART_DEBUG) + +set (inc ${CMAKE_SOURCE_DIR}/include) + +add_library (usbhost + ${USART_HELPERS} + ${inc}/usbh_core.h + ${inc}/usbh_driver_ac_midi.h + ${inc}/usbh_driver_gp_xbox.h + ${inc}/usbh_driver_hid_mouse.h + ${inc}/usbh_driver_hub.h + ${inc}/usbh_lld_stm32f4.h + ${inc}/driver/usbh_device_driver.h + + usbh_core.c + usbh_driver_ac_midi.c + usbh_driver_ac_midi_private.h + usbh_driver_gp_xbox.c + usbh_driver_hid_mouse.c + usbh_driver_hub.c + usbh_driver_hub_private.h + usbh_lld_stm32f4.c +) + +target_link_libraries (usbhost + ${LIBOPENCM3_LIB} +) + +add_executable (demo + demo.c +) + +target_link_libraries (demo + usbhost +) + +add_custom_command (TARGET demo + POST_BUILD + COMMAND ${CMAKE_OBJCOPY} -Oihex $ ${CMAKE_BINARY_DIR}/demo.hex + COMMENT "Generating output files: ${CMAKE_BINARY_DIR}/demo.hex" +) + +add_custom_command (TARGET demo + POST_BUILD + COMMAND ${CMAKE_SIZE} $ + COMMENT "Calculating size of the binary" +) + +add_custom_command (TARGET usbhost + POST_BUILD + COMMENT "Calculating size of the library" + COMMAND ${CMAKE_SIZE} $ +) + diff --git a/src/demo.c b/src/demo.c index 5d829ac..3fedbd9 100644 --- a/src/demo.c +++ b/src/demo.c @@ -215,8 +215,13 @@ int main(void) * Pass array of supported device drivers */ const void *lld_drivers[] = { +#ifdef USE_STM32F4_USBH_DRIVER_FS usbh_lld_stm32f4_driver_fs, // Make sure USE_STM32F4_USBH_DRIVER_FS is defined in usbh_config.h -// usbh_lld_stm32f4_driver_hs, // Make sure USE_STM32F4_USBH_DRIVER_HS is defined in usbh_config.h +#endif + +#ifdef USE_STM32F4_USBH_DRIVER_HS + usbh_lld_stm32f4_driver_hs, // Make sure USE_STM32F4_USBH_DRIVER_HS is defined in usbh_config.h +#endif 0 }; usbh_init(lld_drivers, device_drivers); diff --git a/src/tinyprintf.c b/src/tinyprintf.c new file mode 100644 index 0000000..bb22700 --- /dev/null +++ b/src/tinyprintf.c @@ -0,0 +1,521 @@ +/* +File: tinyprintf.c + +Copyright (C) 2004 Kustaa Nyholm + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "tinyprintf.h" + + +/* + * Configuration + */ + +/* Enable long int support */ +#define PRINTF_LONG_SUPPORT + +/* Enable long long int support (implies long int support) */ +#define PRINTF_LONG_LONG_SUPPORT + +/* Enable %z (size_t) support */ +#define PRINTF_SIZE_T_SUPPORT + +/* + * Configuration adjustments + */ +#ifdef PRINTF_SIZE_T_SUPPORT +#include +#endif + +#ifdef PRINTF_LONG_LONG_SUPPORT +# define PRINTF_LONG_SUPPORT +#endif + +/* __SIZEOF___ defined at least by gcc */ +#ifdef __SIZEOF_POINTER__ +# define SIZEOF_POINTER __SIZEOF_POINTER__ +#endif +#ifdef __SIZEOF_LONG_LONG__ +# define SIZEOF_LONG_LONG __SIZEOF_LONG_LONG__ +#endif +#ifdef __SIZEOF_LONG__ +# define SIZEOF_LONG __SIZEOF_LONG__ +#endif +#ifdef __SIZEOF_INT__ +# define SIZEOF_INT __SIZEOF_INT__ +#endif + +#ifdef __GNUC__ +# define _TFP_GCC_NO_INLINE_ __attribute__ ((noinline)) +#else +# define _TFP_GCC_NO_INLINE_ +#endif + +/* + * Implementation + */ +struct param { + char lz:1; /**< Leading zeros */ + char alt:1; /**< alternate form */ + char uc:1; /**< Upper case (for base16 only) */ + char align_left:1; /**< 0 == align right (default), 1 == align left */ + unsigned int width; /**< field width */ + char sign; /**< The sign to display (if any) */ + unsigned int base; /**< number base (e.g.: 8, 10, 16) */ + char *bf; /**< Buffer to output */ +}; + + +#ifdef PRINTF_LONG_LONG_SUPPORT +static void _TFP_GCC_NO_INLINE_ ulli2a( + unsigned long long int num, struct param *p) +{ + int n = 0; + unsigned long long int d = 1; + char *bf = p->bf; + while (num / d >= p->base) + d *= p->base; + while (d != 0) { + int dgt = num / d; + num %= d; + d /= p->base; + if (n || dgt > 0 || d == 0) { + *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; +} + +static void lli2a(long long int num, struct param *p) +{ + if (num < 0) { + num = -num; + p->sign = '-'; + } + ulli2a(num, p); +} +#endif + +#ifdef PRINTF_LONG_SUPPORT +static void uli2a(unsigned long int num, struct param *p) +{ + int n = 0; + unsigned long int d = 1; + char *bf = p->bf; + while (num / d >= p->base) + d *= p->base; + while (d != 0) { + int dgt = num / d; + num %= d; + d /= p->base; + if (n || dgt > 0 || d == 0) { + *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; +} + +static void li2a(long num, struct param *p) +{ + if (num < 0) { + num = -num; + p->sign = '-'; + } + uli2a(num, p); +} +#endif + +static void ui2a(unsigned int num, struct param *p) +{ + int n = 0; + unsigned int d = 1; + char *bf = p->bf; + while (num / d >= p->base) + d *= p->base; + while (d != 0) { + int dgt = num / d; + num %= d; + d /= p->base; + if (n || dgt > 0 || d == 0) { + *bf++ = dgt + (dgt < 10 ? '0' : (p->uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; +} + +static void i2a(int num, struct param *p) +{ + if (num < 0) { + num = -num; + p->sign = '-'; + } + ui2a(num, p); +} + +static int a2d(char ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else + return -1; +} + +static char a2u(char ch, const char **src, int base, unsigned int *nump) +{ + const char *p = *src; + unsigned int num = 0; + int digit; + while ((digit = a2d(ch)) >= 0) { + if (digit > base) + break; + num = num * base + digit; + ch = *p++; + } + *src = p; + *nump = num; + return ch; +} + +static void putchw(void *putp, putcf putf, struct param *p) +{ + char ch; + int n = p->width; + char *bf = p->bf; + + /* Number of filling characters */ + while (*bf++ && n > 0) + n--; + if (p->sign) + n--; + if (p->alt && p->base == 16) + n -= 2; + else if (p->alt && p->base == 8) + n--; + + /* Fill with space to align to the right, before alternate or sign */ + if (!p->lz && !p->align_left) { + while (n-- > 0) + putf(putp, ' '); + } + + /* print sign */ + if (p->sign) + putf(putp, p->sign); + + /* Alternate */ + if (p->alt && p->base == 16) { + putf(putp, '0'); + putf(putp, (p->uc ? 'X' : 'x')); + } else if (p->alt && p->base == 8) { + putf(putp, '0'); + } + + /* Fill with zeros, after alternate or sign */ + if (p->lz) { + while (n-- > 0) + putf(putp, '0'); + } + + /* Put actual buffer */ + bf = p->bf; + while ((ch = *bf++)) + putf(putp, ch); + + /* Fill with space to align to the left, after string */ + if (!p->lz && p->align_left) { + while (n-- > 0) + putf(putp, ' '); + } +} + +void tfp_format(void *putp, putcf putf, const char *fmt, va_list va) +{ + struct param p; +#ifdef PRINTF_LONG_SUPPORT + char bf[23]; /* long = 64b on some architectures */ +#else + char bf[12]; /* int = 32b on some architectures */ +#endif + char ch; + p.bf = bf; + + while ((ch = *(fmt++))) { + if (ch != '%') { + putf(putp, ch); + } else { +#ifdef PRINTF_LONG_SUPPORT + char lng = 0; /* 1 for long, 2 for long long */ +#endif + /* Init parameter struct */ + p.lz = 0; + p.alt = 0; + p.width = 0; + p.align_left = 0; + p.sign = 0; + + /* Flags */ + while ((ch = *(fmt++))) { + switch (ch) { + case '-': + p.align_left = 1; + continue; + case '0': + p.lz = 1; + continue; + case '#': + p.alt = 1; + continue; + default: + break; + } + break; + } + + /* Width */ + if (ch >= '0' && ch <= '9') { + ch = a2u(ch, &fmt, 10, &(p.width)); + } + + /* We accept 'x.y' format but don't support it completely: + * we ignore the 'y' digit => this ignores 0-fill + * size and makes it == width (ie. 'x') */ + if (ch == '.') { + p.lz = 1; /* zero-padding */ + /* ignore actual 0-fill size: */ + do { + ch = *(fmt++); + } while ((ch >= '0') && (ch <= '9')); + } + +#ifdef PRINTF_SIZE_T_SUPPORT +# ifdef PRINTF_LONG_SUPPORT + if (ch == 'z') { + ch = *(fmt++); + if (sizeof(size_t) == sizeof(unsigned long int)) + lng = 1; +# ifdef PRINTF_LONG_LONG_SUPPORT + else if (sizeof(size_t) == sizeof(unsigned long long int)) + lng = 2; +# endif + } else +# endif +#endif + +#ifdef PRINTF_LONG_SUPPORT + if (ch == 'l') { + ch = *(fmt++); + lng = 1; +#ifdef PRINTF_LONG_LONG_SUPPORT + if (ch == 'l') { + ch = *(fmt++); + lng = 2; + } +#endif + } +#endif + switch (ch) { + case 0: + goto abort; + case 'u': + p.base = 10; +#ifdef PRINTF_LONG_SUPPORT +#ifdef PRINTF_LONG_LONG_SUPPORT + if (2 == lng) + ulli2a(va_arg(va, unsigned long long int), &p); + else +#endif + if (1 == lng) + uli2a(va_arg(va, unsigned long int), &p); + else +#endif + ui2a(va_arg(va, unsigned int), &p); + putchw(putp, putf, &p); + break; + case 'd': + case 'i': + p.base = 10; +#ifdef PRINTF_LONG_SUPPORT +#ifdef PRINTF_LONG_LONG_SUPPORT + if (2 == lng) + lli2a(va_arg(va, long long int), &p); + else +#endif + if (1 == lng) + li2a(va_arg(va, long int), &p); + else +#endif + i2a(va_arg(va, int), &p); + putchw(putp, putf, &p); + break; +#ifdef SIZEOF_POINTER + case 'p': + p.alt = 1; +# if defined(SIZEOF_INT) && SIZEOF_POINTER <= SIZEOF_INT + lng = 0; +# elif defined(SIZEOF_LONG) && SIZEOF_POINTER <= SIZEOF_LONG + lng = 1; +# elif defined(SIZEOF_LONG_LONG) && SIZEOF_POINTER <= SIZEOF_LONG_LONG + lng = 2; +# endif +#endif + case 'x': + case 'X': + p.base = 16; + p.uc = (ch == 'X')?1:0; +#ifdef PRINTF_LONG_SUPPORT +#ifdef PRINTF_LONG_LONG_SUPPORT + if (2 == lng) + ulli2a(va_arg(va, unsigned long long int), &p); + else +#endif + if (1 == lng) + uli2a(va_arg(va, unsigned long int), &p); + else +#endif + ui2a(va_arg(va, unsigned int), &p); + putchw(putp, putf, &p); + break; + case 'o': + p.base = 8; + ui2a(va_arg(va, unsigned int), &p); + putchw(putp, putf, &p); + break; + case 'c': + putf(putp, (char)(va_arg(va, int))); + break; + case 's': + p.bf = va_arg(va, char *); + putchw(putp, putf, &p); + p.bf = bf; + break; + case '%': + putf(putp, ch); + default: + break; + } + } + } + abort:; +} + +#if TINYPRINTF_DEFINE_TFP_PRINTF +static putcf stdout_putf; +static void *stdout_putp; + +void init_printf(void *putp, putcf putf) +{ + stdout_putf = putf; + stdout_putp = putp; +} + +void tfp_printf(char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + tfp_format(stdout_putp, stdout_putf, fmt, va); + va_end(va); +} +#endif + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +struct _vsnprintf_putcf_data +{ + size_t dest_capacity; + char *dest; + size_t num_chars; +}; + +static void _vsnprintf_putcf(void *p, char c) +{ + struct _vsnprintf_putcf_data *data = (struct _vsnprintf_putcf_data*)p; + if (data->num_chars < data->dest_capacity) + data->dest[data->num_chars] = c; + data->num_chars ++; +} + +int tfp_vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + struct _vsnprintf_putcf_data data; + + if (size < 1) + return 0; + + data.dest = str; + data.dest_capacity = size-1; + data.num_chars = 0; + tfp_format(&data, _vsnprintf_putcf, format, ap); + + if (data.num_chars < data.dest_capacity) + data.dest[data.num_chars] = '\0'; + else + data.dest[data.dest_capacity] = '\0'; + + return data.num_chars; +} + +int tfp_snprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + int retval; + + va_start(ap, format); + retval = tfp_vsnprintf(str, size, format, ap); + va_end(ap); + return retval; +} + +struct _vsprintf_putcf_data +{ + char *dest; + size_t num_chars; +}; + +static void _vsprintf_putcf(void *p, char c) +{ + struct _vsprintf_putcf_data *data = (struct _vsprintf_putcf_data*)p; + data->dest[data->num_chars++] = c; +} + +int tfp_vsprintf(char *str, const char *format, va_list ap) +{ + struct _vsprintf_putcf_data data; + data.dest = str; + data.num_chars = 0; + tfp_format(&data, _vsprintf_putcf, format, ap); + data.dest[data.num_chars] = '\0'; + return data.num_chars; +} + +int tfp_sprintf(char *str, const char *format, ...) +{ + va_list ap; + int retval; + + va_start(ap, format); + retval = tfp_vsprintf(str, format, ap); + va_end(ap); + return retval; +} +#endif diff --git a/src/tinyprintf.h b/src/tinyprintf.h new file mode 100644 index 0000000..a769f4a --- /dev/null +++ b/src/tinyprintf.h @@ -0,0 +1,186 @@ +/* +File: tinyprintf.h + +Copyright (C) 2004 Kustaa Nyholm + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +This library is really just two files: 'tinyprintf.h' and 'tinyprintf.c'. + +They provide a simple and small (+400 loc) printf functionality to +be used in embedded systems. + +I've found them so useful in debugging that I do not bother with a +debugger at all. + +They are distributed in source form, so to use them, just compile them +into your project. + +Two printf variants are provided: printf and the 'sprintf' family of +functions ('snprintf', 'sprintf', 'vsnprintf', 'vsprintf'). + +The formats supported by this implementation are: +'c' 'd' 'i' 'o' 'p' 'u' 's' 'x' 'X'. + +Zero padding and field width are also supported. + +If the library is compiled with 'PRINTF_SUPPORT_LONG' defined, then +the long specifier is also supported. Note that this will pull in some +long math routines (pun intended!) and thus make your executable +noticeably longer. Likewise with 'PRINTF_LONG_LONG_SUPPORT' for the +long long specifier, and with 'PRINTF_SIZE_T_SUPPORT' for the size_t +specifier. + +The memory footprint of course depends on the target CPU, compiler and +compiler options, but a rough guesstimate (based on a H8S target) is about +1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. +Not too bad. Your mileage may vary. By hacking the source code you can +get rid of some hundred bytes, I'm sure, but personally I feel the balance of +functionality and flexibility versus code size is close to optimal for +many embedded systems. + +To use the printf, you need to supply your own character output function, +something like : + +void putc ( void* p, char c) +{ + while (!SERIAL_PORT_EMPTY) ; + SERIAL_PORT_TX_REGISTER = c; +} + +Before you can call printf, you need to initialize it to use your +character output function with something like: + +init_printf(NULL,putc); + +Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', +the NULL (or any pointer) you pass into the 'init_printf' will eventually be +passed to your 'putc' routine. This allows you to pass some storage space (or +anything really) to the character output function, if necessary. +This is not often needed but it was implemented like that because it made +implementing the sprintf function so neat (look at the source code). + +The code is re-entrant, except for the 'init_printf' function, so it is safe +to call it from interrupts too, although this may result in mixed output. +If you rely on re-entrancy, take care that your 'putc' function is re-entrant! + +The printf and sprintf functions are actually macros that translate to +'tfp_printf' and 'tfp_sprintf' when 'TINYPRINTF_OVERRIDE_LIBC' is set +(default). Setting it to 0 makes it possible to use them along with +'stdio.h' printf's in a single source file. When +'TINYPRINTF_OVERRIDE_LIBC' is set, please note that printf/sprintf are +not function-like macros, so if you have variables or struct members +with these names, things will explode in your face. Without variadic +macros this is the best we can do to wrap these function. If it is a +problem, just give up the macros and use the functions directly, or +rename them. + +It is also possible to avoid defining tfp_printf and/or tfp_sprintf by +clearing 'TINYPRINTF_DEFINE_TFP_PRINTF' and/or +'TINYPRINTF_DEFINE_TFP_SPRINTF' to 0. This allows for example to +export only tfp_format, which is at the core of all the other +functions. + +For further details see source code. + +regs Kusti, 23.10.2004 +*/ + +#ifndef __TFP_PRINTF__ +#define __TFP_PRINTF__ + +#include + +/* Global configuration */ + +/* Set this to 0 if you do not want to provide tfp_printf */ +#ifndef TINYPRINTF_DEFINE_TFP_PRINTF +# define TINYPRINTF_DEFINE_TFP_PRINTF 1 +#endif + +/* Set this to 0 if you do not want to provide + tfp_sprintf/snprintf/vsprintf/vsnprintf */ +#ifndef TINYPRINTF_DEFINE_TFP_SPRINTF +# define TINYPRINTF_DEFINE_TFP_SPRINTF 1 +#endif + +/* Set this to 0 if you do not want tfp_printf and + tfp_{vsn,sn,vs,s}printf to be also available as + printf/{vsn,sn,vs,s}printf */ +#ifndef TINYPRINTF_OVERRIDE_LIBC +# define TINYPRINTF_OVERRIDE_LIBC 1 +#endif + +/* Optional external types dependencies */ + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +# include /* size_t */ +#endif + +/* Declarations */ + +#ifdef __GNUC__ +# define _TFP_SPECIFY_PRINTF_FMT(fmt_idx,arg1_idx) \ + __attribute__((format (printf, fmt_idx, arg1_idx))) +#else +# define _TFP_SPECIFY_PRINTF_FMT(fmt_idx,arg1_idx) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*putcf) (void *, char); + +/* + 'tfp_format' really is the central function for all tinyprintf. For + each output character after formatting, the 'putf' callback is + called with 2 args: + - an arbitrary void* 'putp' param defined by the user and + passed unmodified from 'tfp_format', + - the character. + The 'tfp_printf' and 'tfp_sprintf' functions simply define their own + callback and pass to it the right 'putp' it is expecting. +*/ +void tfp_format(void *putp, putcf putf, const char *fmt, va_list va); + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +int tfp_vsnprintf(char *str, size_t size, const char *fmt, va_list ap); +int tfp_snprintf(char *str, size_t size, const char *fmt, ...) \ + _TFP_SPECIFY_PRINTF_FMT(3, 4); +int tfp_vsprintf(char *str, const char *fmt, va_list ap); +int tfp_sprintf(char *str, const char *fmt, ...) \ + _TFP_SPECIFY_PRINTF_FMT(2, 3); +# if TINYPRINTF_OVERRIDE_LIBC +# define vsnprintf tfp_vsnprintf +# define snprintf tfp_snprintf +# define vsprintf tfp_vsprintf +# define sprintf tfp_sprintf +# endif +#endif + +#if TINYPRINTF_DEFINE_TFP_PRINTF +void init_printf(void *putp, putcf putf); +void tfp_printf(char *fmt, ...) _TFP_SPECIFY_PRINTF_FMT(1, 2); +# if TINYPRINTF_OVERRIDE_LIBC +# define printf tfp_printf +# endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/usart_helpers.c b/src/usart_helpers.c index 5a9aa03..fc32333 100644 --- a/src/usart_helpers.c +++ b/src/usart_helpers.c @@ -22,14 +22,15 @@ #include "usart_helpers.h" +#define TINYPRINTF_OVERRIDE_LIBC 0 +#define TINYPRINTF_DEFINE_TFP_SPRINTF 0 +#include "tinyprintf.h" #include #include #include #include #include -#include - #define USART_FIFO_OUT_SIZE (4096) uint8_t usart_fifo_out_data[USART_FIFO_OUT_SIZE]; @@ -103,35 +104,22 @@ static void usart_fifo_in_push(uint8_t aData) usart_fifo_in_len++; } - -static void usart_write(const char * data, uint32_t len) +static void putf(void *arg, char c) { - uint32_t i; - for(i = 0; i < len; i++) - { - usart_fifo_push(data[i]); - } + //unused argument + (void)arg; + + usart_fifo_push(c); } + void usart_printf(const char *str, ...) { va_list va; va_start(va, str); - usart_vprintf(str, va); + tfp_format(NULL, putf, str, va); va_end(va); - -} - -void usart_vprintf(const char *str, va_list va) -{ - char databuffer[128]; - int i = vsnprintf(databuffer, 128, str, va); - if (i > 0) { - usart_write(databuffer, i); - } } - - void usart_init(uint32_t arg_usart, uint32_t baudrate) { usart_set_baudrate(arg_usart, baudrate); @@ -145,6 +133,7 @@ void usart_init(uint32_t arg_usart, uint32_t baudrate) usart_enable(arg_usart); usart = arg_usart; } + void usart_interrupt(void) { if (usart_get_interrupt_source(usart, USART_SR_RXNE)) { @@ -230,9 +219,7 @@ void usart_call_cmd(struct usart_commands * commands) LOG_PRINTF("#2"); return; } - //~ for (i = 0; i < command_len; i++) { - //~ LOG_PRINTF("%c", command[i]); - //~ } + i=0; while(commands[i].cmd != NULL) { if (!strcmp((char*)command, (char*)commands[i].cmd)) { @@ -243,7 +230,7 @@ void usart_call_cmd(struct usart_commands * commands) commands[i].callback(&command[command_argindex]); } } - usart_write("\n>>",4); + LOG_PRINTF("\n>>"); command_len = 0; command_argindex = 0; return; diff --git a/src/usart_helpers.h b/src/usart_helpers.h index d36f689..e62f67d 100644 --- a/src/usart_helpers.h +++ b/src/usart_helpers.h @@ -38,7 +38,6 @@ struct usart_commands{ #ifdef USART_DEBUG void usart_init(uint32_t usart, uint32_t baudrate); void usart_printf(const char *str, ...); -void usart_vprintf(const char *str, va_list va); void usart_fifo_send(void); void usart_call_cmd(struct usart_commands * commands); -- cgit