Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for vial macros #40

Merged
merged 2 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 87 additions & 5 deletions keyboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package keyboard

import (
"bytes"
"context"
"machine"
k "machine/usb/hid/keyboard"
Expand All @@ -18,6 +19,7 @@ type Device struct {
Keyboard UpDowner
Mouse Mouser
Override [][]Keycode
Macros [2048]byte
Debug bool
flashCh chan bool
flashCnt int
Expand All @@ -43,6 +45,7 @@ type KBer interface {
type UpDowner interface {
Up(c k.Keycode) error
Down(c k.Keycode) error
Write(b []byte) (n int, err error)
}

type State uint8
Expand Down Expand Up @@ -97,7 +100,7 @@ func (d *Device) Init() error {
keys := d.GetMaxKeyCount()

// TODO: refactor
rbuf := make([]byte, 4+layers*keyboards*keys*2)
rbuf := make([]byte, 4+layers*keyboards*keys*2+len(device.Macros))
_, err := machine.Flash.ReadAt(rbuf, 0)
if err != nil {
return err
Expand All @@ -120,6 +123,14 @@ func (d *Device) Init() error {
}
}

for i, b := range rbuf[offset:] {
if b == 0xFF {
b = 0
}
device.Macros[i] = b
}
//copy(device.Macros[:], rbuf[offset:])

return nil
}

Expand All @@ -141,7 +152,7 @@ func (d *Device) Tick() error {
case <-d.flashCh:
d.flashCnt = 1
default:
if d.flashCnt >= 500 {
if d.flashCnt >= 5000 {
d.flashCnt = 0
err := Save()
if err != nil {
Expand Down Expand Up @@ -200,6 +211,9 @@ func (d *Device) Tick() error {
} else if x == keycodes.KeyRestoreDefaultKeymap {
// restore default keymap for QMK
machine.Flash.EraseBlocks(0, 1)
} else if x&0xFF00 == keycodes.TypeMacroKey {
no := uint8(x & 0x00FF)
d.RunMacro(no)
} else if x&0xF000 == 0xD000 {
switch x & 0x00FF {
case 0x01, 0x02, 0x04, 0x08, 0x10:
Expand Down Expand Up @@ -269,6 +283,54 @@ func (d *Device) Tick() error {
return nil
}

func (d *Device) RunMacro(no uint8) error {
macros := bytes.SplitN(d.Macros[:], []byte{0x00}, 16)

macro := macros[no]

for i := 0; i < len(macro); {
if macro[i] == 0x01 {
p := macro[i:]
if p[1] == 0x04 {
// delayMs
delayMs := int(p[2]) + int(p[3]-1)*255
time.Sleep(time.Duration(delayMs) * time.Millisecond)
i += 4
} else {
kc := keycodeViaToTGK(Keycode(p[2]))
sz := 3
if p[1] > 0x04 {
kc = Keycode(p[2]) + Keycode(p[3])<<8
sz += 1
}
i += sz
kc = keycodeViaToTGK(kc)

switch p[1] {
case 0x01, 0x05:
k.Keyboard.Down(k.Keycode(kc))
k.Keyboard.Up(k.Keycode(kc))
case 0x02, 0x06:
k.Keyboard.Down(k.Keycode(kc))
case 0x03, 0x07:
k.Keyboard.Up(k.Keycode(kc))
}
}
} else {
idx := bytes.Index(macro[i:], []byte{0x01})
if idx == -1 {
idx = len(macro)
} else {
idx = i + idx
}
k.Keyboard.Write(macro[i:idx])
i = idx
}
}

return nil
}

func encKey(kb, layer, index int) uint32 {
return (uint32(kb) << 24) | (uint32(layer) << 16) | uint32(index)
}
Expand Down Expand Up @@ -348,7 +410,11 @@ func (d *Device) KeyVia(layer, kbIndex, index int) Keycode {
// restore default keymap for QMK
kc = keycodes.KeyRestoreDefaultKeymap
default:
kc = kc & 0x0FFF
if kc&0xFF00 == keycodes.TypeMacroKey {
// skip
} else {
kc = kc & 0x0FFF
}
}
return kc
}
Expand All @@ -365,6 +431,12 @@ func (d *Device) SetKeycodeVia(layer, kbIndex, index int, key Keycode) {
return
}
//fmt.Printf("SetKeycodeVia(%d, %d, %d, %04X)\n", layer, kbIndex, index, key)
kc := keycodeViaToTGK(key)

d.kb[kbIndex].SetKeycode(layer, index, kc)
}

func keycodeViaToTGK(key Keycode) Keycode {
kc := key | 0xF000

switch key {
Expand Down Expand Up @@ -395,9 +467,11 @@ func (d *Device) SetKeycodeVia(layer, kbIndex, index int, key Keycode) {
case keycodes.KeyRestoreDefaultKeymap:
kc = keycodes.KeyRestoreDefaultKeymap
default:
if key&0xFF00 == keycodes.TypeMacroKey {
kc = key
}
}

d.kb[kbIndex].SetKeycode(layer, index, kc)
return kc
}

func (d *Device) Layer() int {
Expand Down Expand Up @@ -468,6 +542,10 @@ func (k *Keyboard) Down(c k.Keycode) error {
return nil
}

func (k *Keyboard) Write(b []byte) (n int, err error) {
return k.Port.Write(b)
}

// UartTxKeyboard is a keyboard that simply sends row/col corresponding to key
// placement via UART. For instructions on how to set it up, see bellow.
//
Expand Down Expand Up @@ -506,3 +584,7 @@ func (k *UartTxKeyboard) Down(c k.Keycode) error {
}
return nil
}

func (k *UartTxKeyboard) Write(b []byte) (n int, err error) {
return len(b), nil
}
20 changes: 20 additions & 0 deletions keycodes/keycodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const (
TypeMouse = 0xD000
TypeModKey = 0xFF00
TypeToKey = 0xFF10
TypeMacroKey = 0x7700
)

const (
Expand Down Expand Up @@ -41,6 +42,25 @@ const (
KeyTo5 = TypeToKey | 0x05
)

const (
KeyMacro0 = TypeMacroKey | 0x00
KeyMacro1 = TypeMacroKey | 0x01
KeyMacro2 = TypeMacroKey | 0x02
KeyMacro3 = TypeMacroKey | 0x03
KeyMacro4 = TypeMacroKey | 0x04
KeyMacro5 = TypeMacroKey | 0x05
KeyMacro6 = TypeMacroKey | 0x06
KeyMacro7 = TypeMacroKey | 0x07
KeyMacro8 = TypeMacroKey | 0x08
KeyMacro9 = TypeMacroKey | 0x09
KeyMacro10 = TypeMacroKey | 0x0a
KeyMacro11 = TypeMacroKey | 0x0b
KeyMacro12 = TypeMacroKey | 0x0c
KeyMacro13 = TypeMacroKey | 0x0d
KeyMacro14 = TypeMacroKey | 0x0e
KeyMacro15 = TypeMacroKey | 0x0f
)

const (
// restore default keymap for QMK
KeyRestoreDefaultKeymap = 0x7C03
Expand Down
18 changes: 15 additions & 3 deletions via.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,23 @@ func rxHandler2(b []byte) bool {

case 0x0D:
// DynamicKeymapMacroGetBufferSizeCommand
txb[1] = 0x07
txb[2] = 0x9B
sz := len(device.Macros)
txb[1] = byte(sz >> 8)
txb[2] = byte(sz)
case 0x0C:
// DynamicKeymapMacroGetCountCommand
txb[1] = 0x10
case 0x0E:
// DynamicKeymapMacroGetBufferCommand
offset := (uint16(b[1]) << 8) + uint16(b[2])
sz := b[3]
copy(txb[4:4+sz], device.Macros[offset:])
case 0x0F:
// CMD_VIA_MACRO_SET_BUFFER
offset := (uint16(b[1]) << 8) + uint16(b[2])
sz := b[3]
copy(device.Macros[offset:], txb[4:4+sz])
device.flashCh <- true
case 0x02:
// id_get_keyboard_value
Changed = false
Expand Down Expand Up @@ -258,7 +268,7 @@ func Save() error {
keyboards := len(device.kb)

cnt := device.GetMaxKeyCount()
wbuf := make([]byte, 4+layers*keyboards*cnt*2)
wbuf := make([]byte, 4+layers*keyboards*cnt*2+len(device.Macros))
needed := int64(len(wbuf)) / machine.Flash.EraseBlockSize()
if needed == 0 {
needed = 1
Expand Down Expand Up @@ -287,6 +297,8 @@ func Save() error {
}
}

copy(wbuf[offset:], device.Macros[:])

_, err = machine.Flash.WriteAt(wbuf[:], 0)
if err != nil {
return err
Expand Down