Browse Source

divide usb_keyboard_debug.[c|h] into usb_device, usb_keyboard, usb_debug.

tags/v1.9
tmk 13 years ago
parent
commit
7fd9003f59
9 changed files with 225 additions and 186 deletions
  1. 3
    1
      Makefile
  2. 1
    1
      mykey.c
  3. 1
    1
      print.h
  4. 80
    0
      usb_debug.c
  5. 20
    0
      usb_debug.h
  6. 12
    164
      usb_device.c
  7. 7
    19
      usb_device.h
  8. 76
    0
      usb_keyboard.c
  9. 25
    0
      usb_keyboard.h

+ 3
- 1
Makefile View File

@@ -48,7 +48,9 @@ TARGET = mykey
SRC = $(TARGET).c \
keymap.c \
matrix.c \
usb_keyboard_debug.c \
usb_device.c \
usb_keyboard.c \
usb_debug.c \
print.c



+ 1
- 1
mykey.c View File

@@ -30,7 +30,7 @@
#include <avr/interrupt.h>
#include <util/delay.h>

#include "usb_keyboard_debug.h"
#include "usb_device.h"
#include "print.h"
#include "matrix.h"
#include "keymap.h"

+ 1
- 1
print.h View File

@@ -2,7 +2,7 @@
#define print_h__

#include <avr/pgmspace.h>
#include "usb_keyboard_debug.h"
#include "usb_debug.h"

// this macro allows you to write print("some text") and
// the string is automatically placed into flash memory :)

+ 80
- 0
usb_debug.c View File

@@ -0,0 +1,80 @@
#include <avr/interrupt.h>
#include "usb_debug.h"


// the time remaining before we transmit any partially full
// packet, or send a zero length packet.
volatile uint8_t debug_flush_timer=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_configured()) 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_configured()) 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;
}

+ 20
- 0
usb_debug.h View File

@@ -0,0 +1,20 @@
#ifndef USB_DEBUG_H
#define USB_DEBUG_H 1

#include <stdint.h>
#include "usb_device.h"


#define DEBUG_INTERFACE 1
#define DEBUG_TX_ENDPOINT 4
#define DEBUG_TX_SIZE 32
#define DEBUG_TX_BUFFER EP_DOUBLE_BUFFER


extern volatile uint8_t debug_flush_timer;


int8_t usb_debug_putchar(uint8_t c); // transmit a character
void usb_debug_flush_output(void); // immediately transmit any buffered output

#endif

usb_keyboard_debug.c → usb_device.c View File

@@ -21,11 +21,12 @@
* THE SOFTWARE.
*/

// Version 1.0: Initial Release
// Version 1.1: Add support for Teensy 2.0
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "usb_device.h"
#include "usb_keyboard.h"
#include "usb_debug.h"

#define USB_SERIAL_PRIVATE_INCLUDE
#include "usb_keyboard_debug.h"

