aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-03-05 01:16:05 +0100
committerHarald Welte <laforge@gnumonks.org>2012-03-05 01:16:05 +0100
commit6942f3cf662237048ef6ca4007ea345ebe88179e (patch)
tree34aaf11a52c34ce5b05b888ce3a7af623935d8f8 /src
initial import of early start of a cc32rs512 COS project
Diffstat (limited to 'src')
-rw-r--r--src/Makefile32
-rw-r--r--src/cc32/CC32RS512.lds126
-rw-r--r--src/cc32/cc32_flcon.c101
-rw-r--r--src/cc32/cc32_flcon.h3
-rw-r--r--src/cc32/cc32_irq.c40
-rw-r--r--src/cc32/cc32_irq.h28
-rw-r--r--src/cc32/iso7816_slave.c128
-rw-r--r--src/cc32/iso7816_slave.h9
-rw-r--r--src/cc32/start.s215
-rw-r--r--src/main.c42
10 files changed, 724 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..b51fc78
--- /dev/null
+++ b/src/Makefile
@@ -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
diff --git a/src/cc32/CC32RS512.lds b/src/cc32/CC32RS512.lds
new file mode 100644
index 0000000..cd5cfeb
--- /dev/null
+++ b/src/cc32/CC32RS512.lds
@@ -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) }
+
+}
diff --git a/src/cc32/cc32_flcon.c b/src/cc32/cc32_flcon.c
new file mode 100644
index 0000000..fc9ff1c
--- /dev/null
+++ b/src/cc32/cc32_flcon.c
@@ -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;
+}
diff --git a/src/cc32/cc32_flcon.h b/src/cc32/cc32_flcon.h
new file mode 100644
index 0000000..f7a7ca1
--- /dev/null
+++ b/src/cc32/cc32_flcon.h
@@ -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);
diff --git a/src/cc32/cc32_irq.c b/src/cc32/cc32_irq.c
new file mode 100644
index 0000000..a382409
--- /dev/null
+++ b/src/cc32/cc32_irq.c
@@ -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 */
+}
diff --git a/src/cc32/cc32_irq.h b/src/cc32/cc32_irq.h
new file mode 100644
index 0000000..062455a
--- /dev/null
+++ b/src/cc32/cc32_irq.h
@@ -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
diff --git a/src/cc32/iso7816_slave.c b/src/cc32/iso7816_slave.c
new file mode 100644
index 0000000..3b21eef
--- /dev/null
+++ b/src/cc32/iso7816_slave.c
@@ -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;
+}
diff --git a/src/cc32/iso7816_slave.h b/src/cc32/iso7816_slave.h
new file mode 100644
index 0000000..56f2f3a
--- /dev/null
+++ b/src/cc32/iso7816_slave.h
@@ -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
diff --git a/src/cc32/start.s b/src/cc32/start.s
new file mode 100644
index 0000000..51dab11
--- /dev/null
+++ b/src/cc32/start.s
@@ -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
+
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..9e769cc
--- /dev/null
+++ b/src/main.c
@@ -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);
+ }
+}