iso7816-test/firmware/iso7816soc-test/fw_app.c

211 lines
3.8 KiB
C

/*
* 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 "config.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");
}
// ---------------------------------------------------------------------------
// 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();
/* 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;
}
}
}
}