Merge remote-tracking branch 'tmk/master'

This commit is contained in:
Mark Sikora 2023-11-08 09:14:23 -05:00
commit 98004b2b6b
31 changed files with 9900 additions and 6932 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -508,9 +508,29 @@ static uint8_t mouse_proc(uint8_t addr)
if (buf[1] & 0x40) xneg = true;
// Ignore Byte2 and 3
len = 2;
} else if (mouse_handler == ADB_HANDLER_MICROSPEED_MACTRAC ||
} else if (mouse_handler == ADB_HANDLER_MICROSPEED_MACTRAC && len == 2) {
// MacTRAC 2.0 old firmware
// https://github.com/tmk/tmk_keyboard/issues/725#issuecomment-1779462409
// Byte0: b00 y06 y05 y04 y03 y02 y01 y00
// Byte1: b01 x06 x05 x04 x03 x02 x01 x00
// left button: b00=0, b01=1
// right button: b00=0, b01=0
// center button: Drag Lock
if (buf[0] & 0x40) yneg = true;
if (buf[1] & 0x40) xneg = true;
len = 2;
uint16_t packet = (buf[0] << 8) | buf[1];
// right button
if ((packet & 0x8080) == 0x0000) {
buf[0] |= 0x80;
buf[1] &= ~0x80;
} else {
buf[1] |= 0x80;
}
} else if ((mouse_handler == ADB_HANDLER_MICROSPEED_MACTRAC ||
mouse_handler == ADB_HANDLER_MICROSPEED_UNKNOWN ||
mouse_handler == ADB_HANDLER_CONTOUR_MOUSE) {
mouse_handler == ADB_HANDLER_CONTOUR_MOUSE) && len >= 3) {
// Microspeed:
// Byte0: ??? y06 y05 y04 y03 y02 y01 y00
// Byte1: ??? x06 x05 x04 x03 x02 x01 x00

View file

@ -0,0 +1,89 @@
# Target file name (without extension).
TARGET ?= archimedes_usb
# Directory common source filess exist
TMK_DIR ?= ../../tmk_core
# Directory keyboard dependent files exist
TARGET_DIR ?= .
# project specific files
SRC ?= $(TARGET).c \
protocol/serial_soft.c
CONFIG_H ?= config.h
# MCU name
MCU ?= atmega32u2
# Processor frequency.
# Normally the first thing your program should do is set the clock prescaler,
# 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
#
# LUFA specific
#
# Target architecture (see library "Board Types" documentation).
ARCH ?= AVR8
# Input clock frequency.
# This will define a symbol, F_USB, in all source code files equal to the
# input clock frequency (before any prescaling is performed) in Hz. This value may
# differ from F_CPU if prescaling is used on the latter, and is required as the
# raw input clock is fed directly to the PLL sections of the AVR for high speed
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
# at the end, this will be done automatically to create a 32-bit value in your
# source code.
#
# If no clock division is performed on the input clock inside the AVR (via the
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
F_USB ?= $(F_CPU)
# Build Options
# *Comment out* to disable the options.
#
MOUSEKEY_ENABLE ?= yes # Mouse keys
EXTRAKEY_ENABLE ?= yes # Audio control and System control
CONSOLE_ENABLE ?= yes # Console for debug
COMMAND_ENABLE ?= yes # Commands for debug and configuration
#NKRO_ENABLE ?= yes # USB Nkey Rollover
UNIMAP_ENABLE = yes
KEYMAP_SECTION_ENABLE = yes
#NO_KEYBOARD = yes
#
# Keymap file
#
ifeq (yes,$(strip $(UNIMAP_ENABLE)))
KEYMAP_FILE = unimap
else
ifeq (yes,$(strip $(ACTIONMAP_ENABLE)))
KEYMAP_FILE = actionmap
else
KEYMAP_FILE = keymap
endif
endif
ifdef KEYMAP
SRC := $(KEYMAP_FILE)_$(KEYMAP).c $(SRC)
else
SRC := $(KEYMAP_FILE)_plain.c $(SRC)
endif
# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TMK_DIR)
include $(TMK_DIR)/protocol.mk
include $(TMK_DIR)/protocol/lufa.mk
include $(TMK_DIR)/common.mk
include $(TMK_DIR)/rules.mk

View file

@ -0,0 +1,34 @@
Acorn Archimedes Keyboard Converter
===================================
This covnerter makes Acorn Archimedes keyboard usable on modern USB computer.
Check these for technical information and resources.
- https://github.com/tmk/tmk_keyboard/wiki/ACORN-ARCHIMEDES-Keyboard
- https://geekhack.org/index.php?topic=121747.0
Preassembled converter is available [here](https://geekhack.org/index.php?topic=72052.0).
Pinouts and Wirings
-------------------
Mini-DIN-6P female socket from the front:
Connector AVR pin
------------------------------------
,--_--. 1: Reset PD0
/ o6 5o \ 2: NC
| o4 3o | 3: GND GND
- 2o o1 - 4: 5V VCC
`-___-' 5: In(from keyboard) PD1
6: Out(to keyboard) PD3
Target microcontroller is Atmel ATMega32U2 by default but porting this project to other 8-bit AVR controllers would be easy.
Mouse support
-------------
Not tested with real mouse but it should work somehow.
I don't have Archimedes mouse to test, try and make a report if you have one.

View file

@ -0,0 +1,327 @@
/*
Copyright 2023 Jun Wako <wakojun@gmail.com>
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.
*/
#include <stdint.h>
#include <avr/interrupt.h>
#include "protocol/serial.h"
#include "matrix.h"
#include "wait.h"
#include "timer.h"
#include "host.h"
#include "debug.h"
#include "print.h"
// Archimedes commands
#define HRST 0xFF
#define RAK1 0xFE
#define RAK2 0xFD
#define RQMP 0x22
#define PRST 0x21
#define RQID 0x20
#define LEDS(stat) (0x00 | (stat & 0x7))
#define RQPD(data) (0x40 | (data & 0xF))
// Archimedes Replies
#define BACK 0x3F
#define NACK 0x30
#define SACK 0x31
#define MACK 0x32
#define SMAK 0x33
#define KDDA 0xC0
#define KUDA 0xD0
// mouse data: 0b0xxx xxxx(0x00 - 0x7F)
// mouse delta: -64 - 63
#define MDAT_MIN 0x00
#define MDAT_MAX 0x7F
// Archimedes LED
#define ARC_LED_CAPS_LOCK 0
#define ARC_LED_NUM_LOCK 1
#define ARC_LED_SCROLL_LOCK 2
/* key matrix 8x16
* |R/C| 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| A| B| C| D| E| F|
* |---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
* | 0|ESC| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Prt|ScL|Brk|
* | 1| `~| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -_| =+| £| BS|Ins|
* | 2|Hom|PgU|NmL| P/| P*| P#|Tab| Q| W| E| R| T| Y| U| I| O|
* | 3| P| [{| ]}| \||Del|Cpy|PgD| P7| P8| P9| P-|LCt| A| S| D| F|
* | 4| G| H| J| K| L| ;:| '"|Rtn| P4| P5| P6| P+|LSh| | Z| X|
* | 5| C| V| B| N| M| ,<| .>| /?|RSh| Up| P1| P2| P3|Cap|LAl|Spc|
* | 6|Ral|RCt|Lef|Dow|Rig| P0| P.|PEn| | | | | | | | |
* | 7|SW1|SW2|SW3| | | | | | | | | | | | | |
*/
#define ROW(key) ((key & 0x70) >> 4)
#define COL(key) (key & 0x0F)
static matrix_row_t matrix[MATRIX_ROWS];
void matrix_clear(void)
{
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
}
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_init(void)
{
//debug_enable = true;
//debug_matrix = true;
//debug_keyboard = true;
//debug_mouse = true;
matrix_clear();
serial_init();
// wait for keyboard coming up
// otherwise LED status update fails
print("Archimedes starts.\n");
//xprintf("EIMSK: %02X\n", EIMSK);
//xprintf("EICRA: %02X\n", EICRA);
return;
}
// LED status
static uint8_t arc_led = 0;
static uint8_t arc_led_prev = 0;
static enum {
INIT,
SCAN,
WAIT_KEY_COL,
WAIT_MDAT_Y,
} state = INIT;
static int16_t check_reply(void)
{
int16_t d;
while ((d = serial_recv2()) != -1) {
xprintf("r%02X ", d & 0xFF);
if (d == HRST) state = INIT;
return d;
}
return -1;
}
static void send_cmd(uint8_t cmd)
{
xprintf("s%02X ", cmd);
uint8_t sreg = SREG;
cli();
serial_send(cmd);
SREG = sreg;
}
uint8_t matrix_scan(void)
{
static uint8_t key;
static uint8_t mouse_btn = 0;
static int8_t mouse_x = 0;
static int8_t mouse_y = 0;
switch (state) {
case INIT:
// ignore unprocessed replies
check_reply();
// reset sequence
send_cmd(HRST);
wait_ms(1);
if (HRST != check_reply()) {
wait_ms(1000);
break;
}
send_cmd(RAK1);
wait_ms(1);
if (RAK1 != check_reply()) {
wait_ms(1000);
break;
}
send_cmd(RAK2);
wait_ms(1);
if (RAK2 != check_reply()) {
wait_ms(1000);
break;
}
// ack to scan now
send_cmd(SMAK);
check_reply();
state = SCAN;
break;
case SCAN: {
int16_t d;
d = check_reply();
switch (d) {
case -1: // no input
// update LED
if (arc_led != arc_led_prev) {
wait_ms(1);
send_cmd(LEDS(arc_led));
arc_led_prev = arc_led;
}
break;
case KDDA ... KDDA+15:
case KUDA ... KUDA+15:
// key row
key = (d & 0x7) << 4;
wait_us(100);
// ack
send_cmd(BACK);
state = WAIT_KEY_COL;
break;
case MDAT_MIN ... MDAT_MAX:
// sign bit for int8_t
if (d & 0x40) d |= 0x80;
mouse_x = d;
// ack
send_cmd(BACK);
state = WAIT_MDAT_Y;
break;
default:
state = INIT;
break;
}
break;
}
case WAIT_KEY_COL: {
int16_t d;
d = check_reply();
switch (d) {
case -1:
// no reply
break;
case KDDA ... KDDA+15:
case KUDA ... KUDA+15:
// key col
key |= d & 0xF;
if ((d & KUDA) == KUDA) { key |= 0x80; } // key up flag
// ack
wait_us(100);
send_cmd(SMAK);
state = SCAN;
if (key & 0x80) {
// break
switch (key & 0x7F) {
case 0x70: // mouse SW1
case 0x71: // mouse SW2
case 0x72: // mouse SW3
mouse_btn &= ~(1 << (key & 3));
report_mouse_t mouse_report = {};
mouse_report.buttons = mouse_btn;
host_mouse_send(&mouse_report);
break;
default:
matrix[ROW(key)] &= ~(1 << COL(key));
break;
}
} else {
// make
switch (key & 0x7F) {
case 0x70: // mouse SW1
case 0x71: // mouse SW2
case 0x72: // mouse SW3
mouse_btn |= (1 << (key & 3));
report_mouse_t mouse_report = {};
mouse_report.buttons = mouse_btn;
host_mouse_send(&mouse_report);
break;
default:
matrix[ROW(key)] |= (1 << COL(key));
break;
}
}
xprintf("[k%02X] ", key);
break;
default:
// error
state = INIT;
break;
}
break;
}
case WAIT_MDAT_Y: {
int16_t d;
d = check_reply();
switch (d) {
case -1:
// no reply
break;
case MDAT_MIN ... MDAT_MAX:
// sign bit for int8_t
if (d & 0x40) d |= 0x80;
mouse_y = d;
xprintf("[m%02d,%02d] ", mouse_x, mouse_y);
report_mouse_t mouse_report = {};
mouse_report.buttons = mouse_btn;
// TODO: move direction is not confirmed
mouse_report.x = mouse_x;
mouse_report.y = mouse_y;
host_mouse_send(&mouse_report);
// ack
wait_us(100);
send_cmd(SMAK);
state = SCAN;
break;
default:
state = INIT;
break;
}
break;
}
}
// DEBUG
// toggle ScrollLock LED
/*
static uint16_t time_last;
if (timer_elapsed(time_last) > 1000) {
arc_led = arc_led ^ 1<<ARC_LED_SCROLL_LOCK;
time_last = timer_read();
}
*/
return 0;
}
#include "led.h"
void led_set(uint8_t usb_led)
{
arc_led = 0;
if (usb_led & (1<<USB_LED_NUM_LOCK)) arc_led |= (1<<ARC_LED_NUM_LOCK);
if (usb_led & (1<<USB_LED_CAPS_LOCK)) arc_led |= (1<<ARC_LED_CAPS_LOCK);
if (usb_led & (1<<USB_LED_SCROLL_LOCK)) arc_led |= (1<<ARC_LED_SCROLL_LOCK);
xprintf("[LED:%02X:%02X] ", usb_led, arc_led);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,110 @@
/*
Copyright 2023 Jun Wako <wakojun@gmail.com>
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 CONFIG_H
#define CONFIG_H
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0xACAC
#define DEVICE_VER 0x0100
#define MANUFACTURER TMK
#define PRODUCT Archimedes keyboard converter
#define DESCRIPTION converts Archimedes keyboard into USB
/* matrix size */
#define MATRIX_ROWS 8
#define MATRIX_COLS 16
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT)) || \
keyboard_report->mods == (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI)) || \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
/* Software Serial configuration
* RX: PD1, TX: PD3
* asynchronous, negative logic, 31250 baud
* start bit(0), 8-bit data(LSB first), stop bit(1)
*/
#define SERIAL_SOFT_BAUD 31250
#define SERIAL_SOFT_PARITY_NONE
#define SERIAL_SOFT_BIT_ORDER_LSB
#define SERIAL_SOFT_LOGIC_NEGATIVE
/* debug for signal timing, see debug pin with oscilloscope */
#define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<2)
#define SERIAL_SOFT_DEBUG_TGL() (PIND |= 1<<2)
/* RXD Port */
#define SERIAL_SOFT_RXD_ENABLE
#define SERIAL_SOFT_RXD_DDR DDRD
#define SERIAL_SOFT_RXD_PORT PORTD
#define SERIAL_SOFT_RXD_PIN PIND
#define SERIAL_SOFT_RXD_BIT 1
#define SERIAL_SOFT_RXD_VECT INT1_vect
// XXX: phantom interrupt(INT1) occrus on rising edge of PD3/TXD for some reason.
/* RXD Interupt */
#ifdef SERIAL_SOFT_LOGIC_NEGATIVE
/* enable interrupt: INT1(rising edge) */
#define INTR_TRIG_EDGE ((1<<ISC11)|(1<<ISC10))
#else
/* enable interrupt: INT1(falling edge) */
#define INTR_TRIG_EDGE ((1<<ISC11)|(0<<ISC10))
#endif
#define SERIAL_SOFT_RXD_INIT() do { \
/* pin configuration: input with pull-up */ \
SERIAL_SOFT_RXD_DDR &= ~(1<<SERIAL_SOFT_RXD_BIT); \
SERIAL_SOFT_RXD_PORT |= (1<<SERIAL_SOFT_RXD_BIT); \
EICRA |= INTR_TRIG_EDGE; \
EIMSK |= (1<<INT1); \
sei(); \
} while (0)
#define SERIAL_SOFT_RXD_INT_ENTER()
#define SERIAL_SOFT_RXD_INT_EXIT() do { \
/* clear interrupt flag */ \
EIFR = (1<<INTF1); \
} while (0)
#define SERIAL_SOFT_RXD_READ() (SERIAL_SOFT_RXD_PIN&(1<<SERIAL_SOFT_RXD_BIT))
/* TXD Port */
#define SERIAL_SOFT_TXD_ENABLE
#define SERIAL_SOFT_TXD_DDR DDRD
#define SERIAL_SOFT_TXD_PORT PORTD
#define SERIAL_SOFT_TXD_PIN PIND
#define SERIAL_SOFT_TXD_BIT 3
#define SERIAL_SOFT_TXD_HI() do { SERIAL_SOFT_TXD_PORT |= (1<<SERIAL_SOFT_TXD_BIT); } while (0)
#define SERIAL_SOFT_TXD_LO() do { SERIAL_SOFT_TXD_PORT &= ~(1<<SERIAL_SOFT_TXD_BIT); } while (0)
#define SERIAL_SOFT_TXD_INIT() do { \
/* pin configuration: output */ \
SERIAL_SOFT_TXD_DDR |= (1<<SERIAL_SOFT_TXD_BIT); \
/* idle */ \
SERIAL_SOFT_TXD_ON(); \
} while (0)
#endif //config.h

View file

@ -0,0 +1,32 @@
/*
Copyright 2023 Jun Wako <wakojun@gmail.com>
*/
#include "unimap_trans.h"
#define AC_L1 ACTION_LAYER_MOMENTARY(1)
#ifdef KEYMAP_SECTION_ENABLE
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
#else
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
#endif
UNIMAP(
F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, VOLD,VOLU,MUTE,
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, JYEN,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS,
CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, NUHS,ENT, P4, P5, P6, PCMM,
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RO, RSFT, UP, P1, P2, P3, PENT,
LCTL,LGUI,LALT,MHEN, SPC, HENK,KANA,RALT,RGUI,APP, L1, LEFT,DOWN,RGHT, P0, PDOT,PEQL
),
UNIMAP(
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
GRV, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, INS, TRNS, TRNS,TRNS,TRNS, TRNS,MS_U,TRNS,TRNS,
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, MS_L,TRNS,MS_R,TRNS,
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN, TRNS,TRNS, PGUP, TRNS,MS_D,TRNS,BTN3,
TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, HOME,PGDN,END, BTN1,BTN2,TRNS
),
};

View file

@ -0,0 +1,74 @@
/*
Copyright 2019 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UNIMAP_TRANS_H
#define UNIMAP_TRANS_H
#include <avr/pgmspace.h>
#include "unimap.h"
/* Acorn Archimedes A300
* ,---. ,-----------------------------------------------. ,-----------. ,-----------.
* |Esc| |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12| |Prt|ScL|Brk| |SW1|SW2|SW3|
* `---' `-----------------------------------------------' `-----------' `-----------'
* ,-----------------------------------------------------------. ,-----------. ,---------------.
* | `| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| £|Bsp| |Ins|Hom|PgU| |NmL| /| *| #|
* |-----------------------------------------------------------| |-----------| |---------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ | |Del|Cpy|PgD| | 7| 8| 9| -|
* |-----------------------------------------------------------| `-----------' |---------------|
* |CapsL | A| S| D| F| G| H| J| K| L| ;| '| Enter | | 4| 5| 6| +|
* |-----------------------------------------------------------| ,---. |---------------|
* |Shift | Z| X| C| V| B| N| M| ,| .| /| Shift | |Up | | 1| 2| 3| |
* |-----------------------------------------------------------| ,-----------. |-----------|Ent|
* | Ctrl| | Alt | Space | Alt | | Ctrl| |Lef|Dow|Rig| | 0| .| |
* `-----' `---------------------------------------' `-----' `-----------' `---------------'
*
* ,---. ,-----------------------------------------------. ,-----------. ,-----------.
* | 00| | 01| 02| 03| 04| 05| 06| 07| 08| 09| 0A| 0B| 0C| | 0D| 0E| 0F| | 70| 72| 73|
* `---' `-----------------------------------------------' `-----------' `-----------'
* ,-----------------------------------------------------------. ,-----------. ,---------------.
* | 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 1A| 1B| 1C| 1D| 1E| | 1F| 20| 21| | 22| 23| 24| 25|
* |-----------------------------------------------------------| |-----------| |---------------|
* | 26 | 27| 28| 29| 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33 | | 34| 35| 36| | 37| 38| 39| 3A|
* |-----------------------------------------------------------| `-----------' |---------------|
* | 3B | 3C| 3D| 3E| 3F| 40| 41| 42| 43| 44| 45| 46| 47 | | 48| 49| 4A| 4B|
* |-----------------------------------------------------------| ,---. |---------------|
* | 4C | 4E| 4F| 50| 51| 52| 53| 54| 55| 56| 57| 58 | | 59| | 5A| 5B| 5C| |
* |-----------------------------------------------------------| ,-----------. |-----------| 67|
* | 5D | | 5E | 5F | 60 | | 61 | | 62| 63| 64| | 65| 66| |
* `-----' `---------------------------------------' `-----' `-----------' `---------------'
*/
const uint8_t PROGMEM unimap_trans[MATRIX_ROWS][MATRIX_COLS] = {
{ UNIMAP_ESC, UNIMAP_F1, UNIMAP_F2, UNIMAP_F3, UNIMAP_F4, UNIMAP_F5, UNIMAP_F6, UNIMAP_F7, /* 00-07 */
UNIMAP_F8, UNIMAP_F9, UNIMAP_F10, UNIMAP_F11, UNIMAP_F12, UNIMAP_PSCR, UNIMAP_SLCK, UNIMAP_PAUS }, /* 08-0F */
{ UNIMAP_GRV, UNIMAP_1, UNIMAP_2, UNIMAP_3, UNIMAP_4, UNIMAP_5, UNIMAP_6, UNIMAP_7, /* 10-17 */
UNIMAP_8, UNIMAP_9, UNIMAP_0, UNIMAP_MINS, UNIMAP_EQL, UNIMAP_JPY, UNIMAP_BSPC, UNIMAP_INS }, /* 18-1F */
{ UNIMAP_HOME, UNIMAP_PGUP, UNIMAP_NLCK, UNIMAP_PSLS, UNIMAP_PAST, UNIMAP_PEQL, UNIMAP_TAB, UNIMAP_Q, /* 20-27 */
UNIMAP_W, UNIMAP_E, UNIMAP_R, UNIMAP_T, UNIMAP_Y, UNIMAP_U, UNIMAP_I, UNIMAP_O }, /* 28-2F */
{ UNIMAP_P, UNIMAP_LBRC, UNIMAP_RBRC, UNIMAP_BSLS, UNIMAP_DEL, UNIMAP_END, UNIMAP_PGDN, UNIMAP_P7, /* 30-37 */
UNIMAP_P8, UNIMAP_P9, UNIMAP_PMNS, UNIMAP_LCTL, UNIMAP_A, UNIMAP_S, UNIMAP_D, UNIMAP_F }, /* 38-3F */
{ UNIMAP_G, UNIMAP_H, UNIMAP_J, UNIMAP_K, UNIMAP_L, UNIMAP_SCLN, UNIMAP_QUOT, UNIMAP_ENT, /* 40-47 */
UNIMAP_P4, UNIMAP_P5, UNIMAP_P6, UNIMAP_PPLS, UNIMAP_LSFT, UNIMAP_NUBS, UNIMAP_Z, UNIMAP_X }, /* 48-4F */
{ UNIMAP_C, UNIMAP_V, UNIMAP_B, UNIMAP_N, UNIMAP_M, UNIMAP_COMM, UNIMAP_DOT, UNIMAP_SLSH, /* 50-57 */
UNIMAP_RSFT, UNIMAP_UP, UNIMAP_P1, UNIMAP_P2, UNIMAP_P3, UNIMAP_CAPS, UNIMAP_LALT, UNIMAP_SPC }, /* 58-5F */
{ UNIMAP_RALT, UNIMAP_RCTL, UNIMAP_LEFT, UNIMAP_DOWN, UNIMAP_RIGHT,UNIMAP_P0, UNIMAP_PDOT, UNIMAP_PENT, /* 60-67 */
UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO }, /* 68-6F */
{ UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, /* 70-77 */
UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO }, /* 78-7F */
};
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -950,6 +950,14 @@ uint8_t IBMPCConverter::cs2_e0code(uint8_t code) {
// https://github.com/tmk/tmk_keyboard/pull/760
case 0x00: return 0x65; // TERM FUNC Siemens F500 -> VOLD
// Silitek SK-7100P
case 0x43: return 0x40; // Close Silitek SK-7100P -> F20
case 0x42: return 0x48; // CD Silitek SK-7100P -> F21
case 0x44: return 0x50; // Video Silitek SK-7100P -> F22
case 0x1C: return 0x30; // U/P Silitek SK-7100P -> F18
case 0x24: return 0x28; // Pause Silitek SK-7100P -> F17
case 0x4B: return 0x57; // Display Silitek SK-7100P -> F23
default: return (code & 0x7F); // unknown
}
}

View file

@ -35,11 +35,11 @@ const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
),
UNIMAP(
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
GRV, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, INS, TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, TRNS,TRNS,TRNS,TRNS,
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN, TRNS,TRNS, PGUP, TRNS,TRNS,TRNS,TRNS,
GRV, F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24, EJCT,MSEL,BTLD, TRNS,TRNS,TRNS,
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, MPRV,MPLY,MNXT, WSCH,WHOM,WBAK,TRNS,
CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, INS, TRNS, MRWD,MSTP,MFFD, WFWD,WSTP,WREF,TRNS,
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, WFAV,MAIL,CALC,TRNS,
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN, TRNS,TRNS, PGUP, MYCM,BRTI,BRTD,TRNS,
TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, HOME,PGDN,END, TRNS,TRNS,TRNS
),
};

View file

@ -8,10 +8,9 @@ TMK_DIR = ../../tmk_core
TARGET_DIR = .
# keyboard dependent files
SRC = keymap.c \
matrix.c \
led.c \
news.c
SRC = matrix.c \
tone.c \
protocol/serial_uart.c
CONFIG_H = config.h
@ -71,13 +70,35 @@ OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# *Comment out* to disable the options.
#
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
CONSOLE_ENABLE = yes # Console for debug
COMMAND_ENABLE = yes # Commands for debug and configuration
#NKRO_ENABLE = yes # USB Nkey Rollover(+500)
KEYMAP_SECTION_ENABLE ?= yes
UNIMAP_ENABLE ?= yes
#
# Keymap file
#
ifdef UNIMAP_ENABLE
KEYMAP_FILE = unimap
else
ifdef ACTIONMAP_ENABLE
KEYMAP_FILE = actionmap
else
KEYMAP_FILE = keymap
endif
endif
ifdef KEYMAP
SRC := $(KEYMAP_FILE)_$(KEYMAP).c $(SRC)
else
SRC := $(KEYMAP_FILE)_plain.c $(SRC)
endif
# Search Path
VPATH += $(TARGET_DIR)

View file

@ -1,75 +0,0 @@
#
# Makefile for PJRC Teensy
#
# Target file name (without extension).
TARGET = news_usb_pjrc
# Directory common source filess exist
TMK_DIR = ../../tmk_core
# Directory keyboard dependent files exist
TARGET_DIR = .
# keyboard dependent files
SRC = keymap.c \
matrix.c \
led.c \
news.c
CONFIG_H = config_pjrc.h
# MCU name, you MUST set this to match the board you are using
# type "make clean" after changing this, so all files will be rebuilt
#MCU = at90usb162 # Teensy 1.0
#MCU = atmega32u4 # Teensy 2.0
#MCU = at90usb646 # Teensy++ 1.0
#MCU = at90usb1286 # Teensy++ 2.0
MCU = atmega32u2 # TMK Converter Rev.2
# Processor frequency.
# Normally the first thing your program should do is set the clock prescaler,
# 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
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Build Options
# *Comment out* to disable the options.
#
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+5000)
EXTRAKEY_ENABLE = yes # Audio control and System control(+600)
CONSOLE_ENABLE = yes # Console for debug
COMMAND_ENABLE = yes # Commands for debug and configuration
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
NKRO_ENABLE = yes # USB Nkey Rollover(+500)
#---------------- Programming Options --------------------------
PROGRAM_CMD = teensy_loader_cli -mmcu=$(MCU) -w -v $(TARGET).hex
# Search Path
VPATH += $(TARGET_DIR)
VPATH += $(TMK_DIR)
include $(TMK_DIR)/protocol/pjrc.mk
include $(TMK_DIR)/protocol.mk
include $(TMK_DIR)/common.mk
include $(TMK_DIR)/rules.mk

View file

@ -2,23 +2,32 @@ Sony NEWS keyboard converter
============================
Sony NEWS is a BSD workstation with 68K/MIPS released in 1987 in Japan.
- http://en.wikipedia.org/wiki/Sony_NEWS
- https://www.sony.net/SonyInfo/CorporateInfo/History/SonyHistory/2-12.html#block3
This converter allows NEWS keyboard to be connected to modern PC via USB. It works with NWP-5461 and NWP-411A.
How DIP switches work is unknown and you may need to turn all switches off with this converter.
Limitations:
- Speaker/Buzzer is not supported.
- LEDs on NWP-5461 is not supported.
Pics:
- http://imgur.com/a/JyMzw
- Mouse is not supported.
Discussion:
- https://geekhack.org/index.php?topic=25759
Resources:
- https://github.com/tmk/tmk_keyboard/wiki/Sony-NEWS
Wiring
------
Use PD2(USART RXD) for 'Keyboard Data' pin and give power with VCC and GND. Other pins are optional and not supported at this point.
AVR NEWS
------------------------
PD2 Keyboard Data
PD3 Keyboard Command
PD4 Mouse Data
PD0 BZ
Target microcontroller is Atmel ATMega32U2 by default but porting this project to other 8-bit AVR controllers would be easy.
Protocol
@ -42,6 +51,7 @@ For example 0x29 is sent when 'a' key is pressed and 0xA9 when released.
+---------------- break flag: sets when released
Scan Codes
----------
### NWP-5461
@ -118,3 +128,17 @@ I have three NWP-5461s and GND and FG is connected in one of them for some reaso
8 NC
9 FG
NOTE: These are just from my guess and not confirmed.
Buzzer
------
You can control buzzer using `tone()` and `noTone()`. BZ pin should be connected to PD0.
- `void tone(unsigned int frequency, unsigned long duration)`
- `void noTone(void)`
`tone()` sounds buzzer in frequency(in hertz) for duration(in milliseconds).
When giving -1 as duration to `tone()` buzzer makes a sound forever until `noTone()` is called.
Buzzer is not used by default firmware.

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/*
Copyright 2016 Jun Wako <wakojun@gmail.com>
Copyright 2016,2023 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,8 +21,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x5021
#define DEVICE_VER 0x0001
#define MANUFACTURER t.m.k.
#define DEVICE_VER 0x0101
#define MANUFACTURER TMK
#define PRODUCT SONY NEWS keyboard converter
#define DESCRIPTION converts SONY NEWS protocol into USB
@ -47,14 +47,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* 8-data bit, non parity, 1-stop bit, no flow control
*/
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__)
# define NEWS_KBD_RX_VECT USART1_RX_vect
# define NEWS_KBD_RX_DATA UDR1
# define NEWS_KBD_RX_BAUD 9600
# define NEWS_KBD_RX_UBBR ((F_CPU/(16UL*NEWS_KBD_RX_BAUD))-1)
# define NEWS_KBD_RX_INIT() do { \
UBRR1L = (uint8_t) NEWS_KBD_RX_UBBR; \
UBRR1H = (uint8_t) (NEWS_KBD_RX_UBBR>>8); \
UCSR1B |= (1<<RXCIE1) | (1<<RXEN1); \
# define SERIAL_UART_BAUD 9600
# define SERIAL_UART_DATA UDR1
# define SERIAL_UART_UBBR ((F_CPU/(16UL*SERIAL_UART_BAUD))-1)
# define SERIAL_UART_RXD_VECT USART1_RX_vect
# define SERIAL_UART_TXD_READY (UCSR1A&(1<<UDRE1))
# define SERIAL_UART_INIT() do { \
UBRR1L = (uint8_t) SERIAL_UART_UBBR; \
UBRR1H = (uint8_t) (SERIAL_UART_UBBR>>8); \
UCSR1B |= (1<<RXCIE1) | (1<<RXEN1) | (1<<TXEN1); \
sei(); \
} while(0)
#else
# error "USART configuration is needed."

View file

@ -1,62 +0,0 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONFIG_H
#define CONFIG_H
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x5021
#define MANUFACTURER t.m.k.
#define PRODUCT SONY NEWS keyboard converter
#define DESCRIPTION converts SONY NEWS protocol into USB
/* matrix size */
#define MATRIX_ROWS 16 // keycode bit: 3-0
#define MATRIX_COLS 8 // keycode bit: 6-4
/* legacy keymap support */
#define USE_LEGACY_KEYMAP
/* key combination for command */
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) || \
keyboard_report->mods == (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RSHIFT)) \
)
/* Asynchronous USART
* 8-data bit, non parity, 1-stop bit, no flow control
*/
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega32U2__)
# define NEWS_KBD_RX_VECT USART1_RX_vect
# define NEWS_KBD_RX_DATA UDR1
# define NEWS_KBD_RX_BAUD 9600
# define NEWS_KBD_RX_UBBR ((F_CPU/(16UL*NEWS_KBD_RX_BAUD))-1)
# define NEWS_KBD_RX_INIT() do { \
UBRR1L = (uint8_t) NEWS_KBD_RX_UBBR; \
UBRR1H = (uint8_t) (NEWS_KBD_RX_UBBR>>8); \
UCSR1B |= (1<<RXCIE1) | (1<<RXEN1); \
} while(0)
#else
# error "USART configuration is needed."
#endif
#endif

View file

@ -1,26 +0,0 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stdint.h"
#include "news.h"
#include "led.h"
void led_set(uint8_t usb_led)
{
// not supported now
}

View file

@ -1,5 +1,5 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
Copyright 2012,2023 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,9 +21,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <util/delay.h>
#include "print.h"
#include "util.h"
#include "news.h"
#include "serial.h"
#include "matrix.h"
#include "debug.h"
#include "led.h"
#include "hook.h"
#include "wait.h"
/*
@ -47,10 +50,12 @@ static uint8_t matrix[MATRIX_ROWS];
#define ROW(code) ((code>>3)&0xF)
#define COL(code) (code&0x07)
static uint8_t news_led = 0;
void matrix_init(void)
{
news_init();
serial_init();
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
@ -58,15 +63,67 @@ void matrix_init(void)
return;
}
static uint16_t send_cmd(uint8_t cmd)
{
int16_t ret = 0;
xprintf("s%02X ", cmd);
serial_send(cmd);
wait_ms(10);
int16_t c;
while ((c = serial_recv2()) != -1) {
if ((c != 0x7B) && (c != 0xFB)) {
ret <<= 8;
ret |= c & 0xFF;
}
xprintf("r%02X ", c);
if (c == 0xFB) {
xprintf("\n");
return ret;
}
}
return -1;
}
void hook_late_init(void)
{
/* Commands for starup
* 82 is needed to enable LED command at least
*
* 80 Reset? turns LEDs off
* FB
* 81 replies whether LED command is enabled
* 7B [00|01] FB
* 82 enable LED command
* 83 replies DIP switches status
* 7B 00 0X FB
*/
send_cmd(0x80);
send_cmd(0x82);
send_cmd(0x81);
send_cmd(0x83);
}
void tone(unsigned int frequency, unsigned long duration);
void noTone(void);
uint8_t matrix_scan(void)
{
uint8_t code;
code = news_recv();
if (code == 0) {
static uint8_t sent_led = 0;
int16_t code;
code = serial_recv2();
if (code == -1) {
// update LED
if (news_led != sent_led) {
send_cmd(0xB0);
send_cmd(news_led);
sent_led = news_led;
}
return 0;
}
phex(code); print(" ");
xprintf("%02X ", code);
if (code&0x80) {
// break code
if (matrix_is_on(ROW(code), COL(code))) {
@ -76,6 +133,7 @@ uint8_t matrix_scan(void)
// make code
if (!matrix_is_on(ROW(code), COL(code))) {
matrix[ROW(code)] |= (1<<COL(code));
//tone(80, 100);
}
}
return code;
@ -86,3 +144,12 @@ uint8_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void led_set(uint8_t usb_led)
{
news_led = 0;
if (usb_led & (1<<USB_LED_CAPS_LOCK))
news_led |= 4;
if (usb_led & (1<<USB_LED_NUM_LOCK))
news_led |= 8;
}

124
converter/news_usb/tone.c Normal file
View file

@ -0,0 +1,124 @@
/*
2023 Based on:
https://github.com/arduino/ArduinoCore-avr/blob/a7edf4d66f66d42ebb7e166762ac7c11cb299a3f/cores/arduino/Tone.cpp
A Tone Generator Library
Written by Brett Hagman
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <avr/interrupt.h>
// Pin for buzzer: PD0
#define BZ_PIN_PORT PORTD
#define BZ_PIN_DDR DDRD
#define BZ_PIN_MASK (1<<0)
volatile long toggle_count;
static void toneBegin(void)
{
// Timer 1
//TCCR1A = 0;
//TCCR1B = 0;
// CTC mode
//TCCR1B |= WGM12;
TCCR1B |= _BV(WGM12);
// No prescaling
//TCCR1B |= CS10;
TCCR1B |= _BV(CS10);
BZ_PIN_DDR |= BZ_PIN_MASK;
BZ_PIN_PORT |= BZ_PIN_MASK;
}
// frequency (in hertz) and duration (in milliseconds).
void tone(unsigned int frequency, unsigned long duration)
{
uint8_t prescalarbits = 0b001;
uint32_t ocr = 0;
toneBegin();
// Set the pinMode as OUTPUT
BZ_PIN_DDR |= BZ_PIN_MASK;
// two choices for the 16 bit timers: ck/1 or ck/64
ocr = F_CPU / frequency / 2 - 1;
prescalarbits = 0b001; // CLKio/1
if (ocr > 0xffff) {
ocr = F_CPU / frequency / 2 / 64 - 1;
prescalarbits = 0b011; // CLKio/64
}
TCCR1B = (TCCR1B & 0b11111000) | prescalarbits;
// Calculate the toggle count
if (duration > 0) {
toggle_count = 2 * frequency * duration / 1000;
} else {
toggle_count = -1;
}
uint8_t sreg = SREG;
cli();
OCR1AH = (ocr >> 8) & 0xff;
OCR1AL = ocr & 0xff;
SREG = sreg;
// enable interrupt
TIMSK1 |= (1<<OCIE1A);
}
// XXX: this function only works properly for timer 2 (the only one we use
// currently). for the others, it should end the tone, but won't restore
// proper PWM functionality for the timer.
void disableTimer(void)
{
// disable interrupt
TIMSK1 &= ~(1<<OCIE1A);
TCCR1A = 0;
TCCR1B = 0;
uint8_t sreg = SREG;
cli();
OCR1AH = 0;
OCR1AL = 0;
SREG = sreg;
}
void noTone(void)
{
disableTimer();
BZ_PIN_PORT &= ~(BZ_PIN_MASK);
}
ISR(TIMER1_COMPA_vect)
{
if (toggle_count != 0) {
// toggle the pin
BZ_PIN_PORT ^= BZ_PIN_MASK;
if (toggle_count > 0)
toggle_count--;
} else {
disableTimer();
BZ_PIN_PORT &= ~(BZ_PIN_MASK);
}
}

View file

@ -0,0 +1,33 @@
/*
Copyright 2023 Jun Wako <wakojun@gmail.com>
*/
#include "unimap.h"
#include "unimap_trans.h"
#define AC_L1 ACTION_LAYER_MOMENTARY(1)
#ifdef KEYMAP_SECTION_ENABLE
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] __attribute__ ((section (".keymap.keymaps"))) = {
#else
const action_t actionmaps[][UNIMAP_ROWS][UNIMAP_COLS] PROGMEM = {
#endif
UNIMAP(
F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24,
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, PSCR,SLCK,PAUS, VOLD,VOLU,PWR,
GRV, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,BSPC, INS, HOME,PGUP, NLCK,PSLS,PAST,PMNS,
TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC, BSLS, DEL, END, PGDN, P7, P8, P9, PPLS,
CAPS,A, S, D, F, G, H, J, K, L, SCLN,QUOT, GRV, ENT, P4, P5, P6, COMM,
LSFT,NUBS,Z, X, C, V, B, N, M, COMM,DOT, SLSH, RSFT,RSFT, UP, P1, P2, P3, L1,
LCTL,LGUI,LALT,MHEN, SPC, HENK,NLCK,RALT,RGUI,APP, L1, LEFT,DOWN,RGHT, P0, PDOT,PEQL
),
UNIMAP(
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,
GRV, F11, F12, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,F11, F12, TRNS,TRNS, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,
ESC, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, TRNS,TRNS,TRNS, TRNS,TRNS,TRNS,PSLS,
CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS,UP, TRNS, TRNS, INS, TRNS,TRNS, TRNS,TRNS,TRNS,PAST,
TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,TRNS,TRNS,HOME,PGUP,LEFT,RGHT, TRNS,TRNS, TRNS,TRNS,TRNS,PEQL,
TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,END, PGDN,DOWN, TRNS,TRNS, PGUP, TRNS,TRNS,TRNS,TRNS,
TRNS,TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS,TRNS,TRNS, HOME,PGDN,END, TRNS,TRNS,TRNS
),
};

View file

@ -0,0 +1,89 @@
/*
Copyright 2023 Jun Wako <wakojun@gmail.com>
*/
#ifndef UNIMAP_TRANS_H
#define UNIMAP_TRANS_H
#include <avr/pgmspace.h>
#include "unimap.h"
/* NWP-5461
* ,---. ,------------------------, ,------------------------. ,---------.
* |Pow| | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10| | F11| F12| ,-----------.
* `---' `------------------------' `------------------------' `---------' | *| /| +|
* ,-------------------------------------------------------------. ,---. ,---------------|
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| BS | |Hlp| | 7| 8| 9| -|
* |-------------------------------------------------------------| |---| |---------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Del| | |Ins| | 4| 5| 6| ,|
* |---------------------------------------------------------' | |---| |---------------|
* |Ctrl | A| S| D| F| G| H| J| K| L| ;| '| `|Enter | |Clr| | 1| 2| 3| |
* |-------------------------------------------------------------| |---| |-----------|Ent|
* |Shift | Z| X| C| V| B| N| M| ,| ,| /| | Shift | |PgU| | 0| .| | |
* |-------------------------------------------------------------| |---| |---------------|
* |Alt |Cap| | Space | | | | | |PgD| |Tab| | | |
* `-------------------------------------------------------------' `---' `---------------'
* ,---. ,------------------------, ,------------------------. ,---------.
* | 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|
* `-------------------------------------------------------------' `---' `---------------'
*
* NWP-411A
* ,------------------------, ,------------------------.
* | F1 | F2 | F3 | F4 | F5 | | F6 | F7 | F8 | F9 | F10|
* `------------------------' `------------------------'
* ,-------------------------------------------------------------. ,---------------.
* |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \| BS | | 7| 8| 9| -|
* |-------------------------------------------------------------| |---------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|Del| | | 4| 5| 6| +|
* |---------------------------------------------------------' | |---------------|
* |Ctrl | A| S| D| F| G| H| J| K| L| ;| '| `|Enter | | 1| 2| 3| ,|
* |-------------------------------------------------------------| |---------------|
* |Shift | Z| X| C| V| B| N| M| ,| ,| /| | Shift | | 0| | .| |
* |-------------------------------------------------------------| |-----------|Ent|
* |Alt |Cap| | Space | | | | | | | | | |
* `-------------------------------------------------------------' `---------------'
* ,------------------------, ,------------------------.
* | 01 | 02 | 03 | 04 | 05 | | 06 | 07 | 08 | 09 | 0A |
* `------------------------' `------------------------'
* ,-------------------------------------------------------------. ,---------------.
* | 0B| 0C| 0D| 0E| 0F| 10| 11| 12| 13| 14| 15| 16| 17| 18| 19 | | 4B| 4C| 4D| 4E|
* |-------------------------------------------------------------| |---------------|
* | 1A | 1B| 1C| 1D| 1E| 1F| 20| 21| 22| 23| 24| 25| 26| 27| | | 4F| 50| 51| 52|
* |---------------------------------------------------------' | |---------------|
* | 28 | 29| 2A| 2B| 2C| 2D| 2E| 2F| 30| 31| 32| 33| 34| 35 | | 53| 54| 55| 56|
* |-------------------------------------------------------------| |---------------|
* | 36 | 37| 38| 39| 3A| 3B| 3C| 3D| 3E| 3F| 40| 41| 42 | | 57| 58| 59| |
* |-------------------------------------------------------------| |-----------| 5A|
* | 43 |44 | 45 | 46 | 47 | 48| 49| 4A | | 5B| 5C| 5D| |
* `-------------------------------------------------------------' `---------------'
*/
const uint8_t PROGMEM unimap_trans[MATRIX_ROWS][MATRIX_COLS] = {
{ UNIMAP_NO, UNIMAP_F1, UNIMAP_F2, UNIMAP_F3, UNIMAP_F4, UNIMAP_F5, UNIMAP_F6, UNIMAP_F7, }, /* 00-07 */
{ UNIMAP_F8, UNIMAP_F9, UNIMAP_F10, UNIMAP_ESC, UNIMAP_1, UNIMAP_2, UNIMAP_3, UNIMAP_4, }, /* 08-0F */
{ UNIMAP_5, UNIMAP_6, UNIMAP_7, UNIMAP_8, UNIMAP_9, UNIMAP_0, UNIMAP_MINS, UNIMAP_EQL, }, /* 10-17 */
{ UNIMAP_JPY, UNIMAP_BSPC, UNIMAP_TAB, UNIMAP_Q, UNIMAP_W, UNIMAP_E, UNIMAP_R, UNIMAP_T, }, /* 18-1F */
{ UNIMAP_Y, UNIMAP_U, UNIMAP_I, UNIMAP_O, UNIMAP_P, UNIMAP_LBRC, UNIMAP_RBRC, UNIMAP_DEL, }, /* 20-27 */
{ UNIMAP_LCTL, UNIMAP_A, UNIMAP_S, UNIMAP_D, UNIMAP_F, UNIMAP_G, UNIMAP_H, UNIMAP_J, }, /* 28-2F */
{ UNIMAP_K, UNIMAP_L, UNIMAP_SCLN, UNIMAP_QUOT, UNIMAP_NUHS, UNIMAP_ENT, UNIMAP_LSFT, UNIMAP_Z, }, /* 30-37 */
{ UNIMAP_X, UNIMAP_C, UNIMAP_V, UNIMAP_B, UNIMAP_N, UNIMAP_M, UNIMAP_COMM, UNIMAP_DOT, }, /* 38-3F */
{ UNIMAP_SLSH, UNIMAP_RO, UNIMAP_RSFT, UNIMAP_LALT, UNIMAP_CAPS, UNIMAP_MHEN, UNIMAP_SPC, UNIMAP_HENK,}, /* 40-47 */
{ UNIMAP_APP, UNIMAP_KANA, UNIMAP_RCTL, UNIMAP_P7, UNIMAP_P8, UNIMAP_P9, UNIMAP_PMNS, UNIMAP_P4, }, /* 48-4F */
{ UNIMAP_P5, UNIMAP_P6, UNIMAP_PPLS, UNIMAP_P1, UNIMAP_P2, UNIMAP_P3, UNIMAP_PCMM, UNIMAP_P0, }, /* 50-57 */
{ UNIMAP_UP, UNIMAP_PDOT, UNIMAP_PENT, UNIMAP_LEFT, UNIMAP_DOWN, UNIMAP_RGHT, UNIMAP_NO, UNIMAP_NO, }, /* 58-5F */
{ UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_PAST, UNIMAP_PSLS, UNIMAP_PEQL, UNIMAP_NO, }, /* 60-67 */
{ UNIMAP_F11, UNIMAP_F12, UNIMAP_HOME, UNIMAP_INS, UNIMAP_END, UNIMAP_PGUP, UNIMAP_PGDN, UNIMAP_NO, }, /* 68-6F */
{ UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, }, /* 70-77 */
{ UNIMAP_NO, UNIMAP_NO, UNIMAP_MUTE, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, UNIMAP_NO, }, /* 78-7F */
};
#endif

View file

@ -106,6 +106,10 @@ void host_mouse_send(report_mouse_t *report)
#endif
(*driver->send_mouse)(report);
report->buttons = b;
if (debug_mouse) {
xprintf("mouse: [%02X|%d %d %d %d]\n", report->buttons, report->x, report->y, report->v, report->h);
}
}
void host_system_send(uint16_t report)

View file

@ -105,7 +105,11 @@ host_driver_t lufa_driver = {
* Console
******************************************************************************/
#ifdef CONSOLE_ENABLE
#define SENDBUF_SIZE 256
# ifdef _AVR_ATmega32U2_H_
# define SENDBUF_SIZE 128
# else
# define SENDBUF_SIZE 256
# endif
static uint8_t sbuf[SENDBUF_SIZE];
static ringbuf_t sendbuf = {
.buffer = sbuf,

View file

@ -1,168 +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|
`-------------------------------------------------------------' `---' `---------------'
*/

View file

@ -1,51 +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.
*/
#ifndef NEWS_H
#define NEWS_H
/*
* Primitive PS/2 Library for AVR
*/
/* host role */
void news_init(void);
uint8_t news_recv(void);
/* device role */
#endif

View file

@ -49,7 +49,7 @@ POSSIBILITY OF SUCH DAMAGE.
* TODO: delay is not accurate enough. Instruction cycle should be counted and inline assemby is needed.
*/
#define WAIT_US (1000000L/SERIAL_SOFT_BAUD)
#define WAIT_US (1000000L/SERIAL_SOFT_BAUD - 1)
#ifdef SERIAL_SOFT_LOGIC_NEGATIVE
#define SERIAL_SOFT_RXD_IN() !(SERIAL_SOFT_RXD_READ())
@ -68,11 +68,10 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
/* debug for signal timing, see debug pin with oscilloscope */
#ifdef SERIAL_SOFT_DEBUG
#define SERIAL_SOFT_DEBUG_INIT() (DDRD |= 1<<7)
#define SERIAL_SOFT_DEBUG_TGL() (PORTD ^= 1<<7)
#else
#ifndef SERIAL_SOFT_DEBUG_INIT
#define SERIAL_SOFT_DEBUG_INIT()
#endif
#ifndef SERIAL_SOFT_DEBUG_TGL
#define SERIAL_SOFT_DEBUG_TGL()
#endif
@ -177,6 +176,9 @@ void serial_send(uint8_t data)
ISR(SERIAL_SOFT_RXD_VECT)
{
SERIAL_SOFT_DEBUG_TGL();
/* can be triggered by other pin. don't know why */
if (SERIAL_SOFT_RXD_IN()) { return; }
SERIAL_SOFT_RXD_INT_ENTER();
uint8_t data = 0;
@ -196,6 +198,7 @@ ISR(SERIAL_SOFT_RXD_VECT)
/* to center of start bit */
_delay_us(WAIT_US/2);
SERIAL_SOFT_DEBUG_TGL();
//if (SERIAL_SOFT_RXD_IN()) { return; }
do {
/* to center of next bit */
_delay_us(WAIT_US);