firmware/iso7816soc-usb: Import minimal USB firmware
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
parent
a6a5c12c1e
commit
43e563d4cb
|
@ -0,0 +1,4 @@
|
|||
*.bin
|
||||
*.elf
|
||||
*.o
|
||||
*.gen.h
|
|
@ -0,0 +1,62 @@
|
|||
BOARD ?= icebreaker
|
||||
CROSS ?= riscv-none-embed-
|
||||
CC = $(CROSS)gcc
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
ICEPROG = iceprog
|
||||
|
||||
BOARD_DEFINE=BOARD_$(shell echo $(BOARD) | tr a-z\- A-Z_)
|
||||
CFLAGS=-Wall -Os -march=rv32i -mabi=ilp32 -ffreestanding -flto -nostartfiles -fomit-frame-pointer -Wl,--gc-section --specs=nano.specs -D$(BOARD_DEFINE) -I. -I../common
|
||||
|
||||
HEADERS_common=$(addprefix ../common/, \
|
||||
config.h \
|
||||
console.h \
|
||||
led.h \
|
||||
mini-printf.h \
|
||||
misc.h \
|
||||
no2iso7816.h \
|
||||
spi.h \
|
||||
utils.h \
|
||||
)
|
||||
|
||||
SOURCES_common=$(addprefix ../common/, \
|
||||
start.S \
|
||||
console.c \
|
||||
led.c \
|
||||
mini-printf.c \
|
||||
misc.c \
|
||||
no2iso7816.c \
|
||||
spi.c \
|
||||
utils.c \
|
||||
)
|
||||
|
||||
NO2USB_FW_VERSION=0
|
||||
include ../../gateware/cores/no2usb/fw/fw.mk
|
||||
CFLAGS += $(INC_no2usb)
|
||||
HEADERS_common += $(HEADERS_no2usb)
|
||||
SOURCES_common += $(SOURCES_no2usb)
|
||||
|
||||
HEADERS_app=\
|
||||
usb_str_app.gen.h \
|
||||
$(NULL)
|
||||
|
||||
SOURCES_app=\
|
||||
fw_app.c \
|
||||
usb_desc_app.c \
|
||||
$(NULL)
|
||||
|
||||
|
||||
all: fw_app.bin
|
||||
|
||||
fw_app.elf: ../common/lnk-app.lds $(HEADERS_app) $(SOURCES_app) $(HEADERS_common) $(SOURCES_common)
|
||||
$(CC) $(CFLAGS) -Wl,-Bstatic,-T,../common/lnk-app.lds,--strip-debug -o $@ $(SOURCES_common) $(SOURCES_app)
|
||||
|
||||
%.bin: %.elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
prog: fw_app.bin
|
||||
$(ICEPROG) -o 640k $<
|
||||
|
||||
clean:
|
||||
rm -f *.bin *.hex *.elf *.o *.gen.h
|
||||
|
||||
.PHONY: prog clean
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* fw_app.c
|
||||
*
|
||||
* Copyright (C) 2021-2022 Sylvain Munaut
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "led.h"
|
||||
#include "mini-printf.h"
|
||||
#include "misc.h"
|
||||
#include "no2iso7816.h"
|
||||
#include "spi.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <no2usb/usb.h>
|
||||
#include <no2usb/usb_dfu_rt.h>
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ISO7816 test
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static void
|
||||
iso7816_read_data(const char *desc)
|
||||
{
|
||||
printf("%s :", desc);
|
||||
while (1) {
|
||||
int v = iso7816_get_char();
|
||||
if (v < 0)
|
||||
break;
|
||||
printf(" %02x", v);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
iso7816_test()
|
||||
{
|
||||
/* Setup core with default params */
|
||||
iso7816_init(4);
|
||||
|
||||
/* Power up card */
|
||||
ncn8025_power_up();
|
||||
wait(1000); // 100_000 us
|
||||
|
||||
/* Read ATR */
|
||||
iso7816_read_data("ATR");
|
||||
|
||||
/* Send PPS Request */
|
||||
iso7816_put_char(0xff); // PPPS
|
||||
iso7816_put_char(0x10); // PPS0
|
||||
iso7816_put_char(0x96); // PPS1
|
||||
iso7816_put_char(0x79); // PCK
|
||||
|
||||
wait(100); // 10_000 us
|
||||
|
||||
/* Read PPS response */
|
||||
iso7816_read_data("PPS Response");
|
||||
|
||||
/* Switch core to higher speed */
|
||||
iso7816_setup_brg(512, 32, 4);
|
||||
|
||||
/* Test APDU */
|
||||
iso7816_put_char(0xA0);
|
||||
iso7816_put_char(0xC0);
|
||||
iso7816_put_char(0x00);
|
||||
iso7816_put_char(0x00);
|
||||
iso7816_put_char(0x1A);
|
||||
|
||||
wait(10000); // 100_000 us
|
||||
|
||||
iso7816_read_data("APDU");
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// USB integration
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
extern const struct usb_stack_descriptors app_stack_desc;
|
||||
|
||||
void
|
||||
usb_dfu_rt_cb_reboot(void)
|
||||
{
|
||||
/* Force re-enumeration */
|
||||
usb_disconnect();
|
||||
|
||||
/* Reboot to bootloader */
|
||||
reboot(1);
|
||||
}
|
||||
|
||||
static void
|
||||
serial_no_init()
|
||||
{
|
||||
uint8_t buf[8];
|
||||
char *id, *desc;
|
||||
int i;
|
||||
|
||||
flash_manuf_id(buf);
|
||||
printf("Flash Manufacturer : %s\n", hexstr(buf, 3, true));
|
||||
|
||||
flash_unique_id(buf);
|
||||
printf("Flash Unique ID : %s\n", hexstr(buf, 8, true));
|
||||
|
||||
/* Overwrite descriptor string */
|
||||
/* In theory in rodata ... but nothing is ro here */
|
||||
id = hexstr(buf, 8, false);
|
||||
desc = (char*)app_stack_desc.str[1];
|
||||
for (i=0; i<16; i++)
|
||||
desc[2 + (i << 1)] = id[i];
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Main
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void main()
|
||||
{
|
||||
int cmd = 0;
|
||||
bool card_pwr = false;
|
||||
bool card_rst = true;
|
||||
bool card_clk = false;
|
||||
|
||||
/* Init console IO */
|
||||
console_init();
|
||||
puts("Booting App image..\n");
|
||||
|
||||
/* LED */
|
||||
led_init();
|
||||
led_color(48, 96, 5);
|
||||
led_blink(true, 200, 1000);
|
||||
led_breathe(true, 100, 200);
|
||||
led_state(true);
|
||||
|
||||
/* Setup NCN8025 */
|
||||
ncn8025_init();
|
||||
|
||||
/* SPI */
|
||||
spi_init();
|
||||
|
||||
/* Setup USB */
|
||||
serial_no_init();
|
||||
usb_init(&app_stack_desc);
|
||||
usb_dfu_rt_init();
|
||||
usb_connect();
|
||||
|
||||
/* Main loop */
|
||||
while (1)
|
||||
{
|
||||
/* Prompt ? */
|
||||
if (cmd >= 0)
|
||||
printf("Command> ");
|
||||
|
||||
/* Poll for command */
|
||||
cmd = getchar_nowait();
|
||||
|
||||
if (cmd >= 0) {
|
||||
if (cmd > 32 && cmd < 127)
|
||||
putchar(cmd);
|
||||
putchar('\r');
|
||||
putchar('\n');
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
/* Select voltage */
|
||||
case 'q':
|
||||
printf("Voltage 1V8\n");
|
||||
ncn8025_set_vsel(1800);
|
||||
break;
|
||||
case 'w':
|
||||
printf("Voltage 3V\n");
|
||||
ncn8025_set_vsel(3000);
|
||||
break;
|
||||
case 'e':
|
||||
printf("Voltage 5V\n");
|
||||
ncn8025_set_vsel(5000);
|
||||
break;
|
||||
|
||||
/* Select clock div */
|
||||
case '1':
|
||||
printf("Divider 1:1 (20 MHz)\n");
|
||||
ncn8025_set_clk_div(1);
|
||||
break;
|
||||
case '2':
|
||||
printf("Divider 1:2 (10 MHz)\n");
|
||||
ncn8025_set_clk_div(2);
|
||||
break;
|
||||
case '4':
|
||||
printf("Divider 1:4 (5 MHz)\n");
|
||||
ncn8025_set_clk_div(4);
|
||||
break;
|
||||
case '8':
|
||||
printf("Divider 1:8 (2.5 MHz)\n");
|
||||
ncn8025_set_clk_div(8);
|
||||
break;
|
||||
|
||||
/* Toggle reset */
|
||||
case 'r':
|
||||
card_rst ^= 1;
|
||||
printf("Card reset: %s\n", card_rst ? "Asserted" : "not asserted");
|
||||
ncn8025_set_ll(card_pwr, card_rst, card_clk);
|
||||
break;
|
||||
|
||||
/* Toggle power */
|
||||
case 'p':
|
||||
card_pwr ^= 1;
|
||||
printf("Card power: %s\n", card_pwr ? "Enabled" : "Disabled");
|
||||
ncn8025_set_ll(card_pwr, card_rst, card_clk);
|
||||
break;
|
||||
|
||||
/* Toggle clock */
|
||||
case 'c':
|
||||
card_clk ^= 1;
|
||||
printf("Card clock: %s\n", card_clk ? "Active" : "Inactive");
|
||||
ncn8025_set_ll(card_pwr, card_rst, card_clk);
|
||||
break;
|
||||
|
||||
/* Probe int_n */
|
||||
case 'i':
|
||||
printf("INT_N: %s\n", ncn8025_get_int_n() ? "High" : "Low");
|
||||
break;
|
||||
|
||||
/* Power 'up' sequence */
|
||||
case 'u':
|
||||
ncn8025_power_up();
|
||||
break;
|
||||
|
||||
/* Power 'down' sequence */
|
||||
case 'd':
|
||||
ncn8025_power_down();
|
||||
break;
|
||||
|
||||
case 's':
|
||||
iso7816_debug();
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
iso7816_init(4);
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
iso7816_test();
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
printf("%08x\n", iso7816_get_char());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* USB poll */
|
||||
usb_poll();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* usb_desc_app.c
|
||||
*
|
||||
* Copyright (C) 2019-2022 Sylvain Munaut
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <no2usb/usb_proto.h>
|
||||
#include <no2usb/usb_dfu_proto.h>
|
||||
#include <no2usb/usb.h>
|
||||
|
||||
|
||||
static const struct {
|
||||
/* Configuration */
|
||||
struct usb_conf_desc conf;
|
||||
|
||||
/* DFU Runtime */
|
||||
struct {
|
||||
struct usb_intf_desc intf;
|
||||
struct usb_dfu_func_desc func;
|
||||
} __attribute__ ((packed)) dfu;
|
||||
} __attribute__ ((packed)) _app_conf_desc = {
|
||||
.conf = {
|
||||
.bLength = sizeof(struct usb_conf_desc),
|
||||
.bDescriptorType = USB_DT_CONF,
|
||||
.wTotalLength = sizeof(_app_conf_desc),
|
||||
.bNumInterfaces = 1,
|
||||
.bConfigurationValue = 1,
|
||||
.iConfiguration = 4,
|
||||
.bmAttributes = 0x80,
|
||||
.bMaxPower = 0x32, /* 100 mA */
|
||||
},
|
||||
.dfu = {
|
||||
.intf = {
|
||||
.bLength = sizeof(struct usb_intf_desc),
|
||||
.bDescriptorType = USB_DT_INTF,
|
||||
.bInterfaceNumber = 0,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 0,
|
||||
.bInterfaceClass = USB_CLS_APP_SPECIFIC,
|
||||
.bInterfaceSubClass = 0x01,
|
||||
.bInterfaceProtocol = 0x01,
|
||||
.iInterface = 5,
|
||||
},
|
||||
.func = {
|
||||
.bLength = sizeof(struct usb_dfu_func_desc),
|
||||
.bDescriptorType = USB_DFU_DT_FUNC,
|
||||
.bmAttributes = 0x0d,
|
||||
.wDetachTimeOut = 0,
|
||||
.wTransferSize = 4096,
|
||||
.bcdDFUVersion = 0x0101,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct usb_conf_desc * const _conf_desc_array[] = {
|
||||
&_app_conf_desc.conf,
|
||||
};
|
||||
|
||||
static const struct usb_dev_desc _dev_desc = {
|
||||
.bLength = sizeof(struct usb_dev_desc),
|
||||
.bDescriptorType = USB_DT_DEV,
|
||||
.bcdUSB = 0x0200,
|
||||
.bDeviceClass = 0,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.bMaxPacketSize0 = 64,
|
||||
.idVendor = 0x1d50,
|
||||
.idProduct = 0x6147,
|
||||
.bcdDevice = 0x0001, /* v0.1 */
|
||||
.iManufacturer = 2,
|
||||
.iProduct = 3,
|
||||
.iSerialNumber = 1,
|
||||
.bNumConfigurations = num_elem(_conf_desc_array),
|
||||
};
|
||||
|
||||
#include "usb_str_app.gen.h"
|
||||
|
||||
const struct usb_stack_descriptors app_stack_desc = {
|
||||
.dev = &_dev_desc,
|
||||
.conf = _conf_desc_array,
|
||||
.n_conf = num_elem(_conf_desc_array),
|
||||
.str = _str_desc_array,
|
||||
.n_str = num_elem(_str_desc_array),
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
0000000000000000
|
||||
osmocom
|
||||
ISO7816 USB SoC
|
||||
Main
|
||||
DFU runtime
|
Loading…
Reference in New Issue