Intial commit
This commit is contained in:
parent
9024442baa
commit
1c89ad2ea0
|
@ -0,0 +1,2 @@
|
||||||
|
.vscode/
|
||||||
|
bin/
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "lib/usart"]
|
||||||
|
path = lib/usart
|
||||||
|
url = git@git.chch.tech:avr/usart.git
|
|
@ -0,0 +1,2 @@
|
||||||
|
.vscode/
|
||||||
|
bin/
|
|
@ -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.
|
|
@ -0,0 +1,2 @@
|
||||||
|
# usart
|
||||||
|
|
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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);
|
||||||
|
}
|
|
@ -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
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue