Open zuozhehao opened 8 months ago
@zuozhehao Analyzing and documenting the protocol that the mcu uses to talk to the wireless IC would be tremendously helpful. I haven't found any datasheets or other resources for the BK3632 and there's only very limited information available for similar parts from beken (like the BK3633).
I was thinking of taking a stab at this myself by sniffing the data lines with a logic analyzer and analyzing the stock firmware, but I don't see myself doing that in the near future.
I was thinking of taking a stab at this myself by sniffing the data lines with a logic analyzer and analyzing the stock firmware, but I don't see myself doing that in the near future.
I'm not sure this applies for every board (Although it's likely to be close if they're all just using the same SDK) , but the gist of it for the RK boards looks like:
0xAA 2 byte command sequence Payload bytes Checksum byte
If you load up your dump it should be fairly easy to spot the location of the command buffer. Ie.
MOV DPTR, Buffer MOV A, 0xAA // Magic MOVX DPTR, A INC DPTR MOV A, 0x1D // Command byte 1 MOVX DPTR, A INC DPTR MOV A, 0x02 // Command byte 2 MOVX DPTR
And so forth.
@namidairo thanks!
On a related note, I was just exploring these parts of the stock firmware and found that the SPI comms with the BK3632 are all bit-banged :/
I sniffed the spi lines during the initialization and a couple of keypresses (0x37
), here's the result: bk3632-rf-bootup-key-press.csv.
Command 0x1d 0x02
looks like the keyboard report. It seems similar to the regular USBHID report format, where the first byte is for modifiers and the rest of the bytes are pressed regular key keycodes. That said, the total length of this command is 32 bytes, so I am not yet sure if it's all used just for keys.
I have little understanding of the other commands so far...
That said, the algo for the checksum is pretty simple, it's:
uint8_t checksum(uint8_t *data, int len) // data is all command bytes leading up to the checksum byte
{
uint8_t checksum = 0;
for (int i = 0; i < len; i++) {
checksum += data[i];
}
return 0x55 - checksum;
}
1D 08 - Always get called twice with a small sleep in between, always has the board name + '5.0', and then board name + '3.0' the next time. 03 0A - Keepalive? Ready to send?
1D 02 has a couple code paths that lead to it either reading from a different memory location, or sending the shorter 0B 05 command sequence instead. Not sure what would trigger it. The bit that triggers it gets set inside some comparison loop that I don't really comprehend.
I dug a bit more into 1d 02
, the format seems to be:
aa 1d 02 <MOD_KEYS> <KEY_CODES>{5} <00 or 01> <NKRO>{16} 00{5} <CHECKSUM>
The NKRO bits seem to include only keys that are not represented in KEY_CODES - there's no overlap between them.
When looking at the USBHID data on the USB receiver end, the 6KRO report and the NKRO reports are both sent, but only if the NKRO contains any data, otherwise it's just the 6KRO. Also, the NKRO report is transmitted through several different "pages" with different report IDs (0x07, 0x08, 0x09). The first one contains the first 6 bytes and the other two - 7 subsequent bytes each. Since this adds up to 20 bytes in total, it leads me to assume that 4 of the padded bytes after the NKRO bytes are still part of the NKRO report, but my keyboard just doesn't use them. I'll try to test this once I start adding this to SMK.
Oh, and I just figured out that the second byte in these command frames is actually length_of_the_frame - 3
, example: 32 - 3 = 0x1d
. This applies to all commands.
I am now assuming that only the third byte defines which command this is.
I also have a nuphy60 v1 keyboard. Can I assist with Bluetooth or 2.4G support and what should I pay attention to