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

This commit is contained in:
tmk
2011-02-20 17:46:02 +09:00
parent 239bdbf419
commit 47f5d8b545
11 changed files with 530 additions and 272 deletions
-36
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
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
+34 -3
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
+72 -22
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
+22 -32
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();
}
}
File diff suppressed because it is too large Load Diff
+8
View File
@@ -0,0 +1,8 @@
#include <stdint.h>
#include "sendchar.h"
int8_t sendchar(uint8_t c)
{
return 1;
}
+58
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;
}
-53
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');
}
-121
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__ */
+7 -5
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.