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 + + } + +} +