fl16: Make dynamic serial number a little more generic
First step towards upstreaming. Signed-off-by: Daniel Schaefer <dhs@frame.work>
This commit is contained in:
parent
ef518f5b4b
commit
4827822cdc
51
keyboards/lotus/dyn_serial.c
Normal file
51
keyboards/lotus/dyn_serial.c
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2022 Framework Computer
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "quantum.h"
|
||||
#include "dyn_serial.h"
|
||||
#include "usb_descriptor.h"
|
||||
#include "usb_descriptor_common.h"
|
||||
|
||||
// Prefix string literal with L for descriptors
|
||||
#ifdef SERIAL_NUMBER
|
||||
USB_Descriptor_String_t PROGMEM SerialNumberString = {
|
||||
.Header = {
|
||||
.Size = sizeof(FALLBACK_SERIAL_NUMBER),
|
||||
.Type = DTYPE_String
|
||||
},
|
||||
.UnicodeString = FALLBACK_SERIAL_NUMBER
|
||||
};
|
||||
|
||||
char ascii_serialnum[SERIALNUM_LEN+1];
|
||||
|
||||
void *dyn_serial_number_string(void) {
|
||||
// Exit early, if it was previously read and converted
|
||||
if (ascii_serialnum[0] != '\0' || ascii_serialnum[0] == 0xFF) {
|
||||
return &SerialNumberString;
|
||||
}
|
||||
|
||||
// Read ASCII serial number from memory-mapped flash
|
||||
char *serialnum_ptr = (char*) (FLASH_OFFSET + LAST_4K_BLOCK);
|
||||
memcpy(ascii_serialnum, serialnum_ptr, SERIALNUM_LEN);
|
||||
|
||||
// Just keep fallback serialnumber if the flash is erased
|
||||
if (ascii_serialnum[0] == 0xFF) {
|
||||
return &SerialNumberString;
|
||||
}
|
||||
|
||||
// Convert to UCS-2, which is equivalent to UTF-16, if the input is ASCII
|
||||
for (int i = 0; i < SERIALNUM_LEN; i++) {
|
||||
if (ascii_serialnum[i] > 128) {
|
||||
dprintf("Serial number character %d is not valid ASCII.", ascii_serialnum[i]);
|
||||
SerialNumberString.Header.Size = i * 2;
|
||||
break;
|
||||
}
|
||||
SerialNumberString.UnicodeString[i] = ascii_serialnum[i];
|
||||
}
|
||||
|
||||
return &SerialNumberString;
|
||||
}
|
||||
uint16_t dyn_serial_number_string_len(void) {
|
||||
return pgm_read_byte(&SerialNumberString.Header.Size);
|
||||
}
|
||||
#endif
|
||||
21
keyboards/lotus/dyn_serial.h
Normal file
21
keyboards/lotus/dyn_serial.h
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2022 Framework Computer
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
//#include "quantum.h"
|
||||
|
||||
void *dyn_serial_number_string(void);
|
||||
uint16_t dyn_serial_number_string_len(void);
|
||||
// The serial number is written to the last 4K block in the first 1M of flash
|
||||
#define FLASH_OFFSET 0x10000000
|
||||
#define LAST_4K_BLOCK 0xff000
|
||||
#define SERIALNUM_LEN 18
|
||||
|
||||
// 18-digit serial number. Must be programmed at factory
|
||||
// TODO: Figure out how to do that. Probably a script to compile qmk
|
||||
// Must be wide-string (UTF-16)
|
||||
// KDK = Keyboard RGB Backlight
|
||||
// KDW = Keyboard White Backlight
|
||||
// KDN = Keyboard RGB Gridpad
|
||||
// KDM = Keyboard White Numpad
|
||||
#define FALLBACK_SERIAL_NUMBER L"FRAKDKEN0100000000"
|
||||
_Static_assert(sizeof(FALLBACK_SERIAL_NUMBER) == (SERIALNUM_LEN+1)*2, "Fallback serial number must be same length");
|
||||
@ -8,6 +8,9 @@
|
||||
#if defined(RGB_MATRIX_ENABLE)
|
||||
#include "rgb_matrix.h"
|
||||
#endif
|
||||
#ifdef SERIAL_NUMBER
|
||||
#include "dyn_serial.h"
|
||||
#endif
|
||||
|
||||
enum factory_commands {
|
||||
f_emu_keypress = 0x01, // Next byte is keycode
|
||||
|
||||
@ -4,53 +4,6 @@
|
||||
#include "quantum.h"
|
||||
#include "lotus.h"
|
||||
|
||||
#include "usb_descriptor.h"
|
||||
#include "usb_descriptor_common.h"
|
||||
|
||||
// Prefix string literal with L for descriptors
|
||||
#ifdef SERIAL_NUMBER
|
||||
USB_Descriptor_String_t PROGMEM SerialNumberString = {
|
||||
.Header = {
|
||||
.Size = sizeof(FALLBACK_SERIAL_NUMBER),
|
||||
.Type = DTYPE_String
|
||||
},
|
||||
.UnicodeString = FALLBACK_SERIAL_NUMBER
|
||||
};
|
||||
|
||||
char ascii_serialnum[SERIALNUM_LEN+1];
|
||||
|
||||
void *lotus_serial_number_string(void) {
|
||||
// Exit early, if it was previously read and converted
|
||||
if (ascii_serialnum[0] != '\0' || ascii_serialnum[0] == 0xFF) {
|
||||
return &SerialNumberString;
|
||||
}
|
||||
|
||||
// Read ASCII serial number from memory-mapped flash
|
||||
char *serialnum_ptr = (char*) (FLASH_OFFSET + LAST_4K_BLOCK);
|
||||
memcpy(ascii_serialnum, serialnum_ptr, SERIALNUM_LEN);
|
||||
|
||||
// Just keep fallback serialnumber if the flash is erased
|
||||
if (ascii_serialnum[0] == 0xFF) {
|
||||
return &SerialNumberString;
|
||||
}
|
||||
|
||||
// Convert to UCS-2, which is equivalent to UTF-16, if the input is ASCII
|
||||
for (int i = 0; i < SERIALNUM_LEN; i++) {
|
||||
if (ascii_serialnum[i] > 128) {
|
||||
dprintf("Serial number character %d is not valid ASCII.", ascii_serialnum[i]);
|
||||
SerialNumberString.Header.Size = i * 2;
|
||||
break;
|
||||
}
|
||||
SerialNumberString.UnicodeString[i] = ascii_serialnum[i];
|
||||
}
|
||||
|
||||
return &SerialNumberString;
|
||||
}
|
||||
uint16_t lotus_serial_number_string_len(void) {
|
||||
return pgm_read_byte(&SerialNumberString.Header.Size);
|
||||
}
|
||||
#endif
|
||||
|
||||
void keyboard_post_init_kb(void) {
|
||||
keyboard_post_init_user();
|
||||
|
||||
|
||||
@ -32,20 +32,3 @@ enum lotus_keycodes {
|
||||
#else
|
||||
#define IS31FL3743A_ENABLE_GPIO GP29
|
||||
#endif
|
||||
|
||||
void *lotus_serial_number_string(void);
|
||||
uint16_t lotus_serial_number_string_len(void);
|
||||
// The serial number is written to the last 4K block in the first 1M of flash
|
||||
#define FLASH_OFFSET 0x10000000
|
||||
#define LAST_4K_BLOCK 0xff000
|
||||
#define SERIALNUM_LEN 18
|
||||
|
||||
// 18-digit serial number. Must be programmed at factory
|
||||
// TODO: Figure out how to do that. Probably a script to compile qmk
|
||||
// Must be wide-string (UTF-16)
|
||||
// KDK = Keyboard RGB Backlight
|
||||
// KDW = Keyboard White Backlight
|
||||
// KDN = Keyboard RGB Gridpad
|
||||
// KDM = Keyboard White Numpad
|
||||
#define FALLBACK_SERIAL_NUMBER L"FRAKDKEN0100000000"
|
||||
_Static_assert(sizeof(FALLBACK_SERIAL_NUMBER) == (SERIALNUM_LEN+1)*2, "Fallback serial number must be same length");
|
||||
|
||||
@ -16,6 +16,6 @@ BACKLIGHT_DRIVER = pwm
|
||||
CUSTOM_MATRIX = lite
|
||||
SRC += matrix.c analog.c
|
||||
|
||||
SRC += factory.c
|
||||
SRC += dyn_serial.c factory.c
|
||||
|
||||
DEFAULT_FOLDER = lotus/ansi
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
#include "usb_descriptor.h"
|
||||
#include "usb_descriptor_common.h"
|
||||
|
||||
#include "lotus.h"
|
||||
#include "dyn_serial.h"
|
||||
|
||||
#ifdef JOYSTICK_ENABLE
|
||||
# include "joystick.h"
|
||||
@ -1139,8 +1139,9 @@ uint16_t get_usb_descriptor(const uint16_t wValue, const uint16_t wIndex, const
|
||||
#if defined(SERIAL_NUMBER)
|
||||
case 0x03:
|
||||
// TODO: Give these functions a generic name and let anyone override it
|
||||
Address = lotus_serial_number_string();
|
||||
Size = lotus_serial_number_string_len();
|
||||
// Framework 16 uses this
|
||||
Address = dyn_serial_number_string();
|
||||
Size = dyn_serial_number_string_len();
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "debug.h"
|
||||
#include "wait.h"
|
||||
#include "usb_descriptor_common.h"
|
||||
#include "dyn_serial.h"
|
||||
|
||||
#ifdef RAW_ENABLE
|
||||
# include "raw_hid.h"
|
||||
@ -761,7 +762,7 @@ const PROGMEM usbStringDescriptor_t usbStringDescriptorProduct = {
|
||||
.bString = USBSTR(PRODUCT)
|
||||
};
|
||||
|
||||
// THIS IS NOT USED by Lotus. TODO: Implement flexible serial number here
|
||||
// THIS IS NOT USED by Framework 16. TODO: Implement dynamic serial number here
|
||||
#if defined(SERIAL_NUMBER)
|
||||
const PROGMEM usbStringDescriptor_t usbStringDescriptorSerial =
|
||||
.header = {
|
||||
@ -1035,8 +1036,9 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
|
||||
break;
|
||||
#if defined(SERIAL_NUMBER)
|
||||
case 3: // iSerialNumber
|
||||
usbMsgPtr = (usbMsgPtr_t)lotus_serial_number_string();
|
||||
len = lotus_serial_number_string_len();
|
||||
// Not using this on Framework 16
|
||||
usbMsgPtr = (usbMsgPtr_t)dynamic_serial_number_string();
|
||||
len = dynamic_serial_number_string_len();
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user