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 <tnt@246tNt.com>
This commit is contained in:
Sylvain Munaut 2022-05-02 15:16:40 +02:00
parent 78ce68dd79
commit 3490e33343
4 changed files with 139 additions and 87 deletions

View File

@ -0,0 +1,104 @@
/*
* no2iso7816.c
*
* Copyright (C) 2022 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: MIT
*/
#include <stdio.h>
#include <stdint.h>
#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);
}

View File

@ -0,0 +1,16 @@
/*
* no2iso7816.h
*
* Copyright (C) 2022 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <stdint.h>
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);

View File

@ -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=\

View File

@ -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: