1
0
Fork 0

[Keyboard] Update adb_usb converter to non-avr specific code

This commit is contained in:
Drashna Jael're 2023-10-24 11:41:31 -07:00
parent ec15fdd6dd
commit 0df3dd804f
Signed by: drashna
GPG key ID: DBA1FD3A860D1B11
7 changed files with 139 additions and 142 deletions

View file

@ -37,23 +37,36 @@ POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <util/delay.h> #include "converter/adb_usb/config.h"
#include <avr/io.h> #include "gpio.h"
#include <avr/interrupt.h> #include "wait.h"
#include "adb.h" #include "adb.h"
#include "print.h" #include "print.h"
// GCC doesn't inline functions normally // GCC doesn't inline functions normally
#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) #define data_lo() setPinOutput(ADB_DATA_PIN)
#define data_hi() (ADB_DDR &= ~(1 << ADB_DATA_BIT)) #define data_hi() setPinInput(ADB_DATA_PIN)
#define data_in() (ADB_PIN & (1 << ADB_DATA_BIT)) #define data_in() readPin(ADB_DATA_PIN)
#ifdef ADB_PSW_BIT #ifdef ADB_PSW_PIN
static inline void psw_lo(void); static inline void psw_lo(void);
static inline void psw_hi(void); static inline void psw_hi(void);
static inline bool psw_in(void); static inline bool psw_in(void);
#endif #endif
#ifdef __AVR__
# include <avr/io.h>
# include <avr/interrupt.h>
# define disable_interrupts() cli()
# define enable_interrupts() sei()
# define CLOCK_SPEED F_CPU
#else
# define disable_interrupts() chSysLock()
# define enable_interrupts() chSysUnlock()
# define CLOCK_SPEED CPU_CLOCK
#endif
static inline void attention(void); static inline void attention(void);
static inline void place_bit0(void); static inline void place_bit0(void);
static inline void place_bit1(void); static inline void place_bit1(void);
@ -62,15 +75,17 @@ static inline uint16_t wait_data_lo(uint16_t us);
static inline uint16_t wait_data_hi(uint16_t us); static inline uint16_t wait_data_hi(uint16_t us);
void adb_host_init(void) { void adb_host_init(void) {
ADB_PORT &= ~(1 << ADB_DATA_BIT); writePinLow(ADB_DATA_PIN);
data_hi(); data_hi();
#ifdef ADB_PSW_BIT #ifdef ADB_PSW_PIN
psw_hi(); psw_hi();
#endif #endif
} }
#ifdef ADB_PSW_BIT #ifdef ADB_PSW_PIN
bool adb_host_psw(void) { return psw_in(); } bool adb_host_psw(void) {
return psw_in();
}
#endif #endif
/* /*
@ -81,17 +96,22 @@ bool adb_host_psw(void) { return psw_in(); }
* <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
* <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
*/ */
uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); } uint16_t adb_host_kbd_recv(void) {
return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0);
}
#ifdef ADB_MOUSE_ENABLE #ifdef ADB_MOUSE_ENABLE
uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); } uint16_t adb_host_mouse_recv(void) {
return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0);
}
#endif #endif
// This sends Talk command to read data from register and returns length of the data. // This sends Talk command to read data from register and returns length of the data.
uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
for (int8_t i = 0; i < len; i++) buf[i] = 0; for (int8_t i = 0; i < len; i++)
buf[i] = 0;
cli(); disable_interrupts();
attention(); attention();
send_byte((addr << 4) | ADB_CMD_TALK | reg); send_byte((addr << 4) | ADB_CMD_TALK | reg);
place_bit0(); // Stopbit(0) place_bit0(); // Stopbit(0)
@ -141,23 +161,23 @@ uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
// http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
xprintf("R"); xprintf("R");
sei(); enable_interrupts();
return 0; return 0;
} }
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
sei(); enable_interrupts();
return 0; // No data from device(not error); return 0; // No data from device(not error);
} }
// start bit(1) // start bit(1)
if (!wait_data_hi(40)) { if (!wait_data_hi(40)) {
xprintf("S"); xprintf("S");
sei(); enable_interrupts();
return 0; return 0;
} }
if (!wait_data_lo(100)) { if (!wait_data_lo(100)) {
xprintf("s"); xprintf("s");
sei(); enable_interrupts();
return 0; return 0;
} }
@ -187,7 +207,7 @@ uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
} while (++n); } while (++n);
error: error:
sei(); enable_interrupts();
return n / 8; return n / 8;
} }
@ -200,19 +220,19 @@ uint16_t adb_host_talk(uint8_t addr, uint8_t reg) {
} }
void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
cli(); disable_interrupts();
attention(); attention();
send_byte((addr << 4) | ADB_CMD_LISTEN | reg); send_byte((addr << 4) | ADB_CMD_LISTEN | reg);
place_bit0(); // Stopbit(0) place_bit0(); // Stopbit(0)
// TODO: Service Request // TODO: Service Request
_delay_us(200); // Tlt/Stop to Start wait_us(200); // Tlt/Stop to Start
place_bit1(); // Startbit(1) place_bit1(); // Startbit(1)
for (int8_t i = 0; i < len; i++) { for (int8_t i = 0; i < len; i++) {
send_byte(buf[i]); send_byte(buf[i]);
// xprintf("%02X ", buf[i]); // xprintf("%02X ", buf[i]);
} }
place_bit0(); // Stopbit(0); place_bit0(); // Stopbit(0);
sei(); enable_interrupts();
} }
void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) { void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) {
@ -221,12 +241,12 @@ void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l)
} }
void adb_host_flush(uint8_t addr) { void adb_host_flush(uint8_t addr) {
cli(); disable_interrupts();
attention(); attention();
send_byte((addr << 4) | ADB_CMD_FLUSH); send_byte((addr << 4) | ADB_CMD_FLUSH);
place_bit0(); // Stopbit(0) place_bit0(); // Stopbit(0)
_delay_us(200); // Tlt/Stop to Start wait_us(200); // Tlt/Stop to Start
sei(); enable_interrupts();
} }
// send state of LEDs // send state of LEDs
@ -237,40 +257,38 @@ void adb_host_kbd_led(uint8_t led) {
adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07); adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07);
} }
#ifdef ADB_PSW_BIT #ifdef ADB_PSW_PIN
static inline void psw_lo(void) { static inline void psw_lo(void) {
ADB_DDR |= (1 << ADB_PSW_BIT); setPinOutput(ADB_PSW_PIN);
ADB_PORT &= ~(1 << ADB_PSW_BIT); writePinLow(ADB_PSW_PIN);
} }
static inline void psw_hi(void) { static inline void psw_hi(void) {
ADB_PORT |= (1 << ADB_PSW_BIT); setPinInputHigh(ADB_PSW_PIN);
ADB_DDR &= ~(1 << ADB_PSW_BIT);
} }
static inline bool psw_in(void) { static inline bool psw_in(void) {
ADB_PORT |= (1 << ADB_PSW_BIT); setPinInputHigh(ADB_PSW_PIN);
ADB_DDR &= ~(1 << ADB_PSW_BIT); return readPin(ADB_PSW_PIN);
return ADB_PIN & (1 << ADB_PSW_BIT);
} }
#endif #endif
static inline void attention(void) { static inline void attention(void) {
data_lo(); data_lo();
_delay_us(800 - 35); // bit1 holds lo for 35 more wait_us(800 - 35); // bit1 holds lo for 35 more
place_bit1(); place_bit1();
} }
static inline void place_bit0(void) { static inline void place_bit0(void) {
data_lo(); data_lo();
_delay_us(65); wait_us(65);
data_hi(); data_hi();
_delay_us(35); wait_us(35);
} }
static inline void place_bit1(void) { static inline void place_bit1(void) {
data_lo(); data_lo();
_delay_us(35); wait_us(35);
data_hi(); data_hi();
_delay_us(65); wait_us(65);
} }
static inline void send_byte(uint8_t data) { static inline void send_byte(uint8_t data) {
@ -282,12 +300,16 @@ static inline void send_byte(uint8_t data) {
} }
} }
static inline void adb_wait(void) {
wait_us(1 - (6 * 1000000.0 / CLOCK_SPEED));
}
// These are carefully coded to take 6 cycles of overhead. // These are carefully coded to take 6 cycles of overhead.
// inline asm approach became too convoluted // inline asm approach became too convoluted
static inline uint16_t wait_data_lo(uint16_t us) { static inline uint16_t wait_data_lo(uint16_t us) {
do { do {
if (!data_in()) break; if (!data_in()) break;
_delay_us(1 - (6 * 1000000.0 / F_CPU)); adb_wait();
} while (--us); } while (--us);
return us; return us;
} }
@ -295,7 +317,7 @@ static inline uint16_t wait_data_lo(uint16_t us) {
static inline uint16_t wait_data_hi(uint16_t us) { static inline uint16_t wait_data_hi(uint16_t us) {
do { do {
if (data_in()) break; if (data_in()) break;
_delay_us(1 - (6 * 1000000.0 / F_CPU)); adb_wait();
} while (--us); } while (--us);
return us; return us;
} }

View file

@ -40,10 +40,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#if !(defined(ADB_PORT) && defined(ADB_PIN) && defined(ADB_DDR) && defined(ADB_DATA_BIT))
# error "ADB port setting is required in config.h"
#endif
#define ADB_POWER 0x7F #define ADB_POWER 0x7F
#define ADB_CAPS 0x39 #define ADB_CAPS 0x39

View file

@ -24,8 +24,5 @@ Ported to QMK by Peter Roe <pete@13bit.me>
#define MATRIX_COLS 8 // keycode bit: 6-4 #define MATRIX_COLS 8 // keycode bit: 6-4
/* ADB port setting */ /* ADB port setting */
#define ADB_PORT PORTD #define ADB_DATA_PIN D0
#define ADB_PIN PIND // #define ADB_PSW_PIN D1
#define ADB_DDR DDRD
#define ADB_DATA_BIT 0
//#define ADB_PSW_BIT 1 // optional

View file

@ -16,12 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdint.h> #include <stdint.h>
#include <util/delay.h>
#include "adb.h" #include "adb.h"
#include "led.h" #include "led.h"
void led_set(uint8_t usb_led) {
void led_set(uint8_t usb_led)
{
adb_host_kbd_led(~usb_led); adb_host_kbd_led(~usb_led);
} }

View file

@ -19,9 +19,8 @@ Ported to QMK by Peter Roe <pete@13bit.me>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <avr/io.h>
#include <util/delay.h>
#include "print.h" #include "print.h"
#include "wait.h"
#include "util.h" #include "util.h"
#include "debug.h" #include "debug.h"
#include "adb.h" #include "adb.h"
@ -42,33 +41,27 @@ static matrix_row_t matrix[MATRIX_ROWS];
static void register_key(uint8_t key); static void register_key(uint8_t key);
__attribute__ ((weak)) __attribute__((weak)) void matrix_init_kb(void) {
void matrix_init_kb(void) {
matrix_init_user(); matrix_init_user();
} }
__attribute__ ((weak)) __attribute__((weak)) void matrix_scan_kb(void) {
void matrix_scan_kb(void) {
matrix_scan_user(); matrix_scan_user();
} }
__attribute__ ((weak)) __attribute__((weak)) void matrix_init_user(void) {}
void matrix_init_user(void) {
}
__attribute__ ((weak)) __attribute__((weak)) void matrix_scan_user(void) {}
void matrix_scan_user(void) {
}
void matrix_init(void) void matrix_init(void) {
{
adb_host_init(); adb_host_init();
// wait for keyboard to boot up and receive command // wait for keyboard to boot up and receive command
_delay_ms(2000); wait_ms(2000);
// initialize matrix state: all keys off // initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00; for (uint8_t i = 0; i < MATRIX_ROWS; i++)
matrix[i] = 0x00;
// debug_enable = true; // debug_enable = true;
// debug_matrix = true; // debug_matrix = true;
@ -80,20 +73,13 @@ void matrix_init(void)
} }
#ifdef ADB_MOUSE_ENABLE #ifdef ADB_MOUSE_ENABLE
#ifdef MAX
#undef MAX
#endif
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
static report_mouse_t mouse_report = {}; static report_mouse_t mouse_report = {};
void housekeeping_task_kb(void) { void housekeeping_task_kb(void) {
adb_mouse_task(); adb_mouse_task();
} }
void adb_mouse_task(void) void adb_mouse_task(void) {
{
uint16_t codes; uint16_t codes;
int16_t x, y; int16_t x, y;
static int8_t mouseacc; static int8_t mouseacc;
@ -112,20 +98,16 @@ void adb_mouse_task(void)
return; return;
}; };
// Bit sixteen is button. // Bit sixteen is button.
if (~codes & (1 << 15)) if (~codes & (1 << 15)) mouse_report.buttons |= MOUSE_BTN1;
mouse_report.buttons |= MOUSE_BTN1; if (codes & (1 << 15)) mouse_report.buttons &= ~MOUSE_BTN1;
if (codes & (1 << 15))
mouse_report.buttons &= ~MOUSE_BTN1;
// lower seven bits are movement, as signed int_7. // lower seven bits are movement, as signed int_7.
// low byte is X-axis, high byte is Y. // low byte is X-axis, high byte is Y.
y = (codes>>8 & 0x3F); y = (codes >> 8 & 0x3F);
x = (codes>>0 & 0x3F); x = (codes >> 0 & 0x3F);
// bit seven and fifteen is negative // bit seven and fifteen is negative
// usb does not use int_8, but int_7 (measuring distance) with sign-bit. // usb does not use int_8, but int_7 (measuring distance) with sign-bit.
if (codes & (1 << 6)) if (codes & (1 << 6)) x = (x - 0x40);
x = (x-0x40); if (codes & (1 << 14)) y = (y - 0x40);
if (codes & (1 << 14))
y = (y-0x40);
// Accelerate mouse. (They weren't meant to be used on screens larger than 320x200). // Accelerate mouse. (They weren't meant to be used on screens larger than 320x200).
x *= mouseacc; x *= mouseacc;
y *= mouseacc; y *= mouseacc;
@ -135,23 +117,28 @@ void adb_mouse_task(void)
mouse_report.x = -MAX(-MAX(x, -127), -127); mouse_report.x = -MAX(-MAX(x, -127), -127);
mouse_report.y = -MAX(-MAX(y, -127), -127); mouse_report.y = -MAX(-MAX(y, -127), -127);
if (debug_mouse) { if (debug_mouse) {
print("adb_host_mouse_recv: "); print_bin16(codes); print("\n"); print("adb_host_mouse_recv: ");
print_bin16(codes);
print("\n");
print("adb_mouse raw: ["); print("adb_mouse raw: [");
print_hex8(mouseacc); print(" "); print_hex8(mouseacc);
print_hex8(mouse_report.buttons); print("|"); print(" ");
print_decs(mouse_report.x); print(" "); print_hex8(mouse_report.buttons);
print_decs(mouse_report.y); print("]\n"); print("|");
print_decs(mouse_report.x);
print(" ");
print_decs(mouse_report.y);
print("]\n");
} }
// Send result by usb. // Send result by usb.
host_mouse_send(&mouse_report); host_mouse_send(&mouse_report);
// increase acceleration of mouse // increase acceleration of mouse
mouseacc += ( mouseacc < ADB_MOUSE_MAXACC ? 1 : 0 ); mouseacc += (mouseacc < ADB_MOUSE_MAXACC ? 1 : 0);
return; return;
} }
#endif #endif
uint8_t matrix_scan(void) uint8_t matrix_scan(void) {
{
/* extra_key is volatile and more convoluted than necessary because gcc refused /* extra_key is volatile and more convoluted than necessary because gcc refused
to generate valid code otherwise. Making extra_key uint8_t and constructing codes to generate valid code otherwise. Making extra_key uint8_t and constructing codes
here via codes = extra_key<<8 | 0xFF; would consistently fail to even LOAD here via codes = extra_key<<8 | 0xFF; would consistently fail to even LOAD
@ -168,8 +155,7 @@ uint8_t matrix_scan(void)
codes = extra_key; codes = extra_key;
extra_key = 0xFFFF; extra_key = 0xFFFF;
if ( codes == 0xFFFF ) if (codes == 0xFFFF) {
{
// polling with 12ms interval // polling with 12ms interval
if (timer_elapsed(tick_ms) < 12) return 0; if (timer_elapsed(tick_ms) < 12) return 0;
tick_ms = timer_read(); tick_ms = timer_read();
@ -177,11 +163,13 @@ uint8_t matrix_scan(void)
codes = adb_host_kbd_recv(); codes = adb_host_kbd_recv();
} }
key0 = codes>>8; key0 = codes >> 8;
key1 = codes&0xFF; key1 = codes & 0xFF;
if (debug_matrix && codes) { if (debug_matrix && codes) {
print("adb_host_kbd_recv: "); print_hex16(codes); print("\n"); print("adb_host_kbd_recv: ");
print_hex16(codes);
print("\n");
} }
if (codes == 0) { // no keys if (codes == 0) { // no keys
@ -238,32 +226,26 @@ uint8_t matrix_scan(void)
} }
register_key(key0); register_key(key0);
if (key1 != 0xFF) // key1 is 0xFF when no second key. if (key1 != 0xFF) // key1 is 0xFF when no second key.
extra_key = key1<<8 | 0xFF; // process in a separate call extra_key = key1 << 8 | 0xFF; // process in a separate call
} }
matrix_scan_kb(); matrix_scan_kb();
return 1; return 1;
} }
void matrix_print(void){ void matrix_print(void) {}
} inline matrix_row_t matrix_get_row(uint8_t row) {
inline
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row]; return matrix[row];
} }
inline inline static void register_key(uint8_t key) {
static void register_key(uint8_t key)
{
uint8_t col, row; uint8_t col, row;
col = key&0x07; col = key & 0x07;
row = (key>>3)&0x0F; row = (key >> 3) & 0x0F;
if (key&0x80) { if (key & 0x80) {
matrix[row] &= ~(1<<col); matrix[row] &= ~(1 << col);
} else { } else {
matrix[row] |= (1<<col); matrix[row] |= (1 << col);
} }
} }

View file

@ -0,0 +1,5 @@
ifeq ($(strip $(ADB_MOUSE_ENABLE)), yes)
OPT_DEFS += -DADB_MOUSE_ENABLE
MOUSE_ENABLE := yes
endif

View file

@ -2,6 +2,4 @@ CUSTOM_MATRIX = yes
SRC += matrix.c adb.c led.c SRC += matrix.c adb.c led.c
# OPT_DEFS += -DADB_MOUSE_ENABLE -DMOUSE_ENABLE
DEFAULT_FOLDER = converter/adb_usb/rev1 DEFAULT_FOLDER = converter/adb_usb/rev1