diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..662f6d5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.vscode/
+bin/
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..4d5293e
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "lib/usart"]
+	path = lib/usart
+	url = git@git.chch.tech:avr/usart.git
diff --git a/lib/usart/.gitignore b/lib/usart/.gitignore
new file mode 100644
index 0000000..662f6d5
--- /dev/null
+++ b/lib/usart/.gitignore
@@ -0,0 +1,2 @@
+.vscode/
+bin/
diff --git a/lib/usart/LICENSE b/lib/usart/LICENSE
new file mode 100644
index 0000000..204b93d
--- /dev/null
+++ b/lib/usart/LICENSE
@@ -0,0 +1,19 @@
+MIT License Copyright (c) <year> <copyright holders>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
+OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/lib/usart/README.md b/lib/usart/README.md
new file mode 100644
index 0000000..56d1233
--- /dev/null
+++ b/lib/usart/README.md
@@ -0,0 +1,2 @@
+# usart
+
diff --git a/lib/usart/makefile b/lib/usart/makefile
new file mode 100644
index 0000000..cfdf81e
--- /dev/null
+++ b/lib/usart/makefile
@@ -0,0 +1,28 @@
+MCU=atmega32
+F_CPU=8000000
+PROG=dragon_jtag
+PORT?=/dev/ttyUSB0
+CC=avr-g++
+OBJCOPY=avr-objcopy
+CFLAGS=-Wall -g  -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
+TARGET=main
+SRCS= src/*.cpp test/main.cpp 
+
+all: build flash
+
+build:
+	${CC} ${CFLAGS} -o bin/${TARGET}.bin  ${SRCS}
+	${CC} ${CFLAGS} -o bin/${TARGET}.elf  ${SRCS}
+	${OBJCOPY} -j .text -j .data -O ihex bin/${TARGET}.bin bin/${TARGET}.hex
+
+flash:
+	avrdude -p ${MCU} -c ${PROG}  -U flash:w:bin/main.hex
+
+clean:
+	rm -f bin/* 
+
+term: 
+	python3 term.py
+
+avarice:
+	avarice --program --file bin/main.elf --part atmega32 --dragon :4242
diff --git a/lib/usart/src/usart.cpp b/lib/usart/src/usart.cpp
new file mode 100644
index 0000000..4758601
--- /dev/null
+++ b/lib/usart/src/usart.cpp
@@ -0,0 +1,65 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "usart.h"
+
+namespace usart
+{
+    namespace {
+        static FILE mystdout;
+    }
+    
+    void init( unsigned long baud) {
+        fdev_setup_stream(&mystdout, put_printf, NULL, _FDEV_SETUP_WRITE);
+        stdout = &mystdout;
+        const unsigned int ubrr =  F_CPU/8/baud-1;
+
+        /*Set baud rate */
+        
+        
+        #if defined __AVR_ATmega328P__
+            UBRR0H = (unsigned char)(ubrr>>8);
+            UBRR0L = (unsigned char)ubrr;
+            UCSR0A |= (1<<U2X0);
+            //Enable receiver and transmitter 
+            UCSR0B = (1<<RXEN0)|(1<<TXEN0);
+            //UCSRB |= (1<< RXCIE)|(1<<TXCIE);
+            /* Set frame format: 8data, 2stop bit */
+            UCSR0C = (1<<USBS0)|(3<<UCSZ00);
+        #elif defined  __AVR_ATmega32__ || defined __AVR_ATmega16__
+            UBRRH = (unsigned char)(ubrr>>8);
+            UBRRL = (unsigned char)ubrr;
+            UCSRA |= (1<<U2X);
+            //Enable receiver and transmitter 
+            UCSRB = (1<<RXEN)|(1<<TXEN);
+            //UCSRB |= (1<< RXCIE)|(1<<TXCIE);
+            /* Set frame format: 8data, 2stop bit */
+            UCSRC = (1 << URSEL)|(3<<UCSZ0);
+        #endif
+    
+    }
+
+    void put(char data) {
+        #if defined __AVR_ATmega328P__
+            while ( !( UCSR0A & (1<<UDRE0)) ); UDR0 = data;
+        #elif defined  __AVR_ATmega32__ || defined __AVR_ATmega16__
+            while ( !( UCSRA & (1<<UDRE)) ); UDR = data;
+        #endif
+        
+       
+    }
+
+    char get( void ) {
+        #if defined __AVR_ATmega328P__
+            while ( !(UCSR0A & (1<<RXC0)) ); return UDR0;
+        #elif defined  __AVR_ATmega32__ || defined __AVR_ATmega16__
+            while ( !(UCSRA & (1<<RXC)) ); return UDR;
+        #endif
+    }       
+   
+    int put_printf(char var, FILE *stream) {
+        put(var);
+        return 0;
+    }
+} // namespace usart
+
+
diff --git a/lib/usart/src/usart.h b/lib/usart/src/usart.h
new file mode 100644
index 0000000..ffad848
--- /dev/null
+++ b/lib/usart/src/usart.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <stdio.h>
+
+namespace usart
+{
+    void init(unsigned long baud);
+    void put(char data );
+    char get();
+    int put_printf(char var, FILE *stream);
+} // namespace usart
+
+
+
diff --git a/lib/usart/term.py b/lib/usart/term.py
new file mode 100644
index 0000000..a6c0b3d
--- /dev/null
+++ b/lib/usart/term.py
@@ -0,0 +1,13 @@
+import serial
+from time import sleep
+
+with serial.Serial('/dev/ttyUSB0', 9600, timeout=1) as ser:
+    ser.write(b'a')
+    while True:
+        x = ser.read()          # read one byte
+        if x != b'':
+            pass
+        print(x.decode('utf'))
+        #ser.write(b'a')
+        #print(ser.read())
+        sleep(1)
\ No newline at end of file
diff --git a/lib/usart/test/main.cpp b/lib/usart/test/main.cpp
new file mode 100644
index 0000000..8d72b75
--- /dev/null
+++ b/lib/usart/test/main.cpp
@@ -0,0 +1,21 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "../src/usart.h"
+#include <util/delay.h>
+
+
+
+
+
+int main (void) {
+	DDRD |= (1<<PD3)|(1<<PD4)|(1<<PD5);
+	usart::init(9600);
+	for (;;) {// Loop forever
+		usart::put('A');
+		//printf("Hello");
+		PORTD ^= (1<<PD3)|(1<<PD4)|(1<<PD5);
+		_delay_ms(1000);
+	
+	}   
+}
+
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..6493aad
--- /dev/null
+++ b/makefile
@@ -0,0 +1,35 @@
+MCU=atmega32
+F_CPU=8000000
+PROG=dragon_jtag
+DEBUGGER = dragon
+PORT=/dev/ttyUSB0 
+
+
+CC=avr-g++
+OBJCOPY=avr-objcopy
+CFLAGS=-Wall -g -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
+TARGET=main
+SRCS=src/*.cpp test/main.cpp lib/*/src/*.cpp
+
+default: build flash
+
+build:
+	${CC} ${CFLAGS} -o bin/${TARGET}.bin  ${SRCS}
+	${CC} ${CFLAGS} -o bin/${TARGET}.elf  ${SRCS}
+	${OBJCOPY} -j .text -j .data -O ihex bin/${TARGET}.bin bin/${TARGET}.hex
+
+flash:
+	avrdude -p ${MCU} -c ${PROG} -U flash:w:bin/main.hex
+
+clean:
+	rm -f bin/*
+
+debug: flash avarice
+	avr-gdb -ex "target remote :4242" bin/main.elf
+
+avarice:
+	sleep 1
+	avarice --file bin/main.elf --part ${MCU} --${DEBUGGER} :4242 &{
+
+term:
+	screen ${PORT} 1000000
\ No newline at end of file
diff --git a/src/rc522.cpp b/src/rc522.cpp
new file mode 100644
index 0000000..4a5fa6b
--- /dev/null
+++ b/src/rc522.cpp
@@ -0,0 +1,403 @@
+#include "spi.h"
+#include "rc522.h"
+
+
+void Write_MFRC522(uchar addr, uchar val) 
+{
+    spi::cs_low();
+	spi::transfer((addr<<1)&0x7E);	
+	spi::transfer(val);
+    spi::cs_high();
+}
+
+
+uchar Read_MFRC522(uchar addr)
+{
+	uchar val;
+    spi::cs_low();
+	//address format: 1XXXXXX0
+	spi::transfer(((addr<<1)&0x7E) | 0x80);	
+	val =spi::transfer(0x00);
+	spi::cs_high();
+	return val;	
+}
+
+
+void SetBitMask(uchar reg, uchar mask)  
+{
+    uchar tmp;
+    tmp = Read_MFRC522(reg);
+    Write_MFRC522(reg, tmp | mask);  // set bit mask
+}
+
+
+
+void ClearBitMask(uchar reg, uchar mask)  
+{
+    uchar tmp;
+    tmp = Read_MFRC522(reg);
+    Write_MFRC522(reg, tmp & (~mask));  // clear bit mask
+} 
+
+void AntennaOn(void)
+{
+	uchar temp;
+
+	temp = Read_MFRC522(TxControlReg);
+	if (!(temp & 0x03))
+	{
+		SetBitMask(TxControlReg, 0x03);
+	}
+}
+
+void AntennaOff(void)
+{
+	ClearBitMask(TxControlReg, 0x03);
+}
+
+void MFRC522_Reset(void)
+{
+    Write_MFRC522(CommandReg, PCD_RESETPHASE);
+}
+
+void MFRC522_Init(void)
+{
+    spi::init();
+    NRSTPD_DDR |= (1<<NRSTPD_PIN);
+    NRSTPD_PORT |= (1<<NRSTPD_PIN);
+
+	MFRC522_Reset();
+	 	
+	//Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
+    Write_MFRC522(TModeReg, 0x8D);		//Tauto=1; f(Timer) = 6.78MHz/TPreScaler
+    Write_MFRC522(TPrescalerReg, 0x3E);	//TModeReg[3..0] + TPrescalerReg
+    Write_MFRC522(TReloadRegL, 30);           
+    Write_MFRC522(TReloadRegH, 0);
+	Write_MFRC522(TxAutoReg, 0x40);		//100%ASK
+	Write_MFRC522(ModeReg, 0x3D);		//CRC original value 0x6363	???
+
+	AntennaOn();		// open antenna 
+}
+uchar MFRC522_Request(uchar reqMode, uchar *TagType)
+{
+	uchar status;  
+
+	uint backBits;			// bits of data received
+	Write_MFRC522(BitFramingReg, 0x07);		//TxLastBists = BitFramingReg[2..0]	???
+	
+	TagType[0] = reqMode;
+	status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
+
+	if ((status != MI_OK) || (backBits != 0x10))
+	{    
+		status = MI_ERR;
+	}
+   
+	return status;
+}
+
+uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)
+{
+    uchar status = MI_ERR;
+uchar irqEn = 0x00;
+
+    uchar waitIRq = 0x00;
+    uchar lastBits;
+    uchar n;
+    uint i;
+
+    switch (command)
+    {
+        case PCD_AUTHENT:		// card key authentication 
+		{
+			irqEn = 0x12;
+			waitIRq = 0x10;
+			break;
+		}
+		case PCD_TRANSCEIVE:	// send data in FIFO
+		{
+			irqEn = 0x77;
+			waitIRq = 0x30;
+			break;
+		}
+		default:
+			break;
+    }
+   
+    Write_MFRC522(CommIEnReg, irqEn|0x80);	// permission for interrupt request
+    ClearBitMask(CommIrqReg, 0x80);			// clear all bits of the interrupt request 
+    SetBitMask(FIFOLevelReg, 0x80);			//FlushBuffer=1, FIFO initialize
+    
+	Write_MFRC522(CommandReg, PCD_IDLE);	//NO action; clear current command	???
+
+	// write data into FIFO
+    for (i=0; i<sendLen; i++)
+    {   
+		Write_MFRC522(FIFODataReg, sendData[i]);    
+	}
+
+	// execute command 
+	Write_MFRC522(CommandReg, command);
+    if (command == PCD_TRANSCEIVE)
+    {    
+		SetBitMask(BitFramingReg, 0x80);		//StartSend=1,transmission of data starts  
+	}   
+
+    
+	// wait for the completion of data transmission
+	i = 2000;	// adjust i according to clock frequency, max wait time for M1 card operation 25ms	???
+    do 
+    {
+		//CommIrqReg[7..0]
+		//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
+        n = Read_MFRC522(CommIrqReg);
+        i--;
+    }
+    while ((i!=0) && !(n&0x01) && !(n&waitIRq));
+
+    ClearBitMask(BitFramingReg, 0x80);			//StartSend=0
+	
+    if (i != 0)
+    {    
+        if(!(Read_MFRC522(ErrorReg) & 0x1B))	//BufferOvfl Collerr CRCErr ProtecolErr
+        {
+            status = MI_OK;
+            if (n & irqEn & 0x01)
+            {   
+				status = MI_NOTAGERR;			//??   
+
+			}
+
+            if (command == PCD_TRANSCEIVE)
+            {
+               	n = Read_MFRC522(FIFOLevelReg);
+              	lastBits = Read_MFRC522(ControlReg) & 0x07;
+                if (lastBits)
+                {   
+					*backLen = (n-1)*8 + lastBits;   
+				}
+                else
+                {   
+					*backLen = n*8;   
+				}
+
+                if (n == 0)
+                {   
+					n = 1;    
+				}
+                if (n > MAX_LEN)
+
+                {   
+					n = MAX_LEN;   
+				}
+				
+				// read the data received in FIFO
+                for (i=0; i<n; i++)
+                {   
+					backData[i] = Read_MFRC522(FIFODataReg);    
+				}
+            }
+        }
+        else
+        {   
+			status = MI_ERR;  
+		}
+        
+    }
+	
+    //SetBitMask(ControlReg,0x80);           //timer stops
+    //Write_MFRC522(CommandReg, PCD_IDLE); 
+
+
+    return status;
+}
+
+uchar MFRC522_Anticoll(uchar *serNum)
+{
+    uchar status;
+    uchar i;
+	uchar serNumCheck=0;
+    uint unLen;
+    
+	Write_MFRC522(BitFramingReg, 0x00);		//TxLastBists = BitFramingReg[2..0]
+ 
+    serNum[0] = PICC_ANTICOLL;
+    serNum[1] = 0x20;
+    status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
+
+    if (status == MI_OK)
+	{
+		// verify card sequence number
+		for (i=0; i<4; i++)
+		{   
+
+		 	serNumCheck ^= serNum[i];
+		}
+		if (serNumCheck != serNum[i])
+		{   
+			status = MI_ERR;    
+		}
+    }
+
+    //SetBitMask(CollReg, 0x80);		//ValuesAfterColl=1
+
+    return status;
+} 
+
+void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData)
+{
+    uchar i, n;
+
+    ClearBitMask(DivIrqReg, 0x04);			//CRCIrq = 0
+    SetBitMask(FIFOLevelReg, 0x80);			// clear FIFO pointer
+    //Write_MFRC522(CommandReg, PCD_IDLE);
+
+	// write data into FIFO	
+    for (i=0; i<len; i++)
+    {   
+		Write_MFRC522(FIFODataReg, *(pIndata+i));   
+	}
+    Write_MFRC522(CommandReg, PCD_CALCCRC);
+
+	// wait for completion of CRC calculation 
+    i = 0xFF;
+    do 
+    {
+        n = Read_MFRC522(DivIrqReg);
+        i--;
+    }
+    while ((i!=0) && !(n&0x04));			//CRCIrq = 1
+
+	// read result from CRC calculation
+    pOutData[0] = Read_MFRC522(CRCResultRegL);
+    pOutData[1] = Read_MFRC522(CRCResultRegM);
+}
+
+
+uchar MFRC522_SelectTag(uchar *serNum)
+{
+    uchar i;
+	uchar status;
+	uchar size;
+    uint recvBits;
+    uchar buffer[9]; 
+
+	//ClearBitMask(Status2Reg, 0x08);			//MFCrypto1On=0
+
+    buffer[0] = PICC_SElECTTAG;
+    buffer[1] = 0x70;
+    for (i=0; i<5; i++)
+    {
+    	buffer[i+2] = *(serNum+i);
+    }
+	CalulateCRC(buffer, 7, &buffer[7]);		//??
+    status = MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
+    
+if ((status == MI_OK) && (recvBits == 0x18))
+
+    {   
+		size = buffer[0]; 
+	}
+    else
+    {   
+		size = 0;    
+	}
+
+    return size;
+}
+
+uchar MFRC522_Auth(uchar authMode, uchar BlockAddr, uchar *Sectorkey, uchar *serNum)
+{
+    uchar status;
+    uint recvBits;
+    uchar i;
+	uchar buff[12]; 
+
+	// Verification instructions + block address + sector password + card sequence number
+    buff[0] = authMode;
+    buff[1] = BlockAddr;
+    for (i=0; i<6; i++)
+    {    
+        buff[i+2] = *(Sectorkey+i);   
+    }
+    for (i=0; i<4; i++)
+    {    
+		buff[i+8] = *(serNum+i);   
+	}
+    status = MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);
+
+    if ((status != MI_OK) || (!(Read_MFRC522(Status2Reg) & 0x08)))
+    {   
+		status = MI_ERR;   
+	}
+    
+    return status;
+}
+
+uchar MFRC522_Read(uchar blockAddr, uchar *recvData)
+{
+
+    uchar status;
+    uint unLen;
+
+    recvData[0] = PICC_READ;
+    recvData[1] = blockAddr;
+    CalulateCRC(recvData,2, &recvData[2]);
+    status = MFRC522_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);
+
+    if ((status != MI_OK) || (unLen != 0x90))
+    {
+        status = MI_ERR;
+    }
+    
+    return status;
+}
+
+uchar MFRC522_Write(uchar blockAddr, uchar *writeData)
+{
+    uchar status;
+    uint recvBits;
+    uchar i;
+	uchar buff[18]; 
+    
+
+    buff[0] = PICC_WRITE;
+    buff[1] = blockAddr;
+    CalulateCRC(buff, 2, &buff[2]);
+    status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);
+
+    if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
+    {   
+		status = MI_ERR;   
+	}
+        
+    if (status == MI_OK)
+    {
+        for (i=0; i<16; i++)		// write 16Byte data into FIFO
+        {    
+        	buff[i] = *(writeData+i);   
+        }
+        CalulateCRC(buff, 16, &buff[16]);
+        status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
+        
+		if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
+        {   
+			status = MI_ERR;   
+		}
+    }
+    
+    return status;
+}
+
+void MFRC522_Halt(void)
+{
+	uchar status;
+    uint unLen;
+    uchar buff[4]; 
+
+    buff[0] = PICC_HALT;
+    buff[1] = 0;
+    CalulateCRC(buff, 2, &buff[2]);
+ 
+    status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen);
+}
\ No newline at end of file
diff --git a/src/rc522.h b/src/rc522.h
new file mode 100644
index 0000000..ccda289
--- /dev/null
+++ b/src/rc522.h
@@ -0,0 +1,135 @@
+#ifndef RC522_H
+#define RC522_H
+
+#include <avr/io.h>
+
+
+//MF522command wordu
+#define PCD_IDLE              0x00               //NO action; cancel current command
+#define PCD_AUTHENT           0x0E               //verify key
+#define PCD_RECEIVE           0x08               //receive data
+
+#define PCD_TRANSMIT          0x04               //send data
+#define PCD_TRANSCEIVE        0x0C               //receive and send data
+#define PCD_RESETPHASE        0x0F               //reset
+#define PCD_CALCCRC           0x03               //CRC calculation
+
+//Mifare_One Card command word
+#define PICC_REQIDL           0x26               // line-tracking area is dormant #define PICC_REQALL           0x52                     //line-tracking area is interfered
+#define PICC_ANTICOLL         0x93               //Anti collision
+#define PICC_SElECTTAG        0x93               //choose cards
+#define PICC_AUTHENT1A        0x60               //Verify A key
+#define PICC_AUTHENT1B        0x61               //Verify B key
+#define PICC_READ             0x30               // Reader Module 
+#define PICC_WRITE            0xA0               // letter block
+
+#define PICC_DECREMENT        0xC0               
+#define PICC_INCREMENT        0xC1               
+#define PICC_RESTORE          0xC2               //Transfer data to buffer
+#define PICC_TRANSFER         0xB0               //Save buffer data
+#define PICC_HALT             0x50               //Dormancy
+
+
+//MF522 Error code returned when communication
+#define MI_OK                 0
+#define MI_NOTAGERR           1
+#define MI_ERR                2
+
+
+//------------------MFRC522 Register---------------
+//Page 0:Command and Status
+#define     Reserved00            0x00    
+#define     CommandReg            0x01    
+#define     CommIEnReg            0x02    
+#define     DivlEnReg             0x03    
+#define     CommIrqReg            0x04    
+#define     DivIrqReg             0x05
+#define     ErrorReg              0x06    
+#define     Status1Reg            0x07    
+#define     Status2Reg            0x08    
+#define     FIFODataReg           0x09
+#define     FIFOLevelReg          0x0A
+
+#define     WaterLevelReg         0x0B
+#define     ControlReg            0x0C
+#define     BitFramingReg         0x0D
+#define     CollReg               0x0E
+#define     Reserved01            0x0F
+//Page 1:Command     
+#define     Reserved10            0x10
+#define     ModeReg               0x11
+#define     TxModeReg             0x12
+#define     RxModeReg             0x13
+#define     TxControlReg          0x14
+#define     TxAutoReg             0x15
+#define     TxSelReg              0x16
+#define     RxSelReg              0x17
+#define     RxThresholdReg        0x18
+#define     DemodReg              0x19
+
+#define     Reserved11            0x1A
+#define     Reserved12            0x1B
+#define     MifareReg             0x1C
+#define     Reserved13            0x1D
+#define     Reserved14            0x1E
+#define     SerialSpeedReg        0x1F
+//Page 2:CFG    
+#define     Reserved20            0x20  
+#define     CRCResultRegM         0x21
+#define     CRCResultRegL         0x22
+#define     Reserved21            0x23
+#define     ModWidthReg           0x24
+#define     Reserved22            0x25
+#define     RFCfgReg              0x26
+#define     GsNReg                0x27
+#define     CWGsPReg	          0x28
+#define     ModGsPReg             0x29
+#define     TModeReg              0x2A
+#define     TPrescalerReg         0x2B
+#define     TReloadRegH           0x2C
+#define     TReloadRegL           0x2D
+#define     TCounterValueRegH     0x2E
+#define     TCounterValueRegL     0x2F
+//Page 3:TestRegister     
+#define     Reserved30            0x30
+
+#define     TestSel1Reg           0x31
+#define     TestSel2Reg           0x32
+#define     TestPinEnReg          0x33
+#define     TestPinValueReg       0x34
+#define     TestBusReg            0x35
+#define     AutoTestReg           0x36
+#define     VersionReg            0x37
+#define     AnalogTestReg         0x38
+#define     TestDAC1Reg           0x39  
+#define     TestDAC2Reg           0x3A   
+#define     TestADCReg            0x3B   
+#define     Reserved31            0x3C   
+#define     Reserved32            0x3D   
+#define     Reserved33            0x3E   
+#define     Reserved34			  0x3F
+
+#define	uchar	unsigned char
+#define	uint	unsigned int
+
+#ifndef NRSTPD_PORT
+    #define NRSTPD_PORT PORTB
+    #define NRSTPD_DDR DDRB
+    #define NRSTPD_PIN PB1
+#endif
+
+#define MAX_LEN 16
+
+void MFRC522_Init(void);
+void MFRC522_Halt(void);
+uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen);
+void Write_MFRC522(uchar addr, uchar val);
+uchar Read_MFRC522(uchar addr);
+uchar MFRC522_Auth(uchar authMode, uchar BlockAddr, uchar *Sectorkey, uchar *serNum);
+uchar MFRC522_Write(uchar blockAddr, uchar *writeData);
+uchar MFRC522_Read(uchar blockAddr, uchar *recvData);
+uchar MFRC522_Request(uchar reqMode, uchar *TagType);
+uchar MFRC522_Anticoll(uchar *serNum);
+uchar MFRC522_SelectTag(uchar *serNum);
+
+#endif
\ No newline at end of file
diff --git a/src/spi.cpp b/src/spi.cpp
new file mode 100644
index 0000000..801391f
--- /dev/null
+++ b/src/spi.cpp
@@ -0,0 +1,21 @@
+#include "spi.h"
+
+
+namespace spi
+{
+    void init() {
+        SPI_PORT |= (1<<SPI_CS); //set chip select pin high
+        SPI_DDR |= (1<<SPI_SCK)|(1<<SPI_MOSI)|(1<<SPI_CS); // spi sck mosi and chip select outputs
+
+        SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0); //enable SPI , Master, fck/16
+    }
+
+    uint8_t transfer(uint8_t data) {
+        SPDR = data;
+        while(!(SPSR & (1<<SPIF))); //wait for transmition to complete
+        return SPDR;
+    }
+}
+    
+
+
diff --git a/src/spi.h b/src/spi.h
new file mode 100644
index 0000000..5fbf247
--- /dev/null
+++ b/src/spi.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <avr/io.h>
+
+
+#if defined __AVR_ATmega328P__
+    #define SPI_DDR  DDRB
+    #define SPI_PORT PORTB
+    #define SPI_SCK  PB5
+    #define SPI_MISO PB4
+    #define SPI_MOSI PB3
+    #define SPI_CS   PB2
+#elif defined  __AVR_ATmega32__ || defined __AVR_ATmega16__
+    #define SPI_PORT PORTB
+    #define SPI_DDR DDRB
+    #define SPI_SCK PB7
+    #define SPI_MOSI PB5
+    #define SPI_CS PB4
+#endif
+
+namespace spi
+{
+    void init();
+    uint8_t transfer(uint8_t data);
+  
+    inline void cs_low() {SPI_PORT &= ~(1<<SPI_CS);}
+
+    inline void cs_high() {SPI_PORT |= (1<<SPI_CS);}
+} // namespace spi
+
+
diff --git a/test/main.cpp b/test/main.cpp
new file mode 100644
index 0000000..f9c09a2
--- /dev/null
+++ b/test/main.cpp
@@ -0,0 +1,106 @@
+#include "../src/rc522.h"
+#include <avr/io.h>
+#include "../lib/usart/src/usart.h"
+#include "string.h"
+
+#define	uchar	unsigned char
+#define	uint	unsigned int
+#define MAX_LEN 16
+const int chipSelectPin = 10;
+const int NRSTPD = 5;
+
+uchar serNum[5];
+uchar  writeDate[16] ={'T', 'e', 'n', 'g', ' ', 'B', 'o', 0, 0, 0, 0, 0, 0, 0, 0,0};
+
+uchar sectorKeyA[16][16] = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+                             {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+                             {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+                            };
+ uchar sectorNewKeyA[16][16] = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+                                {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xff,0x07,0x80,0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+                                {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xff,0x07,0x80,0x69, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+                               };
+
+int main() {                
+	usart::init(1000000);
+	printf("Hello");
+   	MFRC522_Init();
+	while(1) {
+		uchar i;
+		uchar status;
+			uchar str[MAX_LEN];
+			uchar RC_size;
+			uchar blockAddr;	//Select the address of the operation 0~63
+
+
+			// searching card, return card type	
+			status = MFRC522_Request(PICC_REQIDL, str);	
+			if (status == MI_OK)
+			{
+			}
+
+			
+			status = MFRC522_Anticoll(str);
+			memcpy(serNum, str, 5);
+			if (status == MI_OK)
+			{
+				printf("The card's number is  : %x%x%x%x%x%x\n\r",
+					serNum[0],
+					serNum[1],
+					serNum[2],
+					serNum[3],
+					serNum[4]);
+			}
+
+			// select card, return card capacity
+			RC_size = MFRC522_SelectTag(serNum);
+			if (RC_size != 0)
+			{}
+					
+			// write data card
+			blockAddr = 7;		// data block 7		
+			status = MFRC522_Auth(PICC_AUTHENT1A, blockAddr, sectorKeyA[blockAddr/4], serNum);	// authentication 
+			if (status == MI_OK)
+
+			{
+				// write data
+				status = MFRC522_Write(blockAddr, sectorNewKeyA[blockAddr/4]);
+				printf("set the new card password, and can modify the data of the Sector: ");
+				printf("%i", blockAddr/4);
+
+				// write data
+				blockAddr = blockAddr - 3 ; 
+				status = MFRC522_Write(blockAddr, writeDate);
+				if(status == MI_OK)
+				{
+					printf("OK!\n\r");
+				}
+			}
+
+			// read card
+			blockAddr = 7;		// data block 7		
+			status = MFRC522_Auth(PICC_AUTHENT1A, blockAddr, 
+
+	sectorNewKeyA[blockAddr/4], serNum);	// authentication 
+			if (status == MI_OK)
+			{
+				// read data
+							blockAddr = blockAddr - 3 ; 
+							status = MFRC522_Read(blockAddr, str);
+				if (status == MI_OK)
+				{
+					printf("Read from the card ,the data is : \n\r");
+					for (i=0; i<16; i++)
+					{
+						printf("%c", str[i]);
+					}
+						printf("\n\r");
+				}
+			}
+			printf("\n\r");
+			MFRC522_Halt();			// command card into sleeping mode              
+			
+	}
+
+}
+