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:
parent
78ce68dd79
commit
3490e33343
|
@ -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);
|
||||
}
|
|
@ -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);
|
|
@ -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=\
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue