Browse Source

core: Add adb_host_talk()

master
tmk 8 years ago
parent
commit
d702fe7504
2 changed files with 70 additions and 52 deletions
  1. 52
    52
      tmk_core/protocol/adb.c
  2. 18
    0
      tmk_core/protocol/adb.h

+ 52
- 52
tmk_core/protocol/adb.c View File

static inline void send_byte(uint8_t data); static inline void send_byte(uint8_t data);
static inline uint16_t wait_data_lo(uint16_t us); static inline uint16_t wait_data_lo(uint16_t us);
static inline uint16_t wait_data_hi(uint16_t us); static inline uint16_t wait_data_hi(uint16_t us);
static inline uint16_t adb_host_dev_recv(uint8_t device);




void adb_host_init(void) void adb_host_init(void)
* <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>
*/ */

// ADB Bit Cells
//
// bit cell time: 70-130us
// low part of bit0: 60-70% of bit cell
// low part of bit1: 30-40% of bit cell
//
// bit cell time 70us 130us
// --------------------------------------------
// low part of bit0 42-49 78-91
// high part of bit0 21-28 39-52
// low part of bit1 21-28 39-52
// high part of bit1 42-49 78-91
//
//
// bit0:
// 70us bit cell:
// ____________~~~~~~
// 42-49 21-28
//
// 130us bit cell:
// ____________~~~~~~
// 78-91 39-52
//
// bit1:
// 70us bit cell:
// ______~~~~~~~~~~~~
// 21-28 42-49
//
// 130us bit cell:
// ______~~~~~~~~~~~~
// 39-52 78-91
//
// [from Apple IIgs Hardware Reference Second Edition]

enum {
ADDR_KEYB = 0x20,
ADDR_MOUSE = 0x30
};

uint16_t adb_host_kbd_recv(void) uint16_t adb_host_kbd_recv(void)
{ {
return adb_host_dev_recv(ADDR_KEYB);
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) uint16_t adb_host_mouse_recv(void)
{ {
return adb_host_dev_recv(ADDR_MOUSE);
return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0);
} }
#endif #endif


static inline uint16_t adb_host_dev_recv(uint8_t device)
uint16_t adb_host_talk(uint8_t addr, uint8_t reg)
{ {
uint16_t data = 0; uint16_t data = 0;
cli(); cli();
attention(); attention();
send_byte(device|0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
send_byte((addr<<4) | (ADB_CMD_TALK<<2) | reg);
place_bit0(); // Stopbit(0) place_bit0(); // Stopbit(0)
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
sei(); sei();
sei(); sei();
return 0; // No data to send return 0; // No data to send
} }
uint8_t n = 17; // start bit + 16 data bits uint8_t n = 17; // start bit + 16 data bits
do { do {
uint8_t lo = (uint8_t) wait_data_hi(130); uint8_t lo = (uint8_t) wait_data_hi(130);
if (!lo) if (!lo)
goto error; goto error;
uint8_t hi = (uint8_t) wait_data_lo(lo); uint8_t hi = (uint8_t) wait_data_lo(lo);
if (!hi) if (!hi)
goto error; goto error;
hi = lo - hi; hi = lo - hi;
lo = 130 - lo; lo = 130 - lo;
data <<= 1; data <<= 1;
if (lo < hi) { if (lo < hi) {
data |= 1; data |= 1;
place_bit0(); // Stopbit(0) place_bit0(); // Stopbit(0)
_delay_us(200); // Tlt/Stop to Start _delay_us(200); // Tlt/Stop to Start
place_bit1(); // Startbit(1) place_bit1(); // Startbit(1)
send_byte(data_h);
send_byte(data_h);
send_byte(data_l); send_byte(data_l);
place_bit0(); // Stopbit(0); place_bit0(); // Stopbit(0);
sei(); sei();
A A A A 1 1 R R Talk(read from a device) A A A A 1 1 R R Talk(read from a device)


The command to read keycodes from keyboard is 0x2C which The command to read keycodes from keyboard is 0x2C which
consist of keyboard address 2 and Talk against register 0.
consist of keyboard address 2 and Talk against register 0.


Address: Address:
2: keyboard 2: keyboard
Keyboard LEDs & state of keys(Register2) Keyboard LEDs & state of keys(Register2)
This register hold current state of three LEDs and nine keys. This register hold current state of three LEDs and nine keys.
The state of LEDs can be changed by sending Listen command. The state of LEDs can be changed by sending Listen command.
1514 . . . . . . 7 6 5 . 3 2 1 0 1514 . . . . . . 7 6 5 . 3 2 1 0
| | | | | | | | | | | | | | | +- LED1(NumLock) | | | | | | | | | | | | | | | +- LED1(NumLock)
| | | | | | | | | | | | | | +--- LED2(CapsLock) | | | | | | | | | | | | | | +--- LED2(CapsLock)
| +----------------------------- Delete | +----------------------------- Delete
+------------------------------- Reserved +------------------------------- Reserved


ADB Bit Cells
bit cell time: 70-130us
low part of bit0: 60-70% of bit cell
low part of bit1: 30-40% of bit cell

bit cell time 70us 130us
--------------------------------------------
low part of bit0 42-49 78-91
high part of bit0 21-28 39-52
low part of bit1 21-28 39-52
high part of bit1 42-49 78-91


bit0:
70us bit cell:
____________~~~~~~
42-49 21-28

130us bit cell:
____________~~~~~~
78-91 39-52

bit1:
70us bit cell:
______~~~~~~~~~~~~
21-28 42-49

130us bit cell:
______~~~~~~~~~~~~
39-52 78-91

[from Apple IIgs Hardware Reference Second Edition]

Keyboard Handle ID
Apple Standard Keyboard M0116: 0x01
Apple Extended Keyboard M0115: 0x02
Apple Extended Keyboard II M3501: 0x02
Apple Adjustable Keybaord: 0x10

http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802

END_OF_ADB END_OF_ADB
*/ */

+ 18
- 0
tmk_core/protocol/adb.h View File

#define ADB_CAPS 0x39 #define ADB_CAPS 0x39




/* ADB commands */
#define ADB_ADDR_KEYBOARD 2
#define ADB_ADDR_MOUSE 3
#define ADB_CMD_LISTEN 2
#define ADB_CMD_TALK 3
#define ADB_REG_0 0
#define ADB_REG_1 1
#define ADB_REG_2 2
#define ADB_REG_3 3

/* ADB keyboard handle id */
#define ADB_HANDLE_M0116 0x01
#define ADB_HANDLE_M0115 0x02
#define ADB_HANDLE_M3501 0x02
#define ADB_HANDLE_M1242 0x10


// ADB host // ADB host
void adb_host_init(void); void adb_host_init(void);
bool adb_host_psw(void); bool adb_host_psw(void);
uint16_t adb_host_kbd_recv(void); uint16_t adb_host_kbd_recv(void);
uint16_t adb_host_mouse_recv(void); uint16_t adb_host_mouse_recv(void);
uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
void adb_host_kbd_led(uint8_t led); void adb_host_kbd_led(uint8_t led);
void adb_mouse_task(void); void adb_mouse_task(void);