- Includes serial putchar and getchar cleanup (overall) - Moved avr-capsense to DPH (renaming) - Basic cleanup for including CLI on the avr architecturesimple
@@ -28,8 +28,8 @@ include( AddFileDependencies ) | |||
#| "avr" # Teensy++ 2.0 | |||
#| "arm" # Teensy 3.0 | |||
#| "arm" # Teensy 3.1 | |||
set( COMPILER_FAMILY "arm" ) | |||
#set( COMPILER_FAMILY "avr" ) | |||
#set( COMPILER_FAMILY "arm" ) | |||
set( COMPILER_FAMILY "avr" ) | |||
message( STATUS "Compiler Family:" ) | |||
message( "${COMPILER_FAMILY}" ) | |||
@@ -138,9 +138,10 @@ add_custom_command( TARGET ${TARGET_ELF} POST_BUILD | |||
# | |||
#| After Changes Size Information | |||
#| TODO Do lookup on Flash and RAM sizes and do % used | |||
add_custom_target( SizeAfter ALL ${SIZE} --target=${FORMAT} ${TARGET_HEX} ${TARGET_ELF} | |||
DEPENDS ${TARGET_ELF} | |||
COMMENT "Size after generation:" | |||
COMMENT "Size after generation\n\tFlash Usage: data (hex)\n\t RAM Usage: data (elf)" | |||
) | |||
@@ -85,15 +85,14 @@ void process_cli() | |||
uint8_t prev_buf_pos = CLILineBufferCurrent; | |||
// Process each character while available | |||
int result = 0; | |||
while ( 1 ) | |||
{ | |||
// No more characters to process | |||
result = usb_serial_getchar(); // Retrieve from serial module // TODO Make USB agnostic | |||
if ( result == -1 ) | |||
if ( output_availablechar() == 0 ) | |||
break; | |||
char cur_char = (char)result; | |||
// Retrieve from output module | |||
char cur_char = (char)output_getchar(); | |||
// Make sure buffer isn't full | |||
if ( CLILineBufferCurrent >= CLILineBufferMaxSize ) | |||
@@ -405,7 +404,7 @@ void cliFunc_reset( char* args ) | |||
void cliFunc_restart( char* args ) | |||
{ | |||
// Trigger an overall software reset | |||
SOFTWARE_RESET(); | |||
output_softReset(); | |||
} | |||
void cliFunc_version( char* args ) |
@@ -31,24 +31,8 @@ | |||
// ----- Functions ----- | |||
// USB HID String Output | |||
void usb_debug_putstr( char* s ) | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
while ( *s != '\0' ) | |||
usb_debug_putchar( *s++ ); | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
// Count characters until NULL character, then send the amount counted | |||
uint32_t count = 0; | |||
while ( s[count] != '\0' ) | |||
count++; | |||
usb_serial_write( s, count ); | |||
#endif | |||
} | |||
// Multiple string Output | |||
void usb_debug_putstrs( char* first, ... ) | |||
void printstrs( char* first, ... ) | |||
{ | |||
// Initialize the variadic function parameter list | |||
va_list ap; | |||
@@ -61,7 +45,7 @@ void usb_debug_putstrs( char* first, ... ) | |||
while ( !( cur[0] == '\0' && cur[1] == '\0' && cur[2] == '\0' ) ) | |||
{ | |||
// Print out the given string | |||
usb_debug_putstr( cur ); | |||
output_putstr( cur ); | |||
// Get the next argument ready | |||
cur = va_arg( ap, char* ); | |||
@@ -71,21 +55,17 @@ void usb_debug_putstrs( char* first, ... ) | |||
} | |||
// Print a constant string | |||
void _print(const char *s) | |||
void _print( const char* s ) | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
// Pull string out of flash | |||
char c; | |||
// Acquire the character from flash, and print it, as long as it's not NULL | |||
// Also, if a newline is found, print a carrige return as well | |||
while ( ( c = pgm_read_byte(s++) ) != '\0' ) | |||
while ( ( c = pgm_read_byte( s++ ) ) != '\0' ) | |||
{ | |||
if ( c == '\n' ) | |||
usb_debug_putchar('\r'); | |||
usb_debug_putchar(c); | |||
output_putchar( c ); | |||
} | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
usb_debug_putstr( (char*)s ); | |||
output_putstr( (char*)s ); | |||
#endif | |||
} | |||
@@ -26,16 +26,12 @@ | |||
// Compiler Includes | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) | |||
#include <avr/pgmspace.h> | |||
#include "avr/usb_keyboard_debug.h" | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) | |||
#include "arm/usb_serial.h" | |||
#endif | |||
// Project Includes | |||
#include <output_com.h> | |||
// ----- Defines ----- | |||
@@ -50,15 +46,15 @@ | |||
*/ | |||
// Function Aliases | |||
#define dPrint(c) usb_debug_putstr(c) | |||
#define dPrintStr(c) usb_debug_putstr(c) | |||
#define dPrintStrs(...) usb_debug_putstrs(__VA_ARGS__, "\0\0\0") // Convenience Variadic Macro | |||
#define dPrintStrNL(c) dPrintStrs (c, NL) // Appends New Line Macro | |||
#define dPrintStrsNL(...) usb_debug_putstrs(__VA_ARGS__, NL, "\0\0\0") // Appends New Line Macro | |||
#define dPrint(c) output_putstr(c) | |||
#define dPrintStr(c) output_putstr(c) | |||
#define dPrintStrs(...) printstrs(__VA_ARGS__, "\0\0\0") // Convenience Variadic Macro | |||
#define dPrintStrNL(c) dPrintStrs (c, NL) // Appends New Line Macro | |||
#define dPrintStrsNL(...) printstrs(__VA_ARGS__, NL, "\0\0\0") // Appends New Line Macro | |||
// Special Msg Constructs (Uses VT100 tags) | |||
#define dPrintMsg(colour_code_str,msg,...) \ | |||
usb_debug_putstrs("\033[", colour_code_str, "m", msg, "\033[0m - ", __VA_ARGS__, NL, "\0\0\0") | |||
printstrs("\033[", colour_code_str, "m", msg, "\033[0m - ", __VA_ARGS__, NL, "\0\0\0") | |||
#define printMsgNL(colour_code_str,msg,str) \ | |||
print("\033[" colour_code_str "m" msg "\033[0m - " str NL) | |||
#define printMsg(colour_code_str,msg,str) \ | |||
@@ -89,8 +85,7 @@ | |||
#define print(s) _print(PSTR(s)) | |||
void _print(const char *s); | |||
void usb_debug_putstr( char* s ); | |||
void usb_debug_putstrs( char* first, ... ); | |||
void printstrs( char* first, ... ); | |||
// Printing numbers |
@@ -30,7 +30,7 @@ | |||
// You can change these to give your code its own name. | |||
#define STR_MANUFACTURER L"@MANUFACTURER@" | |||
#define STR_PRODUCT L"ForceGauge - @ScanModule@ @MacroModule@ @OutputModule@ @DebugModule@" | |||
#define STR_PRODUCT L"Keyboard - @ScanModule@ @MacroModule@ @OutputModule@ @DebugModule@" | |||
#define STR_SERIAL L"@GitLastCommitDate@" | |||
@@ -1,6 +1,7 @@ | |||
/* Teensyduino Core Library | |||
* http://www.pjrc.com/teensy/ | |||
* Copyright (c) 2013 PJRC.COM, LLC. | |||
* Modified by Jacob Alexander (2013-2014) | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
@@ -10,10 +11,10 @@ | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* 1. The above copyright notice and this permission notice shall be | |||
* 1. The above copyright notice and this permission notice shall be | |||
* included in all copies or substantial portions of the Software. | |||
* | |||
* 2. If the Software is incorporated into a build system that allows | |||
* 2. If the Software is incorporated into a build system that allows | |||
* selection among a list of target devices, then similar target | |||
* devices manufactured by PJRC.COM must be included in the list of | |||
* target devices and selectable in the same manner. |
@@ -1,6 +1,7 @@ | |||
/* Teensyduino Core Library | |||
* http://www.pjrc.com/teensy/ | |||
* Copyright (c) 2013 PJRC.COM, LLC. | |||
* Modified by Jacob Alexander (2013-2014) | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
@@ -10,10 +11,10 @@ | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* 1. The above copyright notice and this permission notice shall be | |||
* 1. The above copyright notice and this permission notice shall be | |||
* included in all copies or substantial portions of the Software. | |||
* | |||
* 2. If the Software is incorporated into a build system that allows | |||
* 2. If the Software is incorporated into a build system that allows | |||
* selection among a list of target devices, then similar target | |||
* devices manufactured by PJRC.COM must be included in the list of | |||
* target devices and selectable in the same manner. | |||
@@ -89,6 +90,7 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
#define NUM_ENDPOINTS 6 | |||
#define NUM_USB_BUFFERS 30 | |||
#define NUM_INTERFACE 4 | |||
#define CDC_IAD_DESCRIPTOR 1 | |||
#define CDC_STATUS_INTERFACE 0 | |||
#define CDC_DATA_INTERFACE 1 // Serial | |||
@@ -98,22 +100,27 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
#define CDC_ACM_SIZE 16 | |||
#define CDC_RX_SIZE 64 | |||
#define CDC_TX_SIZE 64 | |||
#define KEYBOARD_INTERFACE 2 // Keyboard | |||
#define KEYBOARD_ENDPOINT 1 | |||
#define KEYBOARD_SIZE 8 | |||
#define KEYBOARD_INTERVAL 1 | |||
#define MOUSE_INTERFACE 3 // Mouse | |||
#define MOUSE_ENDPOINT 5 | |||
#define MOUSE_SIZE 8 | |||
#define MOUSE_INTERVAL 2 | |||
#define JOYSTICK_INTERFACE 4 // Joystick | |||
#define JOYSTICK_ENDPOINT 6 | |||
#define JOYSTICK_SIZE 16 | |||
#define JOYSTICK_INTERVAL 1 | |||
#define KEYBOARD_DESC_OFFSET (9+8 + 9+5+5+4+5+7+9+7+7 + 9) | |||
#define MOUSE_DESC_OFFSET (9+8 + 9+5+5+4+5+7+9+7+7 + 9+9+7 + 9) | |||
#define JOYSTICK_DESC_OFFSET (9+8 + 9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9) | |||
#define CONFIG_DESC_SIZE (9+8 + 9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9+9+7) | |||
#define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
#define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY | |||
#define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY |
@@ -1,705 +0,0 @@ | |||
/* USB Keyboard Plus Debug Channel Example for Teensy USB Development Board | |||
* http://www.pjrc.com/teensy/usb_keyboard.html | |||
* Copyright (c) 2009 PJRC.COM, LLC | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to deal | |||
* in the Software without restriction, including without limitation the rights | |||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
* copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included in | |||
* all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
* THE SOFTWARE. | |||
*/ | |||
// Version 1.0: Initial Release | |||
// Version 1.1: Add support for Teensy 2.0 | |||
#define USB_SERIAL_PRIVATE_INCLUDE | |||
#include "usb_keyboard_debug.h" | |||
/************************************************************************** | |||
* | |||
* Configurable Options | |||
* | |||
**************************************************************************/ | |||
// USB devices are supposed to implment a halt feature, which is | |||
// rarely (if ever) used. If you comment this line out, the halt | |||
// code will be removed, saving 102 bytes of space (gcc 4.3.0). | |||
// This is not strictly USB compliant, but works with all major | |||
// operating systems. | |||
#define SUPPORT_ENDPOINT_HALT | |||
/************************************************************************** | |||
* | |||
* Endpoint Buffer Configuration | |||
* | |||
**************************************************************************/ | |||
#define ENDPOINT0_SIZE 32 | |||
#define KEYBOARD_INTERFACE 0 | |||
#define KEYBOARD_ENDPOINT 3 | |||
#define KEYBOARD_SIZE 8 | |||
#define KEYBOARD_BUFFER EP_DOUBLE_BUFFER | |||
#define DEBUG_INTERFACE 1 | |||
#define DEBUG_TX_ENDPOINT 4 | |||
#define DEBUG_TX_SIZE 32 | |||
#define DEBUG_TX_BUFFER EP_DOUBLE_BUFFER | |||
static const uint8_t PROGMEM endpoint_config_table[] = { | |||
0, | |||
0, | |||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_BUFFER, | |||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(DEBUG_TX_SIZE) | DEBUG_TX_BUFFER | |||
}; | |||
/************************************************************************** | |||
* | |||
* Descriptor Data | |||
* | |||
**************************************************************************/ | |||
// Descriptors are the data that your computer reads when it auto-detects | |||
// this USB device (called "enumeration" in USB lingo). The most commonly | |||
// changed items are editable at the top of this file. Changing things | |||
// in here should only be done by those who've read chapter 9 of the USB | |||
// spec and relevant portions of any USB class specifications! | |||
static const uint8_t PROGMEM device_descriptor[] = { | |||
18, // bLength | |||
1, // bDescriptorType | |||
0x00, 0x02, // bcdUSB | |||
0, // bDeviceClass | |||
0, // bDeviceSubClass | |||
0, // bDeviceProtocol | |||
ENDPOINT0_SIZE, // bMaxPacketSize0 | |||
LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor | |||
LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct | |||
0x00, 0x01, // bcdDevice | |||
1, // iManufacturer | |||
2, // iProduct | |||
3, // iSerialNumber | |||
1 // bNumConfigurations | |||
}; | |||
// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 | |||
static const uint8_t PROGMEM keyboard_hid_report_desc[] = { | |||
0x05, 0x01, // Usage Page (Generic Desktop), | |||
0x09, 0x06, // Usage (Keyboard), | |||
0xA1, 0x01, // Collection (Application), | |||
0x75, 0x01, // Report Size (1), | |||
0x95, 0x08, // Report Count (8), | |||
0x05, 0x07, // Usage Page (Key Codes), | |||
0x19, 0xE0, // Usage Minimum (224), | |||
0x29, 0xE7, // Usage Maximum (231), | |||
0x15, 0x00, // Logical Minimum (0), | |||
0x25, 0x01, // Logical Maximum (1), | |||
0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte | |||
0x95, 0x01, // Report Count (1), | |||
0x75, 0x08, // Report Size (8), | |||
0x81, 0x03, // Input (Constant), ;Reserved byte | |||
0x95, 0x05, // Report Count (5), | |||
0x75, 0x01, // Report Size (1), | |||
0x05, 0x08, // Usage Page (LEDs), | |||
0x19, 0x01, // Usage Minimum (1), | |||
0x29, 0x05, // Usage Maximum (5), | |||
0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report | |||
0x95, 0x01, // Report Count (1), | |||
0x75, 0x03, // Report Size (3), | |||
0x91, 0x03, // Output (Constant), ;LED report padding | |||
0x95, 0x06, // Report Count (6), | |||
0x75, 0x08, // Report Size (8), | |||
0x15, 0x00, // Logical Minimum (0), | |||
0x25, 0x68, // Logical Maximum(104), | |||
0x05, 0x07, // Usage Page (Key Codes), | |||
0x19, 0x00, // Usage Minimum (0), | |||
0x29, 0x68, // Usage Maximum (104), | |||
0x81, 0x00, // Input (Data, Array), | |||
0xc0 // End Collection | |||
}; | |||
static const uint8_t PROGMEM debug_hid_report_desc[] = { | |||
//0x06, 0x30, 0xFF, // Usage Page 0xFF31 (vendor defined) | |||
0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined) | |||
0x09, 0x74, // Usage 0x74 | |||
0xA1, 0x53, // Collection 0x53 | |||
0x75, 0x08, // report size = 8 bits | |||
0x15, 0x00, // logical minimum = 0 | |||
0x26, 0xFF, 0x00, // logical maximum = 255 | |||
0x95, DEBUG_TX_SIZE, // report count | |||
0x09, 0x75, // usage | |||
0x81, 0x02, // Input (array) | |||
0xC0 // end collection | |||
}; | |||
#define CONFIG1_DESC_SIZE (9+9+9+7+9+9+7) | |||
#define KEYBOARD_HID_DESC_OFFSET (9+9) | |||
#define DEBUG_HID_DESC_OFFSET (9+9+9+7+9) | |||
static const uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = { | |||
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 | |||
9, // bLength; | |||
2, // bDescriptorType; | |||
LSB(CONFIG1_DESC_SIZE), // wTotalLength | |||
MSB(CONFIG1_DESC_SIZE), | |||
2, // bNumInterfaces | |||
1, // bConfigurationValue | |||
0, // iConfiguration | |||
0xC0, // bmAttributes | |||
50, // bMaxPower | |||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | |||
9, // bLength | |||
4, // bDescriptorType | |||
KEYBOARD_INTERFACE, // bInterfaceNumber | |||
0, // bAlternateSetting | |||
1, // bNumEndpoints | |||
0x03, // bInterfaceClass (0x03 = HID) | |||
0x01, // bInterfaceSubClass (0x01 = Boot) | |||
0x01, // bInterfaceProtocol (0x01 = Keyboard) | |||
0, // iInterface | |||
// HID interface descriptor, HID 1.11 spec, section 6.2.1 | |||
9, // bLength | |||
0x21, // bDescriptorType | |||
0x11, 0x01, // bcdHID | |||
0, // bCountryCode | |||
1, // bNumDescriptors | |||
0x22, // bDescriptorType | |||
sizeof(keyboard_hid_report_desc), // wDescriptorLength | |||
0, | |||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | |||
7, // bLength | |||
5, // bDescriptorType | |||
KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress | |||
0x03, // bmAttributes (0x03=intr) | |||
KEYBOARD_SIZE, 0, // wMaxPacketSize | |||
1, // bInterval | |||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 | |||
9, // bLength | |||
4, // bDescriptorType | |||
DEBUG_INTERFACE, // bInterfaceNumber | |||
0, // bAlternateSetting | |||
1, // bNumEndpoints | |||
0x03, // bInterfaceClass (0x03 = HID) | |||
0x00, // bInterfaceSubClass | |||
0x00, // bInterfaceProtocol | |||
0, // iInterface | |||
// HID interface descriptor, HID 1.11 spec, section 6.2.1 | |||
9, // bLength | |||
0x21, // bDescriptorType | |||
0x11, 0x01, // bcdHID | |||
0, // bCountryCode | |||
1, // bNumDescriptors | |||
0x22, // bDescriptorType | |||
sizeof(debug_hid_report_desc), // wDescriptorLength | |||
0, | |||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | |||
7, // bLength | |||
5, // bDescriptorType | |||
DEBUG_TX_ENDPOINT | 0x80, // bEndpointAddress | |||
0x03, // bmAttributes (0x03=intr) | |||
DEBUG_TX_SIZE, 0, // wMaxPacketSize | |||
1 // bInterval | |||
}; | |||
// If you're desperate for a little extra code memory, these strings | |||
// can be completely removed if iManufacturer, iProduct, iSerialNumber | |||
// in the device desciptor are changed to zeros. | |||
struct usb_string_descriptor_struct { | |||
uint8_t bLength; | |||
uint8_t bDescriptorType; | |||
int16_t wString[]; | |||
}; | |||
static const struct usb_string_descriptor_struct PROGMEM string0 = { | |||
4, | |||
3, | |||
{0x0409} | |||
}; | |||
static const struct usb_string_descriptor_struct PROGMEM string1 = { | |||
sizeof(STR_MANUFACTURER), | |||
3, | |||
STR_MANUFACTURER | |||
}; | |||
static const struct usb_string_descriptor_struct PROGMEM string2 = { | |||
sizeof(STR_PRODUCT), | |||
3, | |||
STR_PRODUCT | |||
}; | |||
static const struct usb_string_descriptor_struct PROGMEM string3 = { | |||
sizeof(STR_SERIAL), | |||
3, | |||
STR_SERIAL | |||
}; | |||
// This table defines which descriptor data is sent for each specific | |||
// request from the host (in wValue and wIndex). | |||
static const struct descriptor_list_struct { | |||
uint16_t wValue; | |||
uint16_t wIndex; | |||
const uint8_t *addr; | |||
uint8_t length; | |||
} PROGMEM descriptor_list[] = { | |||
{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, | |||
{0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)}, | |||
{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)}, | |||
{0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9}, | |||
{0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)}, | |||
{0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9}, | |||
{0x0300, 0x0000, (const uint8_t *)&string0, 4}, | |||
{0x0301, 0x0409, (const uint8_t *)&string1, sizeof(STR_MANUFACTURER)}, | |||
{0x0302, 0x0409, (const uint8_t *)&string2, sizeof(STR_PRODUCT)}, | |||
{0x0303, 0x0409, (const uint8_t *)&string3, sizeof(STR_SERIAL)} | |||
}; | |||
#define NUM_DESC_LIST (sizeof(descriptor_list)/sizeof(struct descriptor_list_struct)) | |||
/************************************************************************** | |||
* | |||
* Variables - these are the only non-stack RAM usage | |||
* | |||
**************************************************************************/ | |||
// zero when we are not configured, non-zero when enumerated | |||
static volatile uint8_t usb_configuration=0; | |||
// the time remaining before we transmit any partially full | |||
// packet, or send a zero length packet. | |||
static volatile uint8_t debug_flush_timer=0; | |||
/************************************************************************** | |||
* | |||
* Public Functions - these are the API intended for the user | |||
* | |||
**************************************************************************/ | |||
// initialize USB | |||
void usb_init(void) | |||
{ | |||
HW_CONFIG(); | |||
USB_FREEZE(); // enable USB | |||
PLL_CONFIG(); // config PLL | |||
while (!(PLLCSR & (1<<PLOCK))) ; // wait for PLL lock | |||
USB_CONFIG(); // start USB clock | |||
UDCON = 0; // enable attach resistor | |||
usb_configuration = 0; | |||
UDIEN = (1<<EORSTE)|(1<<SOFE); | |||
sei(); | |||
} | |||
// return 0 if the USB is not configured, or the configuration | |||
// number selected by the HOST | |||
uint8_t usb_configured(void) | |||
{ | |||
return usb_configuration; | |||
} | |||
// send the contents of USBKeys_Array and USBKeys_Modifiers | |||
int8_t usb_keyboard_send(void) | |||
{ | |||
uint8_t i, intr_state, timeout; | |||
if (!usb_configuration) return -1; | |||
intr_state = SREG; | |||
cli(); | |||
UENUM = KEYBOARD_ENDPOINT; | |||
timeout = UDFNUML + 50; | |||
while (1) { | |||
// are we ready to transmit? | |||
if (UEINTX & (1<<RWAL)) break; | |||
SREG = intr_state; | |||
// has the USB gone offline? | |||
if (!usb_configuration) return -1; | |||
// have we waited too long? | |||
if (UDFNUML == timeout) return -1; | |||
// get ready to try checking again | |||
intr_state = SREG; | |||
cli(); | |||
UENUM = KEYBOARD_ENDPOINT; | |||
} | |||
UEDATX = USBKeys_Modifiers; | |||
UEDATX = 0; | |||
for (i=0; i<6; i++) { | |||
UEDATX = USBKeys_Array[i]; | |||
} | |||
UEINTX = 0x3A; | |||
USBKeys_Idle_Count = 0; | |||
SREG = intr_state; | |||
return 0; | |||
} | |||
// transmit a character. 0 returned on success, -1 on error | |||
int8_t usb_debug_putchar(uint8_t c) | |||
{ | |||
static uint8_t previous_timeout=0; | |||
uint8_t timeout, intr_state; | |||
// if we're not online (enumerated and configured), error | |||
if (!usb_configuration) return -1; | |||
// interrupts are disabled so these functions can be | |||
// used from the main program or interrupt context, | |||
// even both in the same program! | |||
intr_state = SREG; | |||
cli(); | |||
UENUM = DEBUG_TX_ENDPOINT; | |||
// if we gave up due to timeout before, don't wait again | |||
if (previous_timeout) { | |||
if (!(UEINTX & (1<<RWAL))) { | |||
SREG = intr_state; | |||
return -1; | |||
} | |||
previous_timeout = 0; | |||
} | |||
// wait for the FIFO to be ready to accept data | |||
timeout = UDFNUML + 4; | |||
while (1) { | |||
// are we ready to transmit? | |||
if (UEINTX & (1<<RWAL)) break; | |||
SREG = intr_state; | |||
// have we waited too long? | |||
if (UDFNUML == timeout) { | |||
previous_timeout = 1; | |||
return -1; | |||
} | |||
// has the USB gone offline? | |||
if (!usb_configuration) return -1; | |||
// get ready to try checking again | |||
intr_state = SREG; | |||
cli(); | |||
UENUM = DEBUG_TX_ENDPOINT; | |||
} | |||
// actually write the byte into the FIFO | |||
UEDATX = c; | |||
// if this completed a packet, transmit it now! | |||
if (!(UEINTX & (1<<RWAL))) { | |||
UEINTX = 0x3A; | |||
debug_flush_timer = 0; | |||
} else { | |||
debug_flush_timer = 2; | |||
} | |||
SREG = intr_state; | |||
return 0; | |||
} | |||
// immediately transmit any buffered output. | |||
void usb_debug_flush_output(void) | |||
{ | |||
uint8_t intr_state; | |||
intr_state = SREG; | |||
cli(); | |||
if (debug_flush_timer) { | |||
UENUM = DEBUG_TX_ENDPOINT; | |||
while ((UEINTX & (1<<RWAL))) { | |||
UEDATX = 0; | |||
} | |||
UEINTX = 0x3A; | |||
debug_flush_timer = 0; | |||
} | |||
SREG = intr_state; | |||
} | |||
/************************************************************************** | |||
* | |||
* Private Functions - not intended for general user consumption.... | |||
* | |||
**************************************************************************/ | |||
// USB Device Interrupt - handle all device-level events | |||
// the transmit buffer flushing is triggered by the start of frame | |||
// | |||
ISR(USB_GEN_vect) | |||
{ | |||
uint8_t intbits, t, i; | |||
static uint8_t div4=0; | |||
intbits = UDINT; | |||
UDINT = 0; | |||
if (intbits & (1<<EORSTI)) { | |||
UENUM = 0; | |||
UECONX = 1; | |||
UECFG0X = EP_TYPE_CONTROL; | |||
UECFG1X = EP_SIZE(ENDPOINT0_SIZE) | EP_SINGLE_BUFFER; | |||
UEIENX = (1<<RXSTPE); | |||
usb_configuration = 0; | |||
} | |||
if ((intbits & (1<<SOFI)) && usb_configuration) { | |||
t = debug_flush_timer; | |||
if (t) { | |||
debug_flush_timer = -- t; | |||
if (!t) { | |||
UENUM = DEBUG_TX_ENDPOINT; | |||
while ((UEINTX & (1<<RWAL))) { | |||
UEDATX = 0; | |||
} | |||
UEINTX = 0x3A; | |||
} | |||
} | |||
if (USBKeys_Idle_Config && (++div4 & 3) == 0) { | |||
UENUM = KEYBOARD_ENDPOINT; | |||
if (UEINTX & (1<<RWAL)) { | |||
USBKeys_Idle_Count++; | |||
if (USBKeys_Idle_Count == USBKeys_Idle_Config) { | |||
USBKeys_Idle_Count = 0; | |||
UEDATX = USBKeys_Modifiers; | |||
UEDATX = 0; | |||
for (i=0; i<6; i++) { | |||
UEDATX = USBKeys_Array[i]; | |||
} | |||
UEINTX = 0x3A; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
// Misc functions to wait for ready and send/receive packets | |||
static inline void usb_wait_in_ready(void) | |||
{ | |||
while (!(UEINTX & (1<<TXINI))) ; | |||
} | |||
static inline void usb_send_in(void) | |||
{ | |||
UEINTX = ~(1<<TXINI); | |||
} | |||
static inline void usb_wait_receive_out(void) | |||
{ | |||
while (!(UEINTX & (1<<RXOUTI))) ; | |||
} | |||
static inline void usb_ack_out(void) | |||
{ | |||
UEINTX = ~(1<<RXOUTI); | |||
} | |||
// USB Endpoint Interrupt - endpoint 0 is handled here. The | |||
// other endpoints are manipulated by the user-callable | |||
// functions, and the start-of-frame interrupt. | |||
// | |||
ISR(USB_COM_vect) | |||
{ | |||
uint8_t intbits; | |||
const uint8_t *list; | |||
const uint8_t *cfg; | |||
uint8_t i, n, len, en; | |||
uint8_t bmRequestType; | |||
uint8_t bRequest; | |||
uint16_t wValue; | |||
uint16_t wIndex; | |||
uint16_t wLength; | |||
uint16_t desc_val; | |||
const uint8_t *desc_addr; | |||
uint8_t desc_length; | |||
UENUM = 0; | |||
intbits = UEINTX; | |||
if (intbits & (1<<RXSTPI)) { | |||
bmRequestType = UEDATX; | |||
bRequest = UEDATX; | |||
wValue = UEDATX; | |||
wValue |= (UEDATX << 8); | |||
wIndex = UEDATX; | |||
wIndex |= (UEDATX << 8); | |||
wLength = UEDATX; | |||
wLength |= (UEDATX << 8); | |||
UEINTX = ~((1<<RXSTPI) | (1<<RXOUTI) | (1<<TXINI)); | |||
if (bRequest == GET_DESCRIPTOR) { | |||
list = (const uint8_t *)descriptor_list; | |||
for (i=0; ; i++) { | |||
if (i >= NUM_DESC_LIST) { | |||
UECONX = (1<<STALLRQ)|(1<<EPEN); //stall | |||
return; | |||
} | |||
desc_val = pgm_read_word(list); | |||
if (desc_val != wValue) { | |||
list += sizeof(struct descriptor_list_struct); | |||
continue; | |||
} | |||
list += 2; | |||
desc_val = pgm_read_word(list); | |||
if (desc_val != wIndex) { | |||
list += sizeof(struct descriptor_list_struct)-2; | |||
continue; | |||
} | |||
list += 2; | |||
desc_addr = (const uint8_t *)pgm_read_word(list); | |||
list += 2; | |||
desc_length = pgm_read_byte(list); | |||
break; | |||
} | |||
len = (wLength < 256) ? wLength : 255; | |||
if (len > desc_length) len = desc_length; | |||
do { | |||
// wait for host ready for IN packet | |||
do { | |||
i = UEINTX; | |||
} while (!(i & ((1<<TXINI)|(1<<RXOUTI)))); | |||
if (i & (1<<RXOUTI)) return; // abort | |||
// send IN packet | |||
n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE; | |||
for (i = n; i; i--) { | |||
UEDATX = pgm_read_byte(desc_addr++); | |||
} | |||
len -= n; | |||
usb_send_in(); | |||
} while (len || n == ENDPOINT0_SIZE); | |||
return; | |||
} | |||
if (bRequest == SET_ADDRESS) { | |||
usb_send_in(); | |||
usb_wait_in_ready(); | |||
UDADDR = wValue | (1<<ADDEN); | |||
return; | |||
} | |||
if (bRequest == SET_CONFIGURATION && bmRequestType == 0) { | |||
usb_configuration = wValue; | |||
usb_send_in(); | |||
cfg = endpoint_config_table; | |||
for (i=1; i<5; i++) { | |||
UENUM = i; | |||
en = pgm_read_byte(cfg++); | |||
UECONX = en; | |||
if (en) { | |||
UECFG0X = pgm_read_byte(cfg++); | |||
UECFG1X = pgm_read_byte(cfg++); | |||
} | |||
} | |||
UERST = 0x1E; | |||
UERST = 0; | |||
return; | |||
} | |||
if (bRequest == GET_CONFIGURATION && bmRequestType == 0x80) { | |||
usb_wait_in_ready(); | |||
UEDATX = usb_configuration; | |||
usb_send_in(); | |||
return; | |||
} | |||
if (bRequest == GET_STATUS) { | |||
usb_wait_in_ready(); | |||
i = 0; | |||
#ifdef SUPPORT_ENDPOINT_HALT | |||
if (bmRequestType == 0x82) { | |||
UENUM = wIndex; | |||
if (UECONX & (1<<STALLRQ)) i = 1; | |||
UENUM = 0; | |||
} | |||
#endif | |||
UEDATX = i; | |||
UEDATX = 0; | |||
usb_send_in(); | |||
return; | |||
} | |||
#ifdef SUPPORT_ENDPOINT_HALT | |||
if ((bRequest == CLEAR_FEATURE || bRequest == SET_FEATURE) | |||
&& bmRequestType == 0x02 && wValue == 0) { | |||
i = wIndex & 0x7F; | |||
if (i >= 1 && i <= MAX_ENDPOINT) { | |||
usb_send_in(); | |||
UENUM = i; | |||
if (bRequest == SET_FEATURE) { | |||
UECONX = (1<<STALLRQ)|(1<<EPEN); | |||
} else { | |||
UECONX = (1<<STALLRQC)|(1<<RSTDT)|(1<<EPEN); | |||
UERST = (1 << i); | |||
UERST = 0; | |||
} | |||
return; | |||
} | |||
} | |||
#endif | |||
if (wIndex == KEYBOARD_INTERFACE) { | |||
if (bmRequestType == 0xA1) { | |||
if (bRequest == HID_GET_REPORT) { | |||
usb_wait_in_ready(); | |||
UEDATX = USBKeys_Modifiers; | |||
UEDATX = 0; | |||
for (i=0; i<6; i++) { | |||
UEDATX = USBKeys_Array[i]; | |||
} | |||
usb_send_in(); | |||
return; | |||
} | |||
if (bRequest == HID_GET_IDLE) { | |||
usb_wait_in_ready(); | |||
UEDATX = USBKeys_Idle_Config; | |||
usb_send_in(); | |||
return; | |||
} | |||
if (bRequest == HID_GET_PROTOCOL) { | |||
usb_wait_in_ready(); | |||
UEDATX = USBKeys_Protocol; | |||
usb_send_in(); | |||
return; | |||
} | |||
} | |||
if (bmRequestType == 0x21) { | |||
if (bRequest == HID_SET_REPORT) { | |||
usb_wait_receive_out(); | |||
USBKeys_LEDs = UEDATX; | |||
usb_ack_out(); | |||
usb_send_in(); | |||
return; | |||
} | |||
if (bRequest == HID_SET_IDLE) { | |||
USBKeys_Idle_Config = (wValue >> 8); | |||
USBKeys_Idle_Count = 0; | |||
//usb_wait_in_ready(); | |||
usb_send_in(); | |||
return; | |||
} | |||
if (bRequest == HID_SET_PROTOCOL) { | |||
USBKeys_Protocol = wValue; | |||
//usb_wait_in_ready(); | |||
usb_send_in(); | |||
return; | |||
} | |||
} | |||
} | |||
if (wIndex == DEBUG_INTERFACE) { | |||
if (bRequest == HID_GET_REPORT && bmRequestType == 0xA1) { | |||
len = wLength; | |||
do { | |||
// wait for host ready for IN packet | |||
do { | |||
i = UEINTX; | |||
} while (!(i & ((1<<TXINI)|(1<<RXOUTI)))); | |||
if (i & (1<<RXOUTI)) return; // abort | |||
// send IN packet | |||
n = len < ENDPOINT0_SIZE ? len : ENDPOINT0_SIZE; | |||
for (i = n; i; i--) { | |||
UEDATX = 0; | |||
} | |||
len -= n; | |||
usb_send_in(); | |||
} while (len || n == ENDPOINT0_SIZE); | |||
return; | |||
} | |||
} | |||
} | |||
UECONX = (1<<STALLRQ) | (1<<EPEN); // stall | |||
} | |||
@@ -1,90 +0,0 @@ | |||
#ifndef usb_serial_h__ | |||
#define usb_serial_h__ | |||
#include <stdint.h> | |||
#include "output_com.h" | |||
void usb_init(void); // initialize everything | |||
uint8_t usb_configured(void); // is the USB port configured | |||
int8_t usb_keyboard_send(void); | |||
int8_t usb_debug_putchar(uint8_t c); // transmit a character | |||
void usb_debug_flush_output(void); // immediately transmit any buffered output | |||
#define USB_DEBUG_HID | |||
// Everything below this point is only intended for usb_serial.c | |||
#ifdef USB_SERIAL_PRIVATE_INCLUDE | |||
#include <avr/io.h> | |||
#include <avr/pgmspace.h> | |||
#include <avr/interrupt.h> | |||
#define EP_TYPE_CONTROL 0x00 | |||
#define EP_TYPE_BULK_IN 0x81 | |||
#define EP_TYPE_BULK_OUT 0x80 | |||
#define EP_TYPE_INTERRUPT_IN 0xC1 | |||
#define EP_TYPE_INTERRUPT_OUT 0xC0 | |||
#define EP_TYPE_ISOCHRONOUS_IN 0x41 | |||
#define EP_TYPE_ISOCHRONOUS_OUT 0x40 | |||
#define EP_SINGLE_BUFFER 0x02 | |||
#define EP_DOUBLE_BUFFER 0x06 | |||
#define EP_SIZE(s) ((s) == 64 ? 0x30 : \ | |||
((s) == 32 ? 0x20 : \ | |||
((s) == 16 ? 0x10 : \ | |||
0x00))) | |||
#define MAX_ENDPOINT 4 | |||
#define LSB(n) (n & 255) | |||
#define MSB(n) ((n >> 8) & 255) | |||
#if defined(__AVR_AT90USB162__) | |||
#define HW_CONFIG() | |||
#define PLL_CONFIG() (PLLCSR = ((1<<PLLE)|(1<<PLLP0))) | |||
#define USB_CONFIG() (USBCON = (1<<USBE)) | |||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK))) | |||
#elif defined(__AVR_ATmega32U4__) | |||
#define HW_CONFIG() (UHWCON = 0x01) | |||
#define PLL_CONFIG() (PLLCSR = 0x12) | |||
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE))) | |||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK))) | |||
#elif defined(__AVR_AT90USB646__) | |||
#define HW_CONFIG() (UHWCON = 0x81) | |||
#define PLL_CONFIG() (PLLCSR = 0x1A) | |||
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE))) | |||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK))) | |||
#elif defined(__AVR_AT90USB1286__) | |||
#define HW_CONFIG() (UHWCON = 0x81) | |||
#define PLL_CONFIG() (PLLCSR = 0x16) | |||
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE))) | |||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK))) | |||
#endif | |||
// standard control endpoint request types | |||
#define GET_STATUS 0 | |||
#define CLEAR_FEATURE 1 | |||
#define SET_FEATURE 3 | |||
#define SET_ADDRESS 5 | |||
#define GET_DESCRIPTOR 6 | |||
#define GET_CONFIGURATION 8 | |||
#define SET_CONFIGURATION 9 | |||
#define GET_INTERFACE 10 | |||
#define SET_INTERFACE 11 | |||
// HID (human interface device) | |||
#define HID_GET_REPORT 1 | |||
#define HID_GET_IDLE 2 | |||
#define HID_GET_PROTOCOL 3 | |||
#define HID_SET_REPORT 9 | |||
#define HID_SET_IDLE 10 | |||
#define HID_SET_PROTOCOL 11 | |||
// CDC (communication class device) | |||
#define CDC_SET_LINE_CODING 0x20 | |||
#define CDC_GET_LINE_CODING 0x21 | |||
#define CDC_SET_CONTROL_LINE_STATE 0x22 | |||
#endif | |||
#endif | |||
@@ -0,0 +1,221 @@ | |||
/* USB Keyboard and CDC Serial Device for Teensy USB Development Board | |||
* Copyright (c) 2009 PJRC.COM, LLC | |||
* Modifications by Jacob Alexander (2011-2014) | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to deal | |||
* in the Software without restriction, including without limitation the rights | |||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
* copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice shall be included in | |||
* all copies or substantial portions of the Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
* THE SOFTWARE. | |||
*/ | |||
#ifndef usb_keyboard_serial_h__ | |||
#define usb_keyboard_serial_h__ | |||
// Compiler Includes | |||
#include <stdint.h> | |||
// AVR Includes | |||
#include <avr/io.h> | |||
#include <avr/pgmspace.h> | |||
#include <avr/interrupt.h> | |||
#include <avr/wdt.h> | |||
// AVR Util Includes | |||
#include <util/delay.h> | |||
// Local Includes | |||
#include "output_com.h" | |||
// ----- Function Declarations ----- | |||
// Basic USB Configuration | |||
void usb_init(void); // initialize everything | |||
uint8_t usb_configured(void); // is the USB port configured | |||
// Keyboard HID Functions | |||
int8_t usb_keyboard_send(void); | |||
// Chip Level Functions | |||
void usb_debug_reload(); // Enable firmware reflash mode | |||
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3"))); // Needed for software reset | |||
// USB Serial CDC Functions | |||
int16_t usb_serial_getchar(void); // receive a character (-1 if timeout/error) | |||
uint8_t usb_serial_available(void); // number of bytes in receive buffer | |||
void usb_serial_flush_input(void); // discard any buffered input | |||
// transmitting data | |||
int8_t usb_serial_putchar(uint8_t c); // transmit a character | |||
int8_t usb_serial_putchar_nowait(uint8_t c); // transmit a character, do not wait | |||
int8_t usb_serial_write(const char *buffer, uint16_t size); // transmit a buffer | |||
void usb_serial_flush_output(void); // immediately transmit any buffered output | |||
// serial parameters | |||
uint32_t usb_serial_get_baud(void); // get the baud rate | |||
uint8_t usb_serial_get_stopbits(void); // get the number of stop bits | |||
uint8_t usb_serial_get_paritytype(void);// get the parity type | |||
uint8_t usb_serial_get_numbits(void); // get the number of data bits | |||
uint8_t usb_serial_get_control(void); // get the RTS and DTR signal state | |||
int8_t usb_serial_set_control(uint8_t signals); // set DSR, DCD, RI, etc | |||
// ----- Macros ----- | |||
// Software reset the chip | |||
#define usb_debug_software_reset() do { wdt_enable( WDTO_15MS ); for(;;); } while(0) | |||
#define EP_SIZE(s) ((s) == 64 ? 0x30 : \ | |||
((s) == 32 ? 0x20 : \ | |||
((s) == 16 ? 0x10 : \ | |||
0x00))) | |||
#define LSB(n) (n & 255) | |||
#define MSB(n) ((n >> 8) & 255) | |||
// ----- Defines ----- | |||
// constants corresponding to the various serial parameters | |||
#define USB_SERIAL_DTR 0x01 | |||
#define USB_SERIAL_RTS 0x02 | |||
#define USB_SERIAL_1_STOP 0 | |||
#define USB_SERIAL_1_5_STOP 1 | |||
#define USB_SERIAL_2_STOP 2 | |||
#define USB_SERIAL_PARITY_NONE 0 | |||
#define USB_SERIAL_PARITY_ODD 1 | |||
#define USB_SERIAL_PARITY_EVEN 2 | |||
#define USB_SERIAL_PARITY_MARK 3 | |||
#define USB_SERIAL_PARITY_SPACE 4 | |||
#define USB_SERIAL_DCD 0x01 | |||
#define USB_SERIAL_DSR 0x02 | |||
#define USB_SERIAL_BREAK 0x04 | |||
#define USB_SERIAL_RI 0x08 | |||
#define USB_SERIAL_FRAME_ERR 0x10 | |||
#define USB_SERIAL_PARITY_ERR 0x20 | |||
#define USB_SERIAL_OVERRUN_ERR 0x40 | |||
#define EP_TYPE_CONTROL 0x00 | |||
#define EP_TYPE_BULK_IN 0x81 | |||
#define EP_TYPE_BULK_OUT 0x80 | |||
#define EP_TYPE_INTERRUPT_IN 0xC1 | |||
#define EP_TYPE_INTERRUPT_OUT 0xC0 | |||
#define EP_TYPE_ISOCHRONOUS_IN 0x41 | |||
#define EP_TYPE_ISOCHRONOUS_OUT 0x40 | |||
#define EP_SINGLE_BUFFER 0x02 | |||
#define EP_DOUBLE_BUFFER 0x06 | |||
#define MAX_ENDPOINT 4 | |||
#if defined(__AVR_AT90USB162__) | |||
#define HW_CONFIG() | |||
#define PLL_CONFIG() (PLLCSR = ((1<<PLLE)|(1<<PLLP0))) | |||
#define USB_CONFIG() (USBCON = (1<<USBE)) | |||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK))) | |||
#elif defined(__AVR_ATmega32U4__) | |||
#define HW_CONFIG() (UHWCON = 0x01) | |||
#define PLL_CONFIG() (PLLCSR = 0x12) | |||
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE))) | |||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK))) | |||
#elif defined(__AVR_AT90USB646__) | |||
#define HW_CONFIG() (UHWCON = 0x81) | |||
#define PLL_CONFIG() (PLLCSR = 0x1A) | |||
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE))) | |||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK))) | |||
#elif defined(__AVR_AT90USB1286__) | |||
#define HW_CONFIG() (UHWCON = 0x81) | |||
#define PLL_CONFIG() (PLLCSR = 0x16) | |||
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE))) | |||
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK))) | |||
#endif | |||
// standard control endpoint request types | |||
#define GET_STATUS 0 | |||
#define CLEAR_FEATURE 1 | |||
#define SET_FEATURE 3 | |||
#define SET_ADDRESS 5 | |||
#define GET_DESCRIPTOR 6 | |||
#define GET_CONFIGURATION 8 | |||
#define SET_CONFIGURATION 9 | |||
#define GET_INTERFACE 10 | |||
#define SET_INTERFACE 11 | |||
// HID (human interface device) | |||
#define HID_GET_REPORT 1 | |||
#define HID_GET_IDLE 2 | |||
#define HID_GET_PROTOCOL 3 | |||
#define HID_SET_REPORT 9 | |||
#define HID_SET_IDLE 10 | |||
#define HID_SET_PROTOCOL 11 | |||
// CDC (communication class device) | |||
#define CDC_SET_LINE_CODING 0x20 | |||
#define CDC_GET_LINE_CODING 0x21 | |||
#define CDC_SET_CONTROL_LINE_STATE 0x22 | |||
// ----- Endpoint Configuration ----- | |||
#define ENDPOINT0_SIZE 32 | |||
#define KEYBOARD_INTERFACE 0 | |||
#define KEYBOARD_ENDPOINT 2 | |||
#define KEYBOARD_SIZE 8 | |||
#define KEYBOARD_INTERVAL 1 | |||
#define KEYBOARD_HID_BUFFER EP_DOUBLE_BUFFER | |||
#define CDC_IAD_DESCRIPTOR 1 | |||
#define CDC_STATUS_INTERFACE 1 | |||
#define CDC_DATA_INTERFACE 2 | |||
#define CDC_ACM_ENDPOINT 3 | |||
#define CDC_RX_ENDPOINT 4 | |||
#define CDC_TX_ENDPOINT 5 | |||
#if defined(__AVR_AT90USB162__) | |||
#define CDC_ACM_SIZE 16 | |||
#define CDC_ACM_BUFFER EP_SINGLE_BUFFER | |||
#define CDC_RX_SIZE 32 | |||
#define CDC_RX_BUFFER EP_DOUBLE_BUFFER | |||
#define CDC_TX_SIZE 32 | |||
#define CDC_TX_BUFFER EP_DOUBLE_BUFFER | |||
#else | |||
#define CDC_ACM_SIZE 16 | |||
#define CDC_ACM_BUFFER EP_SINGLE_BUFFER | |||
#define CDC_RX_SIZE 64 | |||
#define CDC_RX_BUFFER EP_DOUBLE_BUFFER | |||
#define CDC_TX_SIZE 64 | |||
#define CDC_TX_BUFFER EP_DOUBLE_BUFFER | |||
#endif | |||
// Endpoint 0 is reserved for the control endpoint | |||
// Endpoint 1 has a 256 byte buffer | |||
// Endpoints 2-6 have 64 byte buffers | |||
static const uint8_t PROGMEM endpoint_config_table[] = { | |||
0, // 256 byte | |||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(KEYBOARD_SIZE) | KEYBOARD_HID_BUFFER, // 64 byte | |||
1, EP_TYPE_INTERRUPT_IN, EP_SIZE(CDC_ACM_SIZE) | CDC_ACM_BUFFER, // 64 byte | |||
1, EP_TYPE_BULK_OUT, EP_SIZE(CDC_RX_SIZE) | CDC_RX_BUFFER, // 64 byte | |||
1, EP_TYPE_BULK_IN, EP_SIZE(CDC_TX_SIZE) | CDC_TX_BUFFER, // 64 byte | |||
}; | |||
#endif // usb_keyboard_serial_h__ | |||
@@ -25,11 +25,13 @@ | |||
#include <Lib/OutputLib.h> | |||
// Project Includes | |||
#include <cli.h> | |||
#include <print.h> | |||
#include <scan_loop.h> | |||
// USB Includes | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) | |||
#include "avr/usb_keyboard_debug.h" | |||
#include "avr/usb_keyboard_serial.h" | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) | |||
#include "arm/usb_keyboard.h" | |||
#include "arm/usb_dev.h" | |||
@@ -40,8 +42,31 @@ | |||
// ----- Function Declarations ----- | |||
void cliFunc_holdKey ( char* args ); | |||
void cliFunc_readLEDs ( char* args ); | |||
void cliFunc_releaseKey( char* args ); | |||
void cliFunc_sendKey ( char* args ); | |||
void cliFunc_setLEDs ( char* args ); | |||
void cliFunc_setMod ( char* args ); | |||
// ----- Variables ----- | |||
// Output Module command dictionary | |||
char* outputCLIDictName = "USB Module Commands"; | |||
CLIDictItem outputCLIDict[] = { | |||
{ "holdKey", "Hold a space separated list of USB codes. Ignores already pressed keys.", cliFunc_holdKey }, | |||
{ "readLEDs", "Read LED byte. See setLEDs.", cliFunc_readLEDs }, | |||
{ "releaseKey", "Release a space separated list of USB codes. Ignores unpressed keys.", cliFunc_releaseKey }, | |||
{ "sendKey", "Send a space separated list of USB codes. Press/Release.", cliFunc_sendKey }, | |||
{ "setLEDs", "Set LED byte: 1 NumLck, 2 CapsLck, 4 ScrlLck, 16 Kana, etc.", cliFunc_setLEDs }, | |||
{ "setMod", "Set the modfier byte: 1 LCtrl, 2 LShft, 4 LAlt, 8 LGUI, 16 RCtrl, 32 RShft, 64 RAlt, 128 RGUI", cliFunc_setMod }, | |||
{ 0, 0, 0 } // Null entry for dictionary end | |||
}; | |||
// which modifier keys are currently pressed | |||
// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui | |||
// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui | |||
@@ -69,7 +94,6 @@ volatile uint8_t USBKeys_LEDs = 0; | |||
uint8_t USBKeys_Idle_Count = 0; | |||
// ----- Functions ----- | |||
// USB Module Setup | |||
@@ -81,9 +105,12 @@ inline void output_setup() | |||
usb_init(); | |||
while ( !usb_configured() ) /* wait */ ; | |||
// Register USB Output dictionary | |||
registerDictionary_cli( outputCLIDict, outputCLIDictName ); | |||
// Wait an extra second for the PC's operating system to load drivers | |||
// and do whatever it does to actually be ready for input | |||
//_delay_ms(1000); // TODO | |||
//_delay_ms(1000); // TODO (is this actually necessary?) | |||
} | |||
@@ -110,8 +137,102 @@ inline void output_send(void) | |||
inline void output_firmwareReload() | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) | |||
usb_debug_reload(); | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) | |||
usb_device_reload(); | |||
#endif | |||
} | |||
// USB Input buffer available | |||
inline unsigned int output_availablechar() | |||
{ | |||
return usb_serial_available(); | |||
} | |||
// USB Get Character from input buffer | |||
inline int output_getchar() | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) | |||
// XXX Make sure to check output_availablechar() first! Information is lost with the cast (error codes) | |||
return (int)usb_serial_getchar(); | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) | |||
return usb_serial_getchar(); | |||
#endif | |||
} | |||
// USB Send Character to output buffer | |||
inline int output_putchar( char c ) | |||
{ | |||
return usb_serial_putchar( c ); | |||
} | |||
// USB Send String to output buffer, null terminated | |||
inline int output_putstr( char* str ) | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR | |||
uint16_t count = 0; | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) // ARM | |||
uint32_t count = 0; | |||
#endif | |||
// Count characters until NULL character, then send the amount counted | |||
while ( str[count] != '\0' ) | |||
count++; | |||
return usb_serial_write( str, count ); | |||
} | |||
// Soft Chip Reset | |||
inline void output_softReset() | |||
{ | |||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) | |||
usb_debug_software_reset(); | |||
#elif defined(_mk20dx128_) || defined(_mk20dx256_) | |||
SOFTWARE_RESET(); | |||
#endif | |||
} | |||
// ----- CLI Command Functions ----- | |||
void cliFunc_holdKey( char* args ) | |||
{ | |||
// TODO | |||
} | |||
void cliFunc_readLEDs( char* args ) | |||
{ | |||
// TODO | |||
} | |||
void cliFunc_releaseKey( char* args ) | |||
{ | |||
// TODO | |||
} | |||
void cliFunc_sendKey( char* args ) | |||
{ | |||
// TODO Argument handling | |||
USBKeys_Array[0] = 4; // KEY_A | |||
USBKeys_Sent = 1; | |||
} | |||
void cliFunc_setLEDs( char* args ) | |||
{ | |||
// TODO | |||
} | |||
void cliFunc_setMod( char* args ) | |||
{ | |||
// TODO | |||
} | |||
@@ -59,10 +59,17 @@ extern uint8_t USBKeys_Idle_Count; | |||
// ----- Functions ----- | |||
void output_setup(); | |||
void output_send(); | |||
void output_firmwareReload(); | |||
void output_softReset(); | |||
// Relies on USB serial module | |||
unsigned int output_availablechar(); | |||
int output_getchar(); | |||
int output_putchar( char c ); | |||
int output_putstr( char* str ); | |||
#endif | |||
@@ -17,7 +17,7 @@ if ( ${COMPILER_FAMILY} MATCHES "avr" ) | |||
set( OUTPUT_SRCS | |||
output_com.c | |||
avr/usb_keyboard_debug.c | |||
avr/usb_keyboard_serial.c | |||
) | |||
#| ARM Compiler |
@@ -24,10 +24,12 @@ AVR Specific (Teensy 1.0/++,2.0/++) (try to use something recent, suggested vers | |||
- avr-libc (1.8.0) | |||
ARM Specific (Teensy 3.0) (Sourcery CodeBench Lite for ARM EABI | |||
ARM Specific (Teensy 3.0/3.1) (Sourcery CodeBench Lite for ARM EABI | |||
(http://www.mentor.com/embedded-software/sourcery-tools/sourcery-codebench/editions/lite-edition/) | |||
- arm-none-eabi | |||
- TODO? | |||
OR | |||
- arm-none-eabi-gcc | |||
- arm-none-eaby-binutils | |||
@@ -42,6 +44,7 @@ The options are: | |||
- Teensy 2.0 | |||
- Teensy 2.0++ | |||
- Teensy 3.0 | |||
- Teensy 3.1 | |||
Open up CMakeLists.txt in your favourite text editor. | |||
You are looking for: | |||
@@ -57,13 +60,14 @@ You are looking for: | |||
#| "avr" # Teensy++ 1.0 | |||
#| "avr" # Teensy++ 2.0 | |||
#| "arm" # Teensy 3.0 | |||
#| "arm" # Teensy 3.1 | |||
set( COMPILER_FAMILY "avr" ) | |||
Just change the COMPILER_FAMILY variable to whatever you are trying to build for. | |||
NOTE: If you change this option, you will *may* to delete the build directory that is created in the Building sections below. | |||
NOTE: If you change this option, you will *may* to delete the build directory that is created in the Building sections below. | |||
@@ -102,6 +106,7 @@ You are looking for: | |||
#| type "make clean" after changing this, so all files will be rebuilt | |||
#| | |||
#| "mk20dx128" # Teensy 3.0 | |||
#| "mk20dx256" # Teensy 3.1 | |||
set( CHIP "mk20dx128" ) | |||
@@ -123,7 +128,7 @@ The Kiibohd Controller is designed around a set of 4 types of modules that corre | |||
- Scan Module | |||
- Macro Module | |||
- USB Module | |||
- Output Module | |||
- Debug Module | |||
The Scan Module is where the most interesting stuff happens. These modules take in "keypress data". | |||
@@ -135,11 +140,11 @@ Each Scan Module has it's own default keymap/modifier map. (TODO recommend keyma | |||
Some scan modules have very specialized hardware requirements, each module directory should have at least a link to the needed parts and/or schematics (TODO!). | |||
The Macro Module takes care of the mapping of the key press/release code into a USB scan code. | |||
The Macro Module takes care of the mapping of the key press/release code into an Output (USB) scan code. | |||
Any layering, macros, keypress intelligence/reaction is done here. | |||
The USB Module is the output module of the microcontroller. Currently USB is the only output protocol. | |||
The Output Module is the module dealing with output from the microcontroller. Currently USB is the only output protocol. | |||
Different USB output implementations are available, pjrc being the safest/least featureful one. | |||
Debug capabilities may depend on the module selected. | |||
@@ -161,7 +166,7 @@ Look for: | |||
#| All of the modules must be specified, as they generate the sources list of files to compile | |||
#| Any modifications to this file will cause a complete rebuild of the project | |||
#| Please look at the {Scan,Macro,USB,Debug}/module.txt for information on the modules and how to create new ones | |||
#| Please look at the {Scan,Macro,Output,Debug}/module.txt for information on the modules and how to create new ones | |||
##| Deals with acquiring the keypress information and turning it into a key index | |||
set( ScanModule "avr-capsense" ) | |||
@@ -170,7 +175,7 @@ Look for: | |||
set( MacroModule "buffer" ) | |||
##| Sends the current list of usb key codes through USB HID | |||
set( USBModule "pjrc" ) | |||
set( OutputModule "pjrc" ) | |||
##| Debugging source to use, each module has it's own set of defines that it sets | |||
set( DebugModule "full" ) | |||
@@ -206,8 +211,8 @@ Example output: | |||
Scan/avr-capsense/scan_loop.c | |||
-- Detected Macro Module Source Files: | |||
Macro/buffer/macro.c | |||
-- Detected USB Module Source Files: | |||
USB/pjrc/usb_com.c;USB/pjrc/avr/usb_keyboard_debug.c | |||
-- Detected Output Module Source Files: | |||
Output/pjrc/usb_com.c;Output/pjrc/avr/usb_keyboard_debug.c | |||
-- Detected Debug Module Source Files: | |||
Debug/full/../led/led.c;Debug/full/../print/print.c | |||
-- Configuring done | |||
@@ -218,8 +223,8 @@ Example output: | |||
[ 12%] Building C object CMakeFiles/kiibohd.elf.dir/main.c.o | |||
[ 25%] Building C object CMakeFiles/kiibohd.elf.dir/Scan/avr-capsense/scan_loop.c.o | |||
[ 37%] Building C object CMakeFiles/kiibohd.elf.dir/Macro/buffer/macro.c.o | |||
[ 50%] Building C object CMakeFiles/kiibohd.elf.dir/USB/pjrc/usb_com.c.o | |||
[ 62%] Building C object CMakeFiles/kiibohd.elf.dir/USB/pjrc/avr/usb_keyboard_debug.c.o | |||
[ 50%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrc/usb_com.c.o | |||
[ 62%] Building C object CMakeFiles/kiibohd.elf.dir/Output/pjrc/avr/usb_keyboard_debug.c.o | |||
[ 75%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/led/led.c.o | |||
[ 87%] Building C object CMakeFiles/kiibohd.elf.dir/Debug/print/print.c.o | |||
Linking C executable kiibohd.elf |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2011-2013 by Joseph Makuch | |||
* Additions by Jacob Alexander (2013) | |||
* Additions by Jacob Alexander (2013-2014) | |||
* | |||
* This library is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public |
@@ -1,6 +1,6 @@ | |||
###| CMake Kiibohd Controller Scan Module |### | |||
# | |||
# Written by Jacob Alexander in 2013 for the Kiibohd Controller | |||
# Written by Jacob Alexander in 2013-2014 for the Kiibohd Controller | |||
# | |||
# Released into the Public Domain | |||
# |
@@ -24,7 +24,7 @@ set( SCAN_SRCS | |||
add_definitions( -I${HEAD_DIR}/Keymap ) | |||
add_definitions( | |||
-I${HEAD_DIR}/Scan/matrix | |||
) | |||
) | |||
#| Keymap Settings | |||
add_definitions( |
@@ -1,15 +1,15 @@ | |||
/* Copyright (C) 2011 by Jacob Alexander | |||
* | |||
/* Copyright (C) 2011,2014 by Jacob Alexander | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to deal | |||
* in the Software without restriction, including without limitation the rights | |||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
* copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | |||
* | |||
* | |||
* The above copyright notice and this permission notice shall be included in | |||
* all copies or substantial portions of the Software. | |||
* | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
@@ -1,15 +1,15 @@ | |||
/* Copyright (C) 2011 by Jacob Alexander | |||
* | |||
/* Copyright (C) 2011,2014 by Jacob Alexander | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to deal | |||
* in the Software without restriction, including without limitation the rights | |||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
* copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | |||
* | |||
* | |||
* The above copyright notice and this permission notice shall be included in | |||
* all copies or substantial portions of the Software. | |||
* | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
@@ -1,15 +1,15 @@ | |||
/* Copyright (C) 2011 by Jacob Alexander | |||
* | |||
/* Copyright (C) 2011,2014 by Jacob Alexander | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to deal | |||
* in the Software without restriction, including without limitation the rights | |||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
* copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | |||
* | |||
* | |||
* The above copyright notice and this permission notice shall be included in | |||
* all copies or substantial portions of the Software. | |||
* | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
@@ -69,7 +69,7 @@ static const uint8_t matrix_pinout[][MAX_ROW_SIZE + 1] = { | |||
// Just layout the matrix by rows and columns | |||
// Usually you'll want to set the scanMode above to scanDual or scanCol_powrRow/scanRow_powrCol | |||
// The mode allows for optimization in the kind of scanning algorithms that are done | |||
// | |||
// | |||
// The key numbers are used to translate into the keymap table (array) (and always start from 1, not 0). | |||
// Thus if a row doesn't use all the key positions, you can denote it as 0, which will be ignored/skipped on each scan | |||
// See the keymap.h file for the various preconfigured arrays. |
@@ -1,15 +1,15 @@ | |||
/* Copyright (C) 2011-2012 by Jacob Alexander | |||
* | |||
/* Copyright (C) 2011-2012,2014 by Jacob Alexander | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to deal | |||
* in the Software without restriction, including without limitation the rights | |||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
* copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | |||
* | |||
* | |||
* The above copyright notice and this permission notice shall be included in | |||
* all copies or substantial portions of the Software. | |||
* | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
@@ -1,15 +1,15 @@ | |||
/* Copyright (C) 2011-2012 by Jacob Alexander | |||
* | |||
/* Copyright (C) 2011-2012,2014 by Jacob Alexander | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a copy | |||
* of this software and associated documentation files (the "Software"), to deal | |||
* in the Software without restriction, including without limitation the rights | |||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
* copies of the Software, and to permit persons to whom the Software is | |||
* furnished to do so, subject to the following conditions: | |||
* | |||
* | |||
* The above copyright notice and this permission notice shall be included in | |||
* all copies or substantial portions of the Software. | |||
* | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
@@ -1,6 +1,6 @@ | |||
###| CMAKE Kiibohd Controller |### | |||
# | |||
# Jacob Alexander 2011-2013 | |||
# Jacob Alexander 2011-2014 | |||
# Due to this file's usefulness: | |||
# | |||
# Released into the Public Domain | |||
@@ -37,8 +37,8 @@ set( SIZE "avr-size" ) | |||
#| "atmega32u4" # Teensy 2.0 | |||
#| "at90usb646" # Teensy++ 1.0 | |||
#| "at90usb1286" # Teensy++ 2.0 | |||
#set( MCU "atmega32u4" ) | |||
set( MCU "at90usb1286" ) | |||
set( MCU "atmega32u4" ) | |||
#set( MCU "at90usb1286" ) | |||
message( STATUS "MCU Selected:" ) | |||
message( "${MCU}" ) | |||
@@ -51,6 +51,15 @@ set( COMPILER_SRCS | |||
) | |||
#| CPU Type | |||
#| This is only informational for AVR microcontrollers | |||
#| The field can be determined by the microcontroller chip, but currently only one CPU type is used atm | |||
set( CPU "megaAVR" ) | |||
message( STATUS "CPU Selected:" ) | |||
message( "${CPU}" ) | |||
#| USB Defines | |||
set( VENDOR_ID "0x16C0" ) | |||
set( PRODUCT_ID "0x047D" ) | |||
@@ -66,7 +75,7 @@ set( CSTANDARD "-std=gnu99" ) | |||
#| Warning Options | |||
#| -Wall...: warning level | |||
set( WARN "-Wall -Wstrict-prototypes" ) | |||
set( WARN "-Wall" ) | |||
#| Tuning Options | |||
@@ -75,7 +84,7 @@ set( WARN "-Wall -Wstrict-prototypes" ) | |||
set( TUNING "-funsigned-char -funsigned-bitfields -ffunction-sections -fpack-struct -fshort-enums" ) | |||
#| Optimization level, can be [0, 1, 2, 3, s]. | |||
#| Optimization level, can be [0, 1, 2, 3, s]. | |||
#| 0 = turn off optimization. s = optimize for size. | |||
#| (Note: 3 is not always the best optimization level. See avr-libc FAQ.) | |||
set( OPT "s" ) |
@@ -139,57 +139,43 @@ int main(void) | |||
{ | |||
// Configuring Pins | |||
pinSetup(); | |||
init_errorLED(); | |||
// Setup Output Module | |||
output_setup(); | |||
// Enable CLI | |||
init_cli(); | |||
// Setup Output Module | |||
output_setup(); | |||
// Setup ISR Timer for flagging a kepress send to USB | |||
usbTimerSetup(); | |||
// Setup the scanning module | |||
//scan_setup(); | |||
// Main Detection Loop | |||
uint8_t ledTimer = F_CPU / 1000000; // Enable LED for a short time | |||
while ( 1 ) | |||
{ | |||
// Setup the scanning module | |||
scan_setup(); | |||
while ( 1 ) | |||
{ | |||
// Acquire Key Indices | |||
// Loop continuously until scan_loop returns 0 | |||
cli(); | |||
while ( scan_loop() ); | |||
sei(); | |||
// Run Macros over Key Indices and convert to USB Keys | |||
process_macros(); | |||
// Send keypresses over USB if the ISR has signalled that it's time | |||
if ( !sendKeypresses ) | |||
continue; | |||
// Send USB Data | |||
output_send(); | |||
// Process CLI | |||
process_cli(); | |||
// Clear sendKeypresses Flag | |||
sendKeypresses = 0; | |||
// Acquire Key Indices | |||
// Loop continuously until scan_loop returns 0 | |||
cli(); | |||
//while ( scan_loop() ); | |||
sei(); | |||
// Indicate Error, if valid | |||
errorLED( ledTimer ); | |||
// Run Macros over Key Indices and convert to USB Keys | |||
process_macros(); | |||
if ( ledTimer > 0 ) | |||
ledTimer--; | |||
} | |||
// Send keypresses over USB if the ISR has signalled that it's time | |||
if ( !sendKeypresses ) | |||
continue; | |||
// Loop should never get here (indicate error) | |||
ledTimer = 255; | |||
// Send USB Data | |||
output_send(); | |||
// HID Debug Error message | |||
erro_print("Detection loop error, this is very bad...bug report!"); | |||
// Clear sendKeypresses Flag | |||
sendKeypresses = 0; | |||
} | |||
} | |||
@@ -20,7 +20,7 @@ | |||
#| Please look at the {Scan,Macro,USB,Debug}/module.txt for information on the modules and how to create new ones | |||
##| Deals with acquiring the keypress information and turning it into a key index | |||
set( ScanModule "MBC-55X" ) | |||
set( ScanModule "SKM67001" ) | |||
##| Uses the key index and potentially applies special conditions to it, mapping it to a usb key code | |||
set( MacroModule "buffer" ) |