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 SACK 0x31
#define MACK 0x32 #define MACK 0x32
#define SMAK 0x33 #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) void matrix_init(void)
@ -53,32 +60,117 @@ void matrix_init(void)
// wait for keyboard coming up // wait for keyboard coming up
// otherwise LED status update fails // otherwise LED status update fails
print("Archimedes starts.\n"); print("Archimedes starts.\n");
print("Sending HRST(0xFF): "); xprintf("EIMSK: %02X\n", EIMSK);
xprintf("EICRA: %02X\n", EICRA);
return; 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) uint8_t matrix_scan(void)
{ {
//while (1) { static uint8_t key;
print(".");
serial_send(0xFF);
_delay_ms(10);
serial_send(RAK1);
_delay_ms(10);
serial_send(RAK2);
_delay_ms(10);
serial_send(SACK);
_delay_ms(10); switch (state) {
//serial_send(LEDS(0x5)); // ScrollLock and CapsLock case INIT:
//serial_send(LEDS(0x3)); // NumLock and CapsLock send_cmd(0xFF);
serial_send(LEDS(0x6)); // NumLock and CapsLock _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) uint8_t matrix_get_row(uint8_t row)
@ -86,3 +178,13 @@ uint8_t matrix_get_row(uint8_t row)
// TODO // TODO
return 0; 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 /* Software Serial configuration
* RX: PD1, TX: PD3 * RX: PD1, TX: PD3
* asynchronous, negative logic, 31250 baud * 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 #define SERIAL_SOFT_BAUD 31250
// TODO: 9th bit is optional?
//#define SERIAL_SOFT_9TH_BIT
#define SERIAL_SOFT_PARITY_NONE #define SERIAL_SOFT_PARITY_NONE
#define SERIAL_SOFT_BIT_ORDER_LSB #define SERIAL_SOFT_BIT_ORDER_LSB
#define SERIAL_SOFT_LOGIC_NEGATIVE #define SERIAL_SOFT_LOGIC_NEGATIVE
/* RXD Port */ /* RXD Port */
#define SERIAL_SOFT_RXD_ENABLE #define SERIAL_SOFT_RXD_ENABLE
#define SERIAL_SOFT_RXD_DDR DDRD #define SERIAL_SOFT_RXD_DDR DDRD
@ -59,6 +59,7 @@ SOFTWARE.
#define SERIAL_SOFT_RXD_PIN PIND #define SERIAL_SOFT_RXD_PIN PIND
#define SERIAL_SOFT_RXD_BIT 1 #define SERIAL_SOFT_RXD_BIT 1
#define SERIAL_SOFT_RXD_VECT INT1_vect #define SERIAL_SOFT_RXD_VECT INT1_vect
/* RXD Interupt */ /* RXD Interupt */
#ifdef SERIAL_SOFT_LOGIC_NEGATIVE #ifdef SERIAL_SOFT_LOGIC_NEGATIVE
/* enable interrupt: INT1(rising edge) */ /* enable interrupt: INT1(rising edge) */
@ -67,26 +68,32 @@ SOFTWARE.
/* enable interrupt: INT1(falling edge) */ /* enable interrupt: INT1(falling edge) */
#define INTR_TRIG_EDGE ((1<<ISC11)|(0<<ISC10)) #define INTR_TRIG_EDGE ((1<<ISC11)|(0<<ISC10))
#endif #endif
#define SERIAL_SOFT_RXD_INIT() do { \ #define SERIAL_SOFT_RXD_INIT() do { \
/* pin configuration: input with pull-up */ \ /* pin configuration: input with pull-up */ \
SERIAL_SOFT_RXD_DDR &= ~(1<<SERIAL_SOFT_RXD_BIT); \ SERIAL_SOFT_RXD_DDR &= ~(1<<SERIAL_SOFT_RXD_BIT); \
SERIAL_SOFT_RXD_PORT |= (1<<SERIAL_SOFT_RXD_BIT); \ SERIAL_SOFT_RXD_PORT |= (1<<SERIAL_SOFT_RXD_BIT); \
EICRA |= INTR_TRIG_EDGE; \ EICRA |= INTR_TRIG_EDGE; \
EIMSK |= (1<<INT2); \ EIMSK |= (1<<INT1); \
sei(); \ sei(); \
} while (0) } while (0)
#define SERIAL_SOFT_RXD_INT_ENTER() #define SERIAL_SOFT_RXD_INT_ENTER()
#define SERIAL_SOFT_RXD_INT_EXIT() do { \ #define SERIAL_SOFT_RXD_INT_EXIT() do { \
/* clear interrupt flag */ \ /* clear interrupt flag */ \
EIFR = (1<<INTF2); \ EIFR = (1<<INTF1); \
} while (0) } while (0)
#define SERIAL_SOFT_RXD_READ() (SERIAL_SOFT_RXD_PIN&(1<<SERIAL_SOFT_RXD_BIT)) #define SERIAL_SOFT_RXD_READ() (SERIAL_SOFT_RXD_PIN&(1<<SERIAL_SOFT_RXD_BIT))
/* TXD Port */ /* TXD Port */
#define SERIAL_SOFT_TXD_ENABLE #define SERIAL_SOFT_TXD_ENABLE
#define SERIAL_SOFT_TXD_DDR DDRD #define SERIAL_SOFT_TXD_DDR DDRD
#define SERIAL_SOFT_TXD_PORT PORTD #define SERIAL_SOFT_TXD_PORT PORTD
#define SERIAL_SOFT_TXD_PIN PIND #define SERIAL_SOFT_TXD_PIN PIND
#define SERIAL_SOFT_TXD_BIT 3 #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_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_LO() do { SERIAL_SOFT_TXD_PORT &= ~(1<<SERIAL_SOFT_TXD_BIT); } while (0)
#define SERIAL_SOFT_TXD_INIT() do { \ #define SERIAL_SOFT_TXD_INIT() do { \