Refactor PHY to support more flexible and scalable architecture.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos 2024-11-05 00:25:41 +01:00
parent 802df9e705
commit 0638409ff8
No known key found for this signature in database
GPG key ID: C0095B7870A4CCD3
12 changed files with 177 additions and 110 deletions

View file

@ -182,6 +182,7 @@ set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/src/fs/flash.c ${CMAKE_CURRENT_LIST_DIR}/src/fs/flash.c
${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c ${CMAKE_CURRENT_LIST_DIR}/src/fs/low_flash.c
${CMAKE_CURRENT_LIST_DIR}/src/fs/otp.c ${CMAKE_CURRENT_LIST_DIR}/src/fs/otp.c
${CMAKE_CURRENT_LIST_DIR}/src/fs/phy.c
${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c ${CMAKE_CURRENT_LIST_DIR}/src/rng/random.c
${CMAKE_CURRENT_LIST_DIR}/src/rng/hwrng.c ${CMAKE_CURRENT_LIST_DIR}/src/rng/hwrng.c
${CMAKE_CURRENT_LIST_DIR}/src/eac.c ${CMAKE_CURRENT_LIST_DIR}/src/eac.c

View file

@ -528,54 +528,3 @@ int delete_file(file_t *ef) {
low_flash_available(); low_flash_available();
return CCID_OK; return CCID_OK;
} }
#ifndef ENABLE_EMULATION
int parse_phy_data(const uint8_t *data, uint8_t len) {
file_t *ef_phy = search_by_fid(EF_PHY, NULL, SPECIFY_EF);
if (!ef_phy) {
return CCID_ERR_FILE_NOT_FOUND;
}
uint8_t tmp[PHY_MAX_SIZE];
memset(tmp, 0, sizeof(tmp));
uint16_t opts = 0;
if (file_has_data(ef_phy)) {
memcpy(tmp, file_get_data(ef_phy), MIN(sizeof(tmp), file_get_size(ef_phy)));
if (file_get_size(ef_phy) >= 8) {
opts = (tmp[PHY_OPTS] << 8) | tmp[PHY_OPTS + 1];
}
}
const uint8_t *p = data;
while (p < data + len) {
uint8_t tag = *p++;
switch (tag) {
case PHY_VID:
memcpy(tmp + PHY_VID, p, 2);
opts |= PHY_OPT_VPID;
p += 2;
break;
case PHY_PID:
memcpy(tmp + PHY_PID, p, 2);
opts |= PHY_OPT_VPID;
p += 2;
break;
case PHY_LED_GPIO:
tmp[PHY_LED_GPIO] = *p++;
opts |= PHY_OPT_GPIO;
break;
case PHY_LED_BTNESS:
tmp[PHY_LED_BTNESS] = *p++;
opts |= PHY_OPT_BTNESS;
break;
case PHY_OPTS:
opts = (opts & ~PHY_OPT_MASK) | (((*p << 8) | *(p + 1)) & PHY_OPT_MASK);
p += 2;
break;
}
}
tmp[PHY_OPTS] = opts >> 8;
tmp[PHY_OPTS + 1] = opts & 0xff;
file_put_data(ef_phy, tmp, sizeof(tmp));
low_flash_available();
return CCID_OK;
}
#endif

View file

@ -15,7 +15,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _FILE_H_ #ifndef _FILE_H_
#define _FILE_H_ #define _FILE_H_
@ -27,6 +26,7 @@
#include <stdint.h> #include <stdint.h>
#endif #endif
#include "compat.h" #include "compat.h"
#include "phy.h"
#define FILE_TYPE_NOT_KNOWN 0x00 #define FILE_TYPE_NOT_KNOWN 0x00
#define FILE_TYPE_DF 0x04 #define FILE_TYPE_DF 0x04
@ -67,28 +67,6 @@
#define EF_SKDFS 0x6045 #define EF_SKDFS 0x6045
#define EF_META 0xE010 #define EF_META 0xE010
#define EF_PHY 0xE020
#define PHY_VID 0x0
#define PHY_PID 0x2
#define PHY_LED_GPIO 0x4
#define PHY_LED_BTNESS 0x5
#define PHY_OPTS 0x6
#define PHY_OPT_WCID 0x1
#define PHY_OPT_VPID 0x2
#define PHY_OPT_GPIO 0x4
#define PHY_OPT_BTNESS 0x8
#define PHY_OPT_DIMM 0x10
#define PHY_OPT_MASK (PHY_OPT_DIMM | PHY_OPT_WCID)
#define PHY_MAX_SIZE 8
#ifndef ENABLE_EMULATION
extern int parse_phy_data(const uint8_t *data, uint8_t len);
#endif
#define MAX_DEPTH 4 #define MAX_DEPTH 4
typedef struct file { typedef struct file {

99
src/fs/phy.c Normal file
View file

@ -0,0 +1,99 @@
/*
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
* Copyright (c) 2022 Pol Henarejos.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pico_keys.h"
#include "file.h"
#ifndef ENABLE_EMULATION
phy_data_t phy_data;
int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len) {
if (!phy || !data || !len) {
return CCID_ERR_NULL_PARAM;
}
uint8_t *p = data;
if (phy->vidpid_present) {
*p++ = PHY_VIDPID;
*p++ = phy->vidpid[1];
*p++ = phy->vidpid[0];
*p++ = phy->vidpid[3];
*p++ = phy->vidpid[2];
}
if (phy->led_gpio_present) {
*p++ = PHY_LED_GPIO;
*p++ = phy->led_gpio;
}
if (phy->led_brightness_present) {
*p++ = PHY_LED_BTNESS;
*p++ = phy->led_brightness;
}
*p++ = PHY_OPTS;
*p++ = phy->opts >> 8;
*p++ = phy->opts & 0xff;
*len = p - data;
return CCID_OK;
}
#include <stdio.h>
int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy) {
if (!phy || !data || !len) {
return CCID_ERR_NULL_PARAM;
}
memset(phy, 0, sizeof(phy_data_t));
const uint8_t *p = data;
while (p < data + len) {
printf("TAG %x\n",*p);
switch (*p++) {
case PHY_VIDPID:
memcpy(phy->vidpid, p, 4);
phy->vidpid[1] = *p++;
phy->vidpid[0] = *p++;
phy->vidpid[3] = *p++;
phy->vidpid[2] = *p++;
phy->vidpid_present = true;
break;
case PHY_LED_GPIO:
phy->led_gpio = *p++;
phy->led_gpio_present = true;
break;
case PHY_LED_BTNESS:
phy->led_brightness = *p++;
phy->led_brightness_present = true;
break;
case PHY_OPTS:
phy->opts = (*p << 8) | *(p + 1);
p += 2;
break;
}
}
return CCID_OK;
}
int phy_init() {
memset(&phy_data, 0, sizeof(phy_data_t));
if (file_has_data(ef_phy)) {
const uint8_t *data = file_get_data(ef_phy);
DEBUG_DATA(data, file_get_size(ef_phy));
int ret = phy_unserialize_data(data, file_get_size(ef_phy), &phy_data);
if (ret != CCID_OK) {
return ret;
}
}
return CCID_OK;
}
#endif

60
src/fs/phy.h Normal file
View file

@ -0,0 +1,60 @@
/*
* This file is part of the Pico Keys SDK distribution (https://github.com/polhenarejos/pico-keys-sdk).
* Copyright (c) 2022 Pol Henarejos.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _PHY_H_
#define _PHY_H_
#define EF_PHY 0xE020
#define PHY_VIDPID 0x0
#define PHY_LED_GPIO 0x4
#define PHY_LED_BTNESS 0x5
#define PHY_OPTS 0x6
#define PHY_OPT_WCID 0x1
#define PHY_OPT_DIMM 0x2
#define PHY_OPT_SECURE_BOOT 0x4
#define PHY_OPT_SECURE_LOCK 0x8
typedef struct phy_data {
union {
struct {
uint16_t vid;
uint16_t pid;
};
uint8_t vidpid[4];
};
uint8_t led_gpio;
uint8_t led_brightness;
uint16_t opts;
bool vidpid_present;
bool led_gpio_present;
bool led_brightness_present;
} phy_data_t;
#define PHY_OPT_MASK (PHY_OPT_SECURE_LOCK | PHY_OPT_SECURE_BOOT | PHY_OPT_DIMM | PHY_OPT_WCID)
#define PHY_MAX_SIZE 8
#ifndef ENABLE_EMULATION
extern int phy_serialize_data(const phy_data_t *phy, uint8_t *data, uint16_t *len);
extern int phy_unserialize_data(const uint8_t *data, uint16_t len, phy_data_t *phy);
extern int phy_init();
extern phy_data_t phy_data;
#endif
#endif // _PHY_H_

View file

@ -31,9 +31,6 @@ extern void led_driver_color(uint8_t, uint32_t, float);
static uint32_t led_mode = MODE_NOT_MOUNTED; static uint32_t led_mode = MODE_NOT_MOUNTED;
uint32_t led_phy_btness = MAX_BTNESS;
bool led_dimmable = false;
void led_set_mode(uint32_t mode) { void led_set_mode(uint32_t mode) {
led_mode = mode; led_mode = mode;
} }

View file

@ -66,7 +66,4 @@ extern void led_blinking_task();
extern void led_off_all(); extern void led_off_all();
extern void led_init(); extern void led_init();
extern uint32_t led_phy_btness;
extern bool led_dimmable;
#endif // _LED_H_ #endif // _LED_H_

View file

@ -47,9 +47,10 @@ void led_driver_init() {
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) { void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
static tNeopixel spx = {.index = 0, .rgb = 0}; static tNeopixel spx = {.index = 0, .rgb = 0};
if (!led_dimmable) { if (!(phy_data.opts & PHY_OPT_DIMM)) {
progress = progress >= 0.5 ? 1 : 0; progress = progress >= 0.5 ? 1 : 0;
} }
uint32_t led_phy_btness = phy_data.led_brightness_present ? phy_data.led_brightness : MAX_BTNESS;
float brightness = ((float)led_brightness / MAX_BTNESS) * ((float)led_phy_btness / MAX_BTNESS) * progress; float brightness = ((float)led_brightness / MAX_BTNESS) * ((float)led_phy_btness / MAX_BTNESS) * progress;
uint32_t pixel_color = pixel[color].rgb; uint32_t pixel_color = pixel[color].rgb;
uint8_t r = (pixel_color >> 16) & 0xFF; uint8_t r = (pixel_color >> 16) & 0xFF;

View file

@ -80,9 +80,11 @@ uint32_t pixel[] = {
}; };
void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) { void led_driver_color(uint8_t color, uint32_t led_brightness, float progress) {
if (!led_dimmable) { if (!(phy_data.opts & PHY_OPT_DIMM)) {
progress = progress >= 0.5 ? 1 : 0; progress = progress >= 0.5 ? 1 : 0;
} }
uint32_t led_phy_btness = phy_data.led_brightness_present ? phy_data.led_brightness : MAX_BTNESS;
float brightness = ((float)led_brightness / MAX_BTNESS) * ((float)led_phy_btness / MAX_BTNESS) * progress; float brightness = ((float)led_brightness / MAX_BTNESS) * ((float)led_phy_btness / MAX_BTNESS) * progress;
uint32_t pixel_color = pixel[color]; uint32_t pixel_color = pixel[color];
uint8_t r = (pixel_color >> 16) & 0xFF; uint8_t r = (pixel_color >> 16) & 0xFF;

View file

@ -268,7 +268,6 @@ pico_unique_board_id_t pico_serial;
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
#define pico_get_unique_board_id(a) do { uint32_t value; esp_efuse_read_block(EFUSE_BLK1, &value, 0, 32); memcpy((uint8_t *)(a), &value, sizeof(uint32_t)); esp_efuse_read_block(EFUSE_BLK1, &value, 32, 32); memcpy((uint8_t *)(a)+4, &value, sizeof(uint32_t)); } while(0) #define pico_get_unique_board_id(a) do { uint32_t value; esp_efuse_read_block(EFUSE_BLK1, &value, 0, 32); memcpy((uint8_t *)(a), &value, sizeof(uint32_t)); esp_efuse_read_block(EFUSE_BLK1, &value, 32, 32); memcpy((uint8_t *)(a)+4, &value, sizeof(uint32_t)); } while(0)
extern tinyusb_config_t tusb_cfg; extern tinyusb_config_t tusb_cfg;
extern bool enable_wcid;
extern const uint8_t desc_config[]; extern const uint8_t desc_config[];
TaskHandle_t hcore0 = NULL, hcore1 = NULL; TaskHandle_t hcore0 = NULL, hcore1 = NULL;
int app_main() { int app_main() {
@ -305,16 +304,19 @@ int main(void) {
init_rtc(); init_rtc();
#ifndef ENABLE_EMULATION
phy_init();
usb_init(); usb_init();
#ifndef ENABLE_EMULATION
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
gpio_pad_select_gpio(BOOT_PIN); gpio_pad_select_gpio(BOOT_PIN);
gpio_set_direction(BOOT_PIN, GPIO_MODE_INPUT); gpio_set_direction(BOOT_PIN, GPIO_MODE_INPUT);
gpio_pulldown_dis(BOOT_PIN); gpio_pulldown_dis(BOOT_PIN);
tusb_cfg.string_descriptor[3] = pico_serial_str; tusb_cfg.string_descriptor[3] = pico_serial_str;
if (enable_wcid) { if (phy_data.opts & PHY_OPT_WCID) {
tusb_cfg.configuration_descriptor = desc_config; tusb_cfg.configuration_descriptor = desc_config;
} }
tinyusb_driver_install(&tusb_cfg); tinyusb_driver_install(&tusb_cfg);

View file

@ -53,29 +53,12 @@ queue_t card_to_usb_q = {0};
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
extern tusb_desc_device_t desc_device; extern tusb_desc_device_t desc_device;
extern bool enable_wcid;
#endif #endif
void usb_init() { void usb_init() {
#ifndef ENABLE_EMULATION #ifndef ENABLE_EMULATION
if (file_has_data(ef_phy)) { if (phy_data.vidpid_present) {
uint8_t *data = file_get_data(ef_phy); desc_device.idVendor = phy_data.vid;
uint16_t opts = 0; desc_device.idProduct = phy_data.pid;
if (file_get_size(ef_phy) >= 8) {
opts = (data[PHY_OPTS] << 8) | data[PHY_OPTS+1];
if (opts & PHY_OPT_WCID) {
enable_wcid = true;
}
if (opts & PHY_OPT_DIMM) {
led_dimmable = true;
}
}
if (file_get_size(ef_phy) >= 4 && opts & PHY_OPT_VPID) {
desc_device.idVendor = (data[PHY_VID] << 8) | data[PHY_VID+1];
desc_device.idProduct = (data[PHY_PID] << 8) | data[PHY_PID+1];
}
if (opts & PHY_OPT_BTNESS) {
led_phy_btness = data[PHY_LED_BTNESS];
}
} }
mutex_init(&mutex); mutex_init(&mutex);
#endif #endif

View file

@ -40,8 +40,6 @@
#define MAX_USB_POWER 2 #define MAX_USB_POWER 2
bool enable_wcid = false;
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Device Descriptors // Device Descriptors
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -172,7 +170,7 @@ uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
#ifndef ESP_PLATFORM #ifndef ESP_PLATFORM
uint8_t const *tud_descriptor_configuration_cb(uint8_t index) { uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
(void) index; // for multiple configurations (void) index; // for multiple configurations
if (enable_wcid) { if (phy_data.opts & PHY_OPT_WCID) {
return desc_config; return desc_config;
} }
return desc_config_nowcid; return desc_config_nowcid;
@ -188,7 +186,7 @@ enum
VENDOR_REQUEST_WEBUSB = 1, VENDOR_REQUEST_WEBUSB = 1,
VENDOR_REQUEST_MICROSOFT = 2 VENDOR_REQUEST_MICROSOFT = 2
}; };
#define URL "www.picokeys.com/pki/" #define URL "www.picokeys.com"
static bool web_serial_connected = false; static bool web_serial_connected = false;
const tusb_desc_webusb_url_t desc_url = const tusb_desc_webusb_url_t desc_url =
@ -279,7 +277,7 @@ uint8_t const desc_bos[] = {
}; };
uint8_t const *tud_descriptor_bos_cb(void) { uint8_t const *tud_descriptor_bos_cb(void) {
if (enable_wcid) { if (phy_data.opts & PHY_OPT_WCID) {
return desc_bos; return desc_bos;
} }
return NULL; return NULL;