Remove unreferenced IBM4704, Sony NEWS, NeXT keyboard code. (#14380)
This commit is contained in:
parent
cf68c6403c
commit
d0ac03ec8b
6 changed files with 0 additions and 776 deletions
|
@ -1,185 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
|
|
||||||
*/
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include "debug.h"
|
|
||||||
#include "ring_buffer.h"
|
|
||||||
#include "ibm4704.h"
|
|
||||||
|
|
||||||
#define WAIT(stat, us, err) \
|
|
||||||
do { \
|
|
||||||
if (!wait_##stat(us)) { \
|
|
||||||
ibm4704_error = err; \
|
|
||||||
goto ERROR; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
uint8_t ibm4704_error = 0;
|
|
||||||
|
|
||||||
void ibm4704_init(void) {
|
|
||||||
inhibit(); // keep keyboard from sending
|
|
||||||
IBM4704_INT_INIT();
|
|
||||||
IBM4704_INT_ON();
|
|
||||||
idle(); // allow keyboard sending
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Host to Keyboard
|
|
||||||
----------------
|
|
||||||
Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
|
|
||||||
|
|
||||||
____ __ __ __ __ __ __ __ __ __ ________
|
|
||||||
Clock \______/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
|
|
||||||
^ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___
|
|
||||||
Data ____|__/ X____X____X____X____X____X____X____X____X____X \___
|
|
||||||
| Start 0 1 2 3 4 5 6 7 P Stop
|
|
||||||
Request by host
|
|
||||||
|
|
||||||
Start bit: can be long as 300-350us.
|
|
||||||
Request: Host pulls Clock line down to request to send a command.
|
|
||||||
Timing: After Request keyboard pull up Data and down Clock line to low for start bit.
|
|
||||||
After request host release Clock line once Data line becomes hi.
|
|
||||||
Host writes a bit while Clock is hi and Keyboard reads while low.
|
|
||||||
Stop bit: Host releases or pulls up Data line to hi after 9th clock and waits for keyboard pull down the line to lo.
|
|
||||||
*/
|
|
||||||
uint8_t ibm4704_send(uint8_t data) {
|
|
||||||
bool parity = true; // odd parity
|
|
||||||
ibm4704_error = 0;
|
|
||||||
|
|
||||||
IBM4704_INT_OFF();
|
|
||||||
|
|
||||||
/* Request to send */
|
|
||||||
idle();
|
|
||||||
clock_lo();
|
|
||||||
|
|
||||||
/* wait for Start bit(Clock:lo/Data:hi) */
|
|
||||||
WAIT(data_hi, 300, 0x30);
|
|
||||||
|
|
||||||
/* Data bit */
|
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
|
||||||
WAIT(clock_hi, 100, 0x40 + i);
|
|
||||||
if (data & (1 << i)) {
|
|
||||||
parity = !parity;
|
|
||||||
data_hi();
|
|
||||||
} else {
|
|
||||||
data_lo();
|
|
||||||
}
|
|
||||||
WAIT(clock_lo, 100, 0x48 + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parity bit */
|
|
||||||
WAIT(clock_hi, 100, 0x34);
|
|
||||||
if (parity) {
|
|
||||||
data_hi();
|
|
||||||
} else {
|
|
||||||
data_lo();
|
|
||||||
}
|
|
||||||
WAIT(clock_lo, 100, 0x35);
|
|
||||||
|
|
||||||
/* Stop bit */
|
|
||||||
WAIT(clock_hi, 100, 0x34);
|
|
||||||
data_hi();
|
|
||||||
|
|
||||||
/* End */
|
|
||||||
WAIT(data_lo, 100, 0x36);
|
|
||||||
|
|
||||||
idle();
|
|
||||||
IBM4704_INT_ON();
|
|
||||||
return 0;
|
|
||||||
ERROR:
|
|
||||||
idle();
|
|
||||||
if (ibm4704_error > 0x30) {
|
|
||||||
xprintf("S:%02X ", ibm4704_error);
|
|
||||||
}
|
|
||||||
IBM4704_INT_ON();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* wait forever to receive data */
|
|
||||||
uint8_t ibm4704_recv_response(void) {
|
|
||||||
while (!rbuf_has_data()) {
|
|
||||||
_delay_ms(1);
|
|
||||||
}
|
|
||||||
return rbuf_dequeue();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t ibm4704_recv(void) {
|
|
||||||
if (rbuf_has_data()) {
|
|
||||||
return rbuf_dequeue();
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Keyboard to Host
|
|
||||||
----------------
|
|
||||||
Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
|
|
||||||
|
|
||||||
____ __ __ __ __ __ __ __ __ __ _______
|
|
||||||
Clock \_____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
|
|
||||||
____ ____ ____ ____ ____ ____ ____ ____ ____ ____
|
|
||||||
Data ____/ X____X____X____X____X____X____X____X____X____X________
|
|
||||||
Start 0 1 2 3 4 5 6 7 P Stop
|
|
||||||
|
|
||||||
Start bit: can be long as 300-350us.
|
|
||||||
Inhibit: Pull Data line down to inhibit keyboard to send.
|
|
||||||
Timing: Host reads bit while Clock is hi.(rising edge)
|
|
||||||
Stop bit: Keyboard pulls down Data line to lo after 9th clock.
|
|
||||||
*/
|
|
||||||
ISR(IBM4704_INT_VECT) {
|
|
||||||
static enum { BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY, STOP } state = BIT0;
|
|
||||||
// LSB first
|
|
||||||
static uint8_t data = 0;
|
|
||||||
// Odd parity
|
|
||||||
static uint8_t parity = false;
|
|
||||||
|
|
||||||
ibm4704_error = 0;
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case BIT0:
|
|
||||||
case BIT1:
|
|
||||||
case BIT2:
|
|
||||||
case BIT3:
|
|
||||||
case BIT4:
|
|
||||||
case BIT5:
|
|
||||||
case BIT6:
|
|
||||||
case BIT7:
|
|
||||||
data >>= 1;
|
|
||||||
if (data_in()) {
|
|
||||||
data |= 0x80;
|
|
||||||
parity = !parity;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PARITY:
|
|
||||||
if (data_in()) {
|
|
||||||
parity = !parity;
|
|
||||||
}
|
|
||||||
if (!parity) goto ERROR;
|
|
||||||
break;
|
|
||||||
case STOP:
|
|
||||||
// Data:Low
|
|
||||||
WAIT(data_lo, 100, state);
|
|
||||||
if (!rbuf_enqueue(data)) {
|
|
||||||
print("rbuf: full\n");
|
|
||||||
}
|
|
||||||
ibm4704_error = IBM4704_ERR_NONE;
|
|
||||||
goto DONE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto ERROR;
|
|
||||||
}
|
|
||||||
state++;
|
|
||||||
goto RETURN;
|
|
||||||
ERROR:
|
|
||||||
ibm4704_error = state;
|
|
||||||
while (ibm4704_send(0xFE)) _delay_ms(1); // resend
|
|
||||||
xprintf("R:%02X%02X\n", state, data);
|
|
||||||
DONE:
|
|
||||||
state = BIT0;
|
|
||||||
data = 0;
|
|
||||||
parity = false;
|
|
||||||
RETURN:
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2014 Jun WAKO <wakojun@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#define IBM4704_ERR_NONE 0
|
|
||||||
#define IBM4704_ERR_PARITY 0x70
|
|
||||||
|
|
||||||
void ibm4704_init(void);
|
|
||||||
uint8_t ibm4704_send(uint8_t data);
|
|
||||||
uint8_t ibm4704_recv_response(void);
|
|
||||||
uint8_t ibm4704_recv(void);
|
|
||||||
|
|
||||||
/* Check pin configuration */
|
|
||||||
#if !(defined(IBM4704_CLOCK_PORT) && defined(IBM4704_CLOCK_PIN) && defined(IBM4704_CLOCK_DDR) && defined(IBM4704_CLOCK_BIT))
|
|
||||||
# error "ibm4704 clock pin configuration is required in config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !(defined(IBM4704_DATA_PORT) && defined(IBM4704_DATA_PIN) && defined(IBM4704_DATA_DDR) && defined(IBM4704_DATA_BIT))
|
|
||||||
# error "ibm4704 data pin configuration is required in config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------
|
|
||||||
* static functions
|
|
||||||
*------------------------------------------------------------------*/
|
|
||||||
static inline void clock_lo(void) {
|
|
||||||
IBM4704_CLOCK_PORT &= ~(1 << IBM4704_CLOCK_BIT);
|
|
||||||
IBM4704_CLOCK_DDR |= (1 << IBM4704_CLOCK_BIT);
|
|
||||||
}
|
|
||||||
static inline void clock_hi(void) {
|
|
||||||
/* input with pull up */
|
|
||||||
IBM4704_CLOCK_DDR &= ~(1 << IBM4704_CLOCK_BIT);
|
|
||||||
IBM4704_CLOCK_PORT |= (1 << IBM4704_CLOCK_BIT);
|
|
||||||
}
|
|
||||||
static inline bool clock_in(void) {
|
|
||||||
IBM4704_CLOCK_DDR &= ~(1 << IBM4704_CLOCK_BIT);
|
|
||||||
IBM4704_CLOCK_PORT |= (1 << IBM4704_CLOCK_BIT);
|
|
||||||
_delay_us(1);
|
|
||||||
return IBM4704_CLOCK_PIN & (1 << IBM4704_CLOCK_BIT);
|
|
||||||
}
|
|
||||||
static inline void data_lo(void) {
|
|
||||||
IBM4704_DATA_PORT &= ~(1 << IBM4704_DATA_BIT);
|
|
||||||
IBM4704_DATA_DDR |= (1 << IBM4704_DATA_BIT);
|
|
||||||
}
|
|
||||||
static inline void data_hi(void) {
|
|
||||||
/* input with pull up */
|
|
||||||
IBM4704_DATA_DDR &= ~(1 << IBM4704_DATA_BIT);
|
|
||||||
IBM4704_DATA_PORT |= (1 << IBM4704_DATA_BIT);
|
|
||||||
}
|
|
||||||
static inline bool data_in(void) {
|
|
||||||
IBM4704_DATA_DDR &= ~(1 << IBM4704_DATA_BIT);
|
|
||||||
IBM4704_DATA_PORT |= (1 << IBM4704_DATA_BIT);
|
|
||||||
_delay_us(1);
|
|
||||||
return IBM4704_DATA_PIN & (1 << IBM4704_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
|
|
||||||
* keyboard checks Data line on start bit(Data:hi) and it stops sending if Data line is low.
|
|
||||||
*/
|
|
||||||
static inline void inhibit(void) {
|
|
||||||
clock_hi();
|
|
||||||
data_lo();
|
|
||||||
}
|
|
|
@ -1,161 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include "news.h"
|
|
||||||
|
|
||||||
void news_init(void) { NEWS_KBD_RX_INIT(); }
|
|
||||||
|
|
||||||
// RX ring buffer
|
|
||||||
#define RBUF_SIZE 8
|
|
||||||
static uint8_t rbuf[RBUF_SIZE];
|
|
||||||
static uint8_t rbuf_head = 0;
|
|
||||||
static uint8_t rbuf_tail = 0;
|
|
||||||
|
|
||||||
uint8_t news_recv(void) {
|
|
||||||
uint8_t data = 0;
|
|
||||||
if (rbuf_head == rbuf_tail) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = rbuf[rbuf_tail];
|
|
||||||
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// USART RX complete interrupt
|
|
||||||
ISR(NEWS_KBD_RX_VECT) {
|
|
||||||
uint8_t next = (rbuf_head + 1) % RBUF_SIZE;
|
|
||||||
if (next != rbuf_tail) {
|
|
||||||
rbuf[rbuf_head] = NEWS_KBD_RX_DATA;
|
|
||||||
rbuf_head = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
SONY NEWS Keyboard Protocol
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Resources
|
|
||||||
---------
|
|
||||||
Mouse protocol of NWA-5461(Japanese)
|
|
||||||
http://groups.google.com/group/fj.sys.news/browse_thread/thread/a01b3e3ac6ae5b2d
|
|
||||||
|
|
||||||
SONY NEWS Info(Japanese)
|
|
||||||
http://katsu.watanabe.name/doc/sonynews/
|
|
||||||
|
|
||||||
|
|
||||||
Pinouts
|
|
||||||
-------
|
|
||||||
EIA 232 male connector from NWP-5461
|
|
||||||
-------------
|
|
||||||
\ 1 2 3 4 5 /
|
|
||||||
\ 6 7 8 9 /
|
|
||||||
---------
|
|
||||||
1 VCC
|
|
||||||
2 BZ(Speaker)
|
|
||||||
3 Keyboard Data(from keyboard MCU TxD)
|
|
||||||
4 NC
|
|
||||||
5 GND
|
|
||||||
6 Unknown Input(to keyboard MCU RxD via schmitt trigger)
|
|
||||||
7 Mouse Data(from Mouse Ext connector)
|
|
||||||
8 Unknown Input(to Keyboard MCU Input via diode and buffer)
|
|
||||||
9 FG
|
|
||||||
NOTE: Two LED on keyboard are controlled by pin 6,8?
|
|
||||||
|
|
||||||
EIA 232 male connector from NWP-411A
|
|
||||||
-------------
|
|
||||||
\ 1 2 3 4 5 /
|
|
||||||
\ 6 7 8 9 /
|
|
||||||
---------
|
|
||||||
1 VCC
|
|
||||||
2 BZ(Speaker)
|
|
||||||
3 Keyboard Data(from keyboard MCU TxD)
|
|
||||||
4 NC
|
|
||||||
5 GND
|
|
||||||
6 NC
|
|
||||||
7 Mouse Data(from Mouse Ext connector)
|
|
||||||
8 NC
|
|
||||||
9 FG
|
|
||||||
NOTE: These are just from my guess and not confirmed.
|
|
||||||
|
|
||||||
|
|
||||||
Signaling
|
|
||||||
---------
|
|
||||||
~~~~~~~~~~ ____XOO0X111X222X333X444X555X666X777~~~~ ~~~~~~~
|
|
||||||
Idle Start LSB MSB Stop Idle
|
|
||||||
|
|
||||||
Idle: High
|
|
||||||
Start bit: Low
|
|
||||||
Stop bit: High
|
|
||||||
Bit order: LSB first
|
|
||||||
|
|
||||||
Baud rate: 9600
|
|
||||||
Interface: TTL level(5V) UART
|
|
||||||
|
|
||||||
NOTE: This is observed on NWP-5461 with its DIP switch all OFF.
|
|
||||||
|
|
||||||
|
|
||||||
Format
|
|
||||||
------
|
|
||||||
MSB LSB
|
|
||||||
7 6 5 4 3 2 1 0 bit
|
|
||||||
| | | | | | | |
|
|
||||||
| +-+-+-+-+-+-+-- scan code(00-7F)
|
|
||||||
+---------------- break flag: sets when released
|
|
||||||
|
|
||||||
|
|
||||||
Scan Codes
|
|
||||||
----------
|
|
||||||
SONY NEWS NWP-5461
|
|
||||||
,---. ,------------------------, ,------------------------. ,---------.
|
|
||||||
| 7A| | 01 | 02 | 03 | 04 | 05 | | 06 | 07 | 08 | 09 | 0A | | 68 | 69 | ,-----------.
|
|
||||||
`---' `------------------------' `------------------------' `---------' | 64| 65| 52|
|
|
||||||
,-------------------------------------------------------------. ,---. ,---------------|
|
|
||||||
| 0B| 0C| 0D| 0E| 0F| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19 | | 6A| | 4B| 4C| 4D| 4E|
|
|
||||||
|-------------------------------------------------------------| |---| |---------------|
|
|
||||||
| 1A | 1B| 1C| 1D| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| | | 6B| | 4F| 50| 51| 56|
|
|
||||||
|---------------------------------------------------------' | |---| |---------------|
|
|
||||||
| 28 | 29| 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35 | | 6C| | 53| 54| 55| |
|
|
||||||
|-------------------------------------------------------------| |---| |-----------| 5A|
|
|
||||||
| 36 | 37| 38| 39| 3A| 3B| 3C| 3D| 3E| 3F| 40| 41| 42 | | 6D| | 57| 59| 58| |
|
|
||||||
|-------------------------------------------------------------| |---| |---------------|
|
|
||||||
| 43 | 44 | 45 | 46 | 47 | 48| 49| 4A | | 6E| | 66| 5B| 5C| 5D|
|
|
||||||
`-------------------------------------------------------------' `---' `---------------'
|
|
||||||
*/
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Primitive PS/2 Library for AVR
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* host role */
|
|
||||||
void news_init(void);
|
|
||||||
uint8_t news_recv(void);
|
|
||||||
|
|
||||||
/* device role */
|
|
|
@ -1,219 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
NeXT non-ADB Keyboard Protocol
|
|
||||||
|
|
||||||
Copyright 2013, Benjamin Gould (bgould@github.com)
|
|
||||||
|
|
||||||
Based on:
|
|
||||||
TMK firmware code Copyright 2011,2012 Jun WAKO <wakojun@gmail.com>
|
|
||||||
Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/), released under BSD license
|
|
||||||
|
|
||||||
Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB
|
|
||||||
Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html
|
|
||||||
Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <util/atomic.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include "next_kbd.h"
|
|
||||||
#include "debug.h"
|
|
||||||
|
|
||||||
static inline void out_lo(void);
|
|
||||||
static inline void out_hi(void);
|
|
||||||
static inline void query(void);
|
|
||||||
static inline void reset(void);
|
|
||||||
static inline uint32_t response(void);
|
|
||||||
|
|
||||||
/* The keyboard sends signal with 50us pulse width on OUT line
|
|
||||||
* while it seems to miss the 50us pulse on In line.
|
|
||||||
* next_kbd_set_leds() often fails to sync LED status with 50us
|
|
||||||
* but it works well with 51us(+1us) on TMK converter(ATMeaga32u2) at least.
|
|
||||||
* TODO: test on Teensy and Pro Micro configuration
|
|
||||||
*/
|
|
||||||
#define out_hi_delay(intervals) \
|
|
||||||
do { \
|
|
||||||
out_hi(); \
|
|
||||||
_delay_us((NEXT_KBD_TIMING + 1) * intervals); \
|
|
||||||
} while (0);
|
|
||||||
#define out_lo_delay(intervals) \
|
|
||||||
do { \
|
|
||||||
out_lo(); \
|
|
||||||
_delay_us((NEXT_KBD_TIMING + 1) * intervals); \
|
|
||||||
} while (0);
|
|
||||||
#define query_delay(intervals) \
|
|
||||||
do { \
|
|
||||||
query(); \
|
|
||||||
_delay_us((NEXT_KBD_TIMING + 1) * intervals); \
|
|
||||||
} while (0);
|
|
||||||
#define reset_delay(intervals) \
|
|
||||||
do { \
|
|
||||||
reset(); \
|
|
||||||
_delay_us((NEXT_KBD_TIMING + 1) * intervals); \
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
void next_kbd_init(void) {
|
|
||||||
out_hi();
|
|
||||||
NEXT_KBD_IN_DDR &= ~(1 << NEXT_KBD_IN_BIT); // KBD_IN to input
|
|
||||||
NEXT_KBD_IN_PORT |= (1 << NEXT_KBD_IN_BIT); // KBD_IN pull up
|
|
||||||
|
|
||||||
query_delay(5);
|
|
||||||
reset_delay(8);
|
|
||||||
|
|
||||||
query_delay(5);
|
|
||||||
reset_delay(8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void next_kbd_set_leds(bool left, bool right) {
|
|
||||||
cli();
|
|
||||||
out_lo_delay(9);
|
|
||||||
|
|
||||||
out_hi_delay(3);
|
|
||||||
out_lo_delay(1);
|
|
||||||
|
|
||||||
if (left) {
|
|
||||||
out_hi_delay(1);
|
|
||||||
} else {
|
|
||||||
out_lo_delay(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (right) {
|
|
||||||
out_hi_delay(1);
|
|
||||||
} else {
|
|
||||||
out_lo_delay(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
out_lo_delay(7);
|
|
||||||
out_hi();
|
|
||||||
sei();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NEXT_KBD_READ (NEXT_KBD_IN_PIN & (1 << NEXT_KBD_IN_BIT))
|
|
||||||
uint32_t next_kbd_recv(void) {
|
|
||||||
// First check to make sure that the keyboard is actually connected;
|
|
||||||
// if not, just return
|
|
||||||
// TODO: reflect the status of the keyboard in a return code
|
|
||||||
if (!NEXT_KBD_READ) {
|
|
||||||
sei();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
query();
|
|
||||||
uint32_t resp = response();
|
|
||||||
|
|
||||||
return resp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t response(void) {
|
|
||||||
cli();
|
|
||||||
|
|
||||||
// try a 5ms read; this should be called after the query method has
|
|
||||||
// been run so if a key is pressed we should get a response within
|
|
||||||
// 5ms; if not then send a reset and exit
|
|
||||||
uint8_t i = 0;
|
|
||||||
uint32_t data = 0;
|
|
||||||
uint16_t reset_timeout = 50000;
|
|
||||||
while (NEXT_KBD_READ && reset_timeout) {
|
|
||||||
asm("");
|
|
||||||
_delay_us(1);
|
|
||||||
reset_timeout--;
|
|
||||||
}
|
|
||||||
if (!reset_timeout) {
|
|
||||||
reset();
|
|
||||||
sei();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
_delay_us(NEXT_KBD_TIMING / 2);
|
|
||||||
for (; i < 22; i++) {
|
|
||||||
if (NEXT_KBD_READ) {
|
|
||||||
data |= ((uint32_t)1 << i);
|
|
||||||
/* Note:
|
|
||||||
* My testing with the ATmega32u4 showed that there might
|
|
||||||
* something wrong with the timing here; by the end of the
|
|
||||||
* second data byte some of the modifiers can get bumped out
|
|
||||||
* to the next bit over if we just cycle through the data
|
|
||||||
* based on the expected interval. There is a bit (i = 10)
|
|
||||||
* in the middle of the data that is always on followed by
|
|
||||||
* one that is always off - so we'll use that to reset our
|
|
||||||
* timing in case we've gotten ahead of the keyboard;
|
|
||||||
*/
|
|
||||||
if (i == 10) {
|
|
||||||
i++;
|
|
||||||
while (NEXT_KBD_READ)
|
|
||||||
;
|
|
||||||
_delay_us(NEXT_KBD_TIMING / 2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* redundant - but I don't want to remove if it might screw
|
|
||||||
* up the timing
|
|
||||||
*/
|
|
||||||
data |= ((uint32_t)0 << i);
|
|
||||||
}
|
|
||||||
_delay_us(NEXT_KBD_TIMING);
|
|
||||||
}
|
|
||||||
|
|
||||||
sei();
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void out_lo(void) {
|
|
||||||
NEXT_KBD_OUT_PORT &= ~(1 << NEXT_KBD_OUT_BIT);
|
|
||||||
NEXT_KBD_OUT_DDR |= (1 << NEXT_KBD_OUT_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void out_hi(void) {
|
|
||||||
/* input with pull up */
|
|
||||||
NEXT_KBD_OUT_DDR &= ~(1 << NEXT_KBD_OUT_BIT);
|
|
||||||
NEXT_KBD_OUT_PORT |= (1 << NEXT_KBD_OUT_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void query(void) {
|
|
||||||
out_lo_delay(5);
|
|
||||||
out_hi_delay(1);
|
|
||||||
out_lo_delay(3);
|
|
||||||
out_hi();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void reset(void) {
|
|
||||||
out_lo_delay(1);
|
|
||||||
out_hi_delay(4);
|
|
||||||
out_lo_delay(1);
|
|
||||||
out_hi_delay(6);
|
|
||||||
out_lo_delay(10);
|
|
||||||
out_hi();
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
NeXT non-ADB Keyboard Protocol
|
|
||||||
|
|
||||||
Copyright 2013, Benjamin Gould (bgould@github.com)
|
|
||||||
|
|
||||||
Based on:
|
|
||||||
TMK firmware code Copyright 2011,2012 Jun WAKO <wakojun@gmail.com>
|
|
||||||
Arduino code by "Ladyada" Limor Fried (http://ladyada.net/, http://adafruit.com/), released under BSD license
|
|
||||||
|
|
||||||
Timing reference thanks to http://m0115.web.fc2.com/ (dead link), http://cfile7.uf.tistory.com/image/14448E464F410BF22380BB
|
|
||||||
Pinouts thanks to http://www.68k.org/~degs/nextkeyboard.html
|
|
||||||
Keycodes from http://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/sys/arch/next68k/dev/
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define NEXT_KBD_KMBUS_IDLE 0x300600
|
|
||||||
#define NEXT_KBD_TIMING 50
|
|
||||||
|
|
||||||
extern uint8_t next_kbd_error;
|
|
||||||
|
|
||||||
/* host role */
|
|
||||||
void next_kbd_init(void);
|
|
||||||
void next_kbd_set_leds(bool left, bool right);
|
|
||||||
uint32_t next_kbd_recv(void);
|
|
Loading…
Reference in a new issue