mirror of
https://github.com/RfidResearchGroup/ChameleonMini.git
synced 2026-05-12 11:20:37 -07:00
Merge pull request #37 from ceres-c/rrg-iso15693-codec-upd
Porting ISO15693 codec and applications updates
This commit is contained in:
@@ -23,9 +23,6 @@ static enum {
|
||||
} State;
|
||||
|
||||
bool loggedIn;
|
||||
uint8_t MyAFI; /* This variable holds current tag's AFI (is used in inventory) */
|
||||
|
||||
CurrentFrame FrameInfo;
|
||||
|
||||
void EM4233AppInit(void) {
|
||||
State = STATE_READY;
|
||||
@@ -38,7 +35,7 @@ void EM4233AppInit(void) {
|
||||
FrameInfo.Selected = false;
|
||||
loggedIn = false;
|
||||
MemoryReadBlock(&MyAFI, EM4233_MEM_AFI_ADDRESS, 1);
|
||||
|
||||
MemoryReadBlock(&Uid, EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize);
|
||||
}
|
||||
|
||||
void EM4233AppReset(void) {
|
||||
@@ -51,6 +48,8 @@ void EM4233AppReset(void) {
|
||||
FrameInfo.Addressed = false;
|
||||
FrameInfo.Selected = false;
|
||||
loggedIn = false;
|
||||
MemoryReadBlock(&MyAFI, EM4233_MEM_AFI_ADDRESS, 1);
|
||||
MemoryReadBlock(&Uid, EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize);
|
||||
}
|
||||
|
||||
void EM4233AppTask(void) {
|
||||
@@ -62,7 +61,7 @@ void EM4233AppTick(void) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Lock_Block(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t BlockAddress = *FrameInfo.Parameters;
|
||||
uint8_t LockStatus = 0;
|
||||
|
||||
@@ -92,7 +91,7 @@ uint16_t EM4233_Lock_Block(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Write_Single(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t BlockAddress = *FrameInfo.Parameters;
|
||||
uint8_t *Dataptr = FrameInfo.Parameters + 0x01; /* Data to write begins on 2nd byte of the frame received by the reader */
|
||||
uint8_t LockStatus = 0;
|
||||
@@ -127,7 +126,7 @@ uint16_t EM4233_Write_Single(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Read_Single(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t FramePtr; /* holds the address where block's data will be put */
|
||||
uint8_t BlockAddress = FrameInfo.Parameters[0];
|
||||
uint8_t LockStatus = 0;
|
||||
@@ -138,7 +137,7 @@ uint16_t EM4233_Read_Single(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
if (BlockAddress >= EM4233_NUMBER_OF_BLCKS) { /* check if the reader is requesting a sector out of bound */
|
||||
if (FrameInfo.Addressed) { /* If the request is addressed */
|
||||
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
|
||||
FrameBuf[ISO15693_RES_ADDR_PARAM] = 0x0F; /* Magic number from real tag */
|
||||
FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC;
|
||||
ResponseByteCount += 2; /* Copied this behaviour from real tag, not specified in ISO documents */
|
||||
}
|
||||
return ResponseByteCount; /* If not addressed real tag does not respond */
|
||||
@@ -168,7 +167,7 @@ uint16_t EM4233_Read_Single(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Read_Multiple(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t FramePtr; /* holds the address where block's data will be put */
|
||||
uint8_t BlockAddress = FrameInfo.Parameters[0];
|
||||
uint8_t BlocksNumber = FrameInfo.Parameters[1] + 0x01; /* according to ISO standard, we have to read 0x08 blocks if we get 0x07 in request */
|
||||
@@ -179,7 +178,7 @@ uint16_t EM4233_Read_Multiple(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
if (BlockAddress >= EM4233_NUMBER_OF_BLCKS) { /* the reader is requesting a block out of bound */
|
||||
if (FrameInfo.Addressed) { /* If the request is addressed */
|
||||
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
|
||||
FrameBuf[ISO15693_RES_ADDR_PARAM] = 0x0F; /* Magic number from real tag */
|
||||
FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_GENERIC;
|
||||
ResponseByteCount += 2; /* Copied this behaviour from real tag, not specified in ISO documents */
|
||||
}
|
||||
return ResponseByteCount; /* If not addressed real tag does not respond */
|
||||
@@ -224,7 +223,7 @@ uint16_t EM4233_Read_Multiple(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Write_AFI(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t AFI = FrameInfo.Parameters[0];
|
||||
uint8_t LockStatus = 0;
|
||||
|
||||
@@ -251,7 +250,7 @@ uint16_t EM4233_Write_AFI(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Lock_AFI(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t LockStatus = 0;
|
||||
|
||||
if (FrameInfo.ParamLen != 0)
|
||||
@@ -278,7 +277,7 @@ uint16_t EM4233_Lock_AFI(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Write_DSFID(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t DSFID = FrameInfo.Parameters[0];
|
||||
uint8_t LockStatus = 0;
|
||||
|
||||
@@ -304,7 +303,7 @@ uint16_t EM4233_Write_DSFID(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Lock_DSFID(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t LockStatus = 0;
|
||||
|
||||
if (FrameInfo.ParamLen != 0)
|
||||
@@ -331,7 +330,7 @@ uint16_t EM4233_Lock_DSFID(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint8_t EM4233_Get_SysInfo(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t FramePtr; /* holds the address where block's data will be put */
|
||||
|
||||
if (FrameInfo.ParamLen != 0)
|
||||
@@ -354,8 +353,6 @@ uint8_t EM4233_Get_SysInfo(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
ResponseByteCount += 1; /* Increment the response count */
|
||||
|
||||
/* Then append UID */
|
||||
uint8_t Uid[ActiveConfiguration.UidSize];
|
||||
EM4233GetUid(Uid);
|
||||
ISO15693CopyUid(&FrameBuf[FramePtr], Uid);
|
||||
FramePtr += ISO15693_GENERIC_UID_SIZE; /* Move forward the buffer data pointer */
|
||||
ResponseByteCount += ISO15693_GENERIC_UID_SIZE; /* Increment the response count */
|
||||
@@ -398,7 +395,7 @@ uint8_t EM4233_Get_SysInfo(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Get_Multi_Block_Sec_Stat(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t FramePtr; /* holds the address where block's data will be put */
|
||||
uint8_t BlockAddress = FrameInfo.Parameters[0];
|
||||
uint8_t BlocksNumber = FrameInfo.Parameters[1] + 0x01;
|
||||
@@ -427,7 +424,7 @@ uint16_t EM4233_Get_Multi_Block_Sec_Stat(uint8_t *FrameBuf, uint16_t FrameBytes)
|
||||
}
|
||||
|
||||
uint16_t EM4233_Select(uint8_t *FrameBuf, uint16_t FrameBytes, uint8_t *Uid) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
/* I've no idea how this request could generate errors ._.
|
||||
if ( ) {
|
||||
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
|
||||
@@ -463,7 +460,7 @@ uint16_t EM4233_Select(uint8_t *FrameBuf, uint16_t FrameBytes, uint8_t *Uid) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Reset_To_Ready(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
/* I've no idea how this request could generate errors ._.
|
||||
if ( ) {
|
||||
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
|
||||
@@ -487,7 +484,7 @@ uint16_t EM4233_Reset_To_Ready(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Login(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t Password[4] = { 0 };
|
||||
|
||||
if (FrameInfo.ParamLen != 4 || !FrameInfo.Addressed || !(FrameInfo.Selected && State == STATE_SELECTED))
|
||||
@@ -523,7 +520,7 @@ uint16_t EM4233_Login(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Auth1(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
// uint8_t KeyNo = *FrameInfo.Parameters; /* Right now this parameter is unused, but it will be useful */
|
||||
|
||||
if (FrameInfo.ParamLen != 1) /* Malformed: not enough or too much data */
|
||||
@@ -548,7 +545,7 @@ uint16_t EM4233_Auth1(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233_Auth2(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
// uint8_t A2 = FrameInfo.Parameters;
|
||||
// uint8_t f = FrameInfo.Parameters + 0x08;
|
||||
// uint8_t g[3] = { 0 }; /* Names according to EM Marin definitions */
|
||||
@@ -566,9 +563,7 @@ uint16_t EM4233_Auth2(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
|
||||
uint16_t EM4233AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t Uid[ActiveConfiguration.UidSize];
|
||||
EM4233GetUid(Uid);
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
|
||||
if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE))
|
||||
/* malformed frame */
|
||||
@@ -585,8 +580,8 @@ uint16_t EM4233AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
return ISO15693_APP_NO_RESPONSE;
|
||||
|
||||
if (State == STATE_READY || State == STATE_SELECTED) {
|
||||
|
||||
if (*FrameInfo.Command == ISO15693_CMD_INVENTORY) {
|
||||
switch (*FrameInfo.Command) {
|
||||
case ISO15693_CMD_INVENTORY:
|
||||
if (FrameInfo.ParamLen == 0)
|
||||
return ISO15693_APP_NO_RESPONSE; /* malformed: not enough or too much data */
|
||||
|
||||
@@ -596,59 +591,77 @@ uint16_t EM4233AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
ISO15693CopyUid(&FrameBuf[ISO15693_RES_ADDR_PARAM + 0x01], Uid);
|
||||
ResponseByteCount += 10;
|
||||
}
|
||||
break;
|
||||
|
||||
} else if ((*FrameInfo.Command == ISO15693_CMD_STAY_QUIET) && FrameInfo.Addressed) {
|
||||
State = STATE_QUIET;
|
||||
case ISO15693_CMD_STAY_QUIET:
|
||||
if (FrameInfo.Addressed)
|
||||
State = STATE_QUIET;
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_READ_SINGLE) {
|
||||
case ISO15693_CMD_READ_SINGLE:
|
||||
ResponseByteCount = EM4233_Read_Single(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_WRITE_SINGLE) {
|
||||
case ISO15693_CMD_WRITE_SINGLE:
|
||||
ResponseByteCount = EM4233_Write_Single(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_LOCK_BLOCK) {
|
||||
case ISO15693_CMD_LOCK_BLOCK:
|
||||
ResponseByteCount = EM4233_Lock_Block(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_READ_MULTIPLE) {
|
||||
case ISO15693_CMD_READ_MULTIPLE:
|
||||
ResponseByteCount = EM4233_Read_Multiple(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_WRITE_AFI) {
|
||||
case ISO15693_CMD_WRITE_AFI:
|
||||
ResponseByteCount = EM4233_Write_AFI(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_LOCK_AFI) {
|
||||
case ISO15693_CMD_LOCK_AFI:
|
||||
ResponseByteCount = EM4233_Lock_AFI(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_WRITE_DSFID) {
|
||||
case ISO15693_CMD_WRITE_DSFID:
|
||||
ResponseByteCount = EM4233_Write_DSFID(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_LOCK_DSFID) {
|
||||
case ISO15693_CMD_LOCK_DSFID:
|
||||
ResponseByteCount = EM4233_Lock_DSFID(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_GET_SYS_INFO) {
|
||||
case ISO15693_CMD_GET_SYS_INFO:
|
||||
ResponseByteCount = EM4233_Get_SysInfo(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_GET_BLOCK_SEC) {
|
||||
case ISO15693_CMD_GET_BLOCK_SEC:
|
||||
ResponseByteCount = EM4233_Get_Multi_Block_Sec_Stat(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) {
|
||||
case ISO15693_CMD_RESET_TO_READY:
|
||||
ResponseByteCount = EM4233_Reset_To_Ready(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == EM4233_CMD_LOGIN) {
|
||||
case EM4233_CMD_LOGIN:
|
||||
ResponseByteCount = EM4233_Login(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == EM4233_CMD_AUTH1) {
|
||||
case EM4233_CMD_AUTH1:
|
||||
ResponseByteCount = EM4233_Auth1(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else if (*FrameInfo.Command == EM4233_CMD_AUTH2) {
|
||||
case EM4233_CMD_AUTH2:
|
||||
ResponseByteCount = EM4233_Auth2(FrameBuf, FrameBytes);
|
||||
break;
|
||||
|
||||
} else {
|
||||
default:
|
||||
if (FrameInfo.Addressed) {
|
||||
FrameBuf[ISO15693_ADDR_FLAGS] = ISO15693_RES_FLAG_ERROR;
|
||||
FrameBuf[ISO15693_RES_ADDR_PARAM] = ISO15693_RES_ERR_NOT_SUPP;
|
||||
ResponseByteCount = 2;
|
||||
} /* EM4233 respond with error flag only to addressed commands */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (State == STATE_QUIET) {
|
||||
if (*FrameInfo.Command == ISO15693_CMD_RESET_TO_READY) {
|
||||
@@ -656,12 +669,6 @@ uint16_t EM4233AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
}
|
||||
}
|
||||
|
||||
if (ResponseByteCount > 0) {
|
||||
/* There is data to send. Append CRC */
|
||||
ISO15693AppendCRC(FrameBuf, ResponseByteCount);
|
||||
ResponseByteCount += ISO15693_CRC16_SIZE;
|
||||
}
|
||||
|
||||
return ResponseByteCount;
|
||||
}
|
||||
|
||||
@@ -669,6 +676,7 @@ void EM4233GetUid(ConfigurationUidType Uid) {
|
||||
MemoryReadBlock(&Uid[0], EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize);
|
||||
}
|
||||
|
||||
void EM4233SetUid(ConfigurationUidType Uid) {
|
||||
MemoryWriteBlock(Uid, EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize);
|
||||
void EM4233SetUid(ConfigurationUidType NewUid) {
|
||||
memcpy(Uid, NewUid, ActiveConfiguration.UidSize);
|
||||
MemoryWriteBlock(NewUid, EM4233_MEM_UID_ADDRESS, ActiveConfiguration.UidSize);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
#include "../Common.h"
|
||||
#include <util/crc16.h>
|
||||
|
||||
CurrentFrame FrameInfo;
|
||||
uint8_t Uid[ISO15693_GENERIC_UID_SIZE];
|
||||
uint8_t MyAFI;
|
||||
uint16_t ResponseByteCount;
|
||||
|
||||
//Refer to ISO/IEC 15693-3:2001 page 41
|
||||
uint16_t calculateCRC(void *FrameBuf, uint16_t FrameBufSize) {
|
||||
uint16_t reg = ISO15693_CRC16_PRESET;
|
||||
|
||||
@@ -85,6 +85,10 @@ typedef struct {
|
||||
bool Addressed;
|
||||
bool Selected;
|
||||
} CurrentFrame;
|
||||
extern CurrentFrame FrameInfo; /* Holds current frame information */
|
||||
extern uint8_t Uid[];
|
||||
extern uint8_t MyAFI; /* Holds current tag's AFI, used during inventory */
|
||||
extern uint16_t ResponseByteCount; /* Length of response, used when building response frames */
|
||||
|
||||
void ISO15693AppendCRC(uint8_t *FrameBuf, uint16_t FrameBufSize);
|
||||
bool ISO15693CheckCRC(void *FrameBuf, uint16_t FrameBufSize);
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
// TODO replace remaining magic numbers
|
||||
|
||||
uint8_t ReaderSendBuffer[CODEC_BUFFER_SIZE];
|
||||
uint16_t ReaderSendBitCount;
|
||||
|
||||
static bool Selected = false;
|
||||
Reader14443Command Reader14443CurrentCommand = Reader14443_Do_Nothing;
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
#define CRC_INIT 0x6363
|
||||
|
||||
uint8_t ReaderSendBuffer[CODEC_BUFFER_SIZE];
|
||||
uint16_t ReaderSendBitCount;
|
||||
extern uint8_t ReaderSendBuffer[];
|
||||
extern uint16_t ReaderSendBitCount;
|
||||
|
||||
void Reader14443AAppInit(void);
|
||||
void Reader14443AAppReset(void);
|
||||
|
||||
@@ -141,12 +141,6 @@ uint16_t Sl2s2002AppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ResponseByteCount > 0) {
|
||||
/* There is data to be sent. Append CRC */
|
||||
ISO15693AppendCRC(FrameBuf, ResponseByteCount);
|
||||
ResponseByteCount += ISO15693_CRC16_SIZE;
|
||||
}
|
||||
|
||||
return ResponseByteCount;
|
||||
|
||||
} else { // Invalid CRC
|
||||
|
||||
@@ -16,10 +16,8 @@ static enum {
|
||||
STATE_QUIET
|
||||
} State;
|
||||
|
||||
uint8_t MyAFI; /* Holds current tag's AFI (is used in inventory) */
|
||||
uint16_t UserLockBits_Mask = 0; /* Holds lock state of blocks */
|
||||
uint16_t FactoryLockBits_Mask = 0; /* Holds lock state of blocks */
|
||||
CurrentFrame FrameInfo;
|
||||
|
||||
void TITagitstandardAppInit(void) {
|
||||
State = STATE_READY;
|
||||
@@ -35,6 +33,7 @@ void TITagitstandardAppInit(void) {
|
||||
FrameInfo.Selected = false;
|
||||
|
||||
MemoryReadBlock(&MyAFI, TITAGIT_MEM_AFI_ADDRESS, 1);
|
||||
TITagitstandardGetUid(Uid);
|
||||
}
|
||||
|
||||
void TITagitstandardAppReset(void) {
|
||||
@@ -46,6 +45,9 @@ void TITagitstandardAppReset(void) {
|
||||
FrameInfo.ParamLen = 0;
|
||||
FrameInfo.Addressed = false;
|
||||
FrameInfo.Selected = false;
|
||||
|
||||
MemoryReadBlock(&MyAFI, TITAGIT_MEM_AFI_ADDRESS, 1);
|
||||
TITagitstandardGetUid(Uid);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +60,7 @@ void TITagitstandardAppTick(void) {
|
||||
}
|
||||
|
||||
uint16_t TITagitstandardAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
uint16_t ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
uint8_t Uid[ActiveConfiguration.UidSize];
|
||||
TITagitstandardGetUid(Uid);
|
||||
ResponseByteCount = ISO15693_APP_NO_RESPONSE;
|
||||
|
||||
if ((FrameBytes < ISO15693_MIN_FRAME_SIZE) || !ISO15693CheckCRC(FrameBuf, FrameBytes - ISO15693_CRC16_SIZE))
|
||||
/* malformed frame */
|
||||
@@ -198,12 +198,6 @@ uint16_t TITagitstandardAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ResponseByteCount > 0) {
|
||||
/* There is data to be sent. Append CRC */
|
||||
ISO15693AppendCRC(FrameBuf, ResponseByteCount);
|
||||
ResponseByteCount += ISO15693_CRC16_SIZE;
|
||||
}
|
||||
|
||||
return ResponseByteCount;
|
||||
}
|
||||
|
||||
@@ -214,7 +208,8 @@ void TITagitstandardGetUid(ConfigurationUidType Uid) {
|
||||
TITagitstandardFlipUid(Uid);
|
||||
}
|
||||
|
||||
void TITagitstandardSetUid(ConfigurationUidType Uid) {
|
||||
void TITagitstandardSetUid(ConfigurationUidType NewUid) {
|
||||
memcpy(Uid, NewUid, ActiveConfiguration.UidSize); // Update the local variable
|
||||
// Reverse UID before writing it
|
||||
TITagitstandardFlipUid(Uid);
|
||||
|
||||
|
||||
@@ -92,12 +92,6 @@ uint16_t VicinityAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ResponseByteCount > 0) {
|
||||
/* There is data to be sent. Append CRC */
|
||||
ISO15693AppendCRC(FrameBuf, ResponseByteCount);
|
||||
ResponseByteCount += ISO15693_CRC16_SIZE;
|
||||
}
|
||||
|
||||
return ResponseByteCount;
|
||||
|
||||
} else { // Invalid CRC
|
||||
|
||||
@@ -24,6 +24,11 @@ static volatile struct {
|
||||
|
||||
uint8_t CodecBuffer[CODEC_BUFFER_SIZE];
|
||||
uint8_t CodecBuffer2[CODEC_BUFFER_SIZE];
|
||||
|
||||
void (* volatile isr_func_CODEC_TIMER_LOADMOD_CCB_VECT)(void) = NULL;
|
||||
void (* volatile isr_func_TCD0_CCC_vect)(void) = NULL;
|
||||
void (* volatile isr_func_CODEC_DEMOD_IN_INT0_VECT)(void) = NULL;
|
||||
|
||||
// the following three functions prevent sending data directly after turning on the reader field
|
||||
void CodecReaderFieldStart(void) { // DO NOT CALL THIS FUNCTION INSIDE APPLICATION!
|
||||
if (!CodecGetReaderField() && !ReaderFieldFlags.ToBeRestarted) {
|
||||
|
||||
@@ -8,26 +8,6 @@
|
||||
#ifndef CODEC_H_
|
||||
#define CODEC_H_
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../Common.h"
|
||||
#include "../Configuration.h"
|
||||
#include "../Settings.h"
|
||||
|
||||
#include "ISO14443-2A.h"
|
||||
#include "Reader14443-2A.h"
|
||||
#include "SniffISO14443-2A.h"
|
||||
#include "ISO15693.h"
|
||||
|
||||
/* Timing definitions for ISO14443A */
|
||||
#define ISO14443A_SUBCARRIER_DIVIDER 16
|
||||
#define ISO14443A_BIT_GRID_CYCLES 128
|
||||
#define ISO14443A_BIT_RATE_CYCLES 128
|
||||
#define ISO14443A_FRAME_DELAY_PREV1 1236
|
||||
#define ISO14443A_FRAME_DELAY_PREV0 1172
|
||||
#define ISO14443A_RX_PENDING_TIMEOUT 4 // ms
|
||||
|
||||
/* Peripheral definitions */
|
||||
#define CODEC_DEMOD_POWER_PORT PORTB
|
||||
#define CODEC_DEMOD_POWER_MASK PIN0_bm
|
||||
@@ -87,6 +67,27 @@
|
||||
#define CODEC_TIMER_TIMESTAMPS_CCA_VECT TCD1_CCA_vect
|
||||
#define CODEC_TIMER_TIMESTAMPS_CCB_VECT TCD1_CCB_vect
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../Common.h"
|
||||
#include "../Configuration.h"
|
||||
#include "../Settings.h"
|
||||
|
||||
#include "ISO14443-2A.h"
|
||||
#include "Reader14443-2A.h"
|
||||
#include "SniffISO14443-2A.h"
|
||||
#include "ISO15693.h"
|
||||
|
||||
/* Timing definitions for ISO14443A */
|
||||
#define ISO14443A_SUBCARRIER_DIVIDER 16
|
||||
#define ISO14443A_BIT_GRID_CYCLES 128
|
||||
#define ISO14443A_BIT_RATE_CYCLES 128
|
||||
#define ISO14443A_FRAME_DELAY_PREV1 1236
|
||||
#define ISO14443A_FRAME_DELAY_PREV0 1172
|
||||
#define ISO14443A_RX_PENDING_TIMEOUT 4 // ms
|
||||
|
||||
#define CODEC_BUFFER_SIZE 256
|
||||
|
||||
@@ -115,13 +116,14 @@ typedef enum {
|
||||
extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE];
|
||||
extern uint8_t CodecBuffer2[CODEC_BUFFER_SIZE];
|
||||
|
||||
void (* volatile isr_func_TCD0_CCC_vect)(void);
|
||||
/* Shared ISR pointers and handlers */
|
||||
extern void (* volatile isr_func_TCD0_CCC_vect)(void);
|
||||
void isr_Reader14443_2A_TCD0_CCC_vect(void);
|
||||
void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void);
|
||||
void (* volatile isr_func_CODEC_DEMOD_IN_INT0_VECT)(void);
|
||||
extern void (* volatile isr_func_CODEC_DEMOD_IN_INT0_VECT)(void);
|
||||
void isr_ISO14443_2A_TCD0_CCC_vect(void);
|
||||
void isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void);
|
||||
void (* volatile isr_func_CODEC_TIMER_LOADMOD_CCB_VECT)(void);
|
||||
extern void (* volatile isr_func_CODEC_TIMER_LOADMOD_CCB_VECT)(void);
|
||||
void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void);
|
||||
void isr_SniffISO14443_2A_CODEC_TIMER_LOADMOD_CCB_VECT(void);
|
||||
|
||||
@@ -285,4 +287,7 @@ bool CodecIsReaderToBeRestarted(void);
|
||||
void CodecThresholdSet(uint16_t th);
|
||||
uint16_t CodecThresholdIncrement(void);
|
||||
void CodecThresholdReset(void);
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* CODEC_H_ */
|
||||
|
||||
@@ -79,13 +79,8 @@ static void StartDemod(void) {
|
||||
CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0;
|
||||
}
|
||||
|
||||
ISR(CODEC_DEMOD_IN_INT0_VECT) {
|
||||
isr_func_CODEC_DEMOD_IN_INT0_VECT();
|
||||
}
|
||||
|
||||
// ISR(CODEC_DEMOD_IN_INT0_VECT)
|
||||
// Find first pause and start sampling
|
||||
void isr_ISO14443_2A_TCD0_CCC_vect(void) {
|
||||
ISR_SHARED isr_ISO14443_2A_TCD0_CCC_vect(void) {
|
||||
/* This is the first edge of the first modulation-pause after StartDemod.
|
||||
* Now we have time to start
|
||||
* demodulating beginning from one bit-width after this edge. */
|
||||
|
||||
@@ -4,6 +4,25 @@
|
||||
* Created on: 25.01.2017
|
||||
* Author: Phillip Nash
|
||||
* Modified by: ceres-c
|
||||
*
|
||||
* Interrupts information
|
||||
* - Compare/Capture Channels are used as compare. They're used to sample the field in different moments of time
|
||||
* - Reader field demodulation events are routed on Event Channel 0, card data modulation on Event Channel 6
|
||||
* - Reader field demodulation uses Compare Channel C, card data modulation Compare Channel D (PORTB in both cases, of course)
|
||||
*
|
||||
* Loadmod code flow:
|
||||
* Loadmodulation is performed via a state machine inside a ISR, triggered by a counter's (TCD0) overflow interrupt. The interrupt
|
||||
* is configured in StartISO15693Demod to have a PER (period) equal to ISO15693 t1 nominal time: 4352 carrier pulses.
|
||||
* (see ISO15693-3:2009, section 9.1).
|
||||
* Once a EOF is reached when demodulating data from the reader, TCD0's PERBUF register is configured with the period of
|
||||
* bit transmission (32 carrier pulses). This means that, once the first period overflow is reached (t1 expiration)
|
||||
* the ISR will output data at the frequency dictated by the standard. This is due to the behaviour of buffered registers, see
|
||||
* 8045A-AVR-02/08 section 3.7.
|
||||
*
|
||||
* Once t1 is reached (the counter overflowed), transmission of data should theoretically begin, but this is not guaranteed,
|
||||
* due to possible slowdowns of data generation in the currently running Application. Until the application is done,
|
||||
* the state machine will be stuck in LOADMOD_WAIT state, not outputting any data.
|
||||
* The ISR will now be invoked every 32 carrier pulses (see ISO15693-2:2006, section 8.2), even when waiting for data.
|
||||
*/
|
||||
|
||||
#include "ISO15693.h"
|
||||
@@ -12,18 +31,20 @@
|
||||
#include "LEDHook.h"
|
||||
#include "AntennaLevel.h"
|
||||
#include "Terminal/Terminal.h"
|
||||
#include <util/delay.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
|
||||
#define SOC_1_OF_4_CODE 0x7B
|
||||
#define SOC_1_OF_256_CODE 0x7E
|
||||
#define EOC_CODE 0xDF
|
||||
#define REQ_SUBCARRIER_SINGLE 0x00
|
||||
#define REQ_SUBCARRIER_DUAL 0x01
|
||||
#define REQ_DATARATE_LOW 0x00
|
||||
#define REQ_DATARATE_HIGH 0x02
|
||||
#define ISO15693_SAMPLE_CLK TC_CLKSEL_DIV2_gc // 13.56MHz
|
||||
#define ISO15693_SAMPLE_PERIOD 128 // 9.4us
|
||||
#define ISO15693_T1_TIME 4352 - 14 /* ISO t1 time - ISR prologue compensation */ // 4192 + 128 + 128 - 1
|
||||
|
||||
#define WRITE_GRID_CYCLES 4096
|
||||
#define SUBCARRIER_1 32
|
||||
#define SUBCARRIER_2 28
|
||||
#define SUBCARRIER_OFF 0
|
||||
@@ -43,7 +64,6 @@
|
||||
static volatile struct {
|
||||
volatile bool DemodFinished;
|
||||
volatile bool LoadmodFinished;
|
||||
volatile bool DemodAborted;
|
||||
} Flags = { 0 };
|
||||
|
||||
typedef enum {
|
||||
@@ -78,28 +98,22 @@ static volatile uint8_t ByteCount;
|
||||
static volatile uint16_t BitRate1;
|
||||
static volatile uint16_t BitRate2;
|
||||
static volatile uint16_t SampleDataCount;
|
||||
static volatile uint16_t ReadCommandFromReader = 0;
|
||||
|
||||
#ifdef CONFIG_VICINITY_SUPPORT
|
||||
|
||||
/* This function implements CODEC_DEMOD_IN_INT0_VECT interrupt vector.
|
||||
* It is called when a pulse is detected in CODEC_DEMOD_IN_PORT (PORTB).
|
||||
* The relevatn interrupt vector is registered to CODEC_DEMOD_IN_MASK0 (PIN1) via:
|
||||
* The relevant interrupt vector was registered to CODEC_DEMOD_IN_MASK0 (PIN1) via:
|
||||
* CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0;
|
||||
* and unregistered writing the INT0MASK to 0
|
||||
*/
|
||||
// ISR(CODEC_DEMOD_IN_INT0_VECT)
|
||||
void isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void) {
|
||||
/* Start sample timer CODEC_TIMER_SAMPLING (TCD0).
|
||||
* Set Counter Channel C (CCC) with relevant bitmask (TC0_CCCIF_bm),
|
||||
* the period for clock sampling is specified in StartISO15693Demod.
|
||||
*/
|
||||
ISR_SHARED isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT(void) {
|
||||
/* Clear Compare Channel C (CCC) interrupt Flags - From 14.12.10 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm;
|
||||
/* Sets register INTCTRLB to TC_CCCINTLVL_HI_gc = (0x03<<4) to enable compare/capture for high level interrupts on Channel C (CCC) */
|
||||
/* Enable compare/capture for high level interrupts on Capture Channel C for TCD0 - From 14.12.7 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_HI_gc;
|
||||
|
||||
/* Disable this interrupt as we've already sensed the relevant pulse and will use our internal clock from now on */
|
||||
/* Disable this interrupt. From now on we will sample the field using our internal clock - From 13.13.11 [8331F–AVR–04/2013] */
|
||||
CODEC_DEMOD_IN_PORT.INT0MASK = 0;
|
||||
|
||||
}
|
||||
|
||||
/* This function is called from isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT
|
||||
@@ -107,36 +121,50 @@ void 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 */
|
||||
BitRate1 = 256 * 4; // 256 * 4 - 1
|
||||
if (CodecBuffer[0] & ISO15693_REQ_DATARATE_HIGH)
|
||||
if (CodecBuffer[0] & REQ_DATARATE_HIGH) {
|
||||
BitRate1 = 256;
|
||||
|
||||
if (CodecBuffer[0] & ISO15693_REQ_SUBCARRIER_DUAL) {
|
||||
BitRate2 = 252 * 4; // 252 * 4 - 3
|
||||
if (CodecBuffer[0] & ISO15693_REQ_DATARATE_HIGH)
|
||||
BitRate2 = 252;
|
||||
BitRate2 = 252; /* If single subcarrier mode is requested, BitRate2 is useless, but setting it nevertheless was still faster than checking */
|
||||
} else {
|
||||
BitRate2 = BitRate1;
|
||||
BitRate1 = 256 * 4; // Possible value: 256 * 4 - 1
|
||||
BitRate2 = 252 * 4; // Possible value: 252 * 4 - 3
|
||||
}
|
||||
|
||||
/* Disable event action for CODEC_TIMER_LOADMOD (TCE0) as we're done receiving data */
|
||||
CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc;
|
||||
/* Set Counter Channel B (CCB) with relevant bitmask (TC0_CCBIF_bm), the period for clock sampling is specified below */
|
||||
CODEC_TIMER_LOADMOD.INTFLAGS = TC0_CCBIF_bm; // TODO This might not be needed since commenting it does not break anything
|
||||
/* Sets register INTCTRLB to TC_CCBINTLVL_HI_gc = (0x03<<2) to enable compare/capture for high level interrupts on channel B */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_HI_gc;
|
||||
/* Set the period for CODEC_TIMER_LOADMOD (TCE0) to Bitrate - 1 because PERBUF is 0-based
|
||||
*
|
||||
* TODO Why are we using PERBUF instead of PER?
|
||||
* With PERBUF the period register will occur on the next overflow.
|
||||
*/
|
||||
CODEC_TIMER_LOADMOD.PERBUF = BitRate1 - 1;
|
||||
|
||||
Flags.DemodFinished = 1;
|
||||
/* Sets timer off for CODEC_TIMER_SAMPLING (TCD0) disabling clock source */
|
||||
/* Disable demodulation interrupt */
|
||||
/* Sets timer off for TCD0, disabling clock source. We're done receiving data from reader and don't need to probe the antenna anymore - From 14.12.1 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc;
|
||||
/* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = 0;
|
||||
/* Disable event action for CODEC_TIMER_SAMPLING (TCD0) - From 14.12.4 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc;
|
||||
/* Disable compare/capture interrupts on Channel C - From 14.12.7 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc;
|
||||
/* Clear Compare Channel C (CCC) interrupt Flags - From 14.12.10 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm;
|
||||
|
||||
/* Enable loadmodulation interrupt */
|
||||
/* Disable the event action for TCE0 - From 14.12.4 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc;
|
||||
/* Enable compare/capture for high level interrupts on channel B for TCE0 - From 14.12.7 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_HI_gc;
|
||||
/* Clear TCE0 interrupt flags for Capture Channel B - From 14.12.10 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_LOADMOD.INTFLAGS = TC0_CCBIF_bm;
|
||||
/* Set the BUFFERED PERIOD to Bitrate - 1 (because PERBUF is 0-based).
|
||||
* The current PERIOD was set in StartISO15693Demod to ISO15693_T1_TIME, once ISO15693_T1_TIME is reached, this will be the new PERIOD.
|
||||
* From 3.7 [8045A-AVR-02/08] */
|
||||
CODEC_TIMER_LOADMOD.PERBUF = BitRate1 - 1;
|
||||
}
|
||||
|
||||
/* Disable data demodulation interrupt and inform the codec to restart demodulation from scratch */
|
||||
INLINE void ISO15693_GARBAGE(void) {
|
||||
Flags.DemodFinished = 1;
|
||||
|
||||
/* Sets timer off for TCD0, disabling clock source. We have demodulated rubbish and don't need to probe the antenna anymore - From 14.12.1 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc;
|
||||
/* Disable event action for CODEC_TIMER_SAMPLING (TCD0) - From 14.12.4 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc;
|
||||
/* Disable compare/capture interrupts on Channel C - From 14.12.7 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc;
|
||||
/* Clear Compare Channel C (CCC) interrupt Flags - From 14.12.10 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm;
|
||||
}
|
||||
|
||||
/* This function is registered to CODEC_TIMER_SAMPLING (TCD0)'s Counter Channel C (CCC).
|
||||
@@ -144,10 +172,9 @@ INLINE void ISO15693_EOC(void) {
|
||||
*
|
||||
* It demodulates bits received from the reader and saves them in CodecBuffer.
|
||||
*
|
||||
* It disables its own interrupt when receives an EOF (calling ISO15693_EOC) or when it receives garbage
|
||||
* It disables its own interrupt when an EOF is found (calling ISO15693_EOC) or when it receives garbage
|
||||
*/
|
||||
// ISR(CODEC_TIMER_SAMPLING_CCC_VECT) // Reading data sent from the reader
|
||||
void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) {
|
||||
ISR_SHARED isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) {
|
||||
/* Shift demod data */
|
||||
SampleRegister = (SampleRegister << 1) | (!(CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK) ? 0x01 : 0x00);
|
||||
|
||||
@@ -163,11 +190,7 @@ void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) {
|
||||
DemodState = DEMOD_1_OUT_OF_256_STATE;
|
||||
SampleDataCount = 0;
|
||||
} else { // No SOC. Restart and try again, we probably received garbage.
|
||||
Flags.DemodFinished = 1;
|
||||
/* Sets timer off for CODEC_TIMER_SAMPLING (TCD0) disabling clock source */
|
||||
CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc;
|
||||
/* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = 0;
|
||||
ISO15693_GARBAGE();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -250,7 +273,6 @@ void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) {
|
||||
SampleDataCount++;
|
||||
}
|
||||
|
||||
|
||||
/* This function is registered to CODEC_TIMER_LOADMOD (TCE0)'s Counter Channel B (CCB).
|
||||
* When the timer is enabled, this is called on counter's overflow
|
||||
*
|
||||
@@ -258,9 +280,9 @@ void isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT(void) {
|
||||
*
|
||||
* It disables its own interrupt when all data has been sent
|
||||
*/
|
||||
//ISR(CODEC_TIMER_LOADMOD_CCB_VECT)
|
||||
void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) {
|
||||
ISR_SHARED isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) {
|
||||
static void *JumpTable[] = {
|
||||
[LOADMOD_WAIT] = && LOADMOD_WAIT_LABEL,
|
||||
[LOADMOD_START_SINGLE] = && LOADMOD_START_SINGLE_LABEL,
|
||||
[LOADMOD_SOF_SINGLE] = && LOADMOD_SOF_SINGLE_LABEL,
|
||||
[LOADMOD_BIT0_SINGLE] = && LOADMOD_BIT0_SINGLE_LABEL,
|
||||
@@ -274,11 +296,11 @@ void isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT(void) {
|
||||
[LOADMOD_FINISHED] = && LOADMOD_FINISHED_LABEL
|
||||
};
|
||||
|
||||
if ((StateRegister >= LOADMOD_START_SINGLE) && (StateRegister <= LOADMOD_FINISHED)) {
|
||||
goto *JumpTable[StateRegister];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
goto *JumpTable[StateRegister]; /* It takes 28 clock cycles to get here from function entry point */
|
||||
|
||||
LOADMOD_WAIT_LABEL:
|
||||
/* ISO t1 is over, but application is not done generating data yet */
|
||||
return;
|
||||
|
||||
LOADMOD_START_SINGLE_LABEL:
|
||||
/* Application produced data. With this interrupt we are aligned to the bit-grid. */
|
||||
@@ -356,9 +378,7 @@ LOADMOD_EOF_SINGLE_LABEL: //End of Manchester encoding
|
||||
if ((BitSent % 8) == 0) {
|
||||
/* Last bit has been put out */
|
||||
StateRegister = LOADMOD_FINISHED;
|
||||
} else {
|
||||
StateRegister = LOADMOD_EOF_SINGLE;
|
||||
}
|
||||
} /* else: stay in this state. No changes needed */
|
||||
return;
|
||||
|
||||
// -------------------------------------------------------------
|
||||
@@ -446,24 +466,20 @@ LOADMOD_EOF_DUAL_LABEL: //End of Manchester encoding
|
||||
if ((BitSent % 8) == 0) {
|
||||
/* Last bit has been put out */
|
||||
StateRegister = LOADMOD_FINISHED;
|
||||
} else {
|
||||
StateRegister = LOADMOD_EOF_DUAL;
|
||||
}
|
||||
} /* else: stay in this state. No changes needed */
|
||||
return;
|
||||
|
||||
LOADMOD_FINISHED_LABEL:
|
||||
/* Sets timer off for CODEC_TIMER_LOADMOD (TCE0) disabling clock source as we're done modulating */
|
||||
CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc;
|
||||
/* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLB = 0;
|
||||
/* Disable compare/capture for all level interrupts on channel B for TCE0 - From 14.12.7 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_OFF_gc;
|
||||
CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OFF, 0);
|
||||
Flags.LoadmodFinished = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_VICINITY_SUPPORT */
|
||||
|
||||
/* This functions resets all global variables used in the codec and enables interrupts to wait for reader data */
|
||||
/* Reset global variables/interrupts to demodulate incoming reader data via ISRs */
|
||||
void StartISO15693Demod(void) {
|
||||
/* Reset global variables to default values */
|
||||
CodecBufferPtr = CodecBuffer;
|
||||
@@ -479,69 +495,85 @@ void StartISO15693Demod(void) {
|
||||
ByteCount = 0;
|
||||
ShiftRegister = 0;
|
||||
|
||||
/* Activate Power for demodulator */
|
||||
CodecSetDemodPower(true);
|
||||
|
||||
/* Configure sampling-timer free running and sync to first modulation-pause. */
|
||||
/* Resets the counter to 0 */
|
||||
CODEC_TIMER_SAMPLING.CNT = 0;
|
||||
/* Set the period for CODEC_TIMER_SAMPLING (TCD0) to ISO15693_SAMPLE_PERIOD - 1 because PER is 0-based */
|
||||
CODEC_TIMER_SAMPLING.PER = ISO15693_SAMPLE_PERIOD - 1;
|
||||
/* Set Counter Channel C (CCC) register with half bit period - 1. (- 14 to compensate ISR timing overhead) */
|
||||
CODEC_TIMER_SAMPLING.CCC = ISO15693_SAMPLE_PERIOD / 2 - 14 - 1;
|
||||
/* Set timer for CODEC_TIMER_SAMPLING (TCD0) to ISO15693_SAMPLE_CLK = TC_CLKSEL_DIV2_gc = System Clock / 2
|
||||
*
|
||||
* TODO Why system clock / 2 and not iso period?
|
||||
/* Set clock source for TCD0 to ISO15693_SAMPLE_CLK = TC_CLKSEL_DIV2_gc = System Clock / 2.
|
||||
* Since the Chameleon is clocked at 13.56*2 MHz (see Makefile), this counter will hit at the same frequency of reader field.
|
||||
* From 14.12.1 [8331F–AVR–04/2013]
|
||||
*/
|
||||
CODEC_TIMER_SAMPLING.CTRLA = ISO15693_SAMPLE_CLK;
|
||||
/* Set event action for CODEC_TIMER_SAMPLING (TCD0) to restart and trigger CODEC_TIMER_MODSTART_EVSEL = TC_EVSEL_CH0_gc = Event Channel 0 */
|
||||
/* Set up TCD0 action/source:
|
||||
* - Event Action: Restart waveform period (reset PER register)
|
||||
* - Event Source Select: trigger on CODEC_TIMER_MODSTART_EVSEL = TC_EVSEL_CH0_gc = Event Channel 0
|
||||
* From 14.12.4 [8331F–AVR–04/2013]
|
||||
*/
|
||||
CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | CODEC_TIMER_MODSTART_EVSEL;
|
||||
/* Set Counter Channel C (CCC) with relevant bitmask (TC0_CCCIF_bm), the period for clock sampling is specified above */
|
||||
CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm;
|
||||
/* Sets register INTCTRLB to TC_CCCINTLVL_OFF_gc = (0x00<<4) to disable compare/capture C interrupts
|
||||
*
|
||||
* TODO Why turn it off?
|
||||
*/
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc;
|
||||
/* Resets the sampling counter (TCD0) to 0 - From 14.12.12 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.CNT = 0;
|
||||
|
||||
/* Set event action for CODEC_TIMER_LOADMOD (TCE0) to restart and trigger CODEC_TIMER_MODSTART_EVSEL = TC_EVSEL_CH0_gc = Event Channel 0 */
|
||||
CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | CODEC_TIMER_MODSTART_EVSEL;
|
||||
/* Set the period for CODEC_TIMER_LOADMOD (TCE0) to... some magic numbers?
|
||||
* Using PER instead of PERBUF breaks it when receiving ISO15693_APP_NO_RESPONSE from Application.
|
||||
*
|
||||
* TODO What are these numbers?
|
||||
/* Set Clock Source for TCE0 to CODEC_TIMER_CARRIER_CLKSEL = TC_CLKSEL_EVCH6_gc = Event Channel 6 */
|
||||
CODEC_TIMER_LOADMOD.CTRLA = CODEC_TIMER_CARRIER_CLKSEL;
|
||||
/* Set up TCE0 action/source:
|
||||
* - Event Action: Restart waveform period (reset PER register)
|
||||
* - Event Source Select: trigger on CODEC_TIMER_MODSTART_EVSEL = TC_EVSEL_CH0_gc = Event Channel 0
|
||||
* From 14.12.4 [8331F–AVR–04/2013]
|
||||
*/
|
||||
CODEC_TIMER_LOADMOD.PERBUF = 4192 + 128 + 128 - 1;
|
||||
/* Sets register INTCTRLA to 0 to disable timer error or overflow interrupts */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLA = 0;
|
||||
/* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLB = 0;
|
||||
/* Set timer for CODEC_TIMER_SAMPLING (TCD0) to TC_CLKSEL_EVCH6_gc = Event Channel 6 */
|
||||
CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_EVCH6_gc;
|
||||
CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | CODEC_TIMER_MODSTART_EVSEL;
|
||||
/* Temporarily disable compare/capture for all level interrupts on channel B for TCE0. They'll be enabled later when load modulation will be needed.
|
||||
* From 14.12.7 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_OFF_gc;
|
||||
/* Set the period for CODEC_TIMER_LOADMOD (TCE0) ISO standard t1 time.
|
||||
* Once this timer is enabled, it will wait for a time equal to t1 and then its ISR will be called.
|
||||
* From 14.12.18 [8331F–AVR–04/2013]
|
||||
*/
|
||||
CODEC_TIMER_LOADMOD.PER = ISO15693_T1_TIME;
|
||||
|
||||
/* Start looking out for modulation pause via interrupt. */
|
||||
/* Sets register INTFLAGS to PORT_INT0LVL_HI_gc = (0x03<<0) to enable compare/capture for high level interrupts on CODEC_DEMOD_IN_PORT (PORTB) */
|
||||
CODEC_DEMOD_IN_PORT.INTFLAGS = PORT_INT0LVL_HI_gc;
|
||||
/* Sets INT0MASK to CODEC_DEMOD_IN_MASK0 = PIN1_bm to use it as source for port interrupt 0 */
|
||||
/* Clear PORTB interrupt flags - From 13.13.13 [8331F–AVR–04/2013] */
|
||||
CODEC_DEMOD_IN_PORT.INTFLAGS = PORT_INT0IF_bm;
|
||||
/* Use PIN1 as a source for modulation pauses. Will trigger PORTB Interrput 0 - From 13.13.11 [8331F–AVR–04/2013] */
|
||||
CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0;
|
||||
}
|
||||
|
||||
/* Configure unvarying interrupts settings.
|
||||
* All configured interrupts will still be disabled once this function is done, they'll be enabled one by one as the communication flow requires them.
|
||||
*/
|
||||
void ISO15693CodecInit(void) {
|
||||
CodecInitCommon();
|
||||
|
||||
/* Register isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT function
|
||||
* to CODEC_TIMER_SAMPLING (TCD0)'s Counter Channel C (CCC)
|
||||
*/
|
||||
/**************************************************
|
||||
* Register function handlers to shared ISR *
|
||||
**************************************************/
|
||||
/* Register isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT function to CODEC_TIMER_SAMPLING (TCD0)'s Counter Channel C (CCC) */
|
||||
isr_func_TCD0_CCC_vect = &isr_ISO15693_CODEC_TIMER_SAMPLING_CCC_VECT;
|
||||
/* Register isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT function
|
||||
* to CODEC_DEMOD_IN_PORT (PORTB) interrupt 0
|
||||
*/
|
||||
/* Register isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT function to CODEC_DEMOD_IN_PORT (PORTB) interrupt 0 */
|
||||
isr_func_CODEC_DEMOD_IN_INT0_VECT = &isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT;
|
||||
/* Register isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT function
|
||||
* to CODEC_TIMER_LOADMOD (TCE0)'s Counter Channel B (CCB)
|
||||
*/
|
||||
/* Register isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT function to CODEC_TIMER_LOADMOD (TCE0)'s Counter Channel B (CCB) */
|
||||
isr_func_CODEC_TIMER_LOADMOD_CCB_VECT = &isr_ISO15693_CODEC_TIMER_LOADMOD_CCB_VECT;
|
||||
|
||||
/**************************************************
|
||||
* Configure demod interrupt *
|
||||
**************************************************/
|
||||
/* Configure sampling-timer free running and sync to first modulation-pause */
|
||||
/* Set the period for TCD0 to ISO15693_SAMPLE_PERIOD - 1 because PER is 0-based - From 14.12.14 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.PER = ISO15693_SAMPLE_PERIOD - 1;
|
||||
/* Set Compare Channel C (CCC) period to half bit period - 1. (- 14 to compensate ISR timing overhead) - From 14.12.16 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.CCC = ISO15693_SAMPLE_PERIOD / 2 - 14 - 1;
|
||||
/* Temporarily disable Compare Channel C (CCC) interrupts.
|
||||
* They'll be enabled later in isr_ISO15693_CODEC_DEMOD_IN_INT0_VECT once we sensed the reader is sending data and we're in sync with the pulses.
|
||||
* From 14.12.7 [8331F–AVR–04/2013]
|
||||
*/
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc;
|
||||
/* Clear Compare Channel C (CCC) interrupt Flags - From 14.12.10 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm;
|
||||
|
||||
/**************************************************
|
||||
* Configure loadmod interrupt *
|
||||
**************************************************/
|
||||
/* Disable timer error and overflow interrupts - From 14.12.6 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLA = 0;
|
||||
|
||||
/* Activate Power for demodulator */
|
||||
CodecSetDemodPower(true);
|
||||
|
||||
StartISO15693Demod();
|
||||
}
|
||||
|
||||
@@ -564,21 +596,21 @@ void ISO15693CodecDeInit(void) {
|
||||
ShiftRegister = 0;
|
||||
|
||||
/* Disable sample timer */
|
||||
/* Sets timer off for CODEC_TIMER_SAMPLING (TCD0) disabling clock source */
|
||||
/* Sets timer off for TCD0, disabling clock source - From 14.12.1 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc;
|
||||
/* Disable event action for CODEC_TIMER_SAMPLING (TCD0) */
|
||||
/* Disable event action for CODEC_TIMER_SAMPLING (TCD0) - From 14.12.4 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc;
|
||||
/* Sets register INTCTRLB to TC_CCCINTLVL_OFF_gc = (0x00<<4) to disable compare/capture C interrupts */
|
||||
/* Disable Compare Channel C (CCC) interrupts - From 14.12.7 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc;
|
||||
/* Restore Counter Channel C (CCC) interrupt mask (TC0_CCCIF_bm) */
|
||||
/* Clear Compare Channel C (CCC) interrupt Flags - From 14.12.10 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm;
|
||||
|
||||
/* Disable load modulation */
|
||||
/* Disable event action for CODEC_TIMER_LOADMOD (TCE0) */
|
||||
/* Disable the event action for TCE0 - From 14.12.4 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc;
|
||||
/* Sets register INTCTRLB to TC_CCBINTLVL_OFF_gc = (0x00<<2) to disable compare/capture B interrupts */
|
||||
/* Disable compare/capture for all level interrupts on channel B for TCE0 - From 14.12.7 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLB = TC_CCBINTLVL_OFF_gc;
|
||||
/* Restore Counter Channel B (CCB) interrupt mask (TC0_CCBIF_bm) */
|
||||
/* Clear TCE0 interrupt flags for Capture Channel B - From 14.12.10 [8331F–AVR–04/2013] */
|
||||
CODEC_TIMER_LOADMOD.INTFLAGS = TC0_CCBIF_bm;
|
||||
|
||||
CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OFF, 0);
|
||||
@@ -598,7 +630,7 @@ void ISO15693CodecTask(void) {
|
||||
LogEntry(LOG_INFO_CODEC_RX_DATA, CodecBuffer, DemodByteCount);
|
||||
LEDHook(LED_CODEC_RX, LED_PULSE);
|
||||
|
||||
if (CodecBuffer[0] & ISO15693_REQ_SUBCARRIER_DUAL) {
|
||||
if (CodecBuffer[0] & REQ_SUBCARRIER_DUAL) {
|
||||
bDualSubcarrier = true;
|
||||
}
|
||||
AppReceivedByteCount = ApplicationProcess(CodecBuffer, DemodByteCount);
|
||||
@@ -606,7 +638,13 @@ void ISO15693CodecTask(void) {
|
||||
|
||||
/* This is only reached when we've received a valid frame */
|
||||
if (AppReceivedByteCount != ISO15693_APP_NO_RESPONSE) {
|
||||
LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, AppReceivedByteCount);
|
||||
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;
|
||||
AppReceivedByteCount = 2;
|
||||
LogEntry(LOG_INFO_GENERIC, "Too much data requested - See PR #274", 38);
|
||||
}
|
||||
|
||||
LEDHook(LED_CODEC_TX, LED_PULSE);
|
||||
|
||||
ByteCount = AppReceivedByteCount;
|
||||
@@ -621,13 +659,21 @@ void ISO15693CodecTask(void) {
|
||||
StateRegister = LOADMOD_START_SINGLE;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* No data to process. Disable CODEC_TIMER_LOADMOD (TCE0) counter and start listening again */
|
||||
/* Sets timer off for CODEC_TIMER_LOADMOD (TCE0) disabling clock source as we're done modulating */
|
||||
CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc;
|
||||
/* Sets register INTCTRLB to 0 to disable all compare/capture interrupts */
|
||||
CODEC_TIMER_LOADMOD.INTCTRLB = 0;
|
||||
/* 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 {
|
||||
/* 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
|
||||
* in the PER register and that will happen on the next UPDATE event.
|
||||
* The next UPDATE event will be timer/counter enablement in ISO15693_EOC, which is executed after StartISO15693Demod,
|
||||
* effectively overwriting PER with an incorrect value.
|
||||
* See 8045A-AVR-02/08 section 3.7 for information about buffered registers.
|
||||
*/
|
||||
CODEC_TIMER_LOADMOD.PERBUF = ISO15693_T1_TIME;
|
||||
StartISO15693Demod();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,26 +8,8 @@
|
||||
#ifndef ISO15693_H_
|
||||
#define ISO15693_H_
|
||||
|
||||
#include "Terminal/CommandLine.h"
|
||||
|
||||
#define ISO15693_APP_NO_RESPONSE 0x0000
|
||||
|
||||
#define SUBCARRIER_1 32
|
||||
#define SUBCARRIER_2 28
|
||||
#define SUBCARRIER_OFF 0
|
||||
#define SOF_PATTERN 0x1D
|
||||
#define EOF_PATTERN 0xB8
|
||||
|
||||
#define T1_NOMINAL_CYCLES 4352 - 14//4352 - 25 /* ISR prologue compensation */
|
||||
#define WRITE_GRID_CYCLES 4096
|
||||
|
||||
//Used when checking the request sent from the reader
|
||||
#define ISO15693_REQ_SUBCARRIER_SINGLE 0x00
|
||||
#define ISO15693_REQ_SUBCARRIER_DUAL 0x01
|
||||
#define ISO15693_REQ_DATARATE_LOW 0x00
|
||||
#define ISO15693_REQ_DATARATE_HIGH 0x02
|
||||
|
||||
|
||||
/* Codec Interface */
|
||||
void ISO15693CodecInit(void);
|
||||
void ISO15693CodecDeInit(void);
|
||||
@@ -37,6 +19,4 @@ void ISO15693CodecTask(void);
|
||||
void ISO15693CodecStart(void);
|
||||
void ISO15693CodecReset(void);
|
||||
|
||||
|
||||
|
||||
#endif /* ISO15693_H_ */
|
||||
|
||||
@@ -170,13 +170,10 @@ INLINE void BufferToSequence(void) {
|
||||
if (BitCount % 8)
|
||||
CodecBuffer[BitCount / 8] = SampleRegister >> (8 - (BitCount % 8));
|
||||
}
|
||||
// Frame Delay Time PCD to PICC ends
|
||||
ISR(CODEC_TIMER_SAMPLING_CCC_VECT) {
|
||||
isr_func_TCD0_CCC_vect();
|
||||
}
|
||||
|
||||
// ISR (TCD0_CCC_vect)
|
||||
void isr_Reader14443_2A_TCD0_CCC_vect(void) {
|
||||
// Frame Delay Time PCD to PICC ends
|
||||
ISR_SHARED isr_Reader14443_2A_TCD0_CCC_vect(void) {
|
||||
CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCCIF_bm;
|
||||
CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCCINTLVL_OFF_gc;
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ static volatile uint16_t ReaderBitCount;
|
||||
static volatile uint16_t CardBitCount;
|
||||
static volatile uint16_t rawBitCount;
|
||||
|
||||
enum RCTraffic TrafficSource;
|
||||
|
||||
INLINE void CardSniffInit(void);
|
||||
INLINE void CardSniffDeinit(void);
|
||||
|
||||
@@ -351,16 +353,13 @@ ISR(ACA_AC0_vect) { // this interrupt either finds the SOC or gets triggered bef
|
||||
StateRegister = PICC_FRAME;
|
||||
}
|
||||
|
||||
ISR(CODEC_TIMER_LOADMOD_CCB_VECT) { // pause found
|
||||
isr_func_CODEC_TIMER_LOADMOD_CCB_VECT();
|
||||
}
|
||||
|
||||
// Called once a pause is found
|
||||
// Decode the Card -> Reader signal
|
||||
// according to the pause and modulated period
|
||||
// if the half bit duration is modulated, then add 1 to buffer
|
||||
// if the half bit duration is not modulated, then add 0 to buffer
|
||||
//ISR(CODEC_TIMER_LOADMOD_CCB_VECT) // pause found
|
||||
void isr_SniffISO14443_2A_CODEC_TIMER_LOADMOD_CCB_VECT(void) {
|
||||
ISR_SHARED isr_SniffISO14443_2A_CODEC_TIMER_LOADMOD_CCB_VECT(void) {
|
||||
uint8_t tmp = CODEC_TIMER_TIMESTAMPS.CNTL;
|
||||
CODEC_TIMER_TIMESTAMPS.CNT = 0;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "Codec.h"
|
||||
#include "Terminal/CommandLine.h"
|
||||
|
||||
enum RCTraffic {TRAFFIC_READER, TRAFFIC_CARD} TrafficSource;
|
||||
extern enum RCTraffic {TRAFFIC_READER, TRAFFIC_CARD} TrafficSource;
|
||||
/* Codec Interface */
|
||||
void Sniff14443ACodecInit(void);
|
||||
void Sniff14443ACodecDeInit(void);
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
#define ODD_PARITY(Value) OddParityBit(Value)//(parity_even_bit(Value) ? 0 : 1)
|
||||
|
||||
#define ISR_SHARED \
|
||||
void __attribute__((signal)) // This function type has to be used for all the interrupt handlers that have to be changed at runtime
|
||||
|
||||
#define INLINE \
|
||||
static inline __attribute__((always_inline))
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
; This file allows to share ISR at runtime with a low overhead.
|
||||
; Functions that have to be shared MUST be defined as ISR_SHARED types
|
||||
; (Defined in Common.h) to instruct GCC to compile them preserving the stack
|
||||
;
|
||||
; Created on: 2019-12-06
|
||||
; Author: ceres-c
|
||||
;
|
||||
|
||||
#include "Codec/Codec.h"
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
; Macro to call ISR functions
|
||||
; For development purposes: cycles penality before landing in the Shared ISR is 10
|
||||
.macro call_isr isr_address
|
||||
push r30 ; 1
|
||||
push r31 ; 1
|
||||
lds r30, \isr_address ; 3
|
||||
lds r31, \isr_address+1 ; 3
|
||||
icall ; 2 (16 bit PC)
|
||||
pop r31
|
||||
pop r30
|
||||
reti
|
||||
.endm
|
||||
|
||||
; Shared ISR must be defined below as globals
|
||||
; Example:
|
||||
;
|
||||
; .global <INTERRUPT-TO-SHARE>
|
||||
; INTERRUPT-TO-SHARE:
|
||||
; call_isr POINTER-TO-VARIABLE-INTERRUPT-HANDLER
|
||||
;
|
||||
; Where:
|
||||
; INTERRUPT-TO-SHARE
|
||||
; The target interrupt which needs to be shared
|
||||
; POINTER-TO-VARIABLE-INTERRUPT-HANDLER
|
||||
; A pointer to the interrupt handler which can be modified at runtime.
|
||||
; Must be a volatile pointer to function declared in Codec.h
|
||||
|
||||
.global CODEC_DEMOD_IN_INT0_VECT
|
||||
CODEC_DEMOD_IN_INT0_VECT:
|
||||
call_isr isr_func_CODEC_DEMOD_IN_INT0_VECT
|
||||
|
||||
.global CODEC_TIMER_SAMPLING_CCC_VECT
|
||||
CODEC_TIMER_SAMPLING_CCC_VECT:
|
||||
call_isr isr_func_TCD0_CCC_vect
|
||||
|
||||
.global CODEC_TIMER_LOADMOD_CCB_VECT
|
||||
CODEC_TIMER_LOADMOD_CCB_VECT:
|
||||
call_isr isr_func_CODEC_TIMER_LOADMOD_CCB_VECT
|
||||
File diff suppressed because it is too large
Load Diff
@@ -97,7 +97,7 @@ F_CPU = 27120000
|
||||
F_USB = 48000000
|
||||
TARGET = Chameleon-Mini
|
||||
OPTIMIZATION = s
|
||||
SRC += $(TARGET).c LUFADescriptors.c System.c Configuration.c Random.c Common.c Memory.c MemoryAsm.S Button.c Log.c Settings.c LED.c Map.c AntennaLevel.c
|
||||
SRC += $(TARGET).c LUFADescriptors.c System.c ISRSharing.S Configuration.c Random.c Common.c Memory.c MemoryAsm.S Button.c Log.c Settings.c LED.c Map.c AntennaLevel.c
|
||||
SRC += Terminal/Terminal.c Terminal/Commands.c Terminal/XModem.c Terminal/CommandLine.c
|
||||
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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user