archimedes: scan logic

This commit is contained in:
tmk 2023-10-17 15:36:09 +09:00
parent 1a057c9737
commit 326cfc57bd
2 changed files with 131 additions and 22 deletions

View file

@ -42,6 +42,13 @@ SOFTWARE.
#define SACK 0x31
#define MACK 0x32
#define SMAK 0x33
#define KDDA 0xC0
#define KUDA 0xD0
// Archimedes LED
#define ARC_LED_CAPS_LOCK 0
#define ARC_LED_NUM_LOCK 1
#define ARC_LED_SCROLL_LOCK 2
void matrix_init(void)
@ -53,32 +60,117 @@ void matrix_init(void)
// wait for keyboard coming up
// otherwise LED status update fails
print("Archimedes starts.\n");
print("Sending HRST(0xFF): ");
xprintf("EIMSK: %02X\n", EIMSK);
xprintf("EICRA: %02X\n", EICRA);
return;
}
static uint8_t arc_led = 1<<ARC_LED_SCROLL_LOCK;
static enum {
INIT,
SCAN,
WAIT_KEY_COL,
} 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);
serial_send(cmd);
}
uint8_t matrix_scan(void)
{
//while (1) {
print(".");
serial_send(0xFF);
_delay_ms(10);
serial_send(RAK1);
_delay_ms(10);
serial_send(RAK2);
_delay_ms(10);
serial_send(SACK);
static uint8_t key;
_delay_ms(10);
//serial_send(LEDS(0x5)); // ScrollLock and CapsLock
//serial_send(LEDS(0x3)); // NumLock and CapsLock
serial_send(LEDS(0x6)); // NumLock and CapsLock
switch (state) {
case INIT:
send_cmd(0xFF);
_delay_ms(10);
check_reply();
//serial_send(RQID);
send_cmd(RAK1);
_delay_ms(10);
check_reply();
_delay_ms(500);
//}
send_cmd(RAK2);
_delay_ms(10);
check_reply();
//send_cmd(SACK);
send_cmd(SMAK);
check_reply();
state = SCAN;
break;
case SCAN: {
int16_t d;
d = check_reply();
switch (d) {
case -1:
// no reply
//xprintf(".");
break;
case KDDA ... KDDA+15:
case KUDA ... KUDA+15:
// key row
key = (d & 0xF) << 4;
_delay_ms(1);
send_cmd(BACK);
state = WAIT_KEY_COL;
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:
if ((d & KUDA) == KUDA) { key |= 0x80; } // key up flag
key |= d & 0xF;
xprintf("[k%02X] ", key);
_delay_ms(1);
send_cmd(SMAK);
state = SCAN;
break;
default:
// error
state = INIT;
break;
}
break;
}
}
// TODO
// toggle ScrollLock LED
/*
_delay_ms(10);
arc_led = arc_led ^ 1<<ARC_LED_SCROLL_LOCK;
serial_send(LEDS(arc_led % 8));
_delay_ms(500);
*/
return 0;
}
uint8_t matrix_get_row(uint8_t row)
@ -86,3 +178,13 @@ uint8_t matrix_get_row(uint8_t row)
// TODO
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\n", usb_led, arc_led);
}

View file

@ -44,14 +44,14 @@ SOFTWARE.
/* Software Serial configuration
* RX: PD1, TX: PD3
* asynchronous, negative logic, 31250 baud
* start bit(0), 8-bit data(LSB first), 9th bit(1), stop bit(1)
* start bit(0), 8-bit data(LSB first), stop bit(1)
*/
#define SERIAL_SOFT_DEBUG
#define SERIAL_SOFT_BAUD 31250
// TODO: 9th bit is optional?
//#define SERIAL_SOFT_9TH_BIT
#define SERIAL_SOFT_PARITY_NONE
#define SERIAL_SOFT_BIT_ORDER_LSB
#define SERIAL_SOFT_LOGIC_NEGATIVE
/* RXD Port */
#define SERIAL_SOFT_RXD_ENABLE
#define SERIAL_SOFT_RXD_DDR DDRD
@ -59,6 +59,7 @@ SOFTWARE.
#define SERIAL_SOFT_RXD_PIN PIND
#define SERIAL_SOFT_RXD_BIT 1
#define SERIAL_SOFT_RXD_VECT INT1_vect
/* RXD Interupt */
#ifdef SERIAL_SOFT_LOGIC_NEGATIVE
/* enable interrupt: INT1(rising edge) */
@ -67,26 +68,32 @@ SOFTWARE.
/* 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<<INT2); \
EIMSK |= (1<<INT1); \
sei(); \
} while (0)
#define SERIAL_SOFT_RXD_INT_ENTER()
#define SERIAL_SOFT_RXD_INT_EXIT() do { \
/* clear interrupt flag */ \
EIFR = (1<<INTF2); \
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 { \