From 8ef021cc354327450d0ee900f9197bb9aa30f0d3 Mon Sep 17 00:00:00 2001 From: eddyem Date: Wed, 22 Jul 2015 14:56:17 +0300 Subject: [PATCH] USB HID --- 1_wire/README | 1 + README | 3 + hid_mouse_keyboard/Makefile | 133 ++++++++++++ hid_mouse_keyboard/Readme.md | 5 + hid_mouse_keyboard/keycodes.c | 74 +++++++ hid_mouse_keyboard/keycodes.h | 138 ++++++++++++ hid_mouse_keyboard/ld/devices.data | 9 + hid_mouse_keyboard/ld/stm32f103x4.ld | 31 +++ hid_mouse_keyboard/ld/stm32f103x6.ld | 31 +++ hid_mouse_keyboard/ld/stm32f103x8.ld | 31 +++ hid_mouse_keyboard/ld/stm32f103xB.ld | 31 +++ hid_mouse_keyboard/ld/stm32f103xC.ld | 31 +++ hid_mouse_keyboard/ld/stm32f103xD.ld | 31 +++ hid_mouse_keyboard/ld/stm32f103xE.ld | 31 +++ hid_mouse_keyboard/ld/stm32f103xF.ld | 31 +++ hid_mouse_keyboard/ld/stm32f103xG.ld | 31 +++ hid_mouse_keyboard/usbhid.bin | Bin 0 -> 6004 bytes hid_mouse_keyboard/usbhid.c | 312 +++++++++++++++++++++++++++ 18 files changed, 954 insertions(+) create mode 100644 hid_mouse_keyboard/Makefile create mode 100644 hid_mouse_keyboard/Readme.md create mode 100644 hid_mouse_keyboard/keycodes.c create mode 100644 hid_mouse_keyboard/keycodes.h create mode 100644 hid_mouse_keyboard/ld/devices.data create mode 100644 hid_mouse_keyboard/ld/stm32f103x4.ld create mode 100644 hid_mouse_keyboard/ld/stm32f103x6.ld create mode 100644 hid_mouse_keyboard/ld/stm32f103x8.ld create mode 100644 hid_mouse_keyboard/ld/stm32f103xB.ld create mode 100644 hid_mouse_keyboard/ld/stm32f103xC.ld create mode 100644 hid_mouse_keyboard/ld/stm32f103xD.ld create mode 100644 hid_mouse_keyboard/ld/stm32f103xE.ld create mode 100644 hid_mouse_keyboard/ld/stm32f103xF.ld create mode 100644 hid_mouse_keyboard/ld/stm32f103xG.ld create mode 100755 hid_mouse_keyboard/usbhid.bin create mode 100644 hid_mouse_keyboard/usbhid.c diff --git a/1_wire/README b/1_wire/README index 8abf06f..472f619 100644 --- a/1_wire/README +++ b/1_wire/README @@ -5,3 +5,4 @@ written for chinese devboard based on STM32F103RBT6 Press H for help // Still some troubles left: for example, can't read ROM; also the code isn't fully done yet + diff --git a/README b/README index c53512d..dd1acbd 100644 --- a/README +++ b/README @@ -3,3 +3,6 @@ These are my simple snippets for STM32 (compiled with libopencm3) - client-term is terminal client used instead of "com" - simple_cdc is simplest USB-CDC working in char-mode, press H for help (another commands are for LEDs switching and test of integer input) + +- 1_wire - pseudo-hardware realisation of 1-wire protocol + diff --git a/hid_mouse_keyboard/Makefile b/hid_mouse_keyboard/Makefile new file mode 100644 index 0000000..94ccdc0 --- /dev/null +++ b/hid_mouse_keyboard/Makefile @@ -0,0 +1,133 @@ +BINARY = usbhid +BOOTPORT ?= /dev/ttyUSB0 +BOOTSPEED ?= 115200 +# change this linking script depending on particular MCU model, +# for example, if you have STM32F103VBT6, you should write: +LDSCRIPT = ld/stm32f103xB.ld +LIBNAME = opencm3_stm32f1 +DEFS = -DSTM32F1 -DEBUG + +OBJDIR = mk +INDEPENDENT_HEADERS= + +FP_FLAGS ?= -msoft-float +ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd + +############################################################################### +# Executables +PREFIX ?= arm-none-eabi + +RM := rm -f +RMDIR := rmdir +CC := $(PREFIX)-gcc +LD := $(PREFIX)-gcc +AR := $(PREFIX)-ar +AS := $(PREFIX)-as +OBJCOPY := $(PREFIX)-objcopy +OBJDUMP := $(PREFIX)-objdump +GDB := $(PREFIX)-gdb +STFLASH = $(shell which st-flash) +STBOOT = $(shell which stm32flash) + +############################################################################### +# Source files +LDSCRIPT ?= $(BINARY).ld +SRC = $(wildcard *.c) +OBJS = $(addprefix $(OBJDIR)/, $(SRC:%.c=%.o)) + +ifeq ($(strip $(OPENCM3_DIR)),) +OPENCM3_DIR := /usr/local/arm-none-eabi +$(info Using $(OPENCM3_DIR) path to library) +endif + +INCLUDE_DIR = $(OPENCM3_DIR)/include +LIB_DIR = $(OPENCM3_DIR)/lib +SCRIPT_DIR = $(OPENCM3_DIR)/scripts + +############################################################################### +# C flags +CFLAGS += -Os -g +CFLAGS += -Wall -Wextra -Wshadow -Wimplicit-function-declaration +CFLAGS += -Wredundant-decls +# -Wmissing-prototypes -Wstrict-prototypes +CFLAGS += -fno-common -ffunction-sections -fdata-sections + +############################################################################### +# C & C++ preprocessor common flags +CPPFLAGS += -MD +CPPFLAGS += -Wall -Werror +CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS) + +############################################################################### +# Linker flags +LDFLAGS += --static -nostartfiles +LDFLAGS += -L$(LIB_DIR) +LDFLAGS += -T$(LDSCRIPT) +LDFLAGS += -Wl,-Map=$(*).map +LDFLAGS += -Wl,--gc-sections + +############################################################################### +# Used libraries +LDLIBS += -l$(LIBNAME) +LDLIBS += -Wl,--start-group -lc -lgcc -Wl,--end-group + +.SUFFIXES: .elf .bin .hex .srec .list .map .images +.SECONDEXPANSION: +.SECONDARY: + +ELF := $(OBJDIR)/$(BINARY).elf +LIST := $(OBJDIR)/$(BINARY).list +BIN := $(BINARY).bin +HEX := $(BINARY).hex + +all: bin + +elf: $(ELF) +bin: $(BIN) +hex: $(HEX) +list: $(LIST) + +$(OBJDIR): + mkdir $(OBJDIR) + +$(OBJDIR)/%.o: %.c + @printf " CC $<\n" + $(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $@ -c $< + +$(SRC) : %.c : %.h $(INDEPENDENT_HEADERS) + @touch $@ + +%.h: ; + +$(BIN): $(ELF) + @printf " OBJCOPY $(BIN)\n" + $(OBJCOPY) -Obinary $(ELF) $(BIN) + +$(HEX): $(ELF) + @printf " OBJCOPY $(HEX)\n" + $(OBJCOPY) -Oihex $(ELF) $(HEX) + +$(LIST): $(ELF) + @printf " OBJDUMP $(LIST)\n" + $(OBJDUMP) -S $(ELF) > $(LIST) + +$(ELF): $(OBJDIR) $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a + @printf " LD $(ELF)\n" + $(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(ELF) + +clean: + @printf " CLEAN\n" + $(RM) $(OBJS) $(OBJDIR)/*.d $(ELF) $(HEX) $(LIST) $(OBJDIR)/*.map + $(RMDIR) $(OBJDIR) + +flash: $(BIN) + @printf " FLASH $(BIN)\n" + $(STFLASH) write $(BIN) 0x8000000 + +boot: $(BIN) + @printf " LOAD $(BIN) through bootloader\n" + $(STBOOT) -b$(BOOTSPEED) $(BOOTPORT) -w $(BIN) + +.PHONY: clean elf hex list flash boot + +#-include $(OBJS:.o=.d) diff --git a/hid_mouse_keyboard/Readme.md b/hid_mouse_keyboard/Readme.md new file mode 100644 index 0000000..91a7553 --- /dev/null +++ b/hid_mouse_keyboard/Readme.md @@ -0,0 +1,5 @@ +### USB HID mouse & keyboard + +This is a very simple example of simultaneous STM32 work as compound USB-HID device: usb & mouse. +Written for STM32F103RBT6 +When you connect your device to computer it will move mouse cursor by square 40x40 and write text "top/bottom right/left" on each corner. diff --git a/hid_mouse_keyboard/keycodes.c b/hid_mouse_keyboard/keycodes.c new file mode 100644 index 0000000..39b09b0 --- /dev/null +++ b/hid_mouse_keyboard/keycodes.c @@ -0,0 +1,74 @@ +/* + * keycodes.c + * + * Copyright 2015 Edward V. Emelianov + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "keycodes.h" +/* + * Keyboard buffer: + * buf[1]: MOD + * buf[2]: reserved + * buf[3]..buf[8] - keycodes 1..6 + */ +static uint8_t buf[9] = {2,0,0,0,0,0,0,0,0}; + +#define _(x) (x|0x80) +// array for keycodes according to ASCII table; MSB is MOD_SHIFT flag +static const uint8_t keycodes[] = { + // space !"#$%&' + KEY_SPACE, _(KEY_1), _(KEY_QUOTE), _(KEY_3), _(KEY_4), _(KEY_5), _(KEY_7), KEY_QUOTE, + // ()*+,-./ + _(KEY_9), _(KEY_0), _(KEY_8), _(KEY_EQUAL), KEY_COMMA, KEY_MINUS, KEY_PERIOD, KEY_SLASH, + // 0..9 + 39, 30, 31, 32, 33, 34, 35, 36, 37, 38, + // :;<=>?@ + _(KEY_SEMICOLON), KEY_SEMICOLON, _(KEY_COMMA), KEY_EQUAL, _(KEY_PERIOD), _(KEY_SLASH), _(KEY_2), + // A..Z: for a in $(seq 0 25); do printf "$((a+132)),"; done + 132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157, + // [\]^_` + KEY_LEFT_BRACE, KEY_BACKSLASH, KEY_RIGHT_BRACE, _(KEY_6), _(KEY_MINUS), KEY_TILDE, + // a..z: for a in $(seq 0 25); do printf "$((a+4)),"; done + 4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29, + // {|}~ + _(KEY_LEFT_BRACE), _(KEY_BACKSLASH), _(KEY_RIGHT_BRACE), _(KEY_TILDE) +}; + +uint8_t *set_key_buf(uint8_t MOD, uint8_t KEY){ + buf[1] = MOD; + buf[3] = KEY; + return buf; +} + +/** + * return buffer for sending symbol "ltr" with addition modificator mod + */ +uint8_t *press_key_mod(char ltr, uint8_t mod){ + uint8_t MOD = 0; + uint8_t KEY = 0; + if(ltr > 31){ + KEY = keycodes[ltr - 32]; + if(KEY & 0x80){ + MOD = MOD_SHIFT; + KEY &= 0x7f; + } + }else if (ltr == '\n') KEY = KEY_ENTER; + buf[1] = MOD | mod; + buf[3] = KEY; + return buf; +} diff --git a/hid_mouse_keyboard/keycodes.h b/hid_mouse_keyboard/keycodes.h new file mode 100644 index 0000000..98a2fa1 --- /dev/null +++ b/hid_mouse_keyboard/keycodes.h @@ -0,0 +1,138 @@ +/* + * keycodes.h + * + * Copyright 2015 Edward V. Emelianov + * + * 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#pragma once +#ifndef __KEYKODES_H__ +#define __KEYKODES_H__ + +#include + +uint8_t *set_key_buf(uint8_t MOD, uint8_t KEY); +#define release_key() set_key_buf(0,0) +uint8_t *press_key_mod(char key, uint8_t mod); +#define press_key(k) press_key_mod(k, 0) + +#define MOD_CTRL 0x01 +#define MOD_SHIFT 0x02 +#define MOD_ALT 0x04 +#define MOD_GUI 0x08 + +#define LEFT(mod) (mod) +#define RIGHT(mod) ((mod << 4)) + +#define KEY_A 4 +#define KEY_B 5 +#define KEY_C 6 +#define KEY_D 7 +#define KEY_E 8 +#define KEY_F 9 +#define KEY_G 10 +#define KEY_H 11 +#define KEY_I 12 +#define KEY_J 13 +#define KEY_K 14 +#define KEY_L 15 +#define KEY_M 16 +#define KEY_N 17 +#define KEY_O 18 +#define KEY_P 19 +#define KEY_Q 20 +#define KEY_R 21 +#define KEY_S 22 +#define KEY_T 23 +#define KEY_U 24 +#define KEY_V 25 +#define KEY_W 26 +#define KEY_X 27 +#define KEY_Y 28 +#define KEY_Z 29 +#define KEY_1 30 +#define KEY_2 31 +#define KEY_3 32 +#define KEY_4 33 +#define KEY_5 34 +#define KEY_6 35 +#define KEY_7 36 +#define KEY_8 37 +#define KEY_9 38 +#define KEY_0 39 +#define KEY_ENTER 40 +#define KEY_ESC 41 +#define KEY_BACKSPACE 42 +#define KEY_TAB 43 +#define KEY_SPACE 44 +#define KEY_MINUS 45 +#define KEY_EQUAL 46 +#define KEY_LEFT_BRACE 47 +#define KEY_RIGHT_BRACE 48 +#define KEY_BACKSLASH 49 +#define KEY_NUMBER 50 +#define KEY_SEMICOLON 51 +#define KEY_QUOTE 52 +#define KEY_TILDE 53 +#define KEY_COMMA 54 +#define KEY_PERIOD 55 +#define KEY_SLASH 56 +#define KEY_CAPS_LOCK 57 +#define KEY_F1 58 +#define KEY_F2 59 +#define KEY_F3 60 +#define KEY_F4 61 +#define KEY_F5 62 +#define KEY_F6 63 +#define KEY_F7 64 +#define KEY_F8 65 +#define KEY_F9 66 +#define KEY_F10 67 +#define KEY_F11 68 +#define KEY_F12 69 +#define KEY_PRINTSCREEN 70 +#define KEY_SCROLL_LOCK 71 +#define KEY_PAUSE 72 +#define KEY_INSERT 73 +#define KEY_HOME 74 +#define KEY_PAGE_UP 75 +#define KEY_DELETE 76 +#define KEY_END 77 +#define KEY_PAGE_DOWN 78 +#define KEY_RIGHT 79 +#define KEY_LEFT 80 +#define KEY_DOWN 81 +#define KEY_UP 82 +#define KEY_NUM_LOCK 83 +#define KEYPAD_SLASH 84 +#define KEYPAD_ASTERIX 85 +#define KEYPAD_MINUS 86 +#define KEYPAD_PLUS 87 +#define KEYPAD_ENTER 88 +#define KEYPAD_1 89 +#define KEYPAD_2 90 +#define KEYPAD_3 91 +#define KEYPAD_4 92 +#define KEYPAD_5 93 +#define KEYPAD_6 94 +#define KEYPAD_7 95 +#define KEYPAD_8 96 +#define KEYPAD_9 97 +#define KEYPAD_0 98 +#define KEYPAD_PERIOD 99 + +#endif // __KEYKODES_H__ diff --git a/hid_mouse_keyboard/ld/devices.data b/hid_mouse_keyboard/ld/devices.data new file mode 100644 index 0000000..7f29538 --- /dev/null +++ b/hid_mouse_keyboard/ld/devices.data @@ -0,0 +1,9 @@ +stm32f103?4* stm32f1 ROM=16K RAM=6K +stm32f103?6* stm32f1 ROM=32K RAM=10K +stm32f103?8* stm32f1 ROM=64K RAM=20K +stm32f103?b* stm32f1 ROM=128K RAM=20K +stm32f103?c* stm32f1 ROM=256K RAM=48K +stm32f103?d* stm32f1 ROM=384K RAM=64K +stm32f103?e* stm32f1 ROM=512K RAM=64K +stm32f103?f* stm32f1 ROM=768K RAM=96K +stm32f103?g* stm32f1 ROM=1024K RAM=96K diff --git a/hid_mouse_keyboard/ld/stm32f103x4.ld b/hid_mouse_keyboard/ld/stm32f103x4.ld new file mode 100644 index 0000000..efed65e --- /dev/null +++ b/hid_mouse_keyboard/ld/stm32f103x4.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 16K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 6K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hid_mouse_keyboard/ld/stm32f103x6.ld b/hid_mouse_keyboard/ld/stm32f103x6.ld new file mode 100644 index 0000000..13f05f9 --- /dev/null +++ b/hid_mouse_keyboard/ld/stm32f103x6.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 32K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 10K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hid_mouse_keyboard/ld/stm32f103x8.ld b/hid_mouse_keyboard/ld/stm32f103x8.ld new file mode 100644 index 0000000..2c4640f --- /dev/null +++ b/hid_mouse_keyboard/ld/stm32f103x8.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hid_mouse_keyboard/ld/stm32f103xB.ld b/hid_mouse_keyboard/ld/stm32f103xB.ld new file mode 100644 index 0000000..138444d --- /dev/null +++ b/hid_mouse_keyboard/ld/stm32f103xB.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hid_mouse_keyboard/ld/stm32f103xC.ld b/hid_mouse_keyboard/ld/stm32f103xC.ld new file mode 100644 index 0000000..fda76bf --- /dev/null +++ b/hid_mouse_keyboard/ld/stm32f103xC.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hid_mouse_keyboard/ld/stm32f103xD.ld b/hid_mouse_keyboard/ld/stm32f103xD.ld new file mode 100644 index 0000000..0f996c2 --- /dev/null +++ b/hid_mouse_keyboard/ld/stm32f103xD.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 384K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hid_mouse_keyboard/ld/stm32f103xE.ld b/hid_mouse_keyboard/ld/stm32f103xE.ld new file mode 100644 index 0000000..b0fcb69 --- /dev/null +++ b/hid_mouse_keyboard/ld/stm32f103xE.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hid_mouse_keyboard/ld/stm32f103xF.ld b/hid_mouse_keyboard/ld/stm32f103xF.ld new file mode 100644 index 0000000..62d47db --- /dev/null +++ b/hid_mouse_keyboard/ld/stm32f103xF.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 768K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hid_mouse_keyboard/ld/stm32f103xG.ld b/hid_mouse_keyboard/ld/stm32f103xG.ld new file mode 100644 index 0000000..0c0c968 --- /dev/null +++ b/hid_mouse_keyboard/ld/stm32f103xG.ld @@ -0,0 +1,31 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Karl Palsson + * + * 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 STM32F100x4, 16K flash, 4K RAM. */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 96K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f1.ld + diff --git a/hid_mouse_keyboard/usbhid.bin b/hid_mouse_keyboard/usbhid.bin new file mode 100755 index 0000000000000000000000000000000000000000..300e091182ccb37fc1132a87e4e68122453e5be5 GIT binary patch literal 6004 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 + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "keycodes.h" + +const struct usb_device_descriptor dev = { + .bLength = USB_DT_DEVICE_SIZE, + .bDescriptorType = USB_DT_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0, + .bDeviceSubClass = 0, + .bDeviceProtocol = 0, + .bMaxPacketSize0 = 64, + .idVendor = 0x0483, + .idProduct = 0x5710, + .bcdDevice = 0x0200, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 3, + .bNumConfigurations = 1, +}; + +static const uint8_t hid_report_descriptor[] = +{ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ + 0x09, 0x02, /* Usage (Mouse) */ + 0xA1, 0x01, /* Collection (Application) */ + 0x09, 0x01, /* Usage (Pointer) */ + 0xA1, 0x00, /* Collection (Physical) */ + 0x85, 0x01, /* Report ID */ + 0x05, 0x09, /* Usage Page (Buttons) */ + 0x19, 0x01, /* Usage Minimum (01) */ + 0x29, 0x03, /* Usage Maximum (03) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (0) */ + 0x95, 0x03, /* Report Count (3) */ + 0x75, 0x01, /* Report Size (1) */ + 0x81, 0x02, /* Input (Data, Variable, Absolute) */ + 0x95, 0x01, /* Report Count (1) */ + 0x75, 0x05, /* Report Size (5) */ + 0x81, 0x01, /* Input (Constant) ;5 bit padding */ + 0x05, 0x01, /* Usage Page (Generic Desktop) */ + 0x09, 0x30, /* Usage (X) */ + 0x09, 0x31, /* Usage (Y) */ + 0x15, 0x81, /* Logical Minimum (-127) */ + 0x25, 0x7F, /* Logical Maximum (127) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x02, /* Report Count (2) */ + 0x81, 0x06, /* Input (Data, Variable, Relative) */ + 0xC0, 0xC0,/* End Collection,End Collection */ +// + 0x09, 0x06, /* Usage (Keyboard) */ + 0xA1, 0x01, /* Collection (Application) */ + 0x85, 0x02, /* Report ID */ + 0x05, 0x07, /* Usage (Key codes) */ + 0x19, 0xE0, /* Usage Minimum (224) */ + 0x29, 0xE7, /* Usage Maximum (231) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x08, /* Report Count (8) */ + 0x81, 0x02, /* Input (Data, Variable, Absolute) */ + 0x95, 0x01, /* Report Count (1) */ + 0x75, 0x08, /* Report Size (8) */ + 0x81, 0x01, /* Input (Constant) ;5 bit padding */ + 0x95, 0x05, /* Report Count (5) */ + 0x75, 0x01, /* Report Size (1) */ + 0x05, 0x08, /* Usage Page (Page# for LEDs) */ + 0x19, 0x01, /* Usage Minimum (01) */ + 0x29, 0x05, /* Usage Maximum (05) */ + 0x91, 0x02, /* Output (Data, Variable, Absolute) */ + 0x95, 0x01, /* Report Count (1) */ + 0x75, 0x03, /* Report Size (3) */ + 0x91, 0x01, /* Output (Constant) */ + 0x95, 0x06, /* Report Count (1) */ + 0x75, 0x08, /* Report Size (3) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x65, /* Logical Maximum (101) */ + 0x05, 0x07, /* Usage (Key codes) */ + 0x19, 0x00, /* Usage Minimum (00) */ + 0x29, 0x65, /* Usage Maximum (101) */ + 0x81, 0x00, /* Input (Data, Array) */ + 0xC0 /* End Collection,End Collection */ +}; + +static const struct { + struct usb_hid_descriptor hid_descriptor; + struct { + uint8_t bReportDescriptorType; + uint16_t wDescriptorLength; + } __attribute__((packed)) hid_report; +} __attribute__((packed)) hid_function = { + .hid_descriptor = { + .bLength = sizeof(hid_function), + .bDescriptorType = USB_DT_HID, + .bcdHID = 0x0100, + .bCountryCode = 0, + .bNumDescriptors = 1, + }, + .hid_report = { + .bReportDescriptorType = USB_DT_REPORT, + .wDescriptorLength = sizeof(hid_report_descriptor), + }, +}; + +const struct usb_endpoint_descriptor hid_endpoint = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x81, + .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT, + .wMaxPacketSize = 9, + .bInterval = 0x05, +}; + +const struct usb_interface_descriptor hid_iface = { + .bLength = USB_DT_INTERFACE_SIZE, + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = 1, // boot + .bInterfaceProtocol = 1, // keyboard + .iInterface = 0, + + .endpoint = &hid_endpoint, + + .extra = &hid_function, + .extralen = sizeof(hid_function), +}; + +const struct usb_interface ifaces[] = {{ + .num_altsetting = 1, + .altsetting = &hid_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 = 0xC0, + .bMaxPower = 0x32, + + .interface = ifaces, +}; + +static const char *usb_strings[] = { + "Something strange", + "Keyboard + mouse", + "demo", +}; + +/* Buffer to be used for control requests. */ +uint8_t usbd_control_buffer[128]; + +static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, + void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req)) +{ + (void)complete; + (void)usbd_dev; + + if ((req->bmRequestType != 0x81) || + (req->bRequest != USB_REQ_GET_DESCRIPTOR) || + (req->wValue != 0x2200)) + return 0; + + /* Handle the HID report descriptor. */ + *buf = (uint8_t *)hid_report_descriptor; + *len = sizeof(hid_report_descriptor); + + return 1; +} + +static void hid_set_config(usbd_device *usbd_dev, uint16_t wValue) +{ + (void)wValue; + (void)usbd_dev; + + usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL); + + usbd_register_control_callback( + usbd_dev, + USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE, + USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT, + hid_control_request); + + systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8); + /* SysTick interrupt every N clock pulses: set reload to N-1 */ + systick_set_reload(99999); + systick_interrupt_enable(); + systick_counter_enable(); +} + +usbd_device *usbd_dev; + +int main(void) +{ + int i; + + rcc_clock_setup_in_hsi_out_48mhz(); + + rcc_periph_clock_enable(RCC_GPIOC); + + gpio_set(GPIOC, GPIO11); + gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + GPIO_CNF_OUTPUT_PUSHPULL, GPIO11); + + usbd_dev = usbd_init(&stm32f103_usb_driver, &dev, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer)); + usbd_register_set_config_callback(usbd_dev, hid_set_config); + + for (i = 0; i < 0x80000; i++) + __asm__("nop"); + + gpio_clear(GPIOC, GPIO11); + + while (1) + usbd_poll(usbd_dev); +} + +void move_mouse(int8_t x, int8_t y){ + /* + * buf[0]: 1 - report ID + * buf[1]: bit2 - middle button, bit1 - right, bit0 - left + * buf[2]: move X + * buf[3]: move Y + * buf[4]: wheel + */ + int8_t buf[5] = {1,0,0,0,0}; + buf[2] = x; buf[3] = y; + while(5 != usbd_ep_write_packet(usbd_dev, 0x81, buf, 5)); +} + +/* + * Keyboard buffer: + * buf[1]: MOD + * buf[2]: reserved + * buf[3]..buf[8] - keycodes 1..6 + */ +void send_word(char *wrd){ + do{ + while(9 != usbd_ep_write_packet(usbd_dev, 0x81, press_key(*wrd), 9)); + while(9 != usbd_ep_write_packet(usbd_dev, 0x81, release_key(), 9)); + }while(*(++wrd)); +} + +void sys_tick_handler(void){ + static int steps = 0; + static uint8_t state = 0; + int8_t x = 0, y = 0; + switch (state){ + case 0: + x = 1; + break; + case 1: + y = 1; + break; + case 2: + x = -1; + break; + default: + y = -1; + break; + } + if(++steps > 40){ + switch (state){ + case 0: + send_word("top right\n"); + break; + case 1: + send_word("bottom right\n"); + break; + case 2: + send_word("bottom left\n"); + break; + default: + send_word("top left\n"); + break; + } + steps = 0; + if(++state == 4) + state = 0; + } + move_mouse(x, y); +} +