211 lines
3.8 KiB
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;
|
|
}
|
|
}
|
|
}
|
|
}
|