@@ -0,0 +1,7 @@ | |||
/* TODO */ | |||
/* ... chip dependent ... */ | |||
#include "bootloader.h" | |||
void bootloader_jump(void) {} |
@@ -0,0 +1,240 @@ | |||
/* | |||
* found at: http://www.sparetimelabs.com/tinyprintf/tinyprintf.php | |||
* and: http://www.sparetimelabs.com/printfrevisited/printfrevisited.php | |||
*/ | |||
/* | |||
File: printf.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 "printf.h" | |||
typedef void (*putcf) (void*,char); | |||
static putcf stdout_putf; | |||
static void* stdout_putp; | |||
// this adds cca 400 bytes | |||
#define PRINTF_LONG_SUPPORT | |||
#ifdef PRINTF_LONG_SUPPORT | |||
static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf) | |||
{ | |||
int n=0; | |||
unsigned int d=1; | |||
while (num/d >= base) | |||
d*=base; | |||
while (d!=0) { | |||
int dgt = num / d; | |||
num%=d; | |||
d/=base; | |||
if (n || dgt>0|| d==0) { | |||
*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); | |||
++n; | |||
} | |||
} | |||
*bf=0; | |||
} | |||
static void li2a (long num, char * bf) | |||
{ | |||
if (num<0) { | |||
num=-num; | |||
*bf++ = '-'; | |||
} | |||
uli2a(num,10,0,bf); | |||
} | |||
#endif | |||
static void ui2a(unsigned int num, unsigned int base, int uc,char * bf) | |||
{ | |||
int n=0; | |||
unsigned int d=1; | |||
while (num/d >= base) | |||
d*=base; | |||
while (d!=0) { | |||
int dgt = num / d; | |||
num%= d; | |||
d/=base; | |||
if (n || dgt>0 || d==0) { | |||
*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); | |||
++n; | |||
} | |||
} | |||
*bf=0; | |||
} | |||
static void i2a (int num, char * bf) | |||
{ | |||
if (num<0) { | |||
num=-num; | |||
*bf++ = '-'; | |||
} | |||
ui2a(num,10,0,bf); | |||
} | |||
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 a2i(char ch, char** src,int base,int* nump) | |||
{ | |||
char* p= *src; | |||
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,int n, char z, char* bf) | |||
{ | |||
char fc=z? '0' : ' '; | |||
char ch; | |||
char* p=bf; | |||
while (*p++ && n > 0) | |||
n--; | |||
while (n-- > 0) | |||
putf(putp,fc); | |||
while ((ch= *bf++)) | |||
putf(putp,ch); | |||
} | |||
void tfp_format(void* putp,putcf putf,char *fmt, va_list va) | |||
{ | |||
char bf[12]; | |||
char ch; | |||
while ((ch=*(fmt++))) { | |||
if (ch!='%') | |||
putf(putp,ch); | |||
else { | |||
char lz=0; | |||
#ifdef PRINTF_LONG_SUPPORT | |||
char lng=0; | |||
#endif | |||
int w=0; | |||
ch=*(fmt++); | |||
if (ch=='0') { | |||
ch=*(fmt++); | |||
lz=1; | |||
} | |||
if (ch>='0' && ch<='9') { | |||
ch=a2i(ch,&fmt,10,&w); | |||
} | |||
#ifdef PRINTF_LONG_SUPPORT | |||
if (ch=='l') { | |||
ch=*(fmt++); | |||
lng=1; | |||
} | |||
#endif | |||
switch (ch) { | |||
case 0: | |||
goto abort; | |||
case 'u' : { | |||
#ifdef PRINTF_LONG_SUPPORT | |||
if (lng) | |||
uli2a(va_arg(va, unsigned long int),10,0,bf); | |||
else | |||
#endif | |||
ui2a(va_arg(va, unsigned int),10,0,bf); | |||
putchw(putp,putf,w,lz,bf); | |||
break; | |||
} | |||
case 'd' : { | |||
#ifdef PRINTF_LONG_SUPPORT | |||
if (lng) | |||
li2a(va_arg(va, unsigned long int),bf); | |||
else | |||
#endif | |||
i2a(va_arg(va, int),bf); | |||
putchw(putp,putf,w,lz,bf); | |||
break; | |||
} | |||
case 'x': case 'X' : | |||
#ifdef PRINTF_LONG_SUPPORT | |||
if (lng) | |||
uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf); | |||
else | |||
#endif | |||
ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf); | |||
putchw(putp,putf,w,lz,bf); | |||
break; | |||
case 'c' : | |||
putf(putp,(char)(va_arg(va, int))); | |||
break; | |||
case 's' : | |||
putchw(putp,putf,w,0,va_arg(va, char*)); | |||
break; | |||
case '%' : | |||
putf(putp,ch); | |||
default: | |||
break; | |||
} | |||
} | |||
} | |||
abort:; | |||
} | |||
void init_printf(void* putp,void (*putf) (void*,char)) | |||
{ | |||
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); | |||
} | |||
static void putcp(void* p,char c) | |||
{ | |||
*(*((char**)p))++ = c; | |||
} | |||
void tfp_sprintf(char* s,char *fmt, ...) | |||
{ | |||
va_list va; | |||
va_start(va,fmt); | |||
tfp_format(&s,putcp,fmt,va); | |||
putcp(&s,0); | |||
va_end(va); | |||
} |
@@ -0,0 +1,111 @@ | |||
/* | |||
* found at: http://www.sparetimelabs.com/tinyprintf/tinyprintf.php | |||
* and: http://www.sparetimelabs.com/printfrevisited/printfrevisited.php | |||
*/ | |||
/* | |||
File: printf.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 realy just two files: 'printf.h' and 'printf.c'. | |||
They provide a simple and small (+200 loc) printf functionality to | |||
be used in embedded systems. | |||
I've found them so usefull 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 sprintf. | |||
The formats supported by this implementation are: 'd' 'u' 'c' '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 noticably longer. | |||
The memory foot print of course depends on the target cpu, compiler and | |||
compiler options, but a rough guestimate (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 milage may vary. By hacking the source code you can | |||
get rid of some hunred 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 realy) 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 interupts 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'. This makes it possible | |||
to use them along with 'stdio.h' printf's in a single source file. | |||
You just need to undef the names before you include the 'stdio.h'. | |||
Note that these 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 | |||
fucnction. If it is a problem just give up the macros and use the | |||
functions directly or rename them. | |||
For further details see source code. | |||
regs Kusti, 23.10.2004 | |||
*/ | |||
#ifndef __TFP_PRINTF__ | |||
#define __TFP_PRINTF__ | |||
#include <stdarg.h> | |||
void init_printf(void* putp,void (*putf) (void*,char)); | |||
void tfp_printf(char *fmt, ...); | |||
void tfp_sprintf(char* s,char *fmt, ...); | |||
void tfp_format(void* putp,void (*putf) (void*,char),char *fmt, va_list va); | |||
#define printf tfp_printf | |||
#define sprintf tfp_sprintf | |||
#endif |
@@ -0,0 +1,8 @@ | |||
/* TODO */ | |||
#include <stdbool.h> | |||
void suspend_power_down(void) {} | |||
bool suspend_wakeup_condition(void) { return true; } | |||
void suspend_wakeup_init(void) {} |
@@ -0,0 +1,27 @@ | |||
#include "ch.h" | |||
#include "timer.h" | |||
void timer_init(void) {} | |||
void timer_clear(void) {} | |||
uint16_t timer_read(void) | |||
{ | |||
return (uint16_t)ST2MS(chVTGetSystemTime()); | |||
} | |||
uint32_t timer_read32(void) | |||
{ | |||
return ST2MS(chVTGetSystemTime()); | |||
} | |||
uint16_t timer_elapsed(uint16_t last) | |||
{ | |||
return (uint16_t)(ST2MS(chVTTimeElapsedSinceX(MS2ST(last)))); | |||
} | |||
uint32_t timer_elapsed32(uint32_t last) | |||
{ | |||
return ST2MS(chVTTimeElapsedSinceX(MS2ST(last))); | |||
} |
@@ -287,6 +287,9 @@ static bool command_common(uint8_t code) | |||
#ifdef PROTOCOL_VUSB | |||
" VUSB" | |||
#endif | |||
#ifdef PROTOCOL_CHIBIOS | |||
" CHIBIOS" | |||
#endif | |||
#ifdef BOOTMAGIC_ENABLE | |||
" BOOTMAGIC" | |||
#endif |
@@ -38,11 +38,15 @@ void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) | |||
xdev_out(sendchar_func); | |||
} | |||
#elif defined(__arm__) | |||
#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ | |||
// don't need anything extra | |||
#elif defined(__arm__) /* __AVR__ */ | |||
// TODO | |||
//void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { } | |||
#endif | |||
#endif /* __AVR__ */ | |||
#endif |
@@ -47,7 +47,15 @@ extern "C" | |||
/* function pointer of sendchar to be used by print utility */ | |||
void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t)); | |||
#elif defined(__arm__) | |||
#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ | |||
#include "chibios/printf.h" | |||
#define print(s) printf(s) | |||
#define println(s) printf(s "\r\n") | |||
#define xprintf printf | |||
#elif defined(__arm__) /* __AVR__ */ | |||
#include "mbed/xprintf.h" | |||
@@ -9,9 +9,13 @@ extern "C" { | |||
# include <util/delay.h> | |||
# define wait_ms(ms) _delay_ms(ms) | |||
# define wait_us(us) _delay_us(us) | |||
#elif defined(__arm__) | |||
#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ | |||
# include "ch.h" | |||
# define wait_ms(ms) chThdSleepMilliseconds(ms) | |||
# define wait_us(us) chThdSleepMicroseconds(us) | |||
#elif defined(__arm__) /* __AVR__ */ | |||
# include "wait_api.h" | |||
#endif | |||
#endif /* __AVR__ */ | |||
#ifdef __cplusplus | |||
} |
@@ -0,0 +1 @@ | |||
chibios |
@@ -0,0 +1,25 @@ | |||
## USB stack implementation using ChibiOS | |||
### Notes | |||
- To use, unpack or symlink ChibiOS here, to `chibios`. | |||
- For gcc options, inspect `chibios.mk`. For instance, I enabled `-Wno-missing-field-initializers`, because TMK common bits generated a lot of hits on that. | |||
Also pay attention to `-O0` (enabled for debugging); for deployment use `-O2`. | |||
- USB string descriptors are a mess. I did not find a way to cleanly generate the right structures from actual strings, so the definitions in individual keyboards' `config.h` are ugly as heck. | |||
- There are some random constants left so far, e.g. 5ms sleep between calling `keyboard_task` in `main.c`. There should be no such in `usb_main.c`. Everything is based on timers/interrupts/kernel scheduling (well except `keyboard_task`), so no periodically called things (again, except `keyboard_task`, which is just how TMK is designed). | |||
- It is easy to add some code for testing (e.g. blink LED, do stuff on button press, etc...) - just create another thread in `main.c`, it will run independently of the keyboard business. | |||
- The USB stack works pretty completely; however there are bits of other TMK stuff that are not done yet: | |||
### Immediate todo | |||
- suspend / sleep led | |||
### Missing / not working (TMK vs ChibiOS bits) | |||
- eeprom / bootmagic (will be chip dependent) | |||
- bootloader jump (chip dependent) | |||
### Tried with | |||
- ChibiOS 3.0.1 and ST F072RB DISCOVERY board. | |||
- Need to test on other STM32 chips (F3, F4) to make it as much chip-independent as possible. |
@@ -0,0 +1,225 @@ | |||
############################################################################## | |||
# Build global options | |||
# NOTE: Can be overridden externally. | |||
# | |||
# Compiler options here. | |||
ifeq ($(USE_OPT),) | |||
USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 -std=gnu99 -DPROTOCOL_CHIBIOS | |||
endif | |||
# C specific options here (added to USE_OPT). | |||
ifeq ($(USE_COPT),) | |||
USE_COPT = | |||
endif | |||
# include specific config.h? | |||
ifdef CONFIG_H | |||
USE_COPT += -include $(CONFIG_H) | |||
endif | |||
# C++ specific options here (added to USE_OPT). | |||
ifeq ($(USE_CPPOPT),) | |||
USE_CPPOPT = -fno-rtti | |||
endif | |||
# Enable this if you want the linker to remove unused code and data | |||
ifeq ($(USE_LINK_GC),) | |||
USE_LINK_GC = yes | |||
endif | |||
# Linker extra options here. | |||
ifeq ($(USE_LDOPT),) | |||
USE_LDOPT = | |||
endif | |||
# Enable this if you want link time optimizations (LTO) | |||
ifeq ($(USE_LTO),) | |||
USE_LTO = yes | |||
endif | |||
# If enabled, this option allows to compile the application in THUMB mode. | |||
ifeq ($(USE_THUMB),) | |||
USE_THUMB = yes | |||
endif | |||
# Enable this if you want to see the full log while compiling. | |||
ifeq ($(USE_VERBOSE_COMPILE),) | |||
USE_VERBOSE_COMPILE = no | |||
endif | |||
# If enabled, this option makes the build process faster by not compiling | |||
# modules not used in the current configuration. | |||
ifeq ($(USE_SMART_BUILD),) | |||
USE_SMART_BUILD = yes | |||
endif | |||
# | |||
# Build global options | |||
############################################################################## | |||
############################################################################## | |||
# Architecture or project specific options | |||
# | |||
# Stack size to be allocated to the Cortex-M process stack. This stack is | |||
# the stack used by the main() thread. | |||
ifeq ($(USE_PROCESS_STACKSIZE),) | |||
USE_PROCESS_STACKSIZE = 0x200 | |||
endif | |||
# Stack size to the allocated to the Cortex-M main/exceptions stack. This | |||
# stack is used for processing interrupts and exceptions. | |||
ifeq ($(USE_EXCEPTIONS_STACKSIZE),) | |||
USE_EXCEPTIONS_STACKSIZE = 0x400 | |||
endif | |||
# | |||
# Architecture or project specific options | |||
############################################################################## | |||
############################################################################## | |||
# Project, sources and paths | |||
# | |||
# Imported source files and paths | |||
CHIBIOS = $(TMK_DIR)/protocol/chibios/chibios | |||
# Startup files. | |||
include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/startup_$(shell echo $(MCU_SERIES) | tr '[:upper:]' '[:lower:]').mk | |||
# HAL-OSAL files (optional). | |||
include $(CHIBIOS)/os/hal/hal.mk | |||
include $(CHIBIOS)/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)/platform.mk | |||
ifneq ("$(wildcard $(TARGET_DIR)/boards/$(BOARD))","") | |||
include $(TARGET_DIR)/boards/$(BOARD)/board.mk | |||
else | |||
include $(CHIBIOS)/os/hal/boards/$(BOARD)/board.mk | |||
endif | |||
include $(CHIBIOS)/os/hal/osal/rt/osal.mk | |||
# RTOS files (optional). | |||
include $(CHIBIOS)/os/rt/rt.mk | |||
include $(CHIBIOS)/os/rt/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk | |||
# Other files (optional). | |||
# Define linker script file here | |||
ifneq ("$(wildcard $(TARGET_DIR)/ld/$(MCU_MODEL_FAMILY).ld)","") | |||
LDSCRIPT = $(TARGET_DIR)/ld/$(MCU_MODEL_FAMILY).ld | |||
else | |||
LDSCRIPT = $(STARTUPLD)/$(MCU_MODEL_FAMILY).ld | |||
endif | |||
# C sources that can be compiled in ARM or THUMB mode depending on the global | |||
# setting. | |||
CSRC = $(STARTUPSRC) \ | |||
$(KERNSRC) \ | |||
$(PORTSRC) \ | |||
$(OSALSRC) \ | |||
$(HALSRC) \ | |||
$(PLATFORMSRC) \ | |||
$(BOARDSRC) \ | |||
$(CHIBIOS)/os/hal/lib/streams/chprintf.c \ | |||
$(TMK_DIR)/protocol/chibios/usb_main.c \ | |||
$(TMK_DIR)/protocol/chibios/main.c \ | |||
$(SRC) | |||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global | |||
# setting. | |||
CPPSRC = | |||
# C sources to be compiled in ARM mode regardless of the global setting. | |||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler | |||
# option that results in lower performance and larger code size. | |||
ACSRC = | |||
# C++ sources to be compiled in ARM mode regardless of the global setting. | |||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler | |||
# option that results in lower performance and larger code size. | |||
ACPPSRC = | |||
# C sources to be compiled in THUMB mode regardless of the global setting. | |||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler | |||
# option that results in lower performance and larger code size. | |||
TCSRC = | |||
# C sources to be compiled in THUMB mode regardless of the global setting. | |||
# NOTE: Mixing ARM and THUMB mode enables the -mthumb-interwork compiler | |||
# option that results in lower performance and larger code size. | |||
TCPPSRC = | |||
# List ASM source files here | |||
ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM) | |||
INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \ | |||
$(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \ | |||
$(CHIBIOS)/os/hal/lib/streams $(CHIBIOS)/os/various \ | |||
$(TMK_DIR) $(COMMON_DIR) $(TMK_DIR)/protocol/chibios \ | |||
$(TARGET_DIR) | |||
# | |||
# Project, sources and paths | |||
############################################################################## | |||
############################################################################## | |||
# Compiler settings | |||
# | |||
MCU = cortex-m0 | |||
#TRGT = arm-elf- | |||
TRGT = arm-none-eabi- | |||
CC = $(TRGT)gcc | |||
CPPC = $(TRGT)g++ | |||
# Enable loading with g++ only if you need C++ runtime support. | |||
# NOTE: You can use C++ even without C++ support if you are careful. C++ | |||
# runtime support makes code size explode. | |||
LD = $(TRGT)gcc | |||
#LD = $(TRGT)g++ | |||
CP = $(TRGT)objcopy | |||
AS = $(TRGT)gcc -x assembler-with-cpp | |||
AR = $(TRGT)ar | |||
OD = $(TRGT)objdump | |||
SZ = $(TRGT)size | |||
HEX = $(CP) -O ihex | |||
BIN = $(CP) -O binary | |||
# ARM-specific options here | |||
AOPT = | |||
# THUMB-specific options here | |||
TOPT = -mthumb -DTHUMB | |||
# Define C warning options here | |||
CWARN = -Wall -Wextra -Wundef -Wstrict-prototypes -Wno-missing-field-initializers | |||
# Define C++ warning options here | |||
CPPWARN = -Wall -Wextra -Wundef | |||
# | |||
# Compiler settings | |||
############################################################################## | |||
############################################################################## | |||
# Start of user section | |||
# | |||
# List all user C define here, like -D_DEBUG=1 | |||
## Select which interfaces to include here! | |||
UDEFS = $(OPT_DEFS) | |||
# Define ASM defines here | |||
UADEFS = | |||
# List all user directories here | |||
UINCDIR = | |||
# List the user directory to look for the libraries here | |||
ULIBDIR = | |||
# List all user libraries here | |||
ULIBS = | |||
# | |||
# End of user defines | |||
############################################################################## | |||
RULESPATH = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC | |||
include $(RULESPATH)/rules.mk |
@@ -0,0 +1,91 @@ | |||
/* | |||
* (c) 2015 flabberast <[email protected]> | |||
* | |||
* Based on the following work: | |||
* - Guillaume Duc's raw hid example (MIT License) | |||
* https://github.com/guiduc/usb-hid-chibios-example | |||
* - PJRC Teensy examples (MIT License) | |||
* https://www.pjrc.com/teensy/usb_keyboard.html | |||
* - hasu's TMK keyboard code (GPL v2 and some code Modified BSD) | |||
* https://github.com/tmk/tmk_keyboard/ | |||
* - ChibiOS demo code (Apache 2.0 License) | |||
* http://www.chibios.org | |||
* | |||
* Since some GPL'd code is used, this work is licensed under | |||
* GPL v2 or later. | |||
*/ | |||
#include "ch.h" | |||
#include "hal.h" | |||
#include "usb_main.h" | |||
/* TMK includes */ | |||
#include "report.h" | |||
#include "host.h" | |||
#include "host_driver.h" | |||
#include "keyboard.h" | |||
#include "action.h" | |||
#include "led.h" | |||
#include "sendchar.h" | |||
#include "debug.h" | |||
#ifdef SLEEP_LED_ENABLE | |||
#include "sleep_led.h" | |||
#endif | |||
#include "suspend.h" | |||
/* ------------------------- | |||
* TMK host driver defs | |||
* ------------------------- | |||
*/ | |||
host_driver_t chibios_driver = { | |||
keyboard_leds, | |||
send_keyboard, | |||
send_mouse, | |||
send_system, | |||
send_consumer | |||
}; | |||
/* Main thread | |||
*/ | |||
int main(void) { | |||
/* ChibiOS/RT init */ | |||
halInit(); | |||
chSysInit(); | |||
palSetPad(GPIOC, GPIOC_LED_BLUE); | |||
chThdSleepMilliseconds(400); | |||
palClearPad(GPIOC, GPIOC_LED_BLUE); | |||
/* Init USB */ | |||
init_usb_driver(); | |||
/* init printf */ | |||
init_printf(NULL,sendchar_pf); | |||
/* Wait until the USB is active */ | |||
while(USB_DRIVER.state != USB_ACTIVE) | |||
chThdSleepMilliseconds(50); | |||
print("USB configured.\n"); | |||
/* init TMK modules */ | |||
keyboard_init(); | |||
host_set_driver(&chibios_driver); | |||
#ifdef SLEEP_LED_ENABLE | |||
sleep_led_init(); | |||
#endif | |||
print("Keyboard start.\n"); | |||
/* Main loop */ | |||
while(true) { | |||
/* TODO: check for suspended event */ | |||
keyboard_task(); | |||
chThdSleepMilliseconds(5); | |||
} | |||
} |
@@ -0,0 +1,149 @@ | |||
/* | |||
* (c) 2015 flabberast <[email protected]> | |||
* | |||
* Based on the following work: | |||
* - Guillaume Duc's raw hid example (MIT License) | |||
* https://github.com/guiduc/usb-hid-chibios-example | |||
* - PJRC Teensy examples (MIT License) | |||
* https://www.pjrc.com/teensy/usb_keyboard.html | |||
* - hasu's TMK keyboard code (GPL v2 and some code Modified BSD) | |||
* https://github.com/tmk/tmk_keyboard/ | |||
* - ChibiOS demo code (Apache 2.0 License) | |||
* http://www.chibios.org | |||
* | |||
* Since some GPL'd code is used, this work is licensed under | |||
* GPL v2 or later. | |||
*/ | |||
#ifndef _USB_MAIN_H_ | |||
#define _USB_MAIN_H_ | |||
#include "ch.h" | |||
#include "hal.h" | |||
/* ------------------------- | |||
* General USB driver header | |||
* ------------------------- | |||
*/ | |||
/* The USB driver to use */ | |||
#define USB_DRIVER USBD1 | |||
/* Initialize the USB driver and bus */ | |||
void init_usb_driver(void); | |||
/* --------------- | |||
* Keyboard header | |||
* --------------- | |||
*/ | |||
/* main keyboard (6kro) */ | |||
#define KBD_INTERFACE 0 | |||
#define KBD_ENDPOINT 1 | |||
#define KBD_SIZE 8 | |||
#define KBD_REPORT_KEYS (KBD_SIZE - 2) | |||
/* secondary keyboard */ | |||
#ifdef NKRO_ENABLE | |||
#define NKRO_INTERFACE 4 | |||
#define NKRO_ENDPOINT 5 | |||
#define NKRO_SIZE 16 | |||
#define NKRO_REPORT_KEYS (NKRO_SIZE - 1) | |||
#endif | |||
/* this defines report_keyboard_t and computes REPORT_SIZE defines */ | |||
#include "report.h" | |||
/* extern report_keyboard_t keyboard_report_sent; */ | |||
/* keyboard IN request callback handler */ | |||
void kbd_in_cb(USBDriver *usbp, usbep_t ep); | |||
/* start-of-frame handler */ | |||
void kbd_sof_cb(USBDriver *usbp); | |||
#ifdef NKRO_ENABLE | |||
/* nkro IN callback hander */ | |||
void nkro_in_cb(USBDriver *usbp, usbep_t ep); | |||
#endif /* NKRO_ENABLE */ | |||
/* ------------ | |||
* Mouse header | |||
* ------------ | |||
*/ | |||
#ifdef MOUSE_ENABLE | |||
#define MOUSE_INTERFACE 1 | |||
#define MOUSE_ENDPOINT 2 | |||
#define MOUSE_SIZE 8 | |||
/* mouse IN request callback handler */ | |||
void mouse_in_cb(USBDriver *usbp, usbep_t ep); | |||
#endif /* MOUSE_ENABLE */ | |||
/* --------------- | |||
* Extrakey header | |||
* --------------- | |||
*/ | |||
#ifdef EXTRAKEY_ENABLE | |||
#define EXTRA_INTERFACE 3 | |||
#define EXTRA_ENDPOINT 4 | |||
#define EXTRA_SIZE 8 | |||
/* extrakey IN request callback handler */ | |||
void extra_in_cb(USBDriver *usbp, usbep_t ep); | |||
/* extra report structure */ | |||
typedef struct { | |||
uint8_t report_id; | |||
uint16_t usage; | |||
} __attribute__ ((packed)) report_extra_t; | |||
#endif /* EXTRAKEY_ENABLE */ | |||
/* -------------- | |||
* Console header | |||
* -------------- | |||
*/ | |||
#ifdef CONSOLE_ENABLE | |||
#define CONSOLE_INTERFACE 2 | |||
#define CONSOLE_ENDPOINT 3 | |||
#define CONSOLE_SIZE 16 | |||
/* Number of IN reports that can be stored inside the output queue */ | |||
#define CONSOLE_QUEUE_CAPACITY 2 | |||
#define CONSOLE_QUEUE_BUFFER_SIZE (CONSOLE_QUEUE_CAPACITY * CONSOLE_SIZE) | |||
/* Console flush time */ | |||
#define CONSOLE_FLUSH_MS 50 | |||
/* Putchar over the USB console */ | |||
int8_t sendchar(uint8_t c); | |||
/* wrapper for printf lib */ | |||
/* Flush output (send everything immediately) */ | |||
void console_flush_output(void); | |||
/* console IN request callback handler */ | |||
void console_in_cb(USBDriver *usbp, usbep_t ep); | |||
#endif /* CONSOLE_ENABLE */ | |||
void sendchar_pf(void *p, char c); | |||
/* --------------------------- | |||
* Host driver functions (TMK) | |||
* --------------------------- | |||
*/ | |||
uint8_t keyboard_leds(void); | |||
void send_keyboard(report_keyboard_t *report); | |||
void send_mouse(report_mouse_t *report); | |||
void send_system(uint16_t data); | |||
void send_consumer(uint16_t data); | |||
#endif /* _USB_MAIN_H_ */ |
@@ -0,0 +1,86 @@ | |||
COMMON_DIR = $(TMK_DIR)/common | |||
SRC += $(COMMON_DIR)/host.c \ | |||
$(COMMON_DIR)/keyboard.c \ | |||
$(COMMON_DIR)/action.c \ | |||
$(COMMON_DIR)/action_tapping.c \ | |||
$(COMMON_DIR)/action_macro.c \ | |||
$(COMMON_DIR)/action_layer.c \ | |||
$(COMMON_DIR)/action_util.c \ | |||
$(COMMON_DIR)/keymap.c \ | |||
$(COMMON_DIR)/print.c \ | |||
$(COMMON_DIR)/debug.c \ | |||
$(COMMON_DIR)/util.c \ | |||
$(COMMON_DIR)/chibios/suspend.c \ | |||
$(COMMON_DIR)/chibios/printf.c \ | |||
$(COMMON_DIR)/chibios/timer.c \ | |||
$(COMMON_DIR)/chibios/bootloader.c | |||
# Option modules | |||
ifdef BOOTMAGIC_ENABLE | |||
$(error Bootmagic Not Supported) | |||
SRC += $(COMMON_DIR)/bootmagic.c | |||
SRC += $(COMMON_DIR)/chibios/eeconfig.c | |||
OPT_DEFS += -DBOOTMAGIC_ENABLE | |||
endif | |||
ifdef MOUSEKEY_ENABLE | |||
SRC += $(COMMON_DIR)/mousekey.c | |||
OPT_DEFS += -DMOUSEKEY_ENABLE | |||
OPT_DEFS += -DMOUSE_ENABLE | |||
endif | |||
ifdef EXTRAKEY_ENABLE | |||
OPT_DEFS += -DEXTRAKEY_ENABLE | |||
endif | |||
ifdef CONSOLE_ENABLE | |||
OPT_DEFS += -DCONSOLE_ENABLE | |||
else | |||
OPT_DEFS += -DNO_PRINT | |||
OPT_DEFS += -DNO_DEBUG | |||
endif | |||
ifdef COMMAND_ENABLE | |||
SRC += $(COMMON_DIR)/command.c | |||
OPT_DEFS += -DCOMMAND_ENABLE | |||
endif | |||
ifdef NKRO_ENABLE | |||
OPT_DEFS += -DNKRO_ENABLE | |||
endif | |||
ifdef USB_6KRO_ENABLE | |||
OPT_DEFS += -DUSB_6KRO_ENABLE | |||
endif | |||
ifdef SLEEP_LED_ENABLE | |||
$(error Sleep LED Not Supported) | |||
SRC += $(COMMON_DIR)/sleep_led.c | |||
OPT_DEFS += -DSLEEP_LED_ENABLE | |||
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN | |||
endif | |||
ifdef BACKLIGHT_ENABLE | |||
SRC += $(COMMON_DIR)/backlight.c | |||
OPT_DEFS += -DBACKLIGHT_ENABLE | |||
endif | |||
ifdef KEYMAP_SECTION_ENABLE | |||
OPT_DEFS += -DKEYMAP_SECTION_ENABLE | |||
ifeq ($(strip $(MCU)),atmega32u2) | |||
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr35.x | |||
else ifeq ($(strip $(MCU)),atmega32u4) | |||
EXTRALDFLAGS = -Wl,-L$(TMK_DIR),-Tldscript_keymap_avr5.x | |||
else | |||
EXTRALDFLAGS = $(error no ldscript for keymap section) | |||
endif | |||
endif | |||
# Version string | |||
OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null) | |||
# Search Path | |||
VPATH += $(TMK_DIR)/common |