From 3490e333432101e436f33200e5722f21873e0a0b Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Mon, 2 May 2022 15:16:40 +0200 Subject: [PATCH] firmware: Start a "no2iso7816" driver base in common/ Really basic but it already allows to share some code between projects. Signed-off-by: Sylvain Munaut --- firmware/common/no2iso7816.c | 104 ++++++++++++++++++++++++++++++ firmware/common/no2iso7816.h | 16 +++++ firmware/iso7816soc-test/Makefile | 2 + firmware/iso7816soc-test/fw_app.c | 104 +++++------------------------- 4 files changed, 139 insertions(+), 87 deletions(-) create mode 100644 firmware/common/no2iso7816.c create mode 100644 firmware/common/no2iso7816.h diff --git a/firmware/common/no2iso7816.c b/firmware/common/no2iso7816.c new file mode 100644 index 0000000..c20121d --- /dev/null +++ b/firmware/common/no2iso7816.c @@ -0,0 +1,104 @@ +/* + * no2iso7816.c + * + * Copyright (C) 2022 Sylvain Munaut + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#include "config.h" + + +struct wb_no2iso7816 { + uint32_t csr; + uint32_t _rsvd1; + uint32_t data; + uint32_t _rsvd2; + uint32_t misc; + uint32_t wt; + uint32_t brg_rate; + uint32_t brg_phase; +} __attribute__((packed,aligned(4))); + +#define NO2ISO7816_CSR_WT_CE (1 << 16) +#define NO2ISO7816_CSR_TX_FIFO_EMPTY (1 << 15) +#define NO2ISO7816_CSR_TX_FIFO_FULL (1 << 14) +#define NO2ISO7816_CSR_TX_FIFO_OVER (1 << 13) +#define NO2ISO7816_CSR_TX_FIFO_CLR (1 << 12) +#define NO2ISO7816_CSR_TX_ERR_PARITY (1 << 11) +#define NO2ISO7816_CSR_TX_ENA (1 << 8) +#define NO2ISO7816_CSR_RX_FIFO_EMPTY (1 << 7) +#define NO2ISO7816_CSR_RX_FIFO_FULL (1 << 6) +#define NO2ISO7816_CSR_RX_FIFO_OVER (1 << 5) +#define NO2ISO7816_CSR_RX_FIFO_CLR (1 << 4) +#define NO2ISO7816_CSR_RX_ERR_PARITY (1 << 3) +#define NO2ISO7816_CSR_RX_ERR_FRAME (1 << 2) +#define NO2ISO7816_CSR_RX_ENA (1 << 0) + +#define NO2ISO7816_MISC_TX_GT(n) (((n) & 0xfff) << 20) +#define NO2ISO7816_MISC_TX_RT(n) ((((n)-1) & 0x7) << 16) +#define NO2ISO7816_MISC_TX_EXC_IRQ (1 << 10) +#define NO2ISO7816_MISC_TX_FIFO_IRQ (1 << 9) +#define NO2ISO7816_MISC_TX_NAK_ENA (1 << 8) +#define NO2ISO7816_MISC_RX_EXC_IRQ (1 << 2) +#define NO2ISO7816_MISC_RX_FIFO_IRQ (1 << 1) +#define NO2ISO7816_MISC_RX_NAK_ENA (1 << 0) + +static volatile struct wb_no2iso7816 * const sc_regs = (void*)(ISO7816_BASE); + + +void +iso7816_setup_brg(int F, int D, int div) +{ + F *= div; + sc_regs->brg_rate = (F << 16) | D; + sc_regs->brg_phase = (F >> 1) - (D << 2); +} + +void +iso7816_init(int div) +{ + /* Core config / reset */ + sc_regs->misc = + NO2ISO7816_MISC_TX_GT(0) | + NO2ISO7816_MISC_TX_RT(3) | + NO2ISO7816_MISC_TX_NAK_ENA | + NO2ISO7816_MISC_RX_NAK_ENA; + + sc_regs->csr = ( + NO2ISO7816_CSR_TX_FIFO_OVER | + NO2ISO7816_CSR_TX_FIFO_CLR | + NO2ISO7816_CSR_TX_ERR_PARITY | + NO2ISO7816_CSR_TX_ENA | + NO2ISO7816_CSR_RX_FIFO_OVER | + NO2ISO7816_CSR_RX_FIFO_CLR | + NO2ISO7816_CSR_RX_ERR_PARITY | + NO2ISO7816_CSR_RX_ERR_FRAME | + NO2ISO7816_CSR_RX_ENA | + 0 + ); + + /* Config BRG for default bitrate */ + iso7816_setup_brg(372, 1, div); +} + +void +iso7816_put_char(uint8_t c) +{ + sc_regs->data = c; +} + +int +iso7816_get_char(void) +{ + uint32_t v = sc_regs->data; + return (v & (1 << 31)) ? -1 : v; +} + +void +iso7816_debug(void) +{ + printf("CSR: %08lx\n", sc_regs->csr); +} diff --git a/firmware/common/no2iso7816.h b/firmware/common/no2iso7816.h new file mode 100644 index 0000000..41d7649 --- /dev/null +++ b/firmware/common/no2iso7816.h @@ -0,0 +1,16 @@ +/* + * no2iso7816.h + * + * Copyright (C) 2022 Sylvain Munaut + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include + +void iso7816_setup_brg(int F, int D, int div); +void iso7816_init(int div); +void iso7816_put_char(uint8_t c); +int iso7816_get_char(void); +void iso7816_debug(void); diff --git a/firmware/iso7816soc-test/Makefile b/firmware/iso7816soc-test/Makefile index dbdaf4f..d5696d5 100644 --- a/firmware/iso7816soc-test/Makefile +++ b/firmware/iso7816soc-test/Makefile @@ -13,6 +13,7 @@ HEADERS_common=$(addprefix ../common/, \ led.h \ mini-printf.h \ misc.h \ + no2iso7816.h \ ) SOURCES_common=$(addprefix ../common/, \ @@ -21,6 +22,7 @@ SOURCES_common=$(addprefix ../common/, \ led.c \ mini-printf.c \ misc.c \ + no2iso7816.c \ ) HEADERS_app=\ diff --git a/firmware/iso7816soc-test/fw_app.c b/firmware/iso7816soc-test/fw_app.c index c52ccae..c5ac084 100644 --- a/firmware/iso7816soc-test/fw_app.c +++ b/firmware/iso7816soc-test/fw_app.c @@ -13,92 +13,22 @@ #include "led.h" #include "mini-printf.h" #include "misc.h" +#include "no2iso7816.h" #include "config.h" // --------------------------------------------------------------------------- -// ISO7816 core +// ISO7816 test // --------------------------------------------------------------------------- -struct wb_no2iso7816 { - uint32_t csr; - uint32_t _rsvd1; - uint32_t data; - uint32_t _rsvd2; - uint32_t misc; - uint32_t wt; - uint32_t brg_rate; - uint32_t brg_phase; -} __attribute__((packed,aligned(4))); - -#define NO2ISO7816_CSR_WT_CE (1 << 16) -#define NO2ISO7816_CSR_TX_FIFO_EMPTY (1 << 15) -#define NO2ISO7816_CSR_TX_FIFO_FULL (1 << 14) -#define NO2ISO7816_CSR_TX_FIFO_OVER (1 << 13) -#define NO2ISO7816_CSR_TX_FIFO_CLR (1 << 12) -#define NO2ISO7816_CSR_TX_ERR_PARITY (1 << 11) -#define NO2ISO7816_CSR_TX_ENA (1 << 8) -#define NO2ISO7816_CSR_RX_FIFO_EMPTY (1 << 7) -#define NO2ISO7816_CSR_RX_FIFO_FULL (1 << 6) -#define NO2ISO7816_CSR_RX_FIFO_OVER (1 << 5) -#define NO2ISO7816_CSR_RX_FIFO_CLR (1 << 4) -#define NO2ISO7816_CSR_RX_ERR_PARITY (1 << 3) -#define NO2ISO7816_CSR_RX_ERR_FRAME (1 << 2) -#define NO2ISO7816_CSR_RX_ENA (1 << 0) - -#define NO2ISO7816_MISC_TX_GT(n) (((n) & 0xfff) << 20) -#define NO2ISO7816_MISC_TX_RT(n) ((((n)-1) & 0x7) << 16) -#define NO2ISO7816_MISC_TX_EXC_IRQ (1 << 10) -#define NO2ISO7816_MISC_TX_FIFO_IRQ (1 << 9) -#define NO2ISO7816_MISC_TX_NAK_ENA (1 << 8) -#define NO2ISO7816_MISC_RX_EXC_IRQ (1 << 2) -#define NO2ISO7816_MISC_RX_FIFO_IRQ (1 << 1) -#define NO2ISO7816_MISC_RX_NAK_ENA (1 << 0) - -static volatile struct wb_no2iso7816 * const sc_regs = (void*)(ISO7816_BASE); - - -static void -iso7816_setup_brg(int F, int D, int div) -{ - F *= div; - sc_regs->brg_rate = (F << 16) | D; - sc_regs->brg_phase = (F >> 1) - (D << 2); -} - -static void -iso7816_setup() -{ - iso7816_setup_brg(372, 1, 4); - - sc_regs->misc = - NO2ISO7816_MISC_TX_GT(0) | - NO2ISO7816_MISC_TX_RT(3) | - NO2ISO7816_MISC_TX_NAK_ENA | - NO2ISO7816_MISC_RX_NAK_ENA; - - sc_regs->csr = ( - NO2ISO7816_CSR_TX_FIFO_OVER | - NO2ISO7816_CSR_TX_FIFO_CLR | - NO2ISO7816_CSR_TX_ERR_PARITY | - NO2ISO7816_CSR_TX_ENA | - NO2ISO7816_CSR_RX_FIFO_OVER | - NO2ISO7816_CSR_RX_FIFO_CLR | - NO2ISO7816_CSR_RX_ERR_PARITY | - NO2ISO7816_CSR_RX_ERR_FRAME | - NO2ISO7816_CSR_RX_ENA | - 0 - ); -} - static void iso7816_read_data(const char *desc) { printf("%s :", desc); while (1) { - uint32_t v = sc_regs->data; - if (v & (1<<31)) + int v = iso7816_get_char(); + if (v < 0) break; printf(" %02x", v); } @@ -109,7 +39,7 @@ static void iso7816_test() { /* Setup core with default params */ - iso7816_setup(); + iso7816_init(4); /* Power up card */ ncn8025_power_up(); @@ -119,10 +49,10 @@ iso7816_test() iso7816_read_data("ATR"); /* Send PPS Request */ - sc_regs->data = 0xff; // PPPS - sc_regs->data = 0x10; // PPS0 - sc_regs->data = 0x96; // PPS1 - sc_regs->data = 0x79; // PCK + 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 @@ -133,11 +63,11 @@ iso7816_test() iso7816_setup_brg(512, 32, 4); /* Test APDU */ - sc_regs->data = 0xA0; - sc_regs->data = 0xC0; - sc_regs->data = 0x00; - sc_regs->data = 0x00; - sc_regs->data = 0x1A; + 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 @@ -257,11 +187,11 @@ void main() break; case 's': - printf("CSR: %08x\n", sc_regs->csr); + iso7816_debug(); break; case 'S': - iso7816_setup(); + iso7816_init(4); break; case 'T': @@ -269,7 +199,7 @@ void main() break; case 'R': - printf("%08x\n", sc_regs->data); + printf("%08x\n", iso7816_get_char()); break; default: