hello world

pull/1/head
Ondřej Hruška 9 years ago
parent 995fd3e73c
commit 19f0d369c1
  1. 2
      CMakeLists.txt
  2. 96
      Inc/circbuf.h
  3. 339
      Inc/keyboard.h
  4. 3
      Inc/main.h
  5. 3
      Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc/usbd_hid.h
  6. 18
      Middlewares/ST/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c
  7. 163
      Src/circbuf.c
  8. 117
      Src/keyboard.c
  9. 69
      Src/main.c
  10. 162
      Src/stm32f1xx_it.c
  11. 32
      Src/syscalls.c

@ -22,7 +22,7 @@ include_directories(Middlewares/ST/STM32_USB_Device_Library/Class/HID/Inc)
include_directories(Middlewares/ST/STM32_USB_Device_Library/Core/Inc)
add_definitions(-DSTM32F103x6)
add_executable(${PROJECT_NAME}.elf ${USER_SOURCES} ${LINKER_SCRIPT} Inc/main.h)
add_executable(${PROJECT_NAME}.elf ${USER_SOURCES} ${LINKER_SCRIPT})
target_link_libraries(${PROJECT_NAME}.elf HAL CMSIS USBFS)

@ -0,0 +1,96 @@
/**
* @file circbuf.h
* @author Ondřej Hruška, 2016
*
* Circular buffer / queue / stack.
* Slots are pre-allocated, values are copied into the buffer.
*
* The buffer may be used as a stack, event queue or a simple buffer.
*
* -------------------------------------
*
* NW LR
* append -> [][][][] -> pop
* <- push
*
* NW - next write pointer (stack base)
* LR - last read position (stack top)
*
* -------------------------------------
*
* MIT license
*/
#ifndef F103_USB_CIRCBUF_H
#define F103_USB_CIRCBUF_H
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct circbuf_struct CircBuf;
/**
* @brief Initialize a circular buffer. The buffer is malloc'd.
* @param capacity : buffer capacity
* @param elem_size : size of one element
* @return pointer to the buffer instance
*/
CircBuf *cbuf_create(size_t capacity, size_t elem_size);
/**
* @brief Destroy a buffer, freeing used memory.
*
* @attention
* If the buffer items have malloc'd members, you have
* to free them manually to avoid a memory leak.
*
* @param cb : buffer
*/
void cbuf_destroy(CircBuf *cb);
/** Test for full buffer */
bool cbuf_full(const CircBuf *cb);
/** Test for empty buffer */
bool cbuf_empty(const CircBuf *cb);
/**
* @brief Append a value to the buffer (FIFO)
* @param cb : buffer
* @param source : pointer to a value (will be copied)
* @return success
*/
bool cbuf_append(CircBuf *cb, const void *source);
/**
* @brief Push a value into the circbuf (LIFO).
*
* @param cb : buffer
* @param source : pointer to a value (will be copied)
* @return success
*/
bool cbuf_push(CircBuf *cb, const void *source);
/**
* @brief Read a value from the buffer, return success.
*
* @param cb : buffer
* @param dest : read destionation. If NULL, value is discarded.
* @return success
*/
bool cbuf_pop(CircBuf *cb, void *dest);
/** @brief Remove all data from buffer */
void cbuf_clear(CircBuf *cb);
#endif // F103_USB_CIRCBUF_H

@ -0,0 +1,339 @@
//
// Created by MightyPork on 7.8.16.
//
#ifndef F103_USB_KEYBOARD_H
#define F103_USB_KEYBOARD_H
#include <stdbool.h>
#include <stdint.h>
/** Max nr of simultaneous keys pressed */
#define KYBD_SLOTS 6
/** Struct that can be used for key buffers */
typedef struct {
uint8_t key;
bool press;
} KeyEvent;
/**
* Toggle key state
*
* @param key : key code
* @param press : key pressed / released
*/
bool kybd_key(uint8_t key, bool press);
/**
* Toggle modifier
*
* @param mod : Modifier mask
* @param press : Modifier pressed / released
*/
void kybd_mod(uint8_t mod, bool press);
/**
* Press a key
*
* @param key : key code
*/
bool kybd_press(uint8_t key);
/**
* Release a key
*
* @param key : key code
*/
bool kybd_release(uint8_t key);
/**
* Release all keys and cancel all modifiers
*/
void kybd_clear();
/**
* Get keyboard bytes for the USB HID report.
*
* @param arr : array long at least KYBD_SLOTS + 2
*/
void kybd_get_bytes(uint8_t *arr);
/* ----------------------------------------------------------- */
/**
* Modifier masks. Those may be used to directly set modifier status,
* as opposed to modifier Scan Codes 0xe0 - 0xe7, which do the same,
* but via the key press/release interface.
*/
#define MOD_LCTRL 0x01
#define MOD_LSHIFT 0x02
#define MOD_LALT 0x04
#define MOD_LMETA 0x08
#define MOD_RCTRL 0x10
#define MOD_RSHIFT 0x20
#define MOD_RALT 0x40
#define MOD_RMETA 0x80
/**
* USB HID Keyboard scan codes as per USB spec 1.11
* plus some additional codes
*
* Created by MightyPork, 2016
* Public domain
*
* Adapted from:
* https://source.android.com/devices/input/keyboard-devices.html
*/
#define KEY_NONE 0x00
#define KEY_ERR_OVF 0x01 // Keyboard Error Roll Over - used for all slots if too many keys are pressed ("Phantom key")
// 0x02 // Keyboard POST Fail
// 0x03 // Keyboard Error Undefined
#define KEY_A 0x04 // Keyboard a and A
#define KEY_B 0x05 // Keyboard b and B
#define KEY_C 0x06 // Keyboard c and C
#define KEY_D 0x07 // Keyboard d and D
#define KEY_E 0x08 // Keyboard e and E
#define KEY_F 0x09 // Keyboard f and F
#define KEY_G 0x0a // Keyboard g and G
#define KEY_H 0x0b // Keyboard h and H
#define KEY_I 0x0c // Keyboard i and I
#define KEY_J 0x0d // Keyboard j and J
#define KEY_K 0x0e // Keyboard k and K
#define KEY_L 0x0f // Keyboard l and L
#define KEY_M 0x10 // Keyboard m and M
#define KEY_N 0x11 // Keyboard n and N
#define KEY_O 0x12 // Keyboard o and O
#define KEY_P 0x13 // Keyboard p and P
#define KEY_Q 0x14 // Keyboard q and Q
#define KEY_R 0x15 // Keyboard r and R
#define KEY_S 0x16 // Keyboard s and S
#define KEY_T 0x17 // Keyboard t and T
#define KEY_U 0x18 // Keyboard u and U
#define KEY_V 0x19 // Keyboard v and V
#define KEY_W 0x1a // Keyboard w and W
#define KEY_X 0x1b // Keyboard x and X
#define KEY_Y 0x1c // Keyboard y and Y
#define KEY_Z 0x1d // Keyboard z and Z
#define KEY_1 0x1e // Keyboard 1 and !
#define KEY_2 0x1f // Keyboard 2 and @
#define KEY_3 0x20 // Keyboard 3 and #
#define KEY_4 0x21 // Keyboard 4 and $
#define KEY_5 0x22 // Keyboard 5 and %
#define KEY_6 0x23 // Keyboard 6 and ^
#define KEY_7 0x24 // Keyboard 7 and &
#define KEY_8 0x25 // Keyboard 8 and *
#define KEY_9 0x26 // Keyboard 9 and (
#define KEY_0 0x27 // Keyboard 0 and )
#define KEY_ENTER 0x28 // Keyboard Return (ENTER)
#define KEY_ESC 0x29 // Keyboard ESCAPE
#define KEY_BACKSPACE 0x2a // Keyboard DELETE (Backspace)
#define KEY_TAB 0x2b // Keyboard Tab
#define KEY_SPACE 0x2c // Keyboard Spacebar
#define KEY_MINUS 0x2d // Keyboard - and _
#define KEY_EQUAL 0x2e // Keyboard = and +
#define KEY_LEFTBRACE 0x2f // Keyboard [ and {
#define KEY_RIGHTBRACE 0x30 // Keyboard ] and }
#define KEY_BACKSLASH 0x31 // Keyboard \ and |
#define KEY_HASHTILDE 0x32 // Keyboard Non-US # and ~
#define KEY_SEMICOLON 0x33 // Keyboard ; and :
#define KEY_APOSTROPHE 0x34 // Keyboard ' and "
#define KEY_GRAVE 0x35 // Keyboard ` and ~
#define KEY_COMMA 0x36 // Keyboard , and <
#define KEY_DOT 0x37 // Keyboard . and >
#define KEY_SLASH 0x38 // Keyboard / and ?
#define KEY_CAPSLOCK 0x39 // Keyboard Caps Lock
#define KEY_F1 0x3a // Keyboard F1
#define KEY_F2 0x3b // Keyboard F2
#define KEY_F3 0x3c // Keyboard F3
#define KEY_F4 0x3d // Keyboard F4
#define KEY_F5 0x3e // Keyboard F5
#define KEY_F6 0x3f // Keyboard F6
#define KEY_F7 0x40 // Keyboard F7
#define KEY_F8 0x41 // Keyboard F8
#define KEY_F9 0x42 // Keyboard F9
#define KEY_F10 0x43 // Keyboard F10
#define KEY_F11 0x44 // Keyboard F11
#define KEY_F12 0x45 // Keyboard F12
#define KEY_SYSRQ 0x46 // Keyboard Print Screen
#define KEY_SCROLLLOCK 0x47 // Keyboard Scroll Lock
#define KEY_PAUSE 0x48 // Keyboard Pause
#define KEY_INSERT 0x49 // Keyboard Insert
#define KEY_HOME 0x4a // Keyboard Home
#define KEY_PAGEUP 0x4b // Keyboard Page Up
#define KEY_DELETE 0x4c // Keyboard Delete Forward
#define KEY_END 0x4d // Keyboard End
#define KEY_PAGEDOWN 0x4e // Keyboard Page Down
#define KEY_RIGHT 0x4f // Keyboard Right Arrow
#define KEY_LEFT 0x50 // Keyboard Left Arrow
#define KEY_DOWN 0x51 // Keyboard Down Arrow
#define KEY_UP 0x52 // Keyboard Up Arrow
#define KEY_NUMLOCK 0x53 // Keyboard Num Lock and Clear
#define KEY_KPSLASH 0x54 // Keypad /
#define KEY_KPASTERISK 0x55 // Keypad *
#define KEY_KPMINUS 0x56 // Keypad -
#define KEY_KPPLUS 0x57 // Keypad +
#define KEY_KPENTER 0x58 // Keypad ENTER
#define KEY_KP1 0x59 // Keypad 1 and End
#define KEY_KP2 0x5a // Keypad 2 and Down Arrow
#define KEY_KP3 0x5b // Keypad 3 and PageDn
#define KEY_KP4 0x5c // Keypad 4 and Left Arrow
#define KEY_KP5 0x5d // Keypad 5
#define KEY_KP6 0x5e // Keypad 6 and Right Arrow
#define KEY_KP7 0x5f // Keypad 7 and Home
#define KEY_KP8 0x60 // Keypad 8 and Up Arrow
#define KEY_KP9 0x61 // Keypad 9 and Page Up
#define KEY_KP0 0x62 // Keypad 0 and Insert
#define KEY_KPDOT 0x63 // Keypad . and Delete
#define KEY_102ND 0x64 // Keyboard Non-US \ and |
#define KEY_COMPOSE 0x65 // Keyboard Application
#define KEY_POWER 0x66 // Keyboard Power
#define KEY_KPEQUAL 0x67 // Keypad =
#define KEY_F13 0x68 // Keyboard F13
#define KEY_F14 0x69 // Keyboard F14
#define KEY_F15 0x6a // Keyboard F15
#define KEY_F16 0x6b // Keyboard F16
#define KEY_F17 0x6c // Keyboard F17
#define KEY_F18 0x6d // Keyboard F18
#define KEY_F19 0x6e // Keyboard F19
#define KEY_F20 0x6f // Keyboard F20
#define KEY_F21 0x70 // Keyboard F21
#define KEY_F22 0x71 // Keyboard F22
#define KEY_F23 0x72 // Keyboard F23
#define KEY_F24 0x73 // Keyboard F24
#define KEY_OPEN 0x74 // Keyboard Execute
#define KEY_HELP 0x75 // Keyboard Help
#define KEY_PROPS 0x76 // Keyboard Menu
#define KEY_FRONT 0x77 // Keyboard Select
#define KEY_STOP 0x78 // Keyboard Stop
#define KEY_AGAIN 0x79 // Keyboard Again
#define KEY_UNDO 0x7a // Keyboard Undo
#define KEY_CUT 0x7b // Keyboard Cut
#define KEY_COPY 0x7c // Keyboard Copy
#define KEY_PASTE 0x7d // Keyboard Paste
#define KEY_FIND 0x7e // Keyboard Find
#define KEY_MUTE 0x7f // Keyboard Mute
#define KEY_VOLUMEUP 0x80 // Keyboard Volume Up
#define KEY_VOLUMEDOWN 0x81 // Keyboard Volume Down
// 0x82 Keyboard Locking Caps Lock
// 0x83 Keyboard Locking Num Lock
// 0x84 Keyboard Locking Scroll Lock
#define KEY_KPCOMMA 0x85 // Keypad Comma
// 0x86 Keypad Equal Sign
#define KEY_RO 0x87 // Keyboard International1
#define KEY_KATAKANAHIRAGANA 0x88 // Keyboard International2
#define KEY_YEN 0x89 // Keyboard International3
#define KEY_HENKAN 0x8a // Keyboard International4
#define KEY_MUHENKAN 0x8b // Keyboard International5
#define KEY_KPJPCOMMA 0x8c // Keyboard International6
// 0x8d Keyboard International7
// 0x8e Keyboard International8
// 0x8f Keyboard International9
#define KEY_HANGEUL 0x90 // Keyboard LANG1
#define KEY_HANJA 0x91 // Keyboard LANG2
#define KEY_KATAKANA 0x92 // Keyboard LANG3
#define KEY_HIRAGANA 0x93 // Keyboard LANG4
#define KEY_ZENKAKUHANKAKU 0x94 // Keyboard LANG5
// 0x95 Keyboard LANG6
// 0x96 Keyboard LANG7
// 0x97 Keyboard LANG8
// 0x98 Keyboard LANG9
// 0x99 Keyboard Alternate Erase
// 0x9a Keyboard SysReq/Attention
// 0x9b Keyboard Cancel
// 0x9c Keyboard Clear
// 0x9d Keyboard Prior
// 0x9e Keyboard Return
// 0x9f Keyboard Separator
// 0xa0 Keyboard Out
// 0xa1 Keyboard Oper
// 0xa2 Keyboard Clear/Again
// 0xa3 Keyboard CrSel/Props
// 0xa4 Keyboard ExSel
// 0xb0 Keypad 00
// 0xb1 Keypad 000
// 0xb2 Thousands Separator
// 0xb3 Decimal Separator
// 0xb4 Currency Unit
// 0xb5 Currency Sub-unit
#define KEY_KPLEFTPAREN 0xb6 // Keypad (
#define KEY_KPRIGHTPAREN 0xb7 // Keypad )
// 0xb8 Keypad {
// 0xb9 Keypad }
// 0xba Keypad Tab
// 0xbb Keypad Backspace
// 0xbc Keypad A
// 0xbd Keypad B
// 0xbe Keypad C
// 0xbf Keypad D
// 0xc0 Keypad E
// 0xc1 Keypad F
// 0xc2 Keypad XOR
// 0xc3 Keypad ^
// 0xc4 Keypad %
// 0xc5 Keypad <
// 0xc6 Keypad >
// 0xc7 Keypad &
// 0xc8 Keypad &&
// 0xc9 Keypad |
// 0xca Keypad ||
// 0xcb Keypad :
// 0xcc Keypad #
// 0xcd Keypad Space
// 0xce Keypad @
// 0xcf Keypad !
// 0xd0 Keypad Memory Store
// 0xd1 Keypad Memory Recall
// 0xd2 Keypad Memory Clear
// 0xd3 Keypad Memory Add
// 0xd4 Keypad Memory Subtract
// 0xd5 Keypad Memory Multiply
// 0xd6 Keypad Memory Divide
// 0xd7 Keypad +/-
// 0xd8 Keypad Clear
// 0xd9 Keypad Clear Entry
// 0xda Keypad Binary
// 0xdb Keypad Octal
// 0xdc Keypad Decimal
// 0xdd Keypad Hexadecimal
#define KEY_LEFTCTRL 0xe0 // Keyboard Left Control
#define KEY_LEFTSHIFT 0xe1 // Keyboard Left Shift
#define KEY_LEFTALT 0xe2 // Keyboard Left Alt
#define KEY_LEFTMETA 0xe3 // Keyboard Left GUI
#define KEY_RIGHTCTRL 0xe4 // Keyboard Right Control
#define KEY_RIGHTSHIFT 0xe5 // Keyboard Right Shift
#define KEY_RIGHTALT 0xe6 // Keyboard Right Alt
#define KEY_RIGHTMETA 0xe7 // Keyboard Right GUI
#define KEY_MEDIA_PLAYPAUSE 0xe8
#define KEY_MEDIA_STOPCD 0xe9
#define KEY_MEDIA_PREVIOUSSONG 0xea
#define KEY_MEDIA_NEXTSONG 0xeb
#define KEY_MEDIA_EJECTCD 0xec
#define KEY_MEDIA_VOLUMEUP 0xed
#define KEY_MEDIA_VOLUMEDOWN 0xee
#define KEY_MEDIA_MUTE 0xef
#define KEY_MEDIA_WWW 0xf0
#define KEY_MEDIA_BACK 0xf1
#define KEY_MEDIA_FORWARD 0xf2
#define KEY_MEDIA_STOP 0xf3
#define KEY_MEDIA_FIND 0xf4
#define KEY_MEDIA_SCROLLUP 0xf5
#define KEY_MEDIA_SCROLLDOWN 0xf6
#define KEY_MEDIA_EDIT 0xf7
#define KEY_MEDIA_SLEEP 0xf8
#define KEY_MEDIA_COFFEE 0xf9
#define KEY_MEDIA_REFRESH 0xfa
#define KEY_MEDIA_CALC 0xfb
#endif //F103_USB_KEYBOARD_H

@ -6,7 +6,10 @@
#define F103_USB_MAIN_H_H
#include "stm32f1xx_hal.h"
#include "circbuf.h"
extern void dbg(const char* msg);
extern CircBuf *key_cbuf;
#endif //F103_USB_MAIN_H_H

@ -50,7 +50,8 @@ extern "C" {
* @{
*/
#define HID_EPIN_ADDR 0x81
#define HID_EPIN_SIZE 0x04
// CHANGED
#define HID_EPIN_SIZE 0x08
#define USB_HID_CONFIG_DESC_SIZ 34
#define USB_HID_DESC_SIZ 9

@ -166,7 +166,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_
0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/
0x01, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*//* CHANGED */
0, /*iInterface: Index of string descriptor*/
/******************** Descriptor of Joystick Mouse HID ********************/
/******************** Descriptor of Keyboard HID ********************/
/* 18 */
0x09, /*bLength: HID Descriptor size*/
HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/
@ -191,6 +191,7 @@ __ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_
};
/* USB HID device Configuration Descriptor */
/* SAME AS ABOVE! */
__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END =
{
/* 18 */
@ -225,7 +226,10 @@ __ALIGN_BEGIN static uint8_t HID_KEYBD_ReportDesc[HID_KEYBD_REPORT_DESC_SIZE] _
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
// Modifier byte - 8 bits
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
@ -233,26 +237,34 @@ __ALIGN_BEGIN static uint8_t HID_KEYBD_ReportDesc[HID_KEYBD_REPORT_DESC_SIZE] _
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
// reserved byte - 8 bits
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
// LEDs report - 5 bits
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x05, // USAGE_MAXIMUM (Kana)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
// Unused padding - 3 bits
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs) - padding, unused
// Key codes - 6 bytes
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) - Key down
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
};

@ -0,0 +1,163 @@
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "circbuf.h"
#define malloc_s malloc
// --- Circbuf data structure ----
/** Offset in void* buffer */
#define PV_OFFS(pvBuf, elem_size, index) ((uint8_t*)(pvBuf) + ((elem_size)*(index)))
// Instance structure
struct circbuf_struct {
void *buf;
size_t elem_size;
size_t cap;
size_t lr; // last read pos
size_t nw; // next write pos
};
/**
* @brief Write data to a CircBuf slot
* @param cb : circbuf
* @param index : slot index
* @param source : data source
*/
static void write_buffer(CircBuf *cb, size_t index, const void *source)
{
memcpy(PV_OFFS(cb->buf, cb->elem_size, index), source, cb->elem_size);
}
/**
* @brief Copy data from a CircBuf slot to a buffer
* @param cb : circbuf
* @param index : slot index
* @param dest : destination buffer
*/
static void read_buffer(const CircBuf *cb, size_t index, void *dest)
{
memcpy(dest, PV_OFFS(cb->buf, cb->elem_size, index), cb->elem_size);
}
/** Create a cbuf */
CircBuf *cbuf_create(size_t capacity, size_t elem_size)
{
// add one, because one is always unused.
capacity++;
// Allocate the structure
CircBuf *cb = malloc_s(sizeof(CircBuf));
// allocate the buffer
cb->buf = malloc_s(capacity * elem_size);
// set capacity, clear state
cb->elem_size = elem_size;
cb->cap = capacity;
cbuf_clear(cb);
return cb;
}
/** Release cbuf memory */
void cbuf_destroy(CircBuf *cb)
{
if (cb != NULL) {
if (cb->buf != NULL) {
free(cb->buf);
}
free(cb);
}
}
/** Check if cbuf is full */
bool cbuf_full(const CircBuf *cb)
{
if (cb == NULL) return false;
return (cb->lr == cb->nw);
}
/** Check if cbuf is empty */
bool cbuf_empty(const CircBuf *cb)
{
if (cb == NULL) return true;
return ((cb->lr + 1) % cb->cap) == cb->nw;
}
/** Write a byte to the buffer, if space left */
bool cbuf_append(CircBuf *cb, const void *source)
{
if (cb == NULL) return false;
if (source == NULL) return false;
if (cbuf_full(cb)) return false;
write_buffer(cb, cb->nw, source);
// increment
cb->nw++;
if (cb->nw == cb->cap) cb->nw = 0;
return true;
}
/** Push value to the end, like a stack. */
bool cbuf_push(CircBuf *cb, const void *source)
{
if (cb == NULL) return false;
if (source == NULL) return false;
if (cbuf_full(cb)) return false;
write_buffer(cb, cb->lr, source);
// move lr back
if (cb->lr == 0) {
cb->lr = cb->cap - 1; // wrap to the end
} else {
cb->lr--;
}
return true;
}
/** Read one byte, if not empty. */
bool cbuf_pop(CircBuf *cb, void *dest)
{
if (cb == NULL || dest == NULL) return false;
if (cbuf_empty(cb)) return false;
// increment
cb->lr++;
if (cb->lr == cb->cap) cb->lr = 0;
read_buffer(cb, cb->lr, dest);
return true;
}
/** Clear a cbuf */
void cbuf_clear(CircBuf *cb)
{
if (cb == NULL) return;
cb->lr = cb->cap - 1;
cb->nw = 0;
}

@ -0,0 +1,117 @@
//
// Created by MightyPork on 7.8.16.
//
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "keyboard.h"
static uint8_t modifiers = 0x00;
static uint8_t keys[KYBD_SLOTS] = {};
static uint8_t free_slot = 0;
static bool err_ovf = false;
/** Clear keys and mods */
void kybd_clear() {
memset(keys, 0x00, KYBD_SLOTS);
modifiers = 0x00;
free_slot = 0;
err_ovf = false;
}
/** Key down */
bool kybd_press(uint8_t key) {
kybd_key(key, true);
}
/** Key up */
bool kybd_release(uint8_t key) {
kybd_key(key, false);
}
/** Modifier press or release */
void kybd_mod(uint8_t mod, bool press) {
if (press) {
modifiers |= mod;
} else {
modifiers &= ~mod;
}
}
/** Key press or release */
bool kybd_key(uint8_t key, bool press) {
if (key >= KEY_LEFTCTRL && key <= KEY_RIGHTMETA) {
// Modifier key
// conveniently, the lower byte indicates the modifier position
uint8_t bitshift = (uint8_t) (key & 0x0F);
// obtain the modifier mask
uint8_t mod = (uint8_t) (1 << bitshift);
// apply modifier
kybd_mod(mod, press);
goto suc;
}
// Regular key
if (press) {
for (int i = 0; i < KYBD_SLOTS; i++) {
if (keys[i] == key) {
// key is already pressed
goto suc;
}
}
if (free_slot < KYBD_SLOTS) {
// press the key
keys[free_slot++] = key;
goto suc;
}
err_ovf = true; // set overflow flag
}
else {
// release
bool found = false;
for (int i = 0; i < KYBD_SLOTS; i++) {
if (found) {
keys[i - 1] = keys[i];
if (i == KYBD_SLOTS - 1) {
keys[i] = 0x00;
}
}
else {
if (keys[i] == key) {
found = true;
}
}
}
if (found) {
err_ovf = false; // clear overflow flag
free_slot--;
goto suc;
}
}
return false;
suc:
return true;
}
/** Get HID report */
void kybd_get_bytes(uint8_t *arr) {
arr[0] = modifiers;
arr[1] = 0x00;
if (err_ovf) {
// all slots ERR_OVF
memset(arr + 2, KEY_ERR_OVF, KYBD_SLOTS);
} else {
// show keys
memcpy(arr + 2, keys, KYBD_SLOTS);
}
}

@ -31,6 +31,10 @@
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <usbd_hid.h>
#include <stdbool.h>
#include <keyboard.h>
#include <circbuf.h>
#include "stm32f1xx_hal.h"
#include "usart.h"
#include "usb_device.h"
@ -59,27 +63,68 @@ void Error_Handler(void);
/* USER CODE BEGIN 0 */
CircBuf *key_cbuf;
void fkey_press(uint8_t key) {
KeyEvent ke = {key, true};
cbuf_append(key_cbuf, &ke);
}
void fkey_release(uint8_t key) {
KeyEvent ke = {key, false};
cbuf_append(key_cbuf, &ke);
}
void fkey_type(uint8_t key, bool shift) {
if(shift) fkey_press(KEY_LEFTSHIFT);
fkey_press(key);
fkey_release(key);
if(shift) fkey_release(KEY_LEFTSHIFT);
}
/** Print a debug message */
void dbg(const char *msg)
{
void dbg(const char *msg) {
HAL_UART_Transmit(&huart2, (char *) msg, (uint16_t) strlen(msg), 10);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
UNUSED(GPIO_Pin);
static uint32_t lasttick = 0;
dbg("EXTI!\r\n");
}
if (HAL_GetTick() - lasttick < 1000) {
dbg("Discard, too soon\r\n");
return;
}
/* USER CODE END 0 */
dbg("HEYOOO\r\n");
fkey_type(KEY_H, true);
fkey_type(KEY_E, false);
fkey_type(KEY_L, false);
fkey_type(KEY_L, false);
fkey_type(KEY_O, false);
fkey_type(KEY_SPACE, false);
fkey_type(KEY_W, true);
fkey_type(KEY_O, false);
fkey_type(KEY_R, false);
fkey_type(KEY_L, false);
fkey_type(KEY_D, false);
fkey_type(KEY_ENTER, false);
}
int main(void)
{
/* USER CODE END 0 */
int main(void) {
/* USER CODE BEGIN 1 */
kybd_clear();
key_cbuf = cbuf_create(100, sizeof(KeyEvent));
/* USER CODE END 1 */
@ -105,6 +150,8 @@ int main(void)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
dbg("-- READY! --\r\n\r\n");
char msg[] = "A\r\n";
while (1) {
@ -132,8 +179,7 @@ int main(void)
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
void SystemClock_Config(void) {
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
@ -182,8 +228,7 @@ void SystemClock_Config(void)
* @param None
* @retval None
*/
void Error_Handler(void)
{
void Error_Handler(void) {
/* USER CODE BEGIN Error_Handler */
/* User can add his own implementation to report the HAL error return state */
while (1) {

@ -31,9 +31,14 @@
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <main.h>
#include <keyboard.h>
#include <usb_device.h>
#include <usbd_hid.h>
#include "stm32f1xx_hal.h"
#include "stm32f1xx.h"
#include "stm32f1xx_it.h"
#include "circbuf.h"
/* USER CODE BEGIN 0 */
@ -43,138 +48,139 @@
extern PCD_HandleTypeDef hpcd_USB_FS;
/******************************************************************************/
/* Cortex-M3 Processor Interruption and Exception Handlers */
/* Cortex-M3 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
void NMI_Handler(void) {
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
/* USER CODE END NonMaskableInt_IRQn 1 */
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
void HardFault_Handler(void) {
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN HardFault_IRQn 1 */
/* USER CODE END HardFault_IRQn 0 */
while (1) {
}
/* USER CODE BEGIN HardFault_IRQn 1 */
/* USER CODE END HardFault_IRQn 1 */
/* USER CODE END HardFault_IRQn 1 */
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
void MemManage_Handler(void) {
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN MemoryManagement_IRQn 1 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1) {
}
/* USER CODE BEGIN MemoryManagement_IRQn 1 */
/* USER CODE END MemoryManagement_IRQn 1 */
/* USER CODE END MemoryManagement_IRQn 1 */
}
/**
* @brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
void BusFault_Handler(void) {
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN BusFault_IRQn 1 */
/* USER CODE END BusFault_IRQn 0 */
while (1) {
}
/* USER CODE BEGIN BusFault_IRQn 1 */
/* USER CODE END BusFault_IRQn 1 */
/* USER CODE END BusFault_IRQn 1 */
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
void UsageFault_Handler(void) {
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
}
/* USER CODE BEGIN UsageFault_IRQn 1 */
/* USER CODE END UsageFault_IRQn 0 */
while (1) {
}
/* USER CODE BEGIN UsageFault_IRQn 1 */
/* USER CODE END UsageFault_IRQn 1 */
/* USER CODE END UsageFault_IRQn 1 */
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
void SVC_Handler(void) {
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
void DebugMon_Handler(void) {
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
void PendSV_Handler(void) {
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
void SysTick_Handler(void) {
/* USER CODE BEGIN SysTick_IRQn 0 */
static uint8_t kreport[8];
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
if (((USBD_HID_HandleTypeDef *) hUsbDeviceFS.pClassData)->state == HID_IDLE) {
KeyEvent ke;
if (cbuf_pop(key_cbuf, &ke)) {
kybd_key(ke.key, ke.press);
// Send report
dbg("key event\r\n");
kybd_get_bytes(kreport);
USBD_HID_SendReport(&hUsbDeviceFS, kreport, 8);
}
}
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
@ -187,22 +193,20 @@ void SysTick_Handler(void)
/**
* @brief This function handles USB low priority or CAN RX0 interrupts.
*/
void USB_LP_CAN1_RX0_IRQHandler(void)
{
/* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */
void USB_LP_CAN1_RX0_IRQHandler(void) {
/* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 0 */
/* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_FS);
/* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */
/* USER CODE END USB_LP_CAN1_RX0_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_FS);
/* USER CODE BEGIN USB_LP_CAN1_RX0_IRQn 1 */
/* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */
/* USER CODE END USB_LP_CAN1_RX0_IRQn 1 */
}
/* USER CODE BEGIN 1 */
void EXTI1_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
void EXTI1_IRQHandler(void) {
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}
/* USER CODE END 1 */

@ -0,0 +1,32 @@
#include <errno.h>
#include <stdio.h>
register char * stack_ptr asm("sp");
caddr_t _sbrk(int incr)
{
extern char end __asm("end");
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0)
heap_end = &end;
prev_heap_end = heap_end;
if (heap_end + incr > stack_ptr)
{
// write(1, "Heap and stack collision\n", 25);
// abort();
errno = ENOMEM;
return (caddr_t) -1;
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
// Other systcalls are defined in
// - com/com_fileio.c
// - hw_utils/reset.h
Loading…
Cancel
Save