Synchronous USART support for PS/2 on V-USB stack

master
tmk 2011-02-20 17:46:02 +09:00
parent 239bdbf419
commit 47f5d8b545
11 changed files with 530 additions and 272 deletions

View File

@ -233,42 +233,6 @@ LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#---------------- Programming Options (avrdude) ----------------
# Programming hardware
# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = stk500v2
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com1 # programmer connected to serial device
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
#---------------- Debugging Options ----------------
# For simulavr only - target MCU frequency.

4
ps2.h
View File

@ -56,6 +56,10 @@ POSSIBILITY OF SUCH DAMAGE.
# error "PS/2 data port setting is required in config.h"
#endif
#define PS2_ACK 0xFA
#define PS2_RESEND 0xFE
#define PS2_SET_LED 0xED
#define PS2_ERR_NONE 0
#define PS2_ERR_PARITY 0x10

View File

@ -12,8 +12,9 @@ TARGET_SRC = main.c \
keymap.c \
matrix.c \
led.c \
ps2.c \
usart_print.c
ps2_usart.c \
sendchar_dummy.c
# sendchar_usart.c
OPT_DEFS = -DDEBUG_LEVEL=0
@ -32,7 +33,7 @@ MCU = atmega168
# so your program will run at the correct speed. You should also set this
# variable to same clock speed. The _delay_ms() macro uses this, and many
# examples use this variable to calculate timings. Do not add a "UL" here.
F_CPU = 16000000
F_CPU = 20000000
# Build Options
@ -43,5 +44,35 @@ MOUSEKEY_ENABLE = yes # Mouse keys
#USB_NKRO_ENABLE = yes # USB Nkey Rollover
#---------------- Programming Options (avrdude) ----------------
# Type: avrdude -c ? to get a full listing.
AVRDUDE_PROGRAMMER = usbasp
AVRDUDE_PORT =
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
#AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS = -p $(MCU) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
include $(COMMON_DIR)/Makefile.vusb
include $(COMMON_DIR)/Makefile.common

View File

@ -3,7 +3,9 @@
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6512
#define PRODUCT_ID 0x2233
// TODO: share these strings with usbconfig.h
// Edit usbconfig.h to change these.
#define MANUFACTURER t.m.k.
#define PRODUCT PS/2 keyboard converter
#define DESCRIPTION convert PS/2 keyboard to USB
@ -33,36 +35,84 @@
#define PS2_CLOCK_PORT PORTD
#define PS2_CLOCK_PIN PIND
#define PS2_CLOCK_DDR DDRD
#define PS2_CLOCK_BIT 3
#define PS2_CLOCK_BIT 4
#define PS2_DATA_PORT PORTD
#define PS2_DATA_PIN PIND
#define PS2_DATA_DDR DDRD
#define PS2_DATA_BIT 7
#define PS2_DATA_BIT 0
/* External interrupt for PS/2 clock line (optional) */
#define PS2_INT_ENABLE() do { \
EIMSK |= (1<<INT1); \
EICRA |= ((1<<ISC11) | (0<<ISC10)); \
EIFR |= (1<<INTF1); \
// Synchronous USART is used to receive data from keyboard.
// Use RXD pin for PS/2 DATA line and XCK for PS/2 CLOCK.
// NOTE: This is recomended strongly if you use V-USB library.
#define PS2_USE_USART
// External or Pin Change Interrupt is used to receive data from keyboard.
// Use INT1 or PCINTxx for PS/2 CLOCK line. see below.
//#define PS2_USE_INT
#ifdef PS2_USE_USART
// synchronous, odd parity, 1-bit stop, 8-bit data, sample at falling edge
// set DDR of CLOCK as input to be slave
#define PS2_USART_INIT() do { \
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT); \
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT); \
UCSR0C = ((1 << UMSEL00) | \
(3 << UPM00) | \
(0 << USBS0) | \
(3 << UCSZ00) | \
(0 << UCPOL0)); \
UCSR0A = 0; \
UBRR0H = 0; \
UBRR0L = 0; \
} while (0)
#define PS2_USART_RX_INT_ON() do { \
UCSR0B = ((1 << RXCIE0) | \
(1 << RXEN0)); \
} while (0)
#define PS2_USART_RX_POLL_ON() do { \
UCSR0B = (1 << RXEN0); \
} while (0)
#define PS2_USART_OFF() do { \
UCSR0C = 0; \
UCSR0B &= ~((1 << RXEN0) | \
(1 << TXEN0)); \
} while (0)
#define PS2_USART_RX_READY (UCSR0A & (1<<RXC0))
#define PS2_USART_RX_DATA UDR0
#define PS2_USART_ERROR (UCSR0A & ((1<<FE0) | (1<<DOR0) | (1<<UPE0)))
#define PS2_USART_RX_VECT USART_RX_vect
#endif
#define PS2_INT_DISABLE() do { \
#ifdef PS2_USE_INT
/* INT1
#define PS2_INT_INIT() do { \
EICRA |= ((1<<ISC11) | \
(0<<ISC10)); \
} while (0)
#define PS2_INT_ON() do { \
EIMSK |= (1<<INT1); \
} while (0)
#define PS2_INT_OFF() do { \
EIMSK &= ~(1<<INT1); \
} while (0)
#define PS2_INT_VECT INT1_vect
/* Pin Change interrupt for PS/2 clock line (optional)
#define PS2_INT_ENABLE() do { \
PCMSK2 |= (1<<PCINT22); \
PCICR |= (1<<PCIE2); \
PCIFR |= (1<<PCIF2); \
} while (0)
#define PS2_INT_DISABLE() do { \
PCMSK2 &= ~(1<<PCINT22); \
PCICR &= ~(1<<PCIE); \
} while (0)
#define PS2_INT_VECT PCINT2_vect
*/
/* PCINT20 */
#define PS2_INT_INIT() do { \
PCICR |= (1<<PCIE2); \
} while (0)
#define PS2_INT_ON() do { \
PCMSK2 |= (1<<PCINT20); \
} while (0)
#define PS2_INT_OFF() do { \
PCMSK2 &= ~(1<<PCINT20); \
PCICR &= ~(1<<PCIE2); \
} while (0)
#define PS2_INT_VECT PCINT2_vect
#endif
#endif

View File

@ -1,3 +1,7 @@
/* PS/2 to USB keyboard converter
* 2011/02/20
* Copyright (c) 2011 tmk
*/
/* Name: main.c
* Project: hid-mouse, a very simple HID example
* Author: Christian Starkjohann
@ -8,65 +12,51 @@
* This Revision: $Id: main.c 790 2010-05-30 21:00:26Z cs $
*/
#include <stdint.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h> /* for sei() */
#include <avr/pgmspace.h> /* required by usbdrv.h */
#include <util/delay.h> /* for _delay_ms() */
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usbdrv.h"
#include "usart_print.h" /* This is also an example for using debug macros */
#include "usb_keycodes.h"
#include "matrix_skel.h"
#include "keymap_skel.h"
#include "mousekey.h"
#include "layer.h"
#include "print.h"
#include "debug.h"
#include "sendchar.h"
#include "host.h"
#include "oddebug.h"
#include "host_vusb.h"
#include "timer.h"
#include "led.h"
#include "keyboard.h"
#if 0
#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0)
#define DEBUGP(x) do { PORTC = x; } while (0)
#else
#define DEBUGP_INIT()
#define DEBUGP(x)
#endif
//static uint8_t last_led = 0;
int main(void)
{
DEBUGP_INIT();
wdt_enable(WDTO_1S);
/* Even if you don't use the watchdog, turn it off here. On newer devices,
* the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
*/
/* RESET status: all port bits are inputs without pull-up.
* That's the way we need D+ and D-. Therefore we don't need any
* additional hardware initialization.
*/
odDebugInit();
usbInit();
print_enable = true;
debug_enable = true;
keyboard_init();
/* enforce re-enumeration, do this while interrupts are disabled! */
usbDeviceDisconnect();
uint8_t i = 0;
while(--i){ /* fake USB disconnect for > 250 ms */
/* fake USB disconnect for > 250 ms */
while(--i){
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
sei();
//uint8_t fn_bits = 0;
while (1) { /* main event loop */
keyboard_init();
while (1) {
DEBUGP(0x1);
wdt_reset();
usbPoll();
DEBUGP(0x2);
keyboard_proc();
DEBUGP(0x3);
host_vusb_keyboard_send();
}
}

View File

@ -0,0 +1,325 @@
/*
Copyright (c) 2010,2011 Jun WAKO <wakojun@gmail.com>
This software is licensed with a Modified BSD License.
All of this is supposed to be Free Software, Open Source, DFSG-free,
GPL-compatible, and OK to use in both free and proprietary applications.
Additions and corrections to this file are welcome.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*
Primitive PS/2 Library for AVR
==============================
Host side is only supported now.
Synchronous USART is used to receive data by hardware process
rather than interrupt. During V-USB interrupt runs, CLOCK interrupt
cannot interpose. In the result it is prone to lost CLOCK edge.
I/O control
-----------
High state is asserted by internal pull-up.
If you have a signaling problem, you may need to have
external pull-up resisters on CLOCK and DATA line.
PS/2 References
---------------
http://www.computer-engineering.org/ps2protocol/
http://www.mcamafia.de/pdf/ibm_hitrc07.pdf
*/
#include <stdbool.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "ps2.h"
#include "debug.h"
#if 0
#define DEBUGP_INIT() do { DDRC = 0xFF; } while (0)
#define DEBUGP(x) do { PORTC = x; } while (0)
#else
#define DEBUGP_INIT()
#define DEBUGP(x)
#endif
#define WAIT(stat, us, err) do { \
if (!wait_##stat(us)) { \
ps2_error = err; \
goto ERROR; \
} \
} while (0)
uint8_t ps2_error = PS2_ERR_NONE;
static inline void clock_lo(void);
static inline void clock_hi(void);
static inline bool clock_in(void);
static inline void data_lo(void);
static inline void data_hi(void);
static inline bool data_in(void);
static inline uint16_t wait_clock_lo(uint16_t us);
static inline uint16_t wait_clock_hi(uint16_t us);
static inline uint16_t wait_data_lo(uint16_t us);
static inline uint16_t wait_data_hi(uint16_t us);
static inline void idle(void);
static inline void inhibit(void);
#if defined PS2_USE_INT || defined PS2_USE_USART
static inline uint8_t pbuf_dequeue(void);
static inline void pbuf_enqueue(uint8_t data);
#endif
void ps2_host_init(void)
{
DEBUGP_INIT();
DEBUGP(0x1);
idle();
PS2_USART_INIT();
PS2_USART_RX_INT_ON();
}
uint8_t ps2_host_send(uint8_t data)
{
uint8_t res = 0;
bool parity = true;
ps2_error = PS2_ERR_NONE;
DEBUGP(0x6);
PS2_USART_OFF();
/* terminate a transmission if we have */
inhibit();
_delay_us(100);
/* start bit [1] */
data_lo();
clock_hi();
WAIT(clock_lo, 15000, 1);
/* data [2-9] */
for (uint8_t i = 0; i < 8; i++) {
_delay_us(15);
if (data&(1<<i)) {
parity = !parity;
data_hi();
} else {
data_lo();
}
WAIT(clock_hi, 50, 2);
WAIT(clock_lo, 50, 3);
}
/* parity [10] */
_delay_us(15);
if (parity) { data_hi(); } else { data_lo(); }
WAIT(clock_hi, 50, 4);
WAIT(clock_lo, 50, 5);
/* stop bit [11] */
_delay_us(15);
data_hi();
/* ack [12] */
WAIT(data_lo, 50, 6);
WAIT(clock_lo, 50, 7);
/* wait for idle state */
WAIT(clock_hi, 50, 8);
WAIT(data_hi, 50, 9);
res = ps2_host_recv_response();
ERROR:
idle();
PS2_USART_INIT();
PS2_USART_RX_INT_ON();
return res;
}
// Do polling data from keyboard to get response to last command.
uint8_t ps2_host_recv_response(void)
{
uint8_t data = 0;
PS2_USART_INIT();
PS2_USART_RX_POLL_ON();
while (!PS2_USART_RX_READY)
;
data = PS2_USART_RX_DATA;
PS2_USART_OFF();
DEBUGP(0x9);
return data;
}
uint8_t ps2_host_recv(void)
{
return pbuf_dequeue();
}
ISR(PS2_USART_RX_VECT)
{
DEBUGP(0x7);
uint8_t error = PS2_USART_ERROR;
uint8_t data = PS2_USART_RX_DATA;
if (error) {
DEBUGP(error>>2);
} else {
pbuf_enqueue(data);
}
DEBUGP(0x8);
}
/* send LED state to keyboard */
void ps2_host_set_led(uint8_t led)
{
// send 0xED then keyboard keeps waiting for next LED data
// and keyboard does not send any scan codes during waiting.
// If fail to send LED data keyboard looks like being freezed.
uint8_t retry = 3;
while (retry-- && ps2_host_send(PS2_SET_LED) != PS2_ACK)
;
retry = 3;
while (retry-- && ps2_host_send(led) != PS2_ACK)
;
}
/*--------------------------------------------------------------------
* static functions
*------------------------------------------------------------------*/
static inline void clock_lo()
{
PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
}
static inline void clock_hi()
{
/* input with pull up */
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
}
static inline bool clock_in()
{
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
_delay_us(1);
return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
}
static inline void data_lo()
{
PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
}
static inline void data_hi()
{
/* input with pull up */
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
}
static inline bool data_in()
{
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
_delay_us(1);
return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
}
static inline uint16_t wait_clock_lo(uint16_t us)
{
while (clock_in() && us) { asm(""); _delay_us(1); us--; }
return us;
}
static inline uint16_t wait_clock_hi(uint16_t us)
{
while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
return us;
}
static inline uint16_t wait_data_lo(uint16_t us)
{
while (data_in() && us) { asm(""); _delay_us(1); us--; }
return us;
}
static inline uint16_t wait_data_hi(uint16_t us)
{
while (!data_in() && us) { asm(""); _delay_us(1); us--; }
return us;
}
/* idle state that device can send */
static inline void idle(void)
{
clock_hi();
data_hi();
}
/* inhibit device to send */
static inline void inhibit(void)
{
clock_lo();
data_hi();
}
/*--------------------------------------------------------------------
* Ring buffer to store scan codes from keyboard
*------------------------------------------------------------------*/
#define PBUF_SIZE 8
static uint8_t pbuf[PBUF_SIZE];
static uint8_t pbuf_head = 0;
static uint8_t pbuf_tail = 0;
static inline void pbuf_enqueue(uint8_t data)
{
if (!data)
return;
uint8_t sreg = SREG;
cli();
uint8_t next = (pbuf_head + 1) % PBUF_SIZE;
if (next != pbuf_tail) {
pbuf[pbuf_head] = data;
pbuf_head = next;
} else {
debug("pbuf: full\n");
}
SREG = sreg;
}
static inline uint8_t pbuf_dequeue(void)
{
uint8_t val = 0;
uint8_t sreg = SREG;
cli();
if (pbuf_head != pbuf_tail) {
val = pbuf[pbuf_tail];
pbuf_tail = (pbuf_tail + 1) % PBUF_SIZE;
}
SREG = sreg;
return val;
}

View File

@ -0,0 +1,8 @@
#include <stdint.h>
#include "sendchar.h"
int8_t sendchar(uint8_t c)
{
return 1;
}

View File

@ -0,0 +1,58 @@
#include <stdint.h>
#include "oddebug.h"
#include "sendchar.h"
/* from oddebug.h */
#if defined UBRR
# define ODDBG_UBRR UBRR
#elif defined UBRRL
# define ODDBG_UBRR UBRRL
#elif defined UBRR0
# define ODDBG_UBRR UBRR0
#elif defined UBRR0L
# define ODDBG_UBRR UBRR0L
#endif
#if defined UCR
# define ODDBG_UCR UCR
#elif defined UCSRB
# define ODDBG_UCR UCSRB
#elif defined UCSR0B
# define ODDBG_UCR UCSR0B
#endif
#if defined TXEN
# define ODDBG_TXEN TXEN
#else
# define ODDBG_TXEN TXEN0
#endif
#if defined USR
# define ODDBG_USR USR
#elif defined UCSRA
# define ODDBG_USR UCSRA
#elif defined UCSR0A
# define ODDBG_USR UCSR0A
#endif
#if defined UDRE
# define ODDBG_UDRE UDRE
#else
# define ODDBG_UDRE UDRE0
#endif
#if defined UDR
# define ODDBG_UDR UDR
#elif defined UDR0
# define ODDBG_UDR UDR0
#endif
/* from oddebug.c */
int8_t sendchar(uint8_t c)
{
while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */
ODDBG_UDR = c;
return 1;
}

View File

@ -1,53 +0,0 @@
/* Name: oddebug.c
* Project: AVR library
* Author: Christian Starkjohann
* Creation Date: 2005-01-16
* Tabsize: 4
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: oddebug.c 692 2008-11-07 15:07:40Z cs $
*/
#include "usart_print.h"
#include "sendchar.h"
int8_t sendchar(uint8_t c)
{
while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */
ODDBG_UDR = c;
return 0;
}
void uartPutc(char c)
{
while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */
ODDBG_UDR = c;
}
static uchar hexAscii(uchar h)
{
h &= 0xf;
if(h >= 10)
h += 'a' - (uchar)10 - '0';
h += '0';
return h;
}
void printHex(uchar c)
{
uartPutc(hexAscii(c >> 4));
uartPutc(hexAscii(c));
}
void odDebug(uchar prefix, uchar *data, uchar len)
{
printHex(prefix);
uartPutc(':');
while(len--){
uartPutc(' ');
printHex(*data++);
}
uartPutc('\r');
uartPutc('\n');
}

View File

@ -1,121 +0,0 @@
/* Name: oddebug.h
* Project: AVR library
* Author: Christian Starkjohann
* Creation Date: 2005-01-16
* Tabsize: 4
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: oddebug.h 692 2008-11-07 15:07:40Z cs $
*/
#ifndef __oddebug_h_included__
#define __oddebug_h_included__
/*
General Description:
This module implements a function for debug logs on the serial line of the
AVR microcontroller. Debugging can be configured with the define
'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging
calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is
2, DBG1 and DBG2 logs will be printed.
A debug log consists of a label ('prefix') to indicate which debug log created
the output and a memory block to dump in hex ('data' and 'len').
*/
#ifndef F_CPU
# define F_CPU 12000000 /* 12 MHz */
#endif
/* make sure we have the UART defines: */
#include "usbportability.h"
#ifndef uchar
# define uchar unsigned char
#endif
#if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */
# warning "Debugging disabled because device has no UART"
# undef DEBUG_LEVEL
#endif
#ifndef DEBUG_LEVEL
# define DEBUG_LEVEL 0
#endif
/* ------------------------------------------------------------------------- */
#if DEBUG_LEVEL > 0
# define DBG1(prefix, data, len) odDebug(prefix, data, len)
#else
# define DBG1(prefix, data, len)
#endif
#if DEBUG_LEVEL > 1
# define DBG2(prefix, data, len) odDebug(prefix, data, len)
#else
# define DBG2(prefix, data, len)
#endif
/* ------------------------------------------------------------------------- */
extern void odDebug(uchar prefix, uchar *data, uchar len);
void uartPutc(char c);
void printHex(uchar c);
/* Try to find our control registers; ATMEL likes to rename these */
#if defined UBRR
# define ODDBG_UBRR UBRR
#elif defined UBRRL
# define ODDBG_UBRR UBRRL
#elif defined UBRR0
# define ODDBG_UBRR UBRR0
#elif defined UBRR0L
# define ODDBG_UBRR UBRR0L
#endif
#if defined UCR
# define ODDBG_UCR UCR
#elif defined UCSRB
# define ODDBG_UCR UCSRB
#elif defined UCSR0B
# define ODDBG_UCR UCSR0B
#endif
#if defined TXEN
# define ODDBG_TXEN TXEN
#else
# define ODDBG_TXEN TXEN0
#endif
#if defined USR
# define ODDBG_USR USR
#elif defined UCSRA
# define ODDBG_USR UCSRA
#elif defined UCSR0A
# define ODDBG_USR UCSR0A
#endif
#if defined UDRE
# define ODDBG_UDRE UDRE
#else
# define ODDBG_UDRE UDRE0
#endif
#if defined UDR
# define ODDBG_UDR UDR
#elif defined UDR0
# define ODDBG_UDR UDR0
#endif
static inline void odDebugInit(void)
{
ODDBG_UCR |= (1<<ODDBG_TXEN);
ODDBG_UBRR = F_CPU / (57600 * 16L) - 1;
}
/* ------------------------------------------------------------------------- */
#endif /* __oddebug_h_included__ */

View File

@ -11,6 +11,8 @@
#ifndef __usbconfig_h_included__
#define __usbconfig_h_included__
#include "config.h"
/*
General Description:
This file is an example configuration (with inline documentation) for the USB
@ -27,7 +29,7 @@ section at the end of this file).
/* This is the port where the USB bus is connected. When you configure it to
* "B", the registers PORTB, PINB and DDRB will be used.
*/
#define USB_CFG_DMINUS_BIT 4
#define USB_CFG_DMINUS_BIT 3
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
* This may be any bit in the port.
*/
@ -216,7 +218,7 @@ section at the end of this file).
/* -------------------------- Device Description --------------------------- */
#define USB_CFG_VENDOR_ID 0xc0, 0x16 /* = 0x16c0 = 5824 = voti.nl */
#define USB_CFG_VENDOR_ID (VENDOR_ID & 0xFF), ((VENDOR_ID >> 8) & 0xFF)
/* USB vendor ID for the device, low byte first. If you have registered your
* own Vendor ID, define it here. Otherwise you may use one of obdev's free
* shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
@ -225,7 +227,7 @@ section at the end of this file).
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
* the implications!
*/
#define USB_CFG_DEVICE_ID 0xdd, 0x05 /* = 0x05dc = 1500 */
#define USB_CFG_DEVICE_ID (PRODUCT_ID & 0xFF), ((PRODUCT_ID >> 8) & 0xFF)
/* This is the ID of the product, low byte first. It is interpreted in the
* scope of the vendor ID. If you have registered your own VID with usb.org
* or if you have licensed a PID from somebody else, define it here. Otherwise
@ -249,8 +251,8 @@ section at the end of this file).
* obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
* details.
*/
#define USB_CFG_DEVICE_NAME 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd'
#define USB_CFG_DEVICE_NAME_LEN 8
#define USB_CFG_DEVICE_NAME 'P', 'S', '/', '2', ' ', 'k', 'e', 'y', 'b', 'o', 'a', 'r', 'd', ' ', 'c', 'o', 'n', 'v', 'e', 'r', 't', 'e', 'r'
#define USB_CFG_DEVICE_NAME_LEN 23
/* Same as above for the device name. If you don't want a device name, undefine
* the macros. See the file USB-IDs-for-free.txt before you assign a name if
* you use a shared VID/PID.