sim-card
/
osmo-cos
Archived
10
0
Fork 0

initial import of early start of a cc32rs512 COS project

This commit is contained in:
Harald Welte 2012-03-05 01:16:05 +01:00
commit 6942f3cf66
11 changed files with 752 additions and 0 deletions

28
include/memory.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef _MEMORY_H
#define _MEMORY_H
#define __arch_getb(a) (*(volatile unsigned char *)(a))
#define __arch_getw(a) (*(volatile unsigned short *)(a))
#define __arch_getl(a) (*(volatile unsigned int *)(a))
#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v))
#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
#define __raw_writeb(v,a) __arch_putb(v,a)
#define __raw_writew(v,a) __arch_putw(v,a)
#define __raw_writel(v,a) __arch_putl(v,a)
#define __raw_readb(a) __arch_getb(a)
#define __raw_readw(a) __arch_getw(a)
#define __raw_readl(a) __arch_getl(a)
#define writeb(v,a) __arch_putb(v,a)
#define writew(v,a) __arch_putw(v,a)
#define writel(v,a) __arch_putl(v,a)
#define readb(a) __arch_getb(a)
#define readw(a) __arch_getw(a)
#define readl(a) __arch_getl(a)
#endif /* _MEMORY_H */

32
src/Makefile Normal file
View File

@ -0,0 +1,32 @@
CROSS_COMPILE = arm-elf-
CC = $(CROSS_COMPILE)gcc
SIZE = $(CROSS_COMPILE)size
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OPTIMIZATION = -Os
ASM_OBJECTS = cc32/start.o
C_OBJECTS = main.o cc32/cc32_flcon.o cc32/cc32_irq.o cc32/iso7816_slave.o
CFLAGS = -Wall -ffunction-sections -fno-exceptions -nostartfiles -nostdlib #-mthumb
CFLAGS += -I../include
CFLAGS += -g $(OPTIMIZATION)
LDFLAGS = -g $(OPTIMIZATION) -nostartfiles -Wl,--gc-sections
target: $(ASM_OBJECTS) $(C_OBJECTS)
$(CC) $(LDFLAGS) -T"cc32/CC32RS512.lds" -o $@.elf $^
$(ASM_OBJECTS): %.o: %.s Makefile
$(CC) $(ASFLAGS) -c -o $@ $<
$(C_OBJECTS): %.o: %.c Makefile
$(CC) $(CFLAGS) -c -o $@ $<
clean:
@rm $(ASM_OBJECTS) $(C_OBJECTS) target.elf

126
src/cc32/CC32RS512.lds Normal file
View File

@ -0,0 +1,126 @@
/* Memory Definitions */
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(exceptions)
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000
RAM (rw) : ORIGIN = 0x000C0000, LENGTH = 0x00004000
STACK (rw) : ORIGIN = 0x000C4000, LENGTH = 0x00000000
}
/* Section Definitions */
SECTIONS
{
.text.exceptions : {
PROVIDE(exceptions = .);
KEEP(*(.text.exceptions))
*(.text.exceptions)
} > FLASH
/* first section is .text which is used for code */
.text : {
* (.text)
* (.glue_7)
* (.glue_7t)
. = ALIGN(4);
} >FLASH
PROVIDE(_text_start = ADDR(.text));
PROVIDE(_text_end = ADDR(.text) + SIZEOF(.text));
.ctors : {
LONG(SIZEOF(.ctors) / 4 - 2)
KEEP(*(SORT(.ctors)))
LONG(0)
} >FLASH
PROVIDE(_ctor_start = LOADADDR(.ctors));
PROVIDE(_ctor_end = LOADADDR(.ctors) + SIZEOF(.ctors));
.dtors : {
LONG(SIZEOF(.dtors) / 4 - 2)
KEEP(*(SORT(.dtors)))
LONG(0)
} >FLASH
PROVIDE(_dtor_start = LOADADDR(.dtors));
PROVIDE(_dtor_end = LOADADDR(.dtors) + SIZEOF(.dtors));
.rodata : {
* (.rodata*)
} > FLASH
PROVIDE(_rodata_start = ADDR(.rodata));
PROVIDE(_rodata_end = ADDR(.rodata) + SIZEOF(.rodata));
.got : {
. = ALIGN(4);
*(.got)
*(.got.plt) *(.igot.plt) *(.got) *(.igot)
. = ALIGN(4);
} > FLASH
PROVIDE(_got_start = ADDR(.got));
PROVIDE(_got_end = ADDR(.got) + SIZEOF(.got));
.data : {
_data = . ;
* (.vectram)
* (.data)
. = ALIGN(4);
} > RAM
PROVIDE(__data_start = LOADADDR(.data));
PROVIDE(__data_end = LOADADDR(.data) + SIZEOF(.data));
PROVIDE(_data_start = ADDR(.data));
PROVIDE(_data_end = ADDR(.data) + SIZEOF(.data));
/* .bss section which is used for uninitialized data */
.bss (NOLOAD) : {
. = ALIGN(4);
*(.bss)
. = ALIGN(4);
} > RAM
PROVIDE(__bss_start = ADDR(.bss));
PROVIDE(__bss_end = ADDR(.bss) + SIZEOF(.bss));
PROVIDE(_bss_start = __bss_start);
PROVIDE(_bss_end = __bss_end);
. = ALIGN(4);
_end = .;
PROVIDE(end = .);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

101
src/cc32/cc32_flcon.c Normal file
View File

@ -0,0 +1,101 @@
/*
* ChipCity CC32RS512 Flash controller driver
*
* Copyright (C) 2012 Harald Welte <laforge@gnumonks.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 or
* (at your option) version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <errno.h>
#include "cc32_irq.h"
#include "cc32_flcon.h"
#define CC32_FLCON_BASE 0x0f2000
enum cc32_flcon_reg {
FLCON = 0x00,
FLSDP1 = 0x04,
FLSDP2 = 0x08,
FLSTS = 0x0C,
FLBUF = 0x10,
};
#define FLCON_REG(x) (uint32_t *)((uint8_t *)CC32_FLCON_BASE + x)
int cc32_flash_erase(uint32_t offset, uint16_t page_size)
{
switch (page_size) {
case 256:
*FLCON_REG(FLCON) = (1 << 3);
break;
case 512:
*FLCON_REG(FLCON) = (0 << 3);
break;
default:
return -EINVAL;
}
/* if we program/erase the first page, we have to disable the interrupt */
if (offset < page_size)
cc32_irq_disable(IRQ_FLCON);
/* clear all flags */
*FLCON_REG(FLSTS) = 3;
*FLCON_REG(FLSDP1) = 0x55;
*FLCON_REG(FLSDP2) = 0xAA;
*(uint32_t *)offset = 0xFF;
while (!(*FLCON_REG(FLSTS) & 1)) {}
return 0;
}
int cc32_flash_program(uint32_t offset, uint16_t page_size, uint32_t *buffer)
{
switch (page_size) {
case 256:
*FLCON_REG(FLCON) = (1 << 3);
break;
case 512:
*FLCON_REG(FLCON) = (0 << 3);
break;
default:
return -EINVAL;
}
/* if we program/erase the first page, we have to disable the interrupt */
if (offset < page_size)
cc32_irq_disable(IRQ_FLCON);
/* clear all flags */
*FLCON_REG(FLSTS) = 3;
*FLCON_REG(FLBUF) = offset;
*FLCON_REG(FLSDP1) = 0xAA;
*FLCON_REG(FLSDP2) = 0x55;
*(uint32_t *)offset = 0x00;
while (!(*FLCON_REG(FLSTS) & 1)) {}
/* clear flag */
*FLCON_REG(FLSTS) |= 1;
return 0;
}

3
src/cc32/cc32_flcon.h Normal file
View File

@ -0,0 +1,3 @@
int cc32_flash_erase(uint32_t offset, uint16_t page_size);
int cc32_flash_program(uint32_t offset, uint16_t page_size, uint32_t *buffer);

40
src/cc32/cc32_irq.c Normal file
View File

@ -0,0 +1,40 @@
#include "cc32_irq.h"
#define CC32_SYSC_BASE 0x0F0000
enum cc32_sysc_reg {
SCCM0 = 0x00,
SCSYS = 0x04,
SCCKOUT = 0x20,
SCRSTFLG = 0x28,
SCRSTEN = 0x2C,
SCSFTRST = 0x30,
SCRSTCON0 = 0x34,
SCRSTCON4 = 0x38,
SCSLEEP = 0x3C,
SCGCON = 0x40,
SCINTSTS = 0x44,
SCINTEN = 0x48,
SCGINT0 = 0x5C,
SCGLEV = 0x64,
SCWUT = 0x68,
SCCM4 = 0x7C,
};
#define SYSC_REG(x) (uint32_t *)((uint8_t *)CC32_SYSC_BASE + x)
void cc32_irq_enable(enum cc32_irq irq)
{
*SYSC_REG(SCINTEN) |= (1 << irq);
}
void cc32_irq_disable(enum cc32_irq irq)
{
*SYSC_REG(SCINTEN) &= ~(1 << irq);
}
void cc32_irq_register(enum cc32_irq irq, void (*handler)(enum cc32_irq irq))
{
/* FIXME */
}

28
src/cc32/cc32_irq.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef _CC32_IRQ_H
#define _CC32_IRQ_H
#include <stdint.h>
enum cc32_irq {
IRQ_TIMER0 = 2,
IRQ_TIMER1 = 3,
IRQ_TIMER2 = 4,
IRQ_FLCON = 6,
IRQ_UART = 8,
IRQ_GPIO = 11,
IRQ_SPI = 13,
IRQ_SCU = 15,
IRQ_MCU = 17,
IRQ_DES = 19,
IRQ_AES = 20,
IRQ_DMA = 22,
IRQ_ISO7816_MST = 26,
IRQ_WUT = 27,
IRQ_RSA = 28,
};
void cc32_irq_enable(enum cc32_irq irq);
void cc32_irq_disable(enum cc32_irq irq);
void cc32_irq_register(enum cc32_irq irq, void (*handler)(enum cc32_irq irq));
#endif

128
src/cc32/iso7816_slave.c Normal file
View File

@ -0,0 +1,128 @@
#include <stdint.h>
#include <memory.h>
#include <errno.h>
#include "cc32_irq.h"
enum iso_slave_reg {
ISOCON = 0x00,
ISOCON1 = 0x04,
ISOCON2 = 0x08,
ISOSTS = 0x0c,
ISOBRC = 0x10,
ISOBUF = 0x14,
ISODIO = 0x18,
ISOMSK = 0x1c,
ISODMACON = 0x30,
ISODMASTS = 0x34,
ISODMABFAD = 0x38,
ISODMABFLEN = 0x3c,
ISODMABFPT = 0x40,
ISODMAMSK = 0x44,
ISOTCON = 0x50,
ISOTDAT = 0x54,
ISOTRLD = 0x58,
ISOTMSK = 0x5c,
ISONULL = 0x60,
};
#define CC32_BASE_UART 0x0F8800
#define UART_REG(n) (CC32_BASE_UART+(n))
#define ISOCON_TR (1 << 5)
#define ISOCON_TACT (1 << 4)
#define ISOSTS_TBE (1 << 0)
#define ISOSTS_RBF (1 << 1)
#define ISOSTS_PE (1 << 2)
#define ISOSTS_OE (1 << 3)
#define ISOCON2_SBIT (1 << 7)
#define ISOBRC_DI(x) ((x) & 0xf)
#define ISOBRC_FI(x) (((x) & 0xf) << 4)
struct iso_slave_state {
uint8_t fi;
uint8_t di;
};
static struct iso_slave_state iss;
/* will be called from FIQ mode */
static void slave_irq(uint8_t irq)
{
//FIXME
}
int iso7816_slave_fi_di(uint8_t fi, uint8_t di)
{
writel(ISOBRC_DI(di) | ISOBRC_FI(fi), UART_REG(ISOBRC));
iss.fi = fi;
iss.di = di;
return 0;
}
int iso7816_slave_tx_ch(uint8_t ch)
{
writel(ISOCON_TR, UART_REG(ISOCON));
writel(ch, UART_REG(ISOBUF));
if (readl(UART_REG(ISOSTS)) & ISOSTS_PE) {
writel(ISOSTS_PE, UART_REG(ISOSTS));
return -EIO;
}
while (readl(UART_REG(ISOCON)) & ISOCON_TACT) { }
return 0;
}
int iso7816_slave_tx5(const uint8_t *data)
{
iso7816_slave_tx_ch(data[0]);
iso7816_slave_tx_ch(data[1]);
iso7816_slave_tx_ch(data[2]);
iso7816_slave_tx_ch(data[3]);
iso7816_slave_tx_ch(data[4]);
return 0;
}
int iso7816_slave_tx(const uint8_t *data, uint8_t len)
{
int i;
/* FIXME: fiq/dma ? */
writel(ISOCON_TR, UART_REG(ISOCON));
for (i = 0; i < len; i++) {
if (iso7816_slave_tx_ch(data[i]) < 0)
return -EIO;
}
return i;
}
int iso7816_slave_init(void)
{
/* receive mode */
writel(0, UART_REG(ISOCON));
/* up to 6 times re-transmission */
writel(6 | ISOCON2_SBIT, UART_REG(ISOCON1));
/* T=0 mode */
writel(0, UART_REG(ISOCON2));
/* clear status bits, if any */
writel(ISOSTS_PE|ISOSTS_OE, UART_REG(ISOSTS));
/* disable SBIT interrupt */
writel(ISOCON2_SBIT, UART_REG(ISOMSK));
/* Initial Fi/Di setting */
iso7816_slave_fi_di(1, 1);
cc32_irq_register(IRQ_UART, &slave_irq);
//cc32_irq_enable(IRQ_UART);
return 0;
}

9
src/cc32/iso7816_slave.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef _ISO7816_SLAVE_H
#define _ISO7816_SLAVE_H
int iso7816_slave_init(void);
int iso7816_slave_tx(const uint8_t *data, uint8_t len);
int iso7816_slave_tx_ch(uint8_t ch);
int iso7816_slave_tx5(const uint8_t *data);
#endif

215
src/cc32/start.s Normal file
View File

@ -0,0 +1,215 @@
/* low-level startup outines for CC32RS512 / ARM7TDMI
* (C) 2006-2012 by Harald Welte <hwelte@hmw-consulting.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/* Configurable values */
.equ ROM_Start, 0x0 /* Base address of ROM(flash) */
.equ RAM_Start, 0x0C0000 /* Base address of RAM */
.equ RAM_Size, 0x4000 /* For CC32RS512 */
.equ SVC_Stack_Size, 128
.equ IRQ_Stack_Size, 128
.equ FIQ_Stack_Size, 128
.equ ABT_Stack_Size, 128
.equ SYS_Stack_Size, 256
/* Computed Values */
.equ FIQ_Stack, RAM_Limit
.equ IRQ_Stack, FIQ_Stack-FIQ_Stack_Size
.equ ABT_Stack, IRQ_Stack-IRQ_Stack_Size
.equ SVC_Stack, ABT_Stack-ABT_Stack_Size
.equ SYS_Stack, SVC_Stack-SVC_Stack_Size
.equ RAM_Limit, RAM_Start+RAM_Size
/* Exception Vectors in RAM */
.text
.arm
.section .vectram, "ax"
#;------------------------------------------------------------------------------
#;- Section Definition
#;-----------------
#;- Section
#;- .internal_ram_top Top_Stack: used by the cstartup for vector initalisation
#;- management defined by ld and affect from ldscript
#;------------------------------------------------------------------------------
.section .internal_ram_top
.code 32
.align 0
.global Top_Stack
Top_Stack:
/*------------------------------------------------------------------------------
*- Area Definition
*------------------------------------------------------------------------------
* .text is used instead of .section .text so it works with arm-aout too. */
.section .text.exceptions
.text
.global exceptions
exceptions:
/*------------------------------------------------------------------------------
//*- Exception vectors
//*--------------------
//*- These vectors can be read at address 0 or at RAM address
//*- They ABSOLUTELY requires to be in relative addresssing mode in order to
//*- guarantee a valid jump. For the moment, all are just looping.
//*- If an exception occurs before remap, this would result in an infinite loop.
//*- To ensure if a exeption occurs before start application to infinite loop.
//*------------------------------------------------------------------------------*/
B InitReset /* 0x00 Reset handler */
undefvec:
B undefvec /* 0x04 Undefined Instruction */
swivec:
B swivec /* 0x08 Software Interrupt */
pabtvec:
B pabtvec /* 0x0C Prefetch Abort */
dabtvec:
b dabtvec /* 0x10 Data Abort */
rsvdvec:
b rsvdvec /* 0x14 reserved */
irqvec:
b IRQ_Handler_Entry /* 0x18 IRQ */
fiqvec:
b FIQ_Handler_Entry /* 0x1c FIQ */
.global IRQ_Handler_Entry
.func IRQ_Handler_Entry
FIQ_Handler_Entry:
b FIQ_Handler_Entry
/*- Save and r0 in FIQ_Register */
/* FIXME: ISO7816 Slave driver */
/*- Restore the Program Counter using the LR_fiq directly in the PC */
subs pc, lr, #4
IRQ_Handler_Entry:
b IRQ_Handler_Entry
/*- Manage Exception Entry */
/*- Adjust and save LR_irq in IRQ stack */
sub lr, lr, #4
stmfd sp!, {lr}
/* FIXME */
/*- Restore adjusted LR_irq from IRQ stack directly in the PC */
ldmia sp!, {pc}^
.size IRQ_Handler_Entry, . - IRQ_Handler_Entry
.endfunc
.align 0
.RAM_TOP:
.word Top_Stack
.global _startup
.func _startup
InitReset:
.equ MPUDisable, 0xfffffffe
/* Disable memory protection unit */
mrc p15, 0, r0, c1, c0, 0
and r0, r0, #MPUDisable
mcr p15, 0, r0, c1, c0, 0
/*------------------------------------------------------------------------------
//*- Top of Stack Definition
//*-------------------------
//*- Interrupt and Supervisor Stack are located at the top of internal memory in
//*- order to speed the exception handling context saving and restoring.
//*- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory.
//*------------------------------------------------------------------------------*/
.EQU ARM_MODE_FIQ, 0x11
.EQU ARM_MODE_IRQ, 0x12
.EQU ARM_MODE_SVC, 0x13
.EQU ARM_MODE_ABT, 0x17
.EQU ARM_MODE_SYS, 0x1F
.EQU I_BIT, 0x80
.EQU F_BIT, 0x40
/*------------------------------------------------------------------------------
//*- Setup the stack for each mode
//*-------------------------------*/
ldr r13, =FIQ_Stack
mov r0, r13
/*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
mov r13, r0
sub r0, r0, #FIQ_Stack_Size
/*- Set up Interrupt Mode and set IRQ Mode Stack*/
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
mov r13, r0 /* Init stack IRQ */
sub r0, r0, #IRQ_Stack_Size
/*- Set up Abort Mode and set Supervisor Mode Stack*/
msr CPSR_c, #ARM_MODE_ABT | I_BIT | F_BIT
mov r13, r0 /* Init stack Sup */
sub r0, r0, #ABT_Stack_Size
/*- Set up Supervisor Mode and set Supervisor Mode Stack*/
msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT
mov r13, r0 /* Init stack Sup */
sub r0, r0, #SVC_Stack_Size
/*- Set up System Mode and Enable Interrupts and FIQ */
msr CPSR_c, #ARM_MODE_SYS
mov r13, r0
# Clear .bss section (Zero init)
MOV R0, #0
LDR R1, =__bss_start
LDR R2, =__bss_end
LoopZI: CMP R1, R2
STRLO R0, [R1], #4
BLO LoopZI
/* prepare c function call to main */
mov r0, #0 /* argc = 0 */
ldr lr, =exit
ldr r10, =main
bx r10
.size InitReset,.-InitReset
.endfunc
/* "exit" dummy to avoid sbrk write read etc. needed by the newlib default "exit" */
.global exit
.func exit
exit:
b .
.size exit, . - exit
.endfunc
.end

42
src/main.c Normal file
View File

@ -0,0 +1,42 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "cc32/cc32_flcon.h"
#include "cc32/cc32_irq.h"
#include "cc32/iso7816_slave.h"
#define BASE_ISO7816_SLAVE 0x0F8800
const uint8_t atr[] = "ThisIsNotAnATR\n";
int main(int argc, char **argv)
{
/* we generally don't want interrupts yet */
cc32_irq_disable(IRQ_FLCON | IRQ_UART);
char *atr2 = "12345";
iso7816_slave_init();
iso7816_slave_tx_ch('H');
iso7816_slave_tx_ch('W');
iso7816_slave_tx_ch('H');
iso7816_slave_tx_ch('W');
//iso7816_slave_tx(atr2, 5);
iso7816_slave_tx_ch(atr2[0]);
iso7816_slave_tx_ch(atr2[1]);
iso7816_slave_tx_ch(atr2[2]);
iso7816_slave_tx_ch(atr2[3]);
iso7816_slave_tx_ch(atr2[4]);
iso7816_slave_tx5(atr2);
if (iso7816_slave_tx(atr, sizeof(atr)) < 0)
cc32_flash_erase(10*256, 256);
while (1) {
//cc32_flash_erase(10*256, 256);
}
}