/* TODO */ | |||||
/* ... chip dependent ... */ | |||||
#include "bootloader.h" | |||||
void bootloader_jump(void) {} |
/* | |||||
* 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); | |||||
} |
/* | |||||
* 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 |
/* TODO */ | |||||
#include <stdbool.h> | |||||
void suspend_power_down(void) {} | |||||
bool suspend_wakeup_condition(void) { return true; } | |||||
void suspend_wakeup_init(void) {} |
#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))); | |||||
} |
#ifdef PROTOCOL_VUSB | #ifdef PROTOCOL_VUSB | ||||
" VUSB" | " VUSB" | ||||
#endif | #endif | ||||
#ifdef PROTOCOL_CHIBIOS | |||||
" CHIBIOS" | |||||
#endif | |||||
#ifdef BOOTMAGIC_ENABLE | #ifdef BOOTMAGIC_ENABLE | ||||
" BOOTMAGIC" | " BOOTMAGIC" | ||||
#endif | #endif |
xdev_out(sendchar_func); | xdev_out(sendchar_func); | ||||
} | } | ||||
#elif defined(__arm__) | |||||
#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ | |||||
// don't need anything extra | |||||
#elif defined(__arm__) /* __AVR__ */ | |||||
// TODO | // TODO | ||||
//void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { } | //void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { } | ||||
#endif | |||||
#endif /* __AVR__ */ | |||||
#endif | #endif |
/* function pointer of sendchar to be used by print utility */ | /* function pointer of sendchar to be used by print utility */ | ||||
void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t)); | 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" | #include "mbed/xprintf.h" | ||||
# include <util/delay.h> | # include <util/delay.h> | ||||
# define wait_ms(ms) _delay_ms(ms) | # define wait_ms(ms) _delay_ms(ms) | ||||
# define wait_us(us) _delay_us(us) | # 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" | # include "wait_api.h" | ||||
#endif | |||||
#endif /* __AVR__ */ | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } |
chibios |
## 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. |
############################################################################## | |||||
# 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 |
/* | |||||
* (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); | |||||
} | |||||
} |
/* | |||||
* (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_ */ |
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 |