Compare commits

...

2 Commits

Author SHA1 Message Date
steven 52a92c70e5 fix(readme): mixup in matrix table description 2021-09-28 19:32:01 -04:00
Adam Engstrom e73304f6f5 Experimental support for custom FN+key combos
Not tested yet
2017-01-24 21:02:43 +01:00
5 changed files with 103 additions and 37 deletions

View File

@ -28,13 +28,13 @@ build/main.o: build/section_data_patch.bin build/section_isr.bin
--change-section-address .vectors=0xffe0 \
--set-start 0x8000 build/section_data_patch.bin $@
build/enter_bsl.o: shellcode/enter_bsl.c
build/fn_hooks.o: shellcode/fn_hooks.c
@echo "Compiling shellcode..."
$(QUIET)msp430-gcc -Os -mmcu=msp430f5510 -c $< -o $@
# The main.o is an relocatable elf which we convert to an actual elf
# for IDA to like it. Also link in our own objects
build/main.elf: build/main.o build/enter_bsl.o
build/main.elf: build/main.o build/fn_hooks.o
@echo "Create main.elf..."
$(QUIET)msp430-gcc -O0 -mmcu=msp430f5510 \
-Wl,--section-start=.text=0x8000 \

View File

@ -95,7 +95,7 @@ lowest 3 bits of key id and the column is the 4 bits above that
from the table below and C is the 0 indexed column. For example ~tab =
5 + (2<<3) = 21~.
First row contains row id:s and first column is column id:s, rest of
First column contains row id:s and first row is column id:s, rest of
the table is the keys..
#+ATTR_HTML: :border 2 :rules all :frame border

View File

@ -98,15 +98,17 @@ def original_fw_valid(path):
m.update(orig.read())
return m.hexdigest() == orig_fw_md5
def write_jump_to_bsl():
'''Make fn + F1 + F4 jump to BSL (firmware update mode)'''
# Replace mov instruction with a call to our own code for checking
# which F keys are currently pressed. If fn + F1 + F4 is pressed
# jump to 0x1000 (BSL entry addr).
def write_handle_fn_key_handler_hooks():
'''Add C hooks for doing stuff when fn + key(s) is pressed'''
# bytecode for asm 'call 0xa780; nop'
# bytecode for asm 'calla 0xa780; nop' (on_fn_key_down)
dest.seek(0x83a)
dest.write('b01280a70343'.decode('hex'))
dest.write('b01380a70343'.decode('hex'))
# calla #0xa8f0 (on_fn_key_up, INCREDIHACK: offest depends on size
# of on_fn_key_down since this is linked after)
dest.seek(0xa98)
dest.write('b01302a8'.decode('hex'))
if __name__ == '__main__':
# Remap caps to ctrl
@ -141,4 +143,4 @@ if __name__ == '__main__':
for text in usb_hid_strings:
write_usb_string(dest, text)
write_jump_to_bsl()
write_handle_fn_key_handler_hooks()

View File

@ -1,26 +0,0 @@
#include <intrinsics.h>
#include <msp430f5510.h>
// Declare pointers to variables we access in Novatouch fw
unsigned char* const repeat_flags = (unsigned char*)0x2404;
unsigned char* const repeat_rate = (unsigned char*)0x252f;
unsigned char* const num_for_7x_c1 = (unsigned char*)0x2530;
void check_bsl_enter() {
// We just replaced this copy to get here, perform it here instead
// (although it seems to be redundant because it is never actually
// read)
*num_for_7x_c1 = *repeat_rate;
// Enter BSL if fn + f1 + f4 is pressed
if ((*repeat_flags & 0x9) == 0x09) {
__dint();
// Maybe need to slow down clock to 8 MHz also, not sure what
// is configured by Novatouch fw
USBKEYPID = 0x9628;
USBCNF &= ~PUR_EN;
USBPWRCTL &= ~VBOFFIE;
USBKEYPID = 0x9600;
((void (*)())0x1000)();
}
}

View File

@ -0,0 +1,90 @@
#include <msp430f5510.h>
// Declare pointers to variables we access in Novatouch fw
unsigned char* const repeat_flags = (unsigned char*)0x2404;
unsigned char* const repeat_rate = (unsigned char*)0x252f;
unsigned char* const num_for_7x_c1 = (unsigned char*)0x2530;
unsigned char* const current_keycode = (unsigned char*)0x2400;
// Defines for internal scancodes (corresponding to scancode_table_1). Find out
// missing ones by using table at bottom of README.org.
#define KEY_H 0x24
#define KEY_J 0x25
#define KEY_K 0x26
#define KEY_L 0x27
#define KEY_UP 0x53
#define KEY_DOWN 0x54
#define KEY_LEFT 0x4f
#define KEY_RIGHT 0x59
// Seems like original FW is compiled with IAR compiler and has different
// calling convention than mspgcc. Use macro to call functions and get correct
// parameter passing.
#define QUEUE_KEY(code) asm("mov.b %0, r12\n" \
"calla #0x91a2" : : "i"(code))
#define UNQUEUE_KEY(code) asm("mov.b %0, r12\n" \
"calla #0x9086" : : "i"(code))
// To be called when key is pressed and fn is also pressed
void on_fn_key_down() {
// We just replaced this copy to get here, perform it here instead
// (although it seems to be redundant because it is never actually
// read)
*num_for_7x_c1 = *repeat_rate;
// Enter BSL if fn + f1 + f4 is pressed
if ((*repeat_flags & 0x9) == 0x09) {
__dint();
// Maybe need to slow down clock to 8 MHz also, not sure what
// is configured by Novatouch fw
USBKEYPID = 0x9628;
USBCNF &= ~PUR_EN;
USBPWRCTL &= ~VBOFFIE;
USBKEYPID = 0x9600;
((void (*)())0x1000)();
}
// Extra bindings for fn + key
switch (*current_keycode) {
case KEY_H:
QUEUE_KEY(KEY_LEFT);
break;
case KEY_J:
QUEUE_KEY(KEY_DOWN);
break;
case KEY_K:
QUEUE_KEY(KEY_UP);
break;
case KEY_L:
QUEUE_KEY(KEY_RIGHT);
break;
}
}
// To be called when key is released and fn is also down
void on_fn_key_up() {
// Extra bindings for fn + key
switch (*current_keycode) {
case KEY_H:
UNQUEUE_KEY(KEY_LEFT);
break;
case KEY_J:
UNQUEUE_KEY(KEY_DOWN);
break;
case KEY_K:
UNQUEUE_KEY(KEY_UP);
break;
case KEY_L:
UNQUEUE_KEY(KEY_RIGHT);
break;
default:
// Moar ugly hacks! To hook this function we replaced the
// original call to unqueue key, setup original argument and
// do the call.
asm("mov.b &0x2400, r12\n"
"calla #0x9086");
break;
}
}