mirror of
https://github.com/RfidResearchGroup/ChameleonMini.git
synced 2026-05-12 11:20:37 -07:00
iClass support
Requires enabling in Makefile and disabling other options to fit in program space below 64k
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
/Chameleon-Mini.eep
|
||||
/Chameleon-Mini.hex
|
||||
/Chameleon-Mini.elf
|
||||
/Chameleon-Mini.map
|
||||
/Chameleon-Mini.bin
|
||||
/Chameleon-Mini.lss
|
||||
/Chameleon-Mini.sym
|
||||
/Chameleon-*.eep
|
||||
/Chameleon-*.hex
|
||||
/Chameleon-*.elf
|
||||
/Chameleon-*.map
|
||||
/Chameleon-*.bin
|
||||
/Chameleon-*.lss
|
||||
/Chameleon-*.sym
|
||||
/Bin/
|
||||
dfu-programmer
|
||||
dfu-programmer.exe
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "EM4233.h"
|
||||
#include "NTAG215.h"
|
||||
#include "Sniff15693.h"
|
||||
#include "IClass.h"
|
||||
|
||||
/* Function wrappers */
|
||||
INLINE void ApplicationInit(void) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* IClass.c
|
||||
*
|
||||
* Created on: 17-05-2020
|
||||
* Author: NVX
|
||||
*/
|
||||
|
||||
#ifndef ICLASS_H_
|
||||
#define ICLASS_H_
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#define ICLASS_BLOCK_SIZE 8
|
||||
#define ICLASS_CSN_SIZE ICLASS_BLOCK_SIZE
|
||||
#define ICLASS_BLOCK_NUM 32
|
||||
#define ICLASS_MEM_SIZE ( ICLASS_BLOCK_SIZE * ICLASS_BLOCK_NUM )
|
||||
#define ICLASS_READ4_SIZE ( ICLASS_BLOCK_SIZE * 4 )
|
||||
|
||||
void IClassAppInit(void);
|
||||
void IClassAppReset(void);
|
||||
void IClassDetectionInit(void);
|
||||
uint16_t IClassAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes);
|
||||
void IClassGetCsn(ConfigurationUidType Uid);
|
||||
void IClassSetCsn(const ConfigurationUidType Uid);
|
||||
|
||||
#endif /* ICLASS_H_ */
|
||||
@@ -292,7 +292,7 @@ static uint8_t AccessAddress;
|
||||
static uint16_t CardATQAValue;
|
||||
static uint8_t CardSAKValue;
|
||||
static bool FromHalt = false;
|
||||
static bool DetectionMode = false;
|
||||
bool DetectionMode = false;
|
||||
|
||||
#define BYTE_SWAP(x) (((uint8_t)(x)>>4)|((uint8_t)(x)<<4))
|
||||
#define NO_ACCESS 0x07
|
||||
@@ -401,7 +401,7 @@ extern uint8_t bUidMode; // Magic card mode switch
|
||||
static uint16_t DetectionLogPtr = FRAM_DETECTION_DATA_ADDR;
|
||||
static uint8_t EEMEM LogDetectionValid = false;
|
||||
|
||||
static void DetectionLogToFlash(uint8_t Entry, const void *Data, uint8_t Length) {
|
||||
void DetectionLogToFlash(uint8_t Entry, const void *Data, uint8_t Length) {
|
||||
if (!DetectionMode)
|
||||
return;
|
||||
|
||||
@@ -1025,7 +1025,7 @@ uint16_t MifareClassicAppProcess(uint8_t *Buffer, uint16_t BitCount) {
|
||||
State = STATE_HALT;
|
||||
Buffer[0] = NAK_NOT_AUTHED ^ Crypto1Nibble();
|
||||
return ACK_NAK_FRAME_SIZE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
DetectionLogToFlash(LOG_INFO_APP_CMD_WRITE, Buffer, 2);
|
||||
/* Write command. Store the address and prepare for the upcoming data.
|
||||
@@ -1313,4 +1313,4 @@ void MifareClassicGetSak(uint8_t * Sak) {
|
||||
|
||||
void MifareClassicSetSak(uint8_t Sak) {
|
||||
CardSAKValue = Sak;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
#define MIFARE_CLASSIC_1K_MEM_SIZE 1024
|
||||
#define MIFARE_CLASSIC_4K_MEM_SIZE 4096
|
||||
|
||||
extern bool DetectionMode;
|
||||
void DetectionLogToFlash(uint8_t Entry, const void *Data, uint8_t Length);
|
||||
|
||||
void DetectionInit(void);
|
||||
void DetectionLogClear(void);
|
||||
void MifareDetectionInit1K(void);
|
||||
|
||||
@@ -121,7 +121,7 @@ ISR_SHARED isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void) {
|
||||
*/
|
||||
INLINE void ISO15693_EOC(void) {
|
||||
/* Set bitrate required by the reader on SOF for our following response */
|
||||
if (CodecBuffer[0] & REQ_DATARATE_HIGH) {
|
||||
if (CodecBuffer[0] & REQ_DATARATE_HIGH || ActiveConfiguration.TagFamily == TAG_FAMILY_ISO15693_ICLASS) {
|
||||
BitRate1 = 256;
|
||||
BitRate2 = 252; /* If single subcarrier mode is requested, BitRate2 is useless, but setting it nevertheless was still faster than checking */
|
||||
} else {
|
||||
@@ -321,8 +321,12 @@ LOADMOD_SOF_SINGLE_LABEL:
|
||||
|
||||
if ((BitSent % 8) == 0) {
|
||||
/* Last SOF bit has been put out. Start sending out data */
|
||||
StateRegister = LOADMOD_BIT0_SINGLE;
|
||||
ShiftRegister = (*CodecBufferPtr++);
|
||||
if (ByteCount == 0) {
|
||||
StateRegister = LOADMOD_FINISHED;
|
||||
} else {
|
||||
StateRegister = LOADMOD_BIT0_SINGLE;
|
||||
ShiftRegister = (*CodecBufferPtr++);
|
||||
}
|
||||
} else {
|
||||
StateRegister = LOADMOD_SOF_SINGLE;
|
||||
}
|
||||
@@ -403,8 +407,12 @@ LOADMOD_SOF_DUAL_LABEL:
|
||||
|
||||
if ((BitSent % 8) == 0) {
|
||||
/* Last SOF bit has been put out. Start sending out data */
|
||||
StateRegister = LOADMOD_BIT0_DUAL;
|
||||
ShiftRegister = (*CodecBufferPtr++);
|
||||
if (ByteCount == 0) {
|
||||
StateRegister = LOADMOD_FINISHED;
|
||||
} else {
|
||||
StateRegister = LOADMOD_BIT0_DUAL;
|
||||
ShiftRegister = (*CodecBufferPtr++);
|
||||
}
|
||||
} else {
|
||||
StateRegister = LOADMOD_SOF_DUAL;
|
||||
}
|
||||
@@ -618,6 +626,23 @@ void ISO15693CodecDeInit(void) {
|
||||
CodecSetLoadmodState(false);
|
||||
}
|
||||
|
||||
void ISO15693StartEarlySend(bool bDualSubcarrier, uint16_t byteCount) {
|
||||
// Buy a little more time to ready the responce (400 cycles == 14.7uS) before sending the SOF
|
||||
CODEC_TIMER_LOADMOD.PER = ISO15693_T1_TIME + 200;
|
||||
|
||||
ByteCount = byteCount;
|
||||
CodecBufferPtr = CodecBuffer;
|
||||
|
||||
/* Start loadmodulating */
|
||||
if (bDualSubcarrier) {
|
||||
CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OOK, SUBCARRIER_2);
|
||||
StateRegister = LOADMOD_START_DUAL;
|
||||
} else {
|
||||
CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OOK, SUBCARRIER_1);
|
||||
StateRegister = LOADMOD_START_SINGLE;
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15693CodecTask(void) {
|
||||
if (Flags.DemodFinished) {
|
||||
Flags.DemodFinished = 0;
|
||||
@@ -630,14 +655,19 @@ void ISO15693CodecTask(void) {
|
||||
LogEntry(LOG_INFO_CODEC_RX_DATA, CodecBuffer, DemodByteCount);
|
||||
LEDHook(LED_CODEC_RX, LED_PULSE);
|
||||
|
||||
if (CodecBuffer[0] & REQ_SUBCARRIER_DUAL) {
|
||||
if (CodecBuffer[0] & REQ_SUBCARRIER_DUAL && ActiveConfiguration.TagFamily != TAG_FAMILY_ISO15693_ICLASS) {
|
||||
bDualSubcarrier = true;
|
||||
}
|
||||
LogEntry(LOG_INFO_GENERIC, "Test1", 5);
|
||||
AppReceivedByteCount = ApplicationProcess(CodecBuffer, DemodByteCount);
|
||||
}
|
||||
|
||||
/* This is only reached when we've received a valid frame */
|
||||
if (AppReceivedByteCount != ISO15693_APP_NO_RESPONSE) {
|
||||
if (AppReceivedByteCount != ISO15693_APP_NO_RESPONSE && AppReceivedByteCount != ISO15693_APP_EARLY_SEND) {
|
||||
if (AppReceivedByteCount == ISO15693_APP_SOF_ONLY) {
|
||||
AppReceivedByteCount = 0;
|
||||
}
|
||||
|
||||
if (AppReceivedByteCount > CODEC_BUFFER_SIZE - ISO15693_CRC16_SIZE) { /* CRC would be written outside codec buffer */
|
||||
CodecBuffer[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
|
||||
CodecBuffer[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP;
|
||||
@@ -660,11 +690,14 @@ void ISO15693CodecTask(void) {
|
||||
}
|
||||
|
||||
/* Calculate the CRC while modulation is already ongoing */
|
||||
ISO15693AppendCRC(CodecBuffer, AppReceivedByteCount);
|
||||
ByteCount += ISO15693_CRC16_SIZE; /* Increase this variable as it will be read by the codec during loadmodulation */
|
||||
LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount + ISO15693_CRC16_SIZE);
|
||||
|
||||
} else {
|
||||
if (ActiveConfiguration.TagFamily != TAG_FAMILY_ISO15693_ICLASS && AppReceivedByteCount != 0) {
|
||||
ISO15693AppendCRC(CodecBuffer, AppReceivedByteCount);
|
||||
ByteCount += ISO15693_CRC16_SIZE; /* Increase this variable as it will be read by the codec during loadmodulation */
|
||||
LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount + ISO15693_CRC16_SIZE);
|
||||
} else {
|
||||
LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount);
|
||||
}
|
||||
} else if (AppReceivedByteCount != ISO15693_APP_EARLY_SEND) {
|
||||
/* Overwrite the PERBUF register, which was configured in ISO15693_EOC, with the new appropriate value.
|
||||
* This is expecially needed because, since load modulation has not been performed, we're jumping here straight after
|
||||
* ISO15693_EOC. This implies that the data stored in the PERBUF register by ISO15693_EOC still has to be copied
|
||||
|
||||
@@ -8,7 +8,12 @@
|
||||
#ifndef ISO15693_H_
|
||||
#define ISO15693_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define ISO15693_APP_NO_RESPONSE 0x0000
|
||||
#define ISO15693_APP_SOF_ONLY 0xFFFF
|
||||
#define ISO15693_APP_EARLY_SEND 0xFFFE
|
||||
|
||||
/* Codec Interface */
|
||||
void ISO15693CodecInit(void);
|
||||
@@ -18,5 +23,6 @@ void ISO15693CodecTask(void);
|
||||
/* Application Interface */
|
||||
void ISO15693CodecStart(void);
|
||||
void ISO15693CodecReset(void);
|
||||
void ISO15693StartEarlySend(bool bDualSubcarrier, uint16_t byteCount);
|
||||
|
||||
#endif /* ISO15693_H_ */
|
||||
|
||||
@@ -69,6 +69,10 @@ static const MapEntryType PROGMEM ConfigurationMap[] = {
|
||||
#ifdef CONFIG_EM4233_SUPPORT
|
||||
{ .Id = CONFIG_EM4233, .Text = "EM4233" },
|
||||
#endif
|
||||
#ifdef CONFIG_ICLASS_SUPPORT
|
||||
{ .Id = CONFIG_ICLASS, .Text = "ICLASS" },
|
||||
{ .Id = CONFIG_ICLASS_DETECTION, .Text = "ICLASS_DETECTION" },
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Include all Codecs and Applications */
|
||||
@@ -499,6 +503,40 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
|
||||
.TagFamily = TAG_FAMILY_ISO14443A
|
||||
},
|
||||
#endif
|
||||
#ifdef CONFIG_ICLASS_SUPPORT
|
||||
[CONFIG_ICLASS] = {
|
||||
.CodecInitFunc = ISO15693CodecInit,
|
||||
.CodecDeInitFunc = ISO15693CodecDeInit,
|
||||
.CodecTaskFunc = ISO15693CodecTask,
|
||||
.ApplicationInitFunc = IClassAppInit,
|
||||
.ApplicationResetFunc = IClassAppReset,
|
||||
.ApplicationTaskFunc = ApplicationTaskDummy,
|
||||
.ApplicationTickFunc = ApplicationTickDummy,
|
||||
.ApplicationProcessFunc = IClassAppProcess,
|
||||
.ApplicationGetUidFunc = IClassGetCsn,
|
||||
.ApplicationSetUidFunc = IClassSetCsn,
|
||||
.UidSize = ICLASS_CSN_SIZE,
|
||||
.MemorySize = ICLASS_MEM_SIZE,
|
||||
.ReadOnly = false,
|
||||
.TagFamily = TAG_FAMILY_ISO15693_ICLASS
|
||||
},
|
||||
[CONFIG_ICLASS_DETECTION] = {
|
||||
.CodecInitFunc = ISO15693CodecInit,
|
||||
.CodecDeInitFunc = ISO15693CodecDeInit,
|
||||
.CodecTaskFunc = ISO15693CodecTask,
|
||||
.ApplicationInitFunc = IClassDetectionInit,
|
||||
.ApplicationResetFunc = IClassAppReset,
|
||||
.ApplicationTaskFunc = ApplicationTaskDummy,
|
||||
.ApplicationTickFunc = ApplicationTickDummy,
|
||||
.ApplicationProcessFunc = IClassAppProcess,
|
||||
.ApplicationGetUidFunc = IClassGetCsn,
|
||||
.ApplicationSetUidFunc = ApplicationSetUidDummy,
|
||||
.UidSize = ICLASS_CSN_SIZE,
|
||||
.MemorySize = ICLASS_MEM_SIZE,
|
||||
.ReadOnly = true,
|
||||
.TagFamily = TAG_FAMILY_ISO15693_ICLASS
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
ConfigurationType ActiveConfiguration;
|
||||
|
||||
@@ -74,16 +74,21 @@ typedef enum {
|
||||
#endif
|
||||
#ifdef CONFIG_EM4233_SUPPORT
|
||||
CONFIG_EM4233,
|
||||
#endif
|
||||
#ifdef CONFIG_ICLASS_SUPPORT
|
||||
CONFIG_ICLASS,
|
||||
CONFIG_ICLASS_DETECTION,
|
||||
#endif
|
||||
/* This HAS to be the last element */
|
||||
CONFIG_COUNT
|
||||
} ConfigurationEnum;
|
||||
|
||||
/** Tag Family definitions **/
|
||||
#define TAG_FAMILY_NONE 0
|
||||
#define TAG_FAMILY_ISO14443A 1
|
||||
#define TAG_FAMILY_ISO14443B 2
|
||||
#define TAG_FAMILY_ISO15693 5
|
||||
#define TAG_FAMILY_NONE 0
|
||||
#define TAG_FAMILY_ISO14443A 1
|
||||
#define TAG_FAMILY_ISO14443B 2
|
||||
#define TAG_FAMILY_ISO15693 5
|
||||
#define TAG_FAMILY_ISO15693_ICLASS 6 // Disables CRC and dual subcarrier
|
||||
|
||||
|
||||
/** With this `struct` the behavior of a configuration is defined. */
|
||||
|
||||
@@ -23,6 +23,7 @@ SETTINGS += -DCONFIG_NTAG215_SUPPORT
|
||||
# SETTINGS += -DCONFIG_TITAGITSTANDARD_SUPPORT
|
||||
# SETTINGS += -DCONFIG_EM4233_SUPPORT
|
||||
SETTINGS += -DCONFIG_ISO15693_SNIFF_SUPPORT
|
||||
#SETTINGS += -DCONFIG_ICLASS_SUPPORT
|
||||
|
||||
#Support magic mode on mifare classic configuration
|
||||
SETTINGS += -DSUPPORT_MF_CLASSIC_MAGIC_MODE
|
||||
@@ -71,7 +72,7 @@ SETTINGS += -DLED_SETTING_GLOBAL
|
||||
#Default logging mode
|
||||
SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_OFF
|
||||
#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_MEMORY
|
||||
#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_TERMINAL
|
||||
#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_LIVE
|
||||
|
||||
#Define if log settings should be global
|
||||
SETTINGS += -DLOG_SETTING_GLOBAL
|
||||
@@ -114,7 +115,7 @@ SRC += Terminal/Terminal.c Terminal/Commands.c Terminal/XModem.c Termina
|
||||
SRC += Codec/Codec.c Codec/ISO14443-2A.c Codec/Reader14443-2A.c Codec/SniffISO14443-2A.c Codec/Reader14443-ISR.S
|
||||
SRC += Application/MifareUltralight.c Application/MifareClassic.c Application/ISO14443-3A.c Application/Crypto1.c Application/Reader14443A.c Application/Sniff14443A.c Application/CryptoTDEA.S Application/NTAG215.c
|
||||
SRC += Codec/ISO15693.c Codec/SniffISO15693.c
|
||||
SRC += Application/Vicinity.c Application/Sl2s2002.c Application/TITagitstandard.c Application/ISO15693-A.c Application/EM4233.c Application/Sniff15693.c
|
||||
SRC += Application/Vicinity.c Application/Sl2s2002.c Application/TITagitstandard.c Application/ISO15693-A.c Application/EM4233.c Application/Sniff15693.c Application/IClass.c
|
||||
SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
||||
LUFA_PATH = ../LUFA
|
||||
CC_FLAGS = -flto -DUSE_LUFA_CONFIG_HEADER -DFLASH_DATA_ADDR=$(FLASH_DATA_ADDR) -DFLASH_DATA_SIZE=$(FLASH_DATA_SIZE) -DSPM_HELPER_ADDR=$(SPM_HELPER_ADDR) -DBUILD_DATE=$(BUILD_DATE) -DCOMMIT_ID=\"$(COMMIT_ID)\" $(SETTINGS)
|
||||
|
||||
@@ -172,15 +172,16 @@ INLINE void FRAMWrite(const void *Buffer, uint16_t Address, uint16_t ByteCount)
|
||||
SPIWriteBlock(Buffer, ByteCount);
|
||||
|
||||
FRAM_PORT.OUTSET = FRAM_CS;
|
||||
if (0 == Address
|
||||
#ifdef CONFIG_ISO14443A_READER_SUPPORT
|
||||
if (0 == Address && GlobalSettings.ActiveSettingPtr->Configuration != CONFIG_ISO14443A_READER) {
|
||||
ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration);
|
||||
}
|
||||
#else
|
||||
if (0 == Address) {
|
||||
ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration);
|
||||
}
|
||||
&& GlobalSettings.ActiveSettingPtr->Configuration != CONFIG_ISO14443A_READER
|
||||
#endif
|
||||
#ifdef CONFIG_ICLASS_SUPPORT
|
||||
&& GlobalSettings.ActiveSettingPtr->Configuration != CONFIG_ICLASS_DETECTION
|
||||
#endif
|
||||
) {
|
||||
ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration);
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void FlashRead(void *Buffer, uint32_t Address, uint16_t ByteCount) {
|
||||
|
||||
Reference in New Issue
Block a user