/**************************************************************************
*
@@ -63,16 +64,6 @@

#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,
@@ -191,7 +182,7 @@ static uint8_t PROGMEM config1_descriptor[CONFIG1_DESC_SIZE] = {
0, // bCountryCode
1, // bNumDescriptors
0x22, // bDescriptorType
sizeof(keyboard_hid_report_desc), // wDescriptorLength
sizeof(keyboard_hid_report_desc), // wDescriptorLength
0,
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
7, // bLength
@@ -255,17 +246,22 @@ static struct usb_string_descriptor_struct PROGMEM string2 = {
// This table defines which descriptor data is sent for each specific
// request from the host (in wValue and wIndex).
static struct descriptor_list_struct {
uint16_t wValue;
uint16_t wValue; // descriptor type
uint16_t wIndex;
const uint8_t *addr;
uint8_t length;
} PROGMEM descriptor_list[] = {
// DEVICE descriptor
{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
// CONFIGURATION descriptor
{0x0200, 0x0000, config1_descriptor, sizeof(config1_descriptor)},
// HID REPORT
{0x2200, KEYBOARD_INTERFACE, keyboard_hid_report_desc, sizeof(keyboard_hid_report_desc)},
{0x2100, KEYBOARD_INTERFACE, config1_descriptor+KEYBOARD_HID_DESC_OFFSET, 9},
// HID REPORT
{0x2200, DEBUG_INTERFACE, debug_hid_report_desc, sizeof(debug_hid_report_desc)},
{0x2100, DEBUG_INTERFACE, config1_descriptor+DEBUG_HID_DESC_OFFSET, 9},
// STRING descriptor
{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)}
@@ -282,33 +278,6 @@ static struct descriptor_list_struct {
// 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;

// 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
uint8_t keyboard_modifier_keys=0;

// which keys are currently pressed, up to 6 keys may be down at once
uint8_t keyboard_keys[6]={0,0,0,0,0,0};

// protocol setting from the host. We use exactly the same report
// either way, so this variable only stores the setting since we
// are required to be able to report which setting is in use.
static uint8_t keyboard_protocol=1;

// the idle configuration, how often we send the report to the
// host (ms * 4) even when it hasn't changed
static uint8_t keyboard_idle_config=125;

// count until idle timeout
static uint8_t keyboard_idle_count=0;

// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
volatile uint8_t keyboard_leds=0;


/**************************************************************************
*
@@ -339,127 +308,6 @@ uint8_t usb_configured(void)
}


// perform a single keystroke
int8_t usb_keyboard_press(uint8_t key, uint8_t modifier)
{
int8_t r;

keyboard_modifier_keys = modifier;
keyboard_keys[0] = key;
r = usb_keyboard_send();
if (r) return r;
keyboard_modifier_keys = 0;
keyboard_keys[0] = 0;
return usb_keyboard_send();
}

// send the contents of keyboard_keys and keyboard_modifier_keys
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 = keyboard_modifier_keys;
UEDATX = 0;
for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i];
}
UEINTX = 0x3A;
keyboard_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;
}



/**************************************************************************
*

usb_keyboard_debug.h → usb_device.h View File

@@ -1,30 +1,18 @@
#ifndef usb_serial_h__
#define usb_serial_h__
#ifndef USB_DEVICE_H
#define USB_DEVICE_H 1

#include <stdint.h>
#include <avr/io.h>
#include "usb_keyboard.h"
#include "usb_debug.h"


void usb_init(void); // initialize everything
uint8_t usb_configured(void); // is the USB port configured

int8_t usb_keyboard_press(uint8_t key, uint8_t modifier);
int8_t usb_keyboard_send(void);
extern uint8_t keyboard_modifier_keys;
extern uint8_t keyboard_keys[6];
extern volatile uint8_t keyboard_leds;

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
@@ -89,5 +77,5 @@ void usb_debug_flush_output(void); // immediately transmit any buffered output
#define CDC_SET_LINE_CODING 0x20
#define CDC_GET_LINE_CODING 0x21
#define CDC_SET_CONTROL_LINE_STATE 0x22
#endif
#endif

+ 76
- 0
usb_keyboard.c View File

@@ -0,0 +1,76 @@
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "usb_keyboard.h"


// 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
uint8_t keyboard_modifier_keys=0;

// which keys are currently pressed, up to 6 keys may be down at once
uint8_t keyboard_keys[6]={0,0,0,0,0,0};

// protocol setting from the host. We use exactly the same report
// either way, so this variable only stores the setting since we
// are required to be able to report which setting is in use.
uint8_t keyboard_protocol=1;

// the idle configuration, how often we send the report to the
// host (ms * 4) even when it hasn't changed
uint8_t keyboard_idle_config=125;

// count until idle timeout
uint8_t keyboard_idle_count=0;

// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana
volatile uint8_t keyboard_leds=0;


// perform a single keystroke
int8_t usb_keyboard_press(uint8_t key, uint8_t modifier)
{
int8_t r;

keyboard_modifier_keys = modifier;
keyboard_keys[0] = key;
r = usb_keyboard_send();
if (r) return r;
keyboard_modifier_keys = 0;
keyboard_keys[0] = 0;
return usb_keyboard_send();
}

// send the contents of keyboard_keys and keyboard_modifier_keys
int8_t usb_keyboard_send(void)
{
uint8_t i, intr_state, timeout;

if (!usb_configured()) 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_configured()) 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 = keyboard_modifier_keys;
UEDATX = 0;
for (i=0; i<6; i++) {
UEDATX = keyboard_keys[i];
}
UEINTX = 0x3A;
keyboard_idle_count = 0;
SREG = intr_state;
return 0;
}

+ 25
- 0
usb_keyboard.h View File

@@ -0,0 +1,25 @@
#ifndef USB_KEYBOARD_H
#define USB_KEYBOARD_H 1

#include <stdint.h>
#include "usb_device.h"


#define KEYBOARD_INTERFACE 0
#define KEYBOARD_ENDPOINT 3
#define KEYBOARD_SIZE 8
#define KEYBOARD_BUFFER EP_DOUBLE_BUFFER


extern uint8_t keyboard_modifier_keys;
extern uint8_t keyboard_keys[6];
extern uint8_t keyboard_protocol;
extern uint8_t keyboard_idle_config;
extern uint8_t keyboard_idle_count;
extern volatile uint8_t keyboard_leds;


int8_t usb_keyboard_press(uint8_t key, uint8_t modifier);
int8_t usb_keyboard_send(void);

#endif

Loading…
Cancel
Save