mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
armsrc: fix mix of spaces & tabs
This commit is contained in:
parent
23f1a253a7
commit
8a7c6825b5
47 changed files with 18186 additions and 18184 deletions
236
armsrc/BigBuf.c
236
armsrc/BigBuf.c
|
@ -20,7 +20,7 @@ Pointer to highest available memory: BigBuf_hi
|
|||
|
||||
high BIGBUF_SIZE
|
||||
reserved = BigBuf_malloc() subtracts amount from BigBuf_hi,
|
||||
low 0x00
|
||||
low 0x00
|
||||
*/
|
||||
|
||||
// High memory mark
|
||||
|
@ -35,92 +35,92 @@ static bool tracing = true; //todo static?
|
|||
|
||||
// get the address of BigBuf
|
||||
uint8_t *BigBuf_get_addr(void) {
|
||||
return (uint8_t *)BigBuf;
|
||||
return (uint8_t *)BigBuf;
|
||||
}
|
||||
|
||||
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
||||
uint8_t *BigBuf_get_EM_addr(void) {
|
||||
// not yet allocated
|
||||
if (emulator_memory == NULL)
|
||||
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
|
||||
// not yet allocated
|
||||
if (emulator_memory == NULL)
|
||||
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
|
||||
|
||||
return emulator_memory;
|
||||
return emulator_memory;
|
||||
}
|
||||
|
||||
// clear ALL of BigBuf
|
||||
void BigBuf_Clear(void) {
|
||||
BigBuf_Clear_ext(true);
|
||||
BigBuf_Clear_ext(true);
|
||||
}
|
||||
|
||||
// clear ALL of BigBuf
|
||||
void BigBuf_Clear_ext(bool verbose) {
|
||||
memset(BigBuf, 0, BIGBUF_SIZE);
|
||||
if (verbose)
|
||||
Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE);
|
||||
memset(BigBuf, 0, BIGBUF_SIZE);
|
||||
if (verbose)
|
||||
Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE);
|
||||
}
|
||||
|
||||
void BigBuf_Clear_EM(void) {
|
||||
memset(BigBuf_get_EM_addr(), 0, CARD_MEMORY_SIZE);
|
||||
memset(BigBuf_get_EM_addr(), 0, CARD_MEMORY_SIZE);
|
||||
}
|
||||
|
||||
void BigBuf_Clear_keep_EM(void) {
|
||||
memset(BigBuf, 0, BigBuf_hi);
|
||||
memset(BigBuf, 0, BigBuf_hi);
|
||||
}
|
||||
|
||||
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
|
||||
// at the beginning of BigBuf is always for traces/samples
|
||||
uint8_t *BigBuf_malloc(uint16_t chunksize) {
|
||||
if (BigBuf_hi - chunksize < 0)
|
||||
return NULL; // no memory left
|
||||
if (BigBuf_hi - chunksize < 0)
|
||||
return NULL; // no memory left
|
||||
|
||||
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
||||
BigBuf_hi -= chunksize; // aligned to 4 Byte boundary
|
||||
return (uint8_t *)BigBuf + BigBuf_hi;
|
||||
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
||||
BigBuf_hi -= chunksize; // aligned to 4 Byte boundary
|
||||
return (uint8_t *)BigBuf + BigBuf_hi;
|
||||
}
|
||||
|
||||
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
|
||||
void BigBuf_free(void){
|
||||
BigBuf_hi = BIGBUF_SIZE;
|
||||
emulator_memory = NULL;
|
||||
// shouldn't this empty BigBuf also?
|
||||
BigBuf_hi = BIGBUF_SIZE;
|
||||
emulator_memory = NULL;
|
||||
// shouldn't this empty BigBuf also?
|
||||
}
|
||||
|
||||
// free allocated chunks EXCEPT the emulator memory
|
||||
void BigBuf_free_keep_EM(void) {
|
||||
if (emulator_memory != NULL)
|
||||
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
||||
else
|
||||
BigBuf_hi = BIGBUF_SIZE;
|
||||
if (emulator_memory != NULL)
|
||||
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
||||
else
|
||||
BigBuf_hi = BIGBUF_SIZE;
|
||||
|
||||
// shouldn't this empty BigBuf also?
|
||||
// shouldn't this empty BigBuf also?
|
||||
}
|
||||
|
||||
void BigBuf_print_status(void) {
|
||||
Dbprintf("Memory");
|
||||
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
|
||||
Dbprintf(" Available memory........%d", BigBuf_hi);
|
||||
Dbprintf("Tracing");
|
||||
Dbprintf(" tracing ................%d", tracing);
|
||||
Dbprintf(" traceLen ...............%d", traceLen);
|
||||
Dbprintf("Memory");
|
||||
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
|
||||
Dbprintf(" Available memory........%d", BigBuf_hi);
|
||||
Dbprintf("Tracing");
|
||||
Dbprintf(" tracing ................%d", tracing);
|
||||
Dbprintf(" traceLen ...............%d", traceLen);
|
||||
}
|
||||
|
||||
// return the maximum trace length (i.e. the unallocated size of BigBuf)
|
||||
uint16_t BigBuf_max_traceLen(void) {
|
||||
return BigBuf_hi;
|
||||
return BigBuf_hi;
|
||||
}
|
||||
|
||||
void clear_trace(void) {
|
||||
traceLen = 0;
|
||||
traceLen = 0;
|
||||
}
|
||||
void set_tracelen(uint32_t value) {
|
||||
traceLen = value;
|
||||
}
|
||||
void set_tracing(bool enable) {
|
||||
tracing = enable;
|
||||
tracing = enable;
|
||||
}
|
||||
|
||||
bool get_tracing(void) {
|
||||
return tracing;
|
||||
return tracing;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -128,7 +128,7 @@ bool get_tracing(void) {
|
|||
* @return
|
||||
*/
|
||||
uint32_t BigBuf_get_traceLen(void) {
|
||||
return traceLen;
|
||||
return traceLen;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,111 +138,111 @@ uint32_t BigBuf_get_traceLen(void) {
|
|||
annotation of commands/responses.
|
||||
**/
|
||||
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) {
|
||||
if (!tracing) return false;
|
||||
if (!tracing) return false;
|
||||
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
|
||||
uint32_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
||||
uint32_t duration = timestamp_end - timestamp_start;
|
||||
uint32_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
||||
uint32_t duration = timestamp_end - timestamp_start;
|
||||
|
||||
// Return when trace is full
|
||||
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) {
|
||||
tracing = false; // don't trace any more
|
||||
return false;
|
||||
}
|
||||
// Traceformat:
|
||||
// 32 bits timestamp (little endian)
|
||||
// 16 bits duration (little endian)
|
||||
// 16 bits data length (little endian, Highest Bit used as readerToTag flag)
|
||||
// y Bytes data
|
||||
// x Bytes parity (one byte per 8 bytes data)
|
||||
// Return when trace is full
|
||||
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) {
|
||||
tracing = false; // don't trace any more
|
||||
return false;
|
||||
}
|
||||
// Traceformat:
|
||||
// 32 bits timestamp (little endian)
|
||||
// 16 bits duration (little endian)
|
||||
// 16 bits data length (little endian, Highest Bit used as readerToTag flag)
|
||||
// y Bytes data
|
||||
// x Bytes parity (one byte per 8 bytes data)
|
||||
|
||||
// timestamp (start)
|
||||
trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
|
||||
trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
|
||||
trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
|
||||
trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
|
||||
// timestamp (start)
|
||||
trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
|
||||
trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
|
||||
trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
|
||||
trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
|
||||
|
||||
// duration
|
||||
trace[traceLen++] = ((duration >> 0) & 0xff);
|
||||
trace[traceLen++] = ((duration >> 8) & 0xff);
|
||||
// duration
|
||||
trace[traceLen++] = ((duration >> 0) & 0xff);
|
||||
trace[traceLen++] = ((duration >> 8) & 0xff);
|
||||
|
||||
// data length
|
||||
trace[traceLen++] = ((iLen >> 0) & 0xff);
|
||||
trace[traceLen++] = ((iLen >> 8) & 0xff);
|
||||
// data length
|
||||
trace[traceLen++] = ((iLen >> 0) & 0xff);
|
||||
trace[traceLen++] = ((iLen >> 8) & 0xff);
|
||||
|
||||
// readerToTag flag
|
||||
if (!readerToTag) {
|
||||
trace[traceLen - 1] |= 0x80;
|
||||
}
|
||||
// readerToTag flag
|
||||
if (!readerToTag) {
|
||||
trace[traceLen - 1] |= 0x80;
|
||||
}
|
||||
|
||||
// data bytes
|
||||
if (btBytes != NULL && iLen != 0) {
|
||||
memcpy(trace + traceLen, btBytes, iLen);
|
||||
}
|
||||
traceLen += iLen;
|
||||
// data bytes
|
||||
if (btBytes != NULL && iLen != 0) {
|
||||
memcpy(trace + traceLen, btBytes, iLen);
|
||||
}
|
||||
traceLen += iLen;
|
||||
|
||||
// parity bytes
|
||||
if (num_paritybytes != 0) {
|
||||
if (parity != NULL) {
|
||||
memcpy(trace + traceLen, parity, num_paritybytes);
|
||||
} else {
|
||||
memset(trace + traceLen, 0x00, num_paritybytes);
|
||||
}
|
||||
}
|
||||
traceLen += num_paritybytes;
|
||||
// parity bytes
|
||||
if (num_paritybytes != 0) {
|
||||
if (parity != NULL) {
|
||||
memcpy(trace + traceLen, parity, num_paritybytes);
|
||||
} else {
|
||||
memset(trace + traceLen, 0x00, num_paritybytes);
|
||||
}
|
||||
}
|
||||
traceLen += num_paritybytes;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag) {
|
||||
/**
|
||||
Todo, rewrite the logger to use the generic functionality instead. It should be noted, however,
|
||||
that this logger takes number of bits as argument, not number of bytes.
|
||||
**/
|
||||
/**
|
||||
Todo, rewrite the logger to use the generic functionality instead. It should be noted, however,
|
||||
that this logger takes number of bits as argument, not number of bytes.
|
||||
**/
|
||||
|
||||
if (!tracing) return false;
|
||||
if (!tracing) return false;
|
||||
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
uint32_t iLen = nbytes(iBits);
|
||||
// Return when trace is full
|
||||
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return false;
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
uint32_t iLen = nbytes(iBits);
|
||||
// Return when trace is full
|
||||
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return false;
|
||||
|
||||
//Hitag traces appear to use this traceformat:
|
||||
// 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
|
||||
// 32 bits parity
|
||||
// 8 bits size (number of bits in the trace entry, not number of bytes)
|
||||
// y Bytes data
|
||||
//Hitag traces appear to use this traceformat:
|
||||
// 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
|
||||
// 32 bits parity
|
||||
// 8 bits size (number of bits in the trace entry, not number of bytes)
|
||||
// y Bytes data
|
||||
|
||||
rsamples += iSamples;
|
||||
trace[traceLen++] = ((rsamples >> 0) & 0xff);
|
||||
trace[traceLen++] = ((rsamples >> 8) & 0xff);
|
||||
trace[traceLen++] = ((rsamples >> 16) & 0xff);
|
||||
trace[traceLen++] = ((rsamples >> 24) & 0xff);
|
||||
rsamples += iSamples;
|
||||
trace[traceLen++] = ((rsamples >> 0) & 0xff);
|
||||
trace[traceLen++] = ((rsamples >> 8) & 0xff);
|
||||
trace[traceLen++] = ((rsamples >> 16) & 0xff);
|
||||
trace[traceLen++] = ((rsamples >> 24) & 0xff);
|
||||
|
||||
if (!readerToTag) {
|
||||
trace[traceLen - 1] |= 0x80;
|
||||
}
|
||||
if (!readerToTag) {
|
||||
trace[traceLen - 1] |= 0x80;
|
||||
}
|
||||
|
||||
trace[traceLen++] = ((dwParity >> 0) & 0xff);
|
||||
trace[traceLen++] = ((dwParity >> 8) & 0xff);
|
||||
trace[traceLen++] = ((dwParity >> 16) & 0xff);
|
||||
trace[traceLen++] = ((dwParity >> 24) & 0xff);
|
||||
trace[traceLen++] = iBits;
|
||||
trace[traceLen++] = ((dwParity >> 0) & 0xff);
|
||||
trace[traceLen++] = ((dwParity >> 8) & 0xff);
|
||||
trace[traceLen++] = ((dwParity >> 16) & 0xff);
|
||||
trace[traceLen++] = ((dwParity >> 24) & 0xff);
|
||||
trace[traceLen++] = iBits;
|
||||
|
||||
memcpy(trace + traceLen, btBytes, iLen);
|
||||
traceLen += iLen;
|
||||
memcpy(trace + traceLen, btBytes, iLen);
|
||||
traceLen += iLen;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Emulator memory
|
||||
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
|
||||
uint8_t* mem = BigBuf_get_EM_addr();
|
||||
if (offset + length < CARD_MEMORY_SIZE) {
|
||||
memcpy(mem+offset, data, length);
|
||||
return 0;
|
||||
}
|
||||
Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset + length), CARD_MEMORY_SIZE);
|
||||
return 1;
|
||||
uint8_t* mem = BigBuf_get_EM_addr();
|
||||
if (offset + length < CARD_MEMORY_SIZE) {
|
||||
memcpy(mem+offset, data, length);
|
||||
return 0;
|
||||
}
|
||||
Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset + length), CARD_MEMORY_SIZE);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
#include "string.h"
|
||||
#include "ticks.h"
|
||||
|
||||
#define BIGBUF_SIZE 40000
|
||||
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
||||
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
|
||||
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
|
||||
#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
|
||||
#define CARD_MEMORY_SIZE 4096
|
||||
#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!?
|
||||
#define BIGBUF_SIZE 40000
|
||||
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
||||
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
|
||||
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
|
||||
#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
|
||||
#define CARD_MEMORY_SIZE 4096
|
||||
#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!?
|
||||
|
||||
extern uint8_t *BigBuf_get_addr(void);
|
||||
extern uint8_t *BigBuf_get_EM_addr(void);
|
||||
|
|
172
armsrc/LCD.c
172
armsrc/LCD.c
|
@ -9,141 +9,141 @@
|
|||
|
||||
void LCDSend(unsigned int data)
|
||||
{
|
||||
// 9th bit set for data, clear for command
|
||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
|
||||
// For clarity's sake we pass data with 9th bit clear and commands with 9th
|
||||
// bit set since they're implemented as defines, se we need to invert bit
|
||||
AT91C_BASE_SPI->SPI_TDR = data^0x100; // Send the data/command
|
||||
// 9th bit set for data, clear for command
|
||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
|
||||
// For clarity's sake we pass data with 9th bit clear and commands with 9th
|
||||
// bit set since they're implemented as defines, se we need to invert bit
|
||||
AT91C_BASE_SPI->SPI_TDR = data^0x100; // Send the data/command
|
||||
}
|
||||
|
||||
void LCDSetXY(unsigned char x, unsigned char y)
|
||||
{
|
||||
LCDSend(PPASET); // page start/end ram
|
||||
LCDSend(y); // Start Page to display to
|
||||
LCDSend(131); // End Page to display to
|
||||
LCDSend(PPASET); // page start/end ram
|
||||
LCDSend(y); // Start Page to display to
|
||||
LCDSend(131); // End Page to display to
|
||||
|
||||
LCDSend(PCASET); // column start/end ram
|
||||
LCDSend(x); // Start Column to display to
|
||||
LCDSend(131); // End Column to display to
|
||||
LCDSend(PCASET); // column start/end ram
|
||||
LCDSend(x); // Start Column to display to
|
||||
LCDSend(131); // End Column to display to
|
||||
}
|
||||
|
||||
void LCDSetPixel(unsigned char x, unsigned char y, unsigned char color)
|
||||
{
|
||||
LCDSetXY(x,y); // Set position
|
||||
LCDSend(PRAMWR); // Now write the pixel to the display
|
||||
LCDSend(color); // Write the data in the specified Color
|
||||
LCDSetXY(x,y); // Set position
|
||||
LCDSend(PRAMWR); // Now write the pixel to the display
|
||||
LCDSend(color); // Write the data in the specified Color
|
||||
}
|
||||
|
||||
void LCDFill (unsigned char xs,unsigned char ys,unsigned char width,unsigned char height, unsigned char color)
|
||||
{
|
||||
unsigned char i,j;
|
||||
|
||||
for (i=0;i < height;i++) // Number of horizontal lines
|
||||
for (i=0;i < height;i++) // Number of horizontal lines
|
||||
{
|
||||
LCDSetXY(xs,ys+i); // Goto start of fill area (Top Left)
|
||||
LCDSend(PRAMWR); // Write to display
|
||||
LCDSetXY(xs,ys+i); // Goto start of fill area (Top Left)
|
||||
LCDSend(PRAMWR); // Write to display
|
||||
|
||||
for (j=0;j < width;j++) // pixels per line
|
||||
LCDSend(color);
|
||||
for (j=0;j < width;j++) // pixels per line
|
||||
LCDSend(color);
|
||||
}
|
||||
}
|
||||
|
||||
void LCDString (char *lcd_string, const char *font_style,unsigned char x, unsigned char y, unsigned char fcolor, unsigned char bcolor)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char mask=0, px, py, xme, yme, offset;
|
||||
const char *data;
|
||||
unsigned int i;
|
||||
unsigned char mask=0, px, py, xme, yme, offset;
|
||||
const char *data;
|
||||
|
||||
data = font_style; // point to the start of the font table
|
||||
data = font_style; // point to the start of the font table
|
||||
|
||||
xme = *data; // get font x width
|
||||
data++;
|
||||
yme = *data; // get font y length
|
||||
data++;
|
||||
offset = *data; // get data bytes per font
|
||||
xme = *data; // get font x width
|
||||
data++;
|
||||
yme = *data; // get font y length
|
||||
data++;
|
||||
offset = *data; // get data bytes per font
|
||||
|
||||
do
|
||||
{
|
||||
// point to data in table to be loaded
|
||||
data = (font_style + offset) + (offset * (int)(*lcd_string - 32));
|
||||
do
|
||||
{
|
||||
// point to data in table to be loaded
|
||||
data = (font_style + offset) + (offset * (int)(*lcd_string - 32));
|
||||
|
||||
for (i=0;i < yme;i++) {
|
||||
mask |=0x80;
|
||||
for (i=0;i < yme;i++) {
|
||||
mask |=0x80;
|
||||
|
||||
for (px=x; px < (x + xme); px++) {
|
||||
py= y + i;
|
||||
for (px=x; px < (x + xme); px++) {
|
||||
py= y + i;
|
||||
|
||||
if (*data & mask) LCDSetPixel (px,py,fcolor);
|
||||
else LCDSetPixel (px,py,bcolor);
|
||||
if (*data & mask) LCDSetPixel (px,py,fcolor);
|
||||
else LCDSetPixel (px,py,bcolor);
|
||||
|
||||
mask>>=1;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
x+=xme;
|
||||
mask>>=1;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
x+=xme;
|
||||
|
||||
lcd_string++; // next character in string
|
||||
lcd_string++; // next character in string
|
||||
|
||||
} while(*lcd_string !='\0'); // keep spitting chars out until end of string
|
||||
} while(*lcd_string !='\0'); // keep spitting chars out until end of string
|
||||
}
|
||||
|
||||
void LCDReset(void)
|
||||
{
|
||||
LED_A_ON();
|
||||
SetupSpi(SPI_LCD_MODE);
|
||||
LOW(GPIO_LRST);
|
||||
SpinDelay(100);
|
||||
LED_A_ON();
|
||||
SetupSpi(SPI_LCD_MODE);
|
||||
LOW(GPIO_LRST);
|
||||
SpinDelay(100);
|
||||
|
||||
HIGH(GPIO_LRST);
|
||||
SpinDelay(100);
|
||||
LED_A_OFF();
|
||||
HIGH(GPIO_LRST);
|
||||
SpinDelay(100);
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
void LCDInit(void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
LCDReset();
|
||||
LCDReset();
|
||||
|
||||
LCDSend(PSWRESET); // software reset
|
||||
SpinDelay(100);
|
||||
LCDSend(PSLEEPOUT); // exit sleep mode
|
||||
LCDSend(PBSTRON); // booster on
|
||||
LCDSend(PDISPON); // display on
|
||||
LCDSend(PNORON); // normal on
|
||||
LCDSend(PMADCTL); // rotate display 180 deg
|
||||
LCDSend(0xC0);
|
||||
LCDSend(PSWRESET); // software reset
|
||||
SpinDelay(100);
|
||||
LCDSend(PSLEEPOUT); // exit sleep mode
|
||||
LCDSend(PBSTRON); // booster on
|
||||
LCDSend(PDISPON); // display on
|
||||
LCDSend(PNORON); // normal on
|
||||
LCDSend(PMADCTL); // rotate display 180 deg
|
||||
LCDSend(0xC0);
|
||||
|
||||
LCDSend(PCOLMOD); // color mode
|
||||
LCDSend(0x02); // 8bpp color mode
|
||||
LCDSend(PCOLMOD); // color mode
|
||||
LCDSend(0x02); // 8bpp color mode
|
||||
|
||||
LCDSend(PSETCON); // set contrast
|
||||
LCDSend(PSETCON); // set contrast
|
||||
LCDSend(0xDC);
|
||||
|
||||
// clear display
|
||||
// clear display
|
||||
LCDSetXY(0,0);
|
||||
LCDSend(PRAMWR); // Write to display
|
||||
i=LCD_XRES*LCD_YRES;
|
||||
while(i--) LCDSend(WHITE);
|
||||
LCDSend(PRAMWR); // Write to display
|
||||
i=LCD_XRES*LCD_YRES;
|
||||
while(i--) LCDSend(WHITE);
|
||||
|
||||
// test text on different colored backgrounds
|
||||
LCDString(" The quick brown fox ", (char *)&FONT6x8,1,1+8*0,WHITE ,BLACK );
|
||||
LCDString(" jumped over the ", (char *)&FONT6x8,1,1+8*1,BLACK ,WHITE );
|
||||
LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED );
|
||||
LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN );
|
||||
LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE );
|
||||
LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8,1,1+8*5,BLUE ,YELLOW);
|
||||
LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8,1,1+8*6,BLACK ,CYAN );
|
||||
LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
|
||||
LCDString(" The quick brown fox ", (char *)&FONT6x8,1,1+8*0,WHITE ,BLACK );
|
||||
LCDString(" jumped over the ", (char *)&FONT6x8,1,1+8*1,BLACK ,WHITE );
|
||||
LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED );
|
||||
LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN );
|
||||
LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE );
|
||||
LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8,1,1+8*5,BLUE ,YELLOW);
|
||||
LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8,1,1+8*6,BLACK ,CYAN );
|
||||
LCDString(" _+{}|:\\\"<>? ", (char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
|
||||
|
||||
// color bands
|
||||
LCDFill(0, 1+8* 8, 132, 8, BLACK);
|
||||
LCDFill(0, 1+8* 9, 132, 8, WHITE);
|
||||
LCDFill(0, 1+8*10, 132, 8, RED);
|
||||
LCDFill(0, 1+8*11, 132, 8, GREEN);
|
||||
LCDFill(0, 1+8*12, 132, 8, BLUE);
|
||||
LCDFill(0, 1+8*13, 132, 8, YELLOW);
|
||||
LCDFill(0, 1+8*14, 132, 8, CYAN);
|
||||
LCDFill(0, 1+8*15, 132, 8, MAGENTA);
|
||||
// color bands
|
||||
LCDFill(0, 1+8* 8, 132, 8, BLACK);
|
||||
LCDFill(0, 1+8* 9, 132, 8, WHITE);
|
||||
LCDFill(0, 1+8*10, 132, 8, RED);
|
||||
LCDFill(0, 1+8*11, 132, 8, GREEN);
|
||||
LCDFill(0, 1+8*12, 132, 8, BLUE);
|
||||
LCDFill(0, 1+8*13, 132, 8, YELLOW);
|
||||
LCDFill(0, 1+8*14, 132, 8, CYAN);
|
||||
LCDFill(0, 1+8*15, 132, 8, MAGENTA);
|
||||
|
||||
}
|
||||
|
|
190
armsrc/LCD.h
190
armsrc/LCD.h
|
@ -14,110 +14,110 @@
|
|||
#include "fonts.h"
|
||||
|
||||
// The resolution of the LCD
|
||||
#define LCD_XRES 132
|
||||
#define LCD_YRES 132
|
||||
#define LCD_XRES 132
|
||||
#define LCD_YRES 132
|
||||
|
||||
// 8bpp Color Mode - Some basic colors defined for ease of use
|
||||
// remember 8bpp color = 3xRed, 3xGreen & 2xBlue bits
|
||||
// organised as RRRGGGBB
|
||||
|
||||
#define BLACK 0x00
|
||||
#define BLUE 0x03
|
||||
#define GREEN 0x1C
|
||||
#define CYAN 0x1F
|
||||
#define RED 0xE0
|
||||
#define MAGENTA 0xE3
|
||||
#define YELLOW 0xFC
|
||||
#define WHITE 0xFF
|
||||
#define BLACK 0x00
|
||||
#define BLUE 0x03
|
||||
#define GREEN 0x1C
|
||||
#define CYAN 0x1F
|
||||
#define RED 0xE0
|
||||
#define MAGENTA 0xE3
|
||||
#define YELLOW 0xFC
|
||||
#define WHITE 0xFF
|
||||
|
||||
// EPSON LCD command set
|
||||
#define ECASET 0x115
|
||||
#define EPWRCTR 0x120
|
||||
#define ENOP 0x125
|
||||
#define ERAMWR 0x15C
|
||||
#define ERAMRD 0x15D
|
||||
#define EPASET 0x175
|
||||
#define EEPSRRD1 0x17C
|
||||
#define EEPSRRD2 0x17D
|
||||
#define EVOLCTR 0x181
|
||||
#define ETMPGRD 0x182
|
||||
#define ESLPOUT 0x194
|
||||
#define ESLPIN 0x195
|
||||
#define EDISNOR 0x1A6
|
||||
#define EDISINV 0x1A7
|
||||
#define EPTLIN 0x1A8
|
||||
#define EPTLOUT 0x1A9
|
||||
#define EASCSET 0x1AA
|
||||
#define ESCSTART 0x1AB
|
||||
#define EDISOFF 0x1AE
|
||||
#define EDISON 0x1AF
|
||||
#define ECOMSCN 0x1BB
|
||||
#define EDATCTL 0x1BC
|
||||
#define EDISCTL 0x1CA
|
||||
#define EEPCOUT 0x1CC
|
||||
#define EEPCTIN 0x1CD
|
||||
#define ERGBSET8 0x1CE
|
||||
#define EOSCON 0x1D1
|
||||
#define EOSCOFF 0x1D2
|
||||
#define EVOLUP 0x1D6
|
||||
#define EVOLDOWN 0x1D7
|
||||
#define ERMWIN 0x1E0
|
||||
#define ERMWOUT 0x1EE
|
||||
#define EEPMWR 0x1FC
|
||||
#define EEPMRD 0x1FD
|
||||
#define ECASET 0x115
|
||||
#define EPWRCTR 0x120
|
||||
#define ENOP 0x125
|
||||
#define ERAMWR 0x15C
|
||||
#define ERAMRD 0x15D
|
||||
#define EPASET 0x175
|
||||
#define EEPSRRD1 0x17C
|
||||
#define EEPSRRD2 0x17D
|
||||
#define EVOLCTR 0x181
|
||||
#define ETMPGRD 0x182
|
||||
#define ESLPOUT 0x194
|
||||
#define ESLPIN 0x195
|
||||
#define EDISNOR 0x1A6
|
||||
#define EDISINV 0x1A7
|
||||
#define EPTLIN 0x1A8
|
||||
#define EPTLOUT 0x1A9
|
||||
#define EASCSET 0x1AA
|
||||
#define ESCSTART 0x1AB
|
||||
#define EDISOFF 0x1AE
|
||||
#define EDISON 0x1AF
|
||||
#define ECOMSCN 0x1BB
|
||||
#define EDATCTL 0x1BC
|
||||
#define EDISCTL 0x1CA
|
||||
#define EEPCOUT 0x1CC
|
||||
#define EEPCTIN 0x1CD
|
||||
#define ERGBSET8 0x1CE
|
||||
#define EOSCON 0x1D1
|
||||
#define EOSCOFF 0x1D2
|
||||
#define EVOLUP 0x1D6
|
||||
#define EVOLDOWN 0x1D7
|
||||
#define ERMWIN 0x1E0
|
||||
#define ERMWOUT 0x1EE
|
||||
#define EEPMWR 0x1FC
|
||||
#define EEPMRD 0x1FD
|
||||
|
||||
// PHILIPS LCD command set
|
||||
#define PNOP 0x100
|
||||
#define PSWRESET 0x101
|
||||
#define PBSTROFF 0x102
|
||||
#define PBSTRON 0x103
|
||||
#define PRDDIDIF 0x104
|
||||
#define PRDDST 0x109
|
||||
#define PSLEEPIN 0x110
|
||||
#define PSLEEPOUT 0x111
|
||||
#define PPTLON 0x112
|
||||
#define PNORON 0x113
|
||||
#define PINVOFF 0x120
|
||||
#define PINVON 0x121
|
||||
#define PDALO 0x122
|
||||
#define PDAL 0x123
|
||||
#define PSETCON 0x125
|
||||
#define PDISPOFF 0x128
|
||||
#define PDISPON 0x129
|
||||
#define PCASET 0x12A
|
||||
#define PPASET 0x12B
|
||||
#define PRAMWR 0x12C
|
||||
#define PRGBSET 0x12D
|
||||
#define PPTLAR 0x130
|
||||
#define PVSCRDEF 0x133
|
||||
#define PTEOFF 0x134
|
||||
#define PTEON 0x135
|
||||
#define PMADCTL 0x136
|
||||
#define PSEP 0x137
|
||||
#define PIDMOFF 0x138
|
||||
#define PIDMON 0x139
|
||||
#define PCOLMOD 0x13A
|
||||
#define PSETVOP 0x1B0
|
||||
#define PBRS 0x1B4
|
||||
#define PTRS 0x1B6
|
||||
#define PFINV 0x1B9
|
||||
#define PDOR 0x1BA
|
||||
#define PTCDFE 0x1BD
|
||||
#define PTCVOPE 0x1BF
|
||||
#define PEC 0x1C0
|
||||
#define PSETMUL 0x1C2
|
||||
#define PTCVOPAB 0x1C3
|
||||
#define PTCVOPCD 0x1C4
|
||||
#define PTCDF 0x1C5
|
||||
#define PDF8C 0x1C6
|
||||
#define PSETBS 0x1C7
|
||||
#define PRDTEMP 0x1C8
|
||||
#define PNLI 0x1C9
|
||||
#define PRDID1 0x1DA
|
||||
#define PRDID2 0x1DB
|
||||
#define PRDID3 0x1DC
|
||||
#define PSFD 0x1EF
|
||||
#define PECM 0x1F0
|
||||
#define PNOP 0x100
|
||||
#define PSWRESET 0x101
|
||||
#define PBSTROFF 0x102
|
||||
#define PBSTRON 0x103
|
||||
#define PRDDIDIF 0x104
|
||||
#define PRDDST 0x109
|
||||
#define PSLEEPIN 0x110
|
||||
#define PSLEEPOUT 0x111
|
||||
#define PPTLON 0x112
|
||||
#define PNORON 0x113
|
||||
#define PINVOFF 0x120
|
||||
#define PINVON 0x121
|
||||
#define PDALO 0x122
|
||||
#define PDAL 0x123
|
||||
#define PSETCON 0x125
|
||||
#define PDISPOFF 0x128
|
||||
#define PDISPON 0x129
|
||||
#define PCASET 0x12A
|
||||
#define PPASET 0x12B
|
||||
#define PRAMWR 0x12C
|
||||
#define PRGBSET 0x12D
|
||||
#define PPTLAR 0x130
|
||||
#define PVSCRDEF 0x133
|
||||
#define PTEOFF 0x134
|
||||
#define PTEON 0x135
|
||||
#define PMADCTL 0x136
|
||||
#define PSEP 0x137
|
||||
#define PIDMOFF 0x138
|
||||
#define PIDMON 0x139
|
||||
#define PCOLMOD 0x13A
|
||||
#define PSETVOP 0x1B0
|
||||
#define PBRS 0x1B4
|
||||
#define PTRS 0x1B6
|
||||
#define PFINV 0x1B9
|
||||
#define PDOR 0x1BA
|
||||
#define PTCDFE 0x1BD
|
||||
#define PTCVOPE 0x1BF
|
||||
#define PEC 0x1C0
|
||||
#define PSETMUL 0x1C2
|
||||
#define PTCVOPAB 0x1C3
|
||||
#define PTCVOPCD 0x1C4
|
||||
#define PTCDF 0x1C5
|
||||
#define PDF8C 0x1C6
|
||||
#define PSETBS 0x1C7
|
||||
#define PRDTEMP 0x1C8
|
||||
#define PNLI 0x1C9
|
||||
#define PRDID1 0x1DA
|
||||
#define PRDID2 0x1DB
|
||||
#define PRDID3 0x1DC
|
||||
#define PSFD 0x1EF
|
||||
#define PECM 0x1F0
|
||||
|
||||
void LCDSend(unsigned int data);
|
||||
void LCDInit(void);
|
||||
|
|
2248
armsrc/appmain.c
2248
armsrc/appmain.c
File diff suppressed because it is too large
Load diff
|
@ -202,8 +202,8 @@ void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t
|
|||
// iso15693.h
|
||||
void RecordRawAdcSamplesIso15693(void);
|
||||
void AcquireRawAdcSamplesIso15693(void);
|
||||
void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg
|
||||
void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg
|
||||
void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg
|
||||
void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg
|
||||
void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag - atrox
|
||||
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI - atrox
|
||||
void Iso15693InitReader(void);
|
||||
|
|
112
armsrc/buzzer.c
112
armsrc/buzzer.c
|
@ -2,9 +2,9 @@
|
|||
|
||||
void Ring_BEE_ONCE(uint16_t music_note) {
|
||||
BEE_ON();
|
||||
SpinDelayUs(music_note);
|
||||
BEE_OFF();
|
||||
SpinDelayUs(music_note);
|
||||
SpinDelayUs(music_note);
|
||||
BEE_OFF();
|
||||
SpinDelayUs(music_note);
|
||||
}
|
||||
|
||||
void ring_2_7khz(uint16_t count) {
|
||||
|
@ -12,9 +12,9 @@ void ring_2_7khz(uint16_t count) {
|
|||
}
|
||||
|
||||
void Ring_BEE_TIME(uint16_t music_note,uint16_t count) {
|
||||
for(uint16_t i=0 ; i < count; i++)
|
||||
Ring_BEE_ONCE(music_note);
|
||||
SpinDelay(9);
|
||||
for(uint16_t i=0 ; i < count; i++)
|
||||
Ring_BEE_ONCE(music_note);
|
||||
SpinDelay(9);
|
||||
}
|
||||
|
||||
void Ring_ALL(uint16_t count) {
|
||||
|
@ -29,58 +29,58 @@ void Ring_ALL(uint16_t count) {
|
|||
}
|
||||
|
||||
void Ring_Little_Star(uint16_t count) {
|
||||
Ring_BEE_TIME(note_1,count);
|
||||
Ring_BEE_TIME(note_1,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_6,count);
|
||||
Ring_BEE_TIME(note_6,count);
|
||||
Ring_BEE_TIME(note_5,2*count);
|
||||
LED_A_ON();
|
||||
/*
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_2,count);
|
||||
Ring_BEE_TIME(note_2,count);
|
||||
Ring_BEE_TIME(note_1,2*count);
|
||||
LED_A_OFF();
|
||||
Ring_BEE_TIME(note_1,count);
|
||||
Ring_BEE_TIME(note_1,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_6,count);
|
||||
Ring_BEE_TIME(note_6,count);
|
||||
Ring_BEE_TIME(note_5,2*count);
|
||||
LED_A_ON();
|
||||
/*
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_2,count);
|
||||
Ring_BEE_TIME(note_2,count);
|
||||
Ring_BEE_TIME(note_1,2*count);
|
||||
LED_A_OFF();
|
||||
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_2,2*count);
|
||||
LED_A_ON();
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_2,2*count);
|
||||
LED_A_ON();
|
||||
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_2,2*count);
|
||||
LED_A_OFF();
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_2,2*count);
|
||||
LED_A_OFF();
|
||||
|
||||
Ring_BEE_TIME(note_1,count);
|
||||
Ring_BEE_TIME(note_1,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_6,count);
|
||||
Ring_BEE_TIME(note_6,count);
|
||||
Ring_BEE_TIME(note_5,2*count);
|
||||
LED_A_ON();
|
||||
Ring_BEE_TIME(note_1,count);
|
||||
Ring_BEE_TIME(note_1,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_5,count);
|
||||
Ring_BEE_TIME(note_6,count);
|
||||
Ring_BEE_TIME(note_6,count);
|
||||
Ring_BEE_TIME(note_5,2*count);
|
||||
LED_A_ON();
|
||||
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_2,count);
|
||||
Ring_BEE_TIME(note_2,count);
|
||||
Ring_BEE_TIME(note_1,2*count);
|
||||
LED_B_ON();
|
||||
*/
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_4,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_3,count);
|
||||
Ring_BEE_TIME(note_2,count);
|
||||
Ring_BEE_TIME(note_2,count);
|
||||
Ring_BEE_TIME(note_1,2*count);
|
||||
LED_B_ON();
|
||||
*/
|
||||
}
|
450
armsrc/des.c
450
armsrc/des.c
|
@ -22,7 +22,7 @@
|
|||
* \email daniel.otte@rub.de
|
||||
* \date 2007-06-16
|
||||
* \brief DES and EDE-DES implementation
|
||||
* \license GPLv3 or later
|
||||
* \license GPLv3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -72,111 +72,111 @@ const uint8_t sbox[256] = {
|
|||
};
|
||||
|
||||
const uint8_t e_permtab[] ={
|
||||
4, 6, /* 4 bytes in 6 bytes out*/
|
||||
32, 1, 2, 3, 4, 5,
|
||||
4, 5, 6, 7, 8, 9,
|
||||
8, 9, 10, 11, 12, 13,
|
||||
12, 13, 14, 15, 16, 17,
|
||||
16, 17, 18, 19, 20, 21,
|
||||
20, 21, 22, 23, 24, 25,
|
||||
24, 25, 26, 27, 28, 29,
|
||||
28, 29, 30, 31, 32, 1
|
||||
4, 6, /* 4 bytes in 6 bytes out*/
|
||||
32, 1, 2, 3, 4, 5,
|
||||
4, 5, 6, 7, 8, 9,
|
||||
8, 9, 10, 11, 12, 13,
|
||||
12, 13, 14, 15, 16, 17,
|
||||
16, 17, 18, 19, 20, 21,
|
||||
20, 21, 22, 23, 24, 25,
|
||||
24, 25, 26, 27, 28, 29,
|
||||
28, 29, 30, 31, 32, 1
|
||||
};
|
||||
|
||||
const uint8_t p_permtab[] ={
|
||||
4, 4, /* 32 bit -> 32 bit */
|
||||
16, 7, 20, 21,
|
||||
29, 12, 28, 17,
|
||||
1, 15, 23, 26,
|
||||
5, 18, 31, 10,
|
||||
2, 8, 24, 14,
|
||||
32, 27, 3, 9,
|
||||
19, 13, 30, 6,
|
||||
22, 11, 4, 25
|
||||
4, 4, /* 32 bit -> 32 bit */
|
||||
16, 7, 20, 21,
|
||||
29, 12, 28, 17,
|
||||
1, 15, 23, 26,
|
||||
5, 18, 31, 10,
|
||||
2, 8, 24, 14,
|
||||
32, 27, 3, 9,
|
||||
19, 13, 30, 6,
|
||||
22, 11, 4, 25
|
||||
};
|
||||
|
||||
const uint8_t ip_permtab[] ={
|
||||
8, 8, /* 64 bit -> 64 bit */
|
||||
58, 50, 42, 34, 26, 18, 10, 2,
|
||||
60, 52, 44, 36, 28, 20, 12, 4,
|
||||
62, 54, 46, 38, 30, 22, 14, 6,
|
||||
64, 56, 48, 40, 32, 24, 16, 8,
|
||||
57, 49, 41, 33, 25, 17, 9, 1,
|
||||
59, 51, 43, 35, 27, 19, 11, 3,
|
||||
61, 53, 45, 37, 29, 21, 13, 5,
|
||||
63, 55, 47, 39, 31, 23, 15, 7
|
||||
8, 8, /* 64 bit -> 64 bit */
|
||||
58, 50, 42, 34, 26, 18, 10, 2,
|
||||
60, 52, 44, 36, 28, 20, 12, 4,
|
||||
62, 54, 46, 38, 30, 22, 14, 6,
|
||||
64, 56, 48, 40, 32, 24, 16, 8,
|
||||
57, 49, 41, 33, 25, 17, 9, 1,
|
||||
59, 51, 43, 35, 27, 19, 11, 3,
|
||||
61, 53, 45, 37, 29, 21, 13, 5,
|
||||
63, 55, 47, 39, 31, 23, 15, 7
|
||||
};
|
||||
|
||||
const uint8_t inv_ip_permtab[] ={
|
||||
8, 8, /* 64 bit -> 64 bit */
|
||||
40, 8, 48, 16, 56, 24, 64, 32,
|
||||
39, 7, 47, 15, 55, 23, 63, 31,
|
||||
38, 6, 46, 14, 54, 22, 62, 30,
|
||||
37, 5, 45, 13, 53, 21, 61, 29,
|
||||
36, 4, 44, 12, 52, 20, 60, 28,
|
||||
35, 3, 43, 11, 51, 19, 59, 27,
|
||||
34, 2, 42, 10, 50, 18, 58, 26,
|
||||
33, 1, 41, 9, 49, 17, 57, 25
|
||||
8, 8, /* 64 bit -> 64 bit */
|
||||
40, 8, 48, 16, 56, 24, 64, 32,
|
||||
39, 7, 47, 15, 55, 23, 63, 31,
|
||||
38, 6, 46, 14, 54, 22, 62, 30,
|
||||
37, 5, 45, 13, 53, 21, 61, 29,
|
||||
36, 4, 44, 12, 52, 20, 60, 28,
|
||||
35, 3, 43, 11, 51, 19, 59, 27,
|
||||
34, 2, 42, 10, 50, 18, 58, 26,
|
||||
33, 1, 41, 9, 49, 17, 57, 25
|
||||
};
|
||||
|
||||
const uint8_t pc1_permtab[] ={
|
||||
8, 7, /* 64 bit -> 56 bit*/
|
||||
57, 49, 41, 33, 25, 17, 9,
|
||||
1, 58, 50, 42, 34, 26, 18,
|
||||
10, 2, 59, 51, 43, 35, 27,
|
||||
19, 11, 3, 60, 52, 44, 36,
|
||||
63, 55, 47, 39, 31, 23, 15,
|
||||
7, 62, 54, 46, 38, 30, 22,
|
||||
14, 6, 61, 53, 45, 37, 29,
|
||||
21, 13, 5, 28, 20, 12, 4
|
||||
8, 7, /* 64 bit -> 56 bit*/
|
||||
57, 49, 41, 33, 25, 17, 9,
|
||||
1, 58, 50, 42, 34, 26, 18,
|
||||
10, 2, 59, 51, 43, 35, 27,
|
||||
19, 11, 3, 60, 52, 44, 36,
|
||||
63, 55, 47, 39, 31, 23, 15,
|
||||
7, 62, 54, 46, 38, 30, 22,
|
||||
14, 6, 61, 53, 45, 37, 29,
|
||||
21, 13, 5, 28, 20, 12, 4
|
||||
};
|
||||
|
||||
const uint8_t pc2_permtab[] ={
|
||||
7, 6, /* 56 bit -> 48 bit */
|
||||
14, 17, 11, 24, 1, 5,
|
||||
3, 28, 15, 6, 21, 10,
|
||||
23, 19, 12, 4, 26, 8,
|
||||
16, 7, 27, 20, 13, 2,
|
||||
41, 52, 31, 37, 47, 55,
|
||||
30, 40, 51, 45, 33, 48,
|
||||
44, 49, 39, 56, 34, 53,
|
||||
46, 42, 50, 36, 29, 32
|
||||
7, 6, /* 56 bit -> 48 bit */
|
||||
14, 17, 11, 24, 1, 5,
|
||||
3, 28, 15, 6, 21, 10,
|
||||
23, 19, 12, 4, 26, 8,
|
||||
16, 7, 27, 20, 13, 2,
|
||||
41, 52, 31, 37, 47, 55,
|
||||
30, 40, 51, 45, 33, 48,
|
||||
44, 49, 39, 56, 34, 53,
|
||||
46, 42, 50, 36, 29, 32
|
||||
};
|
||||
|
||||
const uint8_t splitin6bitword_permtab[] = {
|
||||
8, 8, /* 64 bit -> 64 bit */
|
||||
64, 64, 1, 6, 2, 3, 4, 5,
|
||||
64, 64, 7, 12, 8, 9, 10, 11,
|
||||
64, 64, 13, 18, 14, 15, 16, 17,
|
||||
64, 64, 19, 24, 20, 21, 22, 23,
|
||||
64, 64, 25, 30, 26, 27, 28, 29,
|
||||
64, 64, 31, 36, 32, 33, 34, 35,
|
||||
64, 64, 37, 42, 38, 39, 40, 41,
|
||||
64, 64, 43, 48, 44, 45, 46, 47
|
||||
8, 8, /* 64 bit -> 64 bit */
|
||||
64, 64, 1, 6, 2, 3, 4, 5,
|
||||
64, 64, 7, 12, 8, 9, 10, 11,
|
||||
64, 64, 13, 18, 14, 15, 16, 17,
|
||||
64, 64, 19, 24, 20, 21, 22, 23,
|
||||
64, 64, 25, 30, 26, 27, 28, 29,
|
||||
64, 64, 31, 36, 32, 33, 34, 35,
|
||||
64, 64, 37, 42, 38, 39, 40, 41,
|
||||
64, 64, 43, 48, 44, 45, 46, 47
|
||||
};
|
||||
|
||||
const uint8_t shiftkey_permtab[] = {
|
||||
7, 7, /* 56 bit -> 56 bit */
|
||||
2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24, 25,
|
||||
26, 27, 28, 1,
|
||||
30, 31, 32, 33, 34, 35, 36, 37,
|
||||
38, 39, 40, 41, 42, 43, 44, 45,
|
||||
46, 47, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 29
|
||||
7, 7, /* 56 bit -> 56 bit */
|
||||
2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24, 25,
|
||||
26, 27, 28, 1,
|
||||
30, 31, 32, 33, 34, 35, 36, 37,
|
||||
38, 39, 40, 41, 42, 43, 44, 45,
|
||||
46, 47, 48, 49, 50, 51, 52, 53,
|
||||
54, 55, 56, 29
|
||||
};
|
||||
|
||||
const uint8_t shiftkeyinv_permtab[] = {
|
||||
7, 7,
|
||||
28, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27,
|
||||
56, 29, 30, 31, 32, 33, 34, 35,
|
||||
36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 46, 47, 48, 49, 50, 51,
|
||||
52, 53, 54, 55
|
||||
7, 7,
|
||||
28, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27,
|
||||
56, 29, 30, 31, 32, 33, 34, 35,
|
||||
36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 46, 47, 48, 49, 50, 51,
|
||||
52, 53, 54, 55
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -203,241 +203,241 @@ const uint8_t shiftkeyinv_permtab[] = {
|
|||
/******************************************************************************/
|
||||
|
||||
void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out){
|
||||
uint8_t ob; /* in-bytes and out-bytes */
|
||||
uint8_t byte, bit; /* counter for bit and byte */
|
||||
ob = ptable[1];
|
||||
ptable = &(ptable[2]);
|
||||
for(byte=0; byte<ob; ++byte){
|
||||
uint8_t x,t=0;
|
||||
for(bit=0; bit<8; ++bit){
|
||||
x = *ptable++ - 1;
|
||||
t<<=1;
|
||||
if((in[x/8]) & (0x80>>(x%8)) ){
|
||||
t|=0x01;
|
||||
}
|
||||
}
|
||||
out[byte]=t;
|
||||
}
|
||||
uint8_t ob; /* in-bytes and out-bytes */
|
||||
uint8_t byte, bit; /* counter for bit and byte */
|
||||
ob = ptable[1];
|
||||
ptable = &(ptable[2]);
|
||||
for(byte=0; byte<ob; ++byte){
|
||||
uint8_t x,t=0;
|
||||
for(bit=0; bit<8; ++bit){
|
||||
x = *ptable++ - 1;
|
||||
t<<=1;
|
||||
if((in[x/8]) & (0x80>>(x%8)) ){
|
||||
t|=0x01;
|
||||
}
|
||||
}
|
||||
out[byte]=t;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void changeendian32(uint32_t * a){
|
||||
*a = (*a & 0x000000FF) << 24 |
|
||||
(*a & 0x0000FF00) << 8 |
|
||||
(*a & 0x00FF0000) >> 8 |
|
||||
(*a & 0xFF000000) >> 24;
|
||||
*a = (*a & 0x000000FF) << 24 |
|
||||
(*a & 0x0000FF00) << 8 |
|
||||
(*a & 0x00FF0000) >> 8 |
|
||||
(*a & 0xFF000000) >> 24;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static inline
|
||||
void shiftkey(uint8_t *key){
|
||||
uint8_t k[7];
|
||||
memcpy(k, key, 7);
|
||||
permute((uint8_t*)shiftkey_permtab, k, key);
|
||||
uint8_t k[7];
|
||||
memcpy(k, key, 7);
|
||||
permute((uint8_t*)shiftkey_permtab, k, key);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static inline
|
||||
void shiftkey_inv(uint8_t *key){
|
||||
uint8_t k[7];
|
||||
memcpy(k, key, 7);
|
||||
permute((uint8_t*)shiftkeyinv_permtab, k, key);
|
||||
uint8_t k[7];
|
||||
memcpy(k, key, 7);
|
||||
permute((uint8_t*)shiftkeyinv_permtab, k, key);
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static inline
|
||||
uint64_t splitin6bitwords(uint64_t a){
|
||||
uint64_t ret=0;
|
||||
a &= 0x0000ffffffffffffLL;
|
||||
permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);
|
||||
return ret;
|
||||
uint64_t ret=0;
|
||||
a &= 0x0000ffffffffffffLL;
|
||||
permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static inline
|
||||
uint8_t substitute(uint8_t a, uint8_t * sbp){
|
||||
uint8_t x;
|
||||
x = sbp[a>>1];
|
||||
x = (a&1)?x&0x0F:x>>4;
|
||||
return x;
|
||||
uint8_t x;
|
||||
x = sbp[a>>1];
|
||||
x = (a&1)?x&0x0F:x>>4;
|
||||
return x;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
uint32_t des_f(uint32_t r, uint8_t* kr){
|
||||
uint8_t i;
|
||||
uint32_t t=0,ret;
|
||||
uint64_t data;
|
||||
uint8_t *sbp; /* sboxpointer */
|
||||
permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
|
||||
for(i=0; i<6; ++i)
|
||||
((uint8_t*)&data)[i] ^= kr[i];
|
||||
uint8_t i;
|
||||
uint32_t t=0,ret;
|
||||
uint64_t data;
|
||||
uint8_t *sbp; /* sboxpointer */
|
||||
permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
|
||||
for(i=0; i<6; ++i)
|
||||
((uint8_t*)&data)[i] ^= kr[i];
|
||||
|
||||
/* Sbox substitution */
|
||||
data = splitin6bitwords(data);
|
||||
sbp=(uint8_t*)sbox;
|
||||
for(i=0; i<8; ++i){
|
||||
uint8_t x;
|
||||
x = substitute(((uint8_t*)&data)[i], sbp);
|
||||
t<<=4;
|
||||
t |= x;
|
||||
sbp += 32;
|
||||
}
|
||||
changeendian32(&t);
|
||||
/* Sbox substitution */
|
||||
data = splitin6bitwords(data);
|
||||
sbp=(uint8_t*)sbox;
|
||||
for(i=0; i<8; ++i){
|
||||
uint8_t x;
|
||||
x = substitute(((uint8_t*)&data)[i], sbp);
|
||||
t<<=4;
|
||||
t |= x;
|
||||
sbp += 32;
|
||||
}
|
||||
changeendian32(&t);
|
||||
|
||||
permute((uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret);
|
||||
permute((uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
uint8_t v8[8];
|
||||
uint32_t v32[2];
|
||||
} d;
|
||||
union {
|
||||
uint8_t v8[8];
|
||||
uint32_t v32[2];
|
||||
} d;
|
||||
} data_t;
|
||||
#define R (data.d.v32[1])
|
||||
#define L (data.d.v32[0])
|
||||
|
||||
void des_enc(void* out, const void* in, const void* key){
|
||||
|
||||
uint8_t kr[6], k[7];
|
||||
uint8_t i;
|
||||
data_t data;
|
||||
uint8_t kr[6], k[7];
|
||||
uint8_t i;
|
||||
data_t data;
|
||||
|
||||
permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8);
|
||||
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||
permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8);
|
||||
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||
|
||||
for(i=0; i<8; ++i){
|
||||
shiftkey(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+0))) )
|
||||
shiftkey(k);
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
L ^= des_f(R, kr);
|
||||
for(i=0; i<8; ++i){
|
||||
shiftkey(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+0))) )
|
||||
shiftkey(k);
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
L ^= des_f(R, kr);
|
||||
|
||||
shiftkey(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+1))) )
|
||||
shiftkey(k);
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
R ^= des_f(L, kr);
|
||||
shiftkey(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+1))) )
|
||||
shiftkey(k);
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
R ^= des_f(L, kr);
|
||||
|
||||
}
|
||||
/* L <-> R*/
|
||||
R ^= L;
|
||||
L ^= R;
|
||||
R ^= L;
|
||||
}
|
||||
/* L <-> R*/
|
||||
R ^= L;
|
||||
L ^= R;
|
||||
R ^= L;
|
||||
|
||||
permute((uint8_t*)inv_ip_permtab, data.d.v8, (uint8_t*)out);
|
||||
permute((uint8_t*)inv_ip_permtab, data.d.v8, (uint8_t*)out);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void des_dec(void* out, const void* in, const uint8_t* key){
|
||||
|
||||
uint8_t kr[6],k[7];
|
||||
int8_t i;
|
||||
data_t data;
|
||||
uint8_t kr[6],k[7];
|
||||
int8_t i;
|
||||
data_t data;
|
||||
|
||||
permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8);
|
||||
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||
for(i=7; i>=0; --i){
|
||||
permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8);
|
||||
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||
for(i=7; i>=0; --i){
|
||||
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
L ^= des_f(R, kr);
|
||||
shiftkey_inv(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+1))) ){
|
||||
shiftkey_inv(k);
|
||||
}
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
L ^= des_f(R, kr);
|
||||
shiftkey_inv(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+1))) ){
|
||||
shiftkey_inv(k);
|
||||
}
|
||||
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
R ^= des_f(L, kr);
|
||||
shiftkey_inv(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+0))) ){
|
||||
shiftkey_inv(k);
|
||||
}
|
||||
permute((uint8_t*)pc2_permtab, k, kr);
|
||||
R ^= des_f(L, kr);
|
||||
shiftkey_inv(k);
|
||||
if(ROTTABLE&((1<<((i<<1)+0))) ){
|
||||
shiftkey_inv(k);
|
||||
}
|
||||
|
||||
}
|
||||
/* L <-> R*/
|
||||
R ^= L;
|
||||
L ^= R;
|
||||
R ^= L;
|
||||
}
|
||||
/* L <-> R*/
|
||||
R ^= L;
|
||||
L ^= R;
|
||||
R ^= L;
|
||||
|
||||
permute((uint8_t*)inv_ip_permtab, data.d.v8, (uint8_t*)out);
|
||||
permute((uint8_t*)inv_ip_permtab, data.d.v8, (uint8_t*)out);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void tdes_enc(void* out, void* in, const void* key){
|
||||
des_enc(out, in, (uint8_t*)key + 0);
|
||||
des_dec(out, out, (uint8_t*)key + 8);
|
||||
des_enc(out, out, (uint8_t*)key +16);
|
||||
des_enc(out, in, (uint8_t*)key + 0);
|
||||
des_dec(out, out, (uint8_t*)key + 8);
|
||||
des_enc(out, out, (uint8_t*)key +16);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
void tdes_dec(void* out, void* in, const uint8_t* key){
|
||||
des_dec(out, in, (uint8_t*)key +16);
|
||||
des_enc(out, out, (uint8_t*)key + 8);
|
||||
des_dec(out, out, (uint8_t*)key + 0);
|
||||
des_dec(out, in, (uint8_t*)key +16);
|
||||
des_enc(out, out, (uint8_t*)key + 8);
|
||||
des_dec(out, out, (uint8_t*)key + 0);
|
||||
}
|
||||
|
||||
void tdes_2key_enc(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){
|
||||
|
||||
if( length % 8 ) return;
|
||||
if( length % 8 ) return;
|
||||
|
||||
uint8_t i;
|
||||
uint8_t* tin = (uint8_t*) in;
|
||||
uint8_t* tout = (uint8_t*) out;
|
||||
uint8_t i;
|
||||
uint8_t* tin = (uint8_t*) in;
|
||||
uint8_t* tout = (uint8_t*) out;
|
||||
|
||||
while( length > 0 )
|
||||
{
|
||||
for( i = 0; i < 8; i++ )
|
||||
tout[i] = (unsigned char)( tin[i] ^ iv[i] );
|
||||
while( length > 0 )
|
||||
{
|
||||
for( i = 0; i < 8; i++ )
|
||||
tout[i] = (unsigned char)( tin[i] ^ iv[i] );
|
||||
|
||||
des_enc(tout, tin, (uint8_t*)key + 0);
|
||||
des_dec(tout, tout, (uint8_t*)key + 8);
|
||||
des_enc(tout, tout, (uint8_t*)key + 0);
|
||||
des_enc(tout, tin, (uint8_t*)key + 0);
|
||||
des_dec(tout, tout, (uint8_t*)key + 8);
|
||||
des_enc(tout, tout, (uint8_t*)key + 0);
|
||||
|
||||
memcpy( iv, tout, 8 );
|
||||
memcpy( iv, tout, 8 );
|
||||
|
||||
tin += 8;
|
||||
tout += 8;
|
||||
length -= 8;
|
||||
}
|
||||
tin += 8;
|
||||
tout += 8;
|
||||
length -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void tdes_2key_dec(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){
|
||||
|
||||
if( length % 8 ) return;
|
||||
if( length % 8 ) return;
|
||||
|
||||
uint8_t i;
|
||||
unsigned char temp[8];
|
||||
uint8_t* tin = (uint8_t*) in;
|
||||
uint8_t* tout = (uint8_t*) out;
|
||||
uint8_t i;
|
||||
unsigned char temp[8];
|
||||
uint8_t* tin = (uint8_t*) in;
|
||||
uint8_t* tout = (uint8_t*) out;
|
||||
|
||||
while( length > 0 )
|
||||
{
|
||||
memcpy( temp, tin, 8 );
|
||||
while( length > 0 )
|
||||
{
|
||||
memcpy( temp, tin, 8 );
|
||||
|
||||
des_dec(tout, tin, (uint8_t*)key + 0);
|
||||
des_enc(tout, tout, (uint8_t*)key + 8);
|
||||
des_dec(tout, tout, (uint8_t*)key + 0);
|
||||
des_dec(tout, tin, (uint8_t*)key + 0);
|
||||
des_enc(tout, tout, (uint8_t*)key + 8);
|
||||
des_dec(tout, tout, (uint8_t*)key + 0);
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
tout[i] = (unsigned char)( tout[i] ^ iv[i] );
|
||||
for( i = 0; i < 8; i++ )
|
||||
tout[i] = (unsigned char)( tout[i] ^ iv[i] );
|
||||
|
||||
memcpy( iv, temp, 8 );
|
||||
memcpy( iv, temp, 8 );
|
||||
|
||||
tin += 8;
|
||||
tout += 8;
|
||||
length -= 8;
|
||||
}
|
||||
tin += 8;
|
||||
tout += 8;
|
||||
length -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
10
armsrc/des.h
10
armsrc/des.h
|
@ -17,11 +17,11 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* \file des.h
|
||||
* \author Daniel Otte
|
||||
* \date 2007-06-16
|
||||
* \brief des and tdes declarations
|
||||
* \license GPLv3 or later
|
||||
* \file des.h
|
||||
* \author Daniel Otte
|
||||
* \date 2007-06-16
|
||||
* \brief des and tdes declarations
|
||||
* \license GPLv3 or later
|
||||
*
|
||||
*/
|
||||
#ifndef __DES_H_
|
||||
|
|
|
@ -85,20 +85,20 @@ void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t l
|
|||
mifare_cypher_blocks_chained (NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER);
|
||||
|
||||
memcpy (cmac, ivect, kbs);
|
||||
free(buffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
size_t key_block_size (const desfirekey_t key) {
|
||||
size_t block_size = 8;
|
||||
switch (key->type) {
|
||||
case T_DES:
|
||||
case T_3DES:
|
||||
case T_3K3DES:
|
||||
block_size = 8;
|
||||
break;
|
||||
case T_AES:
|
||||
block_size = 16;
|
||||
break;
|
||||
case T_DES:
|
||||
case T_3DES:
|
||||
case T_3K3DES:
|
||||
block_size = 8;
|
||||
break;
|
||||
case T_AES:
|
||||
block_size = 16;
|
||||
break;
|
||||
}
|
||||
return block_size;
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes
|
|||
break;
|
||||
// Append MAC
|
||||
size_t bla = maced_data_length (DESFIRE(tag)->session_key, *nbytes - offset) + offset;
|
||||
bla++;
|
||||
bla++;
|
||||
|
||||
memcpy (res + *nbytes, mac, 4);
|
||||
|
||||
|
@ -224,7 +224,7 @@ void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes
|
|||
|
||||
if (append_mac) {
|
||||
size_t len = maced_data_length (key, *nbytes);
|
||||
++len;
|
||||
++len;
|
||||
memcpy (res, data, *nbytes);
|
||||
memcpy (res + *nbytes, DESFIRE (tag)->cmac, CMAC_LENGTH);
|
||||
*nbytes += CMAC_LENGTH;
|
||||
|
@ -448,7 +448,7 @@ void* mifare_cryto_postprocess_data (desfiretag_t tag, void *data, size_t *nbyte
|
|||
case AS_LEGACY:
|
||||
AddCrc14A( (uint8_t*)res, end_crc_pos);
|
||||
end_crc_pos = crc_pos + 2;
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
crc = crc16;
|
||||
|
@ -529,11 +529,11 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect
|
|||
switch (operation) {
|
||||
case MCO_ENCYPHER:
|
||||
//DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
|
||||
des_enc(edata, data, key->data);
|
||||
des_enc(edata, data, key->data);
|
||||
break;
|
||||
case MCO_DECYPHER:
|
||||
//DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
|
||||
des_dec(edata, data, key->data);
|
||||
des_dec(edata, data, key->data);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -543,27 +543,27 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect
|
|||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
|
||||
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
|
||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
|
||||
tdes_enc(edata,data, key->data);
|
||||
tdes_enc(edata,data, key->data);
|
||||
break;
|
||||
case MCO_DECYPHER:
|
||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
|
||||
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
|
||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
|
||||
tdes_dec(data, edata, key->data);
|
||||
tdes_dec(data, edata, key->data);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case T_3K3DES:
|
||||
switch (operation) {
|
||||
case MCO_ENCYPHER:
|
||||
tdes_enc(edata,data, key->data);
|
||||
tdes_enc(edata,data, key->data);
|
||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
|
||||
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
|
||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
|
||||
break;
|
||||
case MCO_DECYPHER:
|
||||
tdes_dec(data, edata, key->data);
|
||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT);
|
||||
tdes_dec(data, edata, key->data);
|
||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT);
|
||||
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
|
||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
|
||||
break;
|
||||
|
@ -571,21 +571,21 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect
|
|||
break;
|
||||
case T_AES:
|
||||
switch (operation)
|
||||
{
|
||||
case MCO_ENCYPHER:
|
||||
{
|
||||
AesCtx ctx;
|
||||
AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
|
||||
AesEncrypt(&ctx, data, edata, sizeof(edata) );
|
||||
break;
|
||||
}
|
||||
case MCO_DECYPHER:
|
||||
{
|
||||
AesCtx ctx;
|
||||
AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
|
||||
AesDecrypt(&ctx, edata, data, sizeof(edata));
|
||||
break;
|
||||
}
|
||||
{
|
||||
case MCO_ENCYPHER:
|
||||
{
|
||||
AesCtx ctx;
|
||||
AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
|
||||
AesEncrypt(&ctx, data, edata, sizeof(edata) );
|
||||
break;
|
||||
}
|
||||
case MCO_DECYPHER:
|
||||
{
|
||||
AesCtx ctx;
|
||||
AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
|
||||
AesDecrypt(&ctx, edata, data, sizeof(edata));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -620,11 +620,11 @@ void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *
|
|||
ivect = DESFIRE (tag)->ivect;
|
||||
|
||||
switch (DESFIRE (tag)->authentication_scheme) {
|
||||
case AS_LEGACY:
|
||||
memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
|
||||
break;
|
||||
case AS_NEW:
|
||||
break;
|
||||
case AS_LEGACY:
|
||||
memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
|
||||
break;
|
||||
case AS_NEW:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,12 +38,12 @@ void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key) {
|
|||
}
|
||||
|
||||
void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key) {
|
||||
if ( key != NULL) {
|
||||
key->type = T_DES;
|
||||
memcpy (key->data, value, 8);
|
||||
memcpy (key->data+8, value, 8);
|
||||
update_key_schedules (key);
|
||||
}
|
||||
if ( key != NULL) {
|
||||
key->type = T_DES;
|
||||
memcpy (key->data, value, 8);
|
||||
memcpy (key->data+8, value, 8);
|
||||
update_key_schedules (key);
|
||||
}
|
||||
}
|
||||
|
||||
void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key) {
|
||||
|
@ -58,11 +58,11 @@ void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key) {
|
|||
|
||||
void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key) {
|
||||
if ( key != NULL ){
|
||||
key->type = T_3DES;
|
||||
memcpy (key->data, value, 16);
|
||||
memcpy (key->data + 16, value, 8);
|
||||
update_key_schedules (key);
|
||||
}
|
||||
key->type = T_3DES;
|
||||
memcpy (key->data, value, 16);
|
||||
memcpy (key->data + 16, value, 8);
|
||||
update_key_schedules (key);
|
||||
}
|
||||
}
|
||||
|
||||
void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key) {
|
||||
|
@ -74,11 +74,11 @@ void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key) {
|
|||
}
|
||||
|
||||
void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key) {
|
||||
if ( key != NULL){
|
||||
key->type = T_3K3DES;
|
||||
memcpy (key->data, value, 24);
|
||||
update_key_schedules (key);
|
||||
}
|
||||
if ( key != NULL){
|
||||
key->type = T_3K3DES;
|
||||
memcpy (key->data, value, 24);
|
||||
update_key_schedules (key);
|
||||
}
|
||||
}
|
||||
|
||||
void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key) {
|
||||
|
@ -87,11 +87,11 @@ void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t
|
|||
|
||||
void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version, desfirekey_t key) {
|
||||
|
||||
if (key != NULL) {
|
||||
memcpy (key->data, value, 16);
|
||||
key->type = T_AES;
|
||||
key->aes_version = version;
|
||||
}
|
||||
if (key != NULL) {
|
||||
memcpy (key->data, value, 16);
|
||||
key->type = T_AES;
|
||||
key->aes_version = version;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Desfire_key_get_version (desfirekey_t key) {
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
#include "iso14443a.h"
|
||||
#include "desfire.h"
|
||||
//#include "mifare.h" // iso14a_card_select_t struct
|
||||
void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key);
|
||||
void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key);
|
||||
void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key);
|
||||
void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key);
|
||||
void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key);
|
||||
void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key);
|
||||
void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key);
|
||||
void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version,desfirekey_t key);
|
||||
uint8_t Desfire_key_get_version (desfirekey_t key);
|
||||
void Desfire_key_set_version (desfirekey_t key, uint8_t version);
|
||||
void Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key);
|
||||
void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key);
|
||||
void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key);
|
||||
void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key);
|
||||
void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key);
|
||||
void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key);
|
||||
void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key);
|
||||
void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key);
|
||||
void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version,desfirekey_t key);
|
||||
uint8_t Desfire_key_get_version (desfirekey_t key);
|
||||
void Desfire_key_set_version (desfirekey_t key, uint8_t version);
|
||||
void Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key);
|
||||
#endif
|
728
armsrc/epa.c
728
armsrc/epa.c
|
@ -21,41 +21,41 @@ static const uint8_t pps[] = {0xD0, 0x11, 0x00, 0x52, 0xA6};
|
|||
|
||||
// General Authenticate (request encrypted nonce) WITHOUT the Le at the end
|
||||
static const uint8_t apdu_general_authenticate_pace_get_nonce[] = {
|
||||
0x10, // CLA
|
||||
0x86, // INS
|
||||
0x00, // P1
|
||||
0x00, // P2
|
||||
0x02, // Lc
|
||||
0x7C, // Type: Dynamic Authentication Data
|
||||
0x00, // Length: 0 bytes
|
||||
0x10, // CLA
|
||||
0x86, // INS
|
||||
0x00, // P1
|
||||
0x00, // P2
|
||||
0x02, // Lc
|
||||
0x7C, // Type: Dynamic Authentication Data
|
||||
0x00, // Length: 0 bytes
|
||||
};
|
||||
|
||||
// MSE: Set AT (only CLA, INS, P1 and P2)
|
||||
static const uint8_t apdu_mse_set_at_start[] = {
|
||||
0x00, // CLA
|
||||
0x22, // INS
|
||||
0xC1, // P1
|
||||
0xA4, // P2
|
||||
0x00, // CLA
|
||||
0x22, // INS
|
||||
0xC1, // P1
|
||||
0xA4, // P2
|
||||
};
|
||||
|
||||
// SELECT BINARY with the ID for EF.CardAccess
|
||||
static const uint8_t apdu_select_binary_cardaccess[] = {
|
||||
0x00, // CLA
|
||||
0xA4, // INS
|
||||
0x02, // P1
|
||||
0x0C, // P2
|
||||
0x02, // Lc
|
||||
0x01, // ID
|
||||
0x1C // ID
|
||||
0x00, // CLA
|
||||
0xA4, // INS
|
||||
0x02, // P1
|
||||
0x0C, // P2
|
||||
0x02, // Lc
|
||||
0x01, // ID
|
||||
0x1C // ID
|
||||
};
|
||||
|
||||
// READ BINARY
|
||||
static const uint8_t apdu_read_binary[] = {
|
||||
0x00, // CLA
|
||||
0xB0, // INS
|
||||
0x00, // P1
|
||||
0x00, // P2
|
||||
0x38 // Le
|
||||
0x00, // CLA
|
||||
0xB0, // INS
|
||||
0x00, // P1
|
||||
0x00, // P2
|
||||
0x38 // Le
|
||||
};
|
||||
|
||||
|
||||
|
@ -84,14 +84,14 @@ static uint8_t apdu_replay_general_authenticate_pace_mutual_authenticate[75];
|
|||
static uint8_t apdu_replay_general_authenticate_pace_perform_key_agreement[18];
|
||||
// pointers to the APDUs (for iterations)
|
||||
static struct {
|
||||
uint8_t len;
|
||||
uint8_t *data;
|
||||
uint8_t len;
|
||||
uint8_t *data;
|
||||
} const apdus_replay[] = {
|
||||
{sizeof(apdu_replay_mse_set_at_pace), apdu_replay_mse_set_at_pace},
|
||||
{sizeof(apdu_replay_general_authenticate_pace_get_nonce), apdu_replay_general_authenticate_pace_get_nonce},
|
||||
{sizeof(apdu_replay_general_authenticate_pace_map_nonce), apdu_replay_general_authenticate_pace_map_nonce},
|
||||
{sizeof(apdu_replay_general_authenticate_pace_mutual_authenticate), apdu_replay_general_authenticate_pace_mutual_authenticate},
|
||||
{sizeof(apdu_replay_general_authenticate_pace_perform_key_agreement), apdu_replay_general_authenticate_pace_perform_key_agreement}
|
||||
{sizeof(apdu_replay_mse_set_at_pace), apdu_replay_mse_set_at_pace},
|
||||
{sizeof(apdu_replay_general_authenticate_pace_get_nonce), apdu_replay_general_authenticate_pace_get_nonce},
|
||||
{sizeof(apdu_replay_general_authenticate_pace_map_nonce), apdu_replay_general_authenticate_pace_map_nonce},
|
||||
{sizeof(apdu_replay_general_authenticate_pace_mutual_authenticate), apdu_replay_general_authenticate_pace_mutual_authenticate},
|
||||
{sizeof(apdu_replay_general_authenticate_pace_perform_key_agreement), apdu_replay_general_authenticate_pace_perform_key_agreement}
|
||||
};
|
||||
|
||||
// lengths of the replay APDUs
|
||||
|
@ -105,18 +105,18 @@ static char iso_type = 0;
|
|||
//-----------------------------------------------------------------------------
|
||||
int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response)
|
||||
{
|
||||
switch(iso_type)
|
||||
{
|
||||
case 'a':
|
||||
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
|
||||
break;
|
||||
case 'b':
|
||||
return iso14443b_apdu(apdu, length, response);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
switch(iso_type)
|
||||
{
|
||||
case 'a':
|
||||
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
|
||||
break;
|
||||
case 'b':
|
||||
return iso14443b_apdu(apdu, length, response);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -124,9 +124,9 @@ int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response)
|
|||
//-----------------------------------------------------------------------------
|
||||
void EPA_Finish()
|
||||
{
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
iso_type = 0;
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
iso_type = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -146,68 +146,68 @@ size_t EPA_Parse_CardAccess(uint8_t *data,
|
|||
size_t length,
|
||||
pace_version_info_t *pace_info)
|
||||
{
|
||||
size_t index = 0;
|
||||
size_t index = 0;
|
||||
|
||||
while (index <= length - 2) {
|
||||
// determine type of element
|
||||
// SET or SEQUENCE
|
||||
if (data[index] == 0x31 || data[index] == 0x30) {
|
||||
// enter the set (skip tag + length)
|
||||
index += 2;
|
||||
// check for extended length
|
||||
if ((data[index - 1] & 0x80) != 0) {
|
||||
index += (data[index-1] & 0x7F);
|
||||
}
|
||||
}
|
||||
// OID
|
||||
else if (data[index] == 0x06) {
|
||||
// is this a PACE OID?
|
||||
if (data[index + 1] == 0x0A // length matches
|
||||
&& memcmp(data + index + 2,
|
||||
oid_pace_start,
|
||||
sizeof(oid_pace_start)) == 0 // content matches
|
||||
&& pace_info != NULL)
|
||||
{
|
||||
// first, clear the pace_info struct
|
||||
memset(pace_info, 0, sizeof(pace_version_info_t));
|
||||
memcpy(pace_info->oid, data + index + 2, sizeof(pace_info->oid));
|
||||
// a PACE OID is followed by the version
|
||||
index += data[index + 1] + 2;
|
||||
if (data[index] == 02 && data[index + 1] == 01) {
|
||||
pace_info->version = data[index + 2];
|
||||
index += 3;
|
||||
}
|
||||
else {
|
||||
return index;
|
||||
}
|
||||
// after that there might(!) be the parameter ID
|
||||
if (data[index] == 02 && data[index + 1] == 01) {
|
||||
pace_info->parameter_id = data[index + 2];
|
||||
index += 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// skip this OID
|
||||
index += 2 + data[index + 1];
|
||||
}
|
||||
}
|
||||
// if the length is 0, something is wrong
|
||||
// TODO: This needs to be extended to support long tags
|
||||
else if (data[index + 1] == 0) {
|
||||
return index;
|
||||
}
|
||||
else {
|
||||
// skip this part
|
||||
// TODO: This needs to be extended to support long tags
|
||||
// TODO: This needs to be extended to support unknown elements with
|
||||
// a size > 0x7F
|
||||
index += 2 + data[index + 1];
|
||||
}
|
||||
}
|
||||
while (index <= length - 2) {
|
||||
// determine type of element
|
||||
// SET or SEQUENCE
|
||||
if (data[index] == 0x31 || data[index] == 0x30) {
|
||||
// enter the set (skip tag + length)
|
||||
index += 2;
|
||||
// check for extended length
|
||||
if ((data[index - 1] & 0x80) != 0) {
|
||||
index += (data[index-1] & 0x7F);
|
||||
}
|
||||
}
|
||||
// OID
|
||||
else if (data[index] == 0x06) {
|
||||
// is this a PACE OID?
|
||||
if (data[index + 1] == 0x0A // length matches
|
||||
&& memcmp(data + index + 2,
|
||||
oid_pace_start,
|
||||
sizeof(oid_pace_start)) == 0 // content matches
|
||||
&& pace_info != NULL)
|
||||
{
|
||||
// first, clear the pace_info struct
|
||||
memset(pace_info, 0, sizeof(pace_version_info_t));
|
||||
memcpy(pace_info->oid, data + index + 2, sizeof(pace_info->oid));
|
||||
// a PACE OID is followed by the version
|
||||
index += data[index + 1] + 2;
|
||||
if (data[index] == 02 && data[index + 1] == 01) {
|
||||
pace_info->version = data[index + 2];
|
||||
index += 3;
|
||||
}
|
||||
else {
|
||||
return index;
|
||||
}
|
||||
// after that there might(!) be the parameter ID
|
||||
if (data[index] == 02 && data[index + 1] == 01) {
|
||||
pace_info->parameter_id = data[index + 2];
|
||||
index += 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// skip this OID
|
||||
index += 2 + data[index + 1];
|
||||
}
|
||||
}
|
||||
// if the length is 0, something is wrong
|
||||
// TODO: This needs to be extended to support long tags
|
||||
else if (data[index + 1] == 0) {
|
||||
return index;
|
||||
}
|
||||
else {
|
||||
// skip this part
|
||||
// TODO: This needs to be extended to support long tags
|
||||
// TODO: This needs to be extended to support unknown elements with
|
||||
// a size > 0x7F
|
||||
index += 2 + data[index + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: We should check whether we reached the end in error, but for that
|
||||
// we need a better parser (e.g. with states like IN_SET or IN_PACE_INFO)
|
||||
return 0;
|
||||
// TODO: We should check whether we reached the end in error, but for that
|
||||
// we need a better parser (e.g. with states like IN_SET or IN_PACE_INFO)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -217,42 +217,42 @@ size_t EPA_Parse_CardAccess(uint8_t *data,
|
|||
//-----------------------------------------------------------------------------
|
||||
int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
|
||||
{
|
||||
// the response APDU of the card
|
||||
// since the card doesn't always care for the expected length we send it,
|
||||
// we reserve 262 bytes here just to be safe (256-byte APDU + SW + ISO frame)
|
||||
uint8_t response_apdu[262];
|
||||
int rapdu_length = 0;
|
||||
// the response APDU of the card
|
||||
// since the card doesn't always care for the expected length we send it,
|
||||
// we reserve 262 bytes here just to be safe (256-byte APDU + SW + ISO frame)
|
||||
uint8_t response_apdu[262];
|
||||
int rapdu_length = 0;
|
||||
|
||||
// select the file EF.CardAccess
|
||||
rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess,
|
||||
sizeof(apdu_select_binary_cardaccess),
|
||||
response_apdu);
|
||||
if (rapdu_length < 6
|
||||
|| response_apdu[rapdu_length - 4] != 0x90
|
||||
|| response_apdu[rapdu_length - 3] != 0x00)
|
||||
{
|
||||
DbpString("Failed to select EF.CardAccess!");
|
||||
return -1;
|
||||
}
|
||||
// select the file EF.CardAccess
|
||||
rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess,
|
||||
sizeof(apdu_select_binary_cardaccess),
|
||||
response_apdu);
|
||||
if (rapdu_length < 6
|
||||
|| response_apdu[rapdu_length - 4] != 0x90
|
||||
|| response_apdu[rapdu_length - 3] != 0x00)
|
||||
{
|
||||
DbpString("Failed to select EF.CardAccess!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// read the file
|
||||
rapdu_length = EPA_APDU((uint8_t *)apdu_read_binary,
|
||||
sizeof(apdu_read_binary),
|
||||
response_apdu);
|
||||
if (rapdu_length <= 6
|
||||
|| response_apdu[rapdu_length - 4] != 0x90
|
||||
|| response_apdu[rapdu_length - 3] != 0x00)
|
||||
{
|
||||
Dbprintf("Failed to read EF.CardAccess!");
|
||||
return -1;
|
||||
}
|
||||
// read the file
|
||||
rapdu_length = EPA_APDU((uint8_t *)apdu_read_binary,
|
||||
sizeof(apdu_read_binary),
|
||||
response_apdu);
|
||||
if (rapdu_length <= 6
|
||||
|| response_apdu[rapdu_length - 4] != 0x90
|
||||
|| response_apdu[rapdu_length - 3] != 0x00)
|
||||
{
|
||||
Dbprintf("Failed to read EF.CardAccess!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// copy the content into the buffer
|
||||
// length of data available: apdu_length - 4 (ISO frame) - 2 (SW)
|
||||
size_t to_copy = rapdu_length - 6;
|
||||
to_copy = to_copy < max_length ? to_copy : max_length;
|
||||
memcpy(buffer, response_apdu+2, to_copy);
|
||||
return to_copy;
|
||||
// copy the content into the buffer
|
||||
// length of data available: apdu_length - 4 (ISO frame) - 2 (SW)
|
||||
size_t to_copy = rapdu_length - 6;
|
||||
to_copy = to_copy < max_length ? to_copy : max_length;
|
||||
memcpy(buffer, response_apdu+2, to_copy);
|
||||
return to_copy;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -261,11 +261,11 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
|
|||
//-----------------------------------------------------------------------------
|
||||
static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
|
||||
{
|
||||
// power down the field
|
||||
EPA_Finish();
|
||||
// power down the field
|
||||
EPA_Finish();
|
||||
|
||||
// send the USB packet
|
||||
cmd_send(CMD_ACK,step,func_return,0,0,0);
|
||||
// send the USB packet
|
||||
cmd_send(CMD_ACK,step,func_return,0,0,0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -273,68 +273,68 @@ static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
|
|||
//-----------------------------------------------------------------------------
|
||||
void EPA_PACE_Collect_Nonce(UsbCommand *c)
|
||||
{
|
||||
/*
|
||||
* ack layout:
|
||||
* arg:
|
||||
* 1. element
|
||||
* step where the error occured or 0 if no error occured
|
||||
/*
|
||||
* ack layout:
|
||||
* arg:
|
||||
* 1. element
|
||||
* step where the error occured or 0 if no error occured
|
||||
* 2. element
|
||||
* return code of the last executed function
|
||||
* d:
|
||||
* Encrypted nonce
|
||||
*/
|
||||
* d:
|
||||
* Encrypted nonce
|
||||
*/
|
||||
|
||||
// return value of a function
|
||||
int func_return = 0;
|
||||
// return value of a function
|
||||
int func_return = 0;
|
||||
|
||||
// set up communication
|
||||
func_return = EPA_Setup();
|
||||
if (func_return != 0) {
|
||||
EPA_PACE_Collect_Nonce_Abort(1, func_return);
|
||||
return;
|
||||
}
|
||||
// set up communication
|
||||
func_return = EPA_Setup();
|
||||
if (func_return != 0) {
|
||||
EPA_PACE_Collect_Nonce_Abort(1, func_return);
|
||||
return;
|
||||
}
|
||||
|
||||
// read the CardAccess file
|
||||
// this array will hold the CardAccess file
|
||||
uint8_t card_access[256] = {0};
|
||||
int card_access_length = EPA_Read_CardAccess(card_access, 256);
|
||||
// the response has to be at least this big to hold the OID
|
||||
if (card_access_length < 18) {
|
||||
EPA_PACE_Collect_Nonce_Abort(2, card_access_length);
|
||||
return;
|
||||
}
|
||||
// read the CardAccess file
|
||||
// this array will hold the CardAccess file
|
||||
uint8_t card_access[256] = {0};
|
||||
int card_access_length = EPA_Read_CardAccess(card_access, 256);
|
||||
// the response has to be at least this big to hold the OID
|
||||
if (card_access_length < 18) {
|
||||
EPA_PACE_Collect_Nonce_Abort(2, card_access_length);
|
||||
return;
|
||||
}
|
||||
|
||||
// this will hold the PACE info of the card
|
||||
pace_version_info_t pace_version_info;
|
||||
// search for the PACE OID
|
||||
func_return = EPA_Parse_CardAccess(card_access,
|
||||
card_access_length,
|
||||
&pace_version_info);
|
||||
if (func_return != 0 || pace_version_info.version == 0) {
|
||||
EPA_PACE_Collect_Nonce_Abort(3, func_return);
|
||||
return;
|
||||
}
|
||||
// this will hold the PACE info of the card
|
||||
pace_version_info_t pace_version_info;
|
||||
// search for the PACE OID
|
||||
func_return = EPA_Parse_CardAccess(card_access,
|
||||
card_access_length,
|
||||
&pace_version_info);
|
||||
if (func_return != 0 || pace_version_info.version == 0) {
|
||||
EPA_PACE_Collect_Nonce_Abort(3, func_return);
|
||||
return;
|
||||
}
|
||||
|
||||
// initiate the PACE protocol
|
||||
// use the CAN for the password since that doesn't change
|
||||
func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2);
|
||||
// initiate the PACE protocol
|
||||
// use the CAN for the password since that doesn't change
|
||||
func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2);
|
||||
|
||||
// now get the nonce
|
||||
uint8_t nonce[256] = {0};
|
||||
uint8_t requested_size = (uint8_t)c->arg[0];
|
||||
func_return = EPA_PACE_Get_Nonce(requested_size, nonce);
|
||||
// check if the command succeeded
|
||||
if (func_return < 0)
|
||||
{
|
||||
EPA_PACE_Collect_Nonce_Abort(4, func_return);
|
||||
return;
|
||||
}
|
||||
// now get the nonce
|
||||
uint8_t nonce[256] = {0};
|
||||
uint8_t requested_size = (uint8_t)c->arg[0];
|
||||
func_return = EPA_PACE_Get_Nonce(requested_size, nonce);
|
||||
// check if the command succeeded
|
||||
if (func_return < 0)
|
||||
{
|
||||
EPA_PACE_Collect_Nonce_Abort(4, func_return);
|
||||
return;
|
||||
}
|
||||
|
||||
// all done, return
|
||||
EPA_Finish();
|
||||
// all done, return
|
||||
EPA_Finish();
|
||||
|
||||
// save received information
|
||||
cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
|
||||
// save received information
|
||||
cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -347,44 +347,44 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c)
|
|||
//-----------------------------------------------------------------------------
|
||||
int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce)
|
||||
{
|
||||
// build the APDU
|
||||
uint8_t apdu[sizeof(apdu_general_authenticate_pace_get_nonce) + 1];
|
||||
// copy the constant part
|
||||
memcpy(apdu,
|
||||
apdu_general_authenticate_pace_get_nonce,
|
||||
sizeof(apdu_general_authenticate_pace_get_nonce));
|
||||
// append Le (requested length + 2 due to tag/length taking 2 bytes) in RAPDU
|
||||
apdu[sizeof(apdu_general_authenticate_pace_get_nonce)] = requested_length + 4;
|
||||
// build the APDU
|
||||
uint8_t apdu[sizeof(apdu_general_authenticate_pace_get_nonce) + 1];
|
||||
// copy the constant part
|
||||
memcpy(apdu,
|
||||
apdu_general_authenticate_pace_get_nonce,
|
||||
sizeof(apdu_general_authenticate_pace_get_nonce));
|
||||
// append Le (requested length + 2 due to tag/length taking 2 bytes) in RAPDU
|
||||
apdu[sizeof(apdu_general_authenticate_pace_get_nonce)] = requested_length + 4;
|
||||
|
||||
// send it
|
||||
uint8_t response_apdu[262];
|
||||
int send_return = EPA_APDU(apdu,
|
||||
sizeof(apdu),
|
||||
response_apdu);
|
||||
// check if the command succeeded
|
||||
if (send_return < 6
|
||||
|| response_apdu[send_return - 4] != 0x90
|
||||
|| response_apdu[send_return - 3] != 0x00)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
// send it
|
||||
uint8_t response_apdu[262];
|
||||
int send_return = EPA_APDU(apdu,
|
||||
sizeof(apdu),
|
||||
response_apdu);
|
||||
// check if the command succeeded
|
||||
if (send_return < 6
|
||||
|| response_apdu[send_return - 4] != 0x90
|
||||
|| response_apdu[send_return - 3] != 0x00)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if there is no nonce in the RAPDU, return here
|
||||
if (send_return < 10)
|
||||
{
|
||||
// no error
|
||||
return 0;
|
||||
}
|
||||
// get the actual length of the nonce
|
||||
uint8_t nonce_length = response_apdu[5];
|
||||
if (nonce_length > send_return - 10)
|
||||
{
|
||||
nonce_length = send_return - 10;
|
||||
}
|
||||
// copy the nonce
|
||||
memcpy(nonce, response_apdu + 6, nonce_length);
|
||||
// if there is no nonce in the RAPDU, return here
|
||||
if (send_return < 10)
|
||||
{
|
||||
// no error
|
||||
return 0;
|
||||
}
|
||||
// get the actual length of the nonce
|
||||
uint8_t nonce_length = response_apdu[5];
|
||||
if (nonce_length > send_return - 10)
|
||||
{
|
||||
nonce_length = send_return - 10;
|
||||
}
|
||||
// copy the nonce
|
||||
memcpy(nonce, response_apdu + 6, nonce_length);
|
||||
|
||||
return nonce_length;
|
||||
return nonce_length;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -393,53 +393,53 @@ int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce)
|
|||
//-----------------------------------------------------------------------------
|
||||
int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
|
||||
{
|
||||
// create the MSE: Set AT APDU
|
||||
uint8_t apdu[23];
|
||||
// the minimum length (will be increased as more data is added)
|
||||
size_t apdu_length = 20;
|
||||
// copy the constant part
|
||||
memcpy(apdu,
|
||||
apdu_mse_set_at_start,
|
||||
sizeof(apdu_mse_set_at_start));
|
||||
// type: OID
|
||||
apdu[5] = 0x80;
|
||||
// length of the OID
|
||||
apdu[6] = sizeof(pace_version_info.oid);
|
||||
// copy the OID
|
||||
memcpy(apdu + 7,
|
||||
pace_version_info.oid,
|
||||
sizeof(pace_version_info.oid));
|
||||
// type: password
|
||||
apdu[17] = 0x83;
|
||||
// length: 1
|
||||
apdu[18] = 1;
|
||||
// password
|
||||
apdu[19] = password;
|
||||
// if standardized domain parameters are used, copy the ID
|
||||
if (pace_version_info.parameter_id != 0) {
|
||||
apdu_length += 3;
|
||||
// type: domain parameter
|
||||
apdu[20] = 0x84;
|
||||
// length: 1
|
||||
apdu[21] = 1;
|
||||
// copy the parameter ID
|
||||
apdu[22] = pace_version_info.parameter_id;
|
||||
}
|
||||
// now set Lc to the actual length
|
||||
apdu[4] = apdu_length - 5;
|
||||
// send it
|
||||
uint8_t response_apdu[6];
|
||||
int send_return = EPA_APDU(apdu,
|
||||
apdu_length,
|
||||
response_apdu);
|
||||
// check if the command succeeded
|
||||
if (send_return != 6
|
||||
|| response_apdu[send_return - 4] != 0x90
|
||||
|| response_apdu[send_return - 3] != 0x00)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
// create the MSE: Set AT APDU
|
||||
uint8_t apdu[23];
|
||||
// the minimum length (will be increased as more data is added)
|
||||
size_t apdu_length = 20;
|
||||
// copy the constant part
|
||||
memcpy(apdu,
|
||||
apdu_mse_set_at_start,
|
||||
sizeof(apdu_mse_set_at_start));
|
||||
// type: OID
|
||||
apdu[5] = 0x80;
|
||||
// length of the OID
|
||||
apdu[6] = sizeof(pace_version_info.oid);
|
||||
// copy the OID
|
||||
memcpy(apdu + 7,
|
||||
pace_version_info.oid,
|
||||
sizeof(pace_version_info.oid));
|
||||
// type: password
|
||||
apdu[17] = 0x83;
|
||||
// length: 1
|
||||
apdu[18] = 1;
|
||||
// password
|
||||
apdu[19] = password;
|
||||
// if standardized domain parameters are used, copy the ID
|
||||
if (pace_version_info.parameter_id != 0) {
|
||||
apdu_length += 3;
|
||||
// type: domain parameter
|
||||
apdu[20] = 0x84;
|
||||
// length: 1
|
||||
apdu[21] = 1;
|
||||
// copy the parameter ID
|
||||
apdu[22] = pace_version_info.parameter_id;
|
||||
}
|
||||
// now set Lc to the actual length
|
||||
apdu[4] = apdu_length - 5;
|
||||
// send it
|
||||
uint8_t response_apdu[6];
|
||||
int send_return = EPA_APDU(apdu,
|
||||
apdu_length,
|
||||
response_apdu);
|
||||
// check if the command succeeded
|
||||
if (send_return != 6
|
||||
|| response_apdu[send_return - 4] != 0x90
|
||||
|| response_apdu[send_return - 3] != 0x00)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -447,66 +447,66 @@ int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
|
|||
//-----------------------------------------------------------------------------
|
||||
void EPA_PACE_Replay(UsbCommand *c)
|
||||
{
|
||||
uint32_t timings[sizeof(apdu_lengths_replay) / sizeof(apdu_lengths_replay[0])] = {0};
|
||||
uint32_t timings[sizeof(apdu_lengths_replay) / sizeof(apdu_lengths_replay[0])] = {0};
|
||||
|
||||
// if an APDU has been passed, save it
|
||||
if (c->arg[0] != 0) {
|
||||
// make sure it's not too big
|
||||
if(c->arg[2] > apdus_replay[c->arg[0] - 1].len)
|
||||
{
|
||||
cmd_send(CMD_ACK, 1, 0, 0, NULL, 0);
|
||||
}
|
||||
memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1],
|
||||
c->d.asBytes,
|
||||
c->arg[2]);
|
||||
// save/update APDU length
|
||||
if (c->arg[1] == 0) {
|
||||
apdu_lengths_replay[c->arg[0] - 1] = c->arg[2];
|
||||
} else {
|
||||
apdu_lengths_replay[c->arg[0] - 1] += c->arg[2];
|
||||
}
|
||||
cmd_send(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||
return;
|
||||
}
|
||||
// if an APDU has been passed, save it
|
||||
if (c->arg[0] != 0) {
|
||||
// make sure it's not too big
|
||||
if(c->arg[2] > apdus_replay[c->arg[0] - 1].len)
|
||||
{
|
||||
cmd_send(CMD_ACK, 1, 0, 0, NULL, 0);
|
||||
}
|
||||
memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1],
|
||||
c->d.asBytes,
|
||||
c->arg[2]);
|
||||
// save/update APDU length
|
||||
if (c->arg[1] == 0) {
|
||||
apdu_lengths_replay[c->arg[0] - 1] = c->arg[2];
|
||||
} else {
|
||||
apdu_lengths_replay[c->arg[0] - 1] += c->arg[2];
|
||||
}
|
||||
cmd_send(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// return value of a function
|
||||
int func_return;
|
||||
// return value of a function
|
||||
int func_return;
|
||||
|
||||
// set up communication
|
||||
func_return = EPA_Setup();
|
||||
if (func_return != 0) {
|
||||
EPA_Finish();
|
||||
cmd_send(CMD_ACK, 2, func_return, 0, NULL, 0);
|
||||
return;
|
||||
}
|
||||
// set up communication
|
||||
func_return = EPA_Setup();
|
||||
if (func_return != 0) {
|
||||
EPA_Finish();
|
||||
cmd_send(CMD_ACK, 2, func_return, 0, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// increase the timeout (at least some cards really do need this!)/////////////
|
||||
// iso14a_set_timeout(0x0003FFFF);
|
||||
// increase the timeout (at least some cards really do need this!)/////////////
|
||||
// iso14a_set_timeout(0x0003FFFF);
|
||||
|
||||
// response APDU
|
||||
uint8_t response_apdu[300] = {0};
|
||||
// response APDU
|
||||
uint8_t response_apdu[300] = {0};
|
||||
|
||||
// now replay the data and measure the timings
|
||||
for (int i = 0; i < sizeof(apdu_lengths_replay); i++) {
|
||||
StartCountUS();
|
||||
func_return = EPA_APDU(apdus_replay[i].data,
|
||||
apdu_lengths_replay[i],
|
||||
response_apdu);
|
||||
timings[i] = GetCountUS();
|
||||
// every step but the last one should succeed
|
||||
if (i < sizeof(apdu_lengths_replay) - 1
|
||||
&& (func_return < 6
|
||||
|| response_apdu[func_return - 4] != 0x90
|
||||
|| response_apdu[func_return - 3] != 0x00))
|
||||
{
|
||||
EPA_Finish();
|
||||
cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20);
|
||||
return;
|
||||
}
|
||||
}
|
||||
EPA_Finish();
|
||||
cmd_send(CMD_ACK,0,0,0,timings,20);
|
||||
return;
|
||||
// now replay the data and measure the timings
|
||||
for (int i = 0; i < sizeof(apdu_lengths_replay); i++) {
|
||||
StartCountUS();
|
||||
func_return = EPA_APDU(apdus_replay[i].data,
|
||||
apdu_lengths_replay[i],
|
||||
response_apdu);
|
||||
timings[i] = GetCountUS();
|
||||
// every step but the last one should succeed
|
||||
if (i < sizeof(apdu_lengths_replay) - 1
|
||||
&& (func_return < 6
|
||||
|| response_apdu[func_return - 4] != 0x90
|
||||
|| response_apdu[func_return - 3] != 0x00))
|
||||
{
|
||||
EPA_Finish();
|
||||
cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20);
|
||||
return;
|
||||
}
|
||||
}
|
||||
EPA_Finish();
|
||||
cmd_send(CMD_ACK,0,0,0,timings,20);
|
||||
return;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -515,40 +515,40 @@ void EPA_PACE_Replay(UsbCommand *c)
|
|||
//-----------------------------------------------------------------------------
|
||||
int EPA_Setup()
|
||||
{
|
||||
int return_code = 0;
|
||||
uint8_t uid[10];
|
||||
uint8_t pps_response[3];
|
||||
uint8_t pps_response_par[1];
|
||||
iso14a_card_select_t card_a_info;
|
||||
iso14b_card_select_t card_b_info;
|
||||
int return_code = 0;
|
||||
uint8_t uid[10];
|
||||
uint8_t pps_response[3];
|
||||
uint8_t pps_response_par[1];
|
||||
iso14a_card_select_t card_a_info;
|
||||
iso14b_card_select_t card_b_info;
|
||||
|
||||
// first, look for type A cards
|
||||
// power up the field
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||
// select the card
|
||||
return_code = iso14443a_select_card(uid, &card_a_info, NULL, true, 0, false);
|
||||
if (return_code == 1) {
|
||||
// send the PPS request
|
||||
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
|
||||
return_code = ReaderReceive(pps_response, pps_response_par);
|
||||
if (return_code != 3 || pps_response[0] != 0xD0) {
|
||||
return return_code == 0 ? 2 : return_code;
|
||||
}
|
||||
Dbprintf("ISO 14443 Type A");
|
||||
iso_type = 'a';
|
||||
return 0;
|
||||
}
|
||||
// first, look for type A cards
|
||||
// power up the field
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||
// select the card
|
||||
return_code = iso14443a_select_card(uid, &card_a_info, NULL, true, 0, false);
|
||||
if (return_code == 1) {
|
||||
// send the PPS request
|
||||
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
|
||||
return_code = ReaderReceive(pps_response, pps_response_par);
|
||||
if (return_code != 3 || pps_response[0] != 0xD0) {
|
||||
return return_code == 0 ? 2 : return_code;
|
||||
}
|
||||
Dbprintf("ISO 14443 Type A");
|
||||
iso_type = 'a';
|
||||
return 0;
|
||||
}
|
||||
|
||||
// if we're here, there is no type A card, so we look for type B
|
||||
// power up the field
|
||||
iso14443b_setup();
|
||||
// select the card
|
||||
return_code = iso14443b_select_card( &card_b_info );
|
||||
if (return_code == 0) {
|
||||
Dbprintf("ISO 14443 Type B");
|
||||
iso_type = 'b';
|
||||
return 0;
|
||||
}
|
||||
Dbprintf("No card found.");
|
||||
return 1;
|
||||
// if we're here, there is no type A card, so we look for type B
|
||||
// power up the field
|
||||
iso14443b_setup();
|
||||
// select the card
|
||||
return_code = iso14443b_select_card( &card_b_info );
|
||||
if (return_code == 0) {
|
||||
Dbprintf("ISO 14443 Type B");
|
||||
iso_type = 'b';
|
||||
return 0;
|
||||
}
|
||||
Dbprintf("No card found.");
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
// this struct is used by EPA_Parse_CardAccess and contains info about the
|
||||
// PACE protocol supported by the chip
|
||||
typedef struct {
|
||||
uint8_t oid[10];
|
||||
uint8_t version;
|
||||
uint8_t parameter_id;
|
||||
uint8_t oid[10];
|
||||
uint8_t version;
|
||||
uint8_t parameter_id;
|
||||
} pace_version_info_t;
|
||||
|
||||
// note: EPA_PACE_Collect_Nonce and EPA_PACE_Replay are declared in apps.h
|
||||
|
|
806
armsrc/felica.c
806
armsrc/felica.c
File diff suppressed because it is too large
Load diff
|
@ -18,118 +18,118 @@ void FlashmemSetSpiBaudrate(uint32_t baudrate){
|
|||
Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE/1000000);
|
||||
}
|
||||
|
||||
// initialize
|
||||
// initialize
|
||||
bool FlashInit() {
|
||||
FlashSetup(FLASHMEM_SPIBAUDRATE);
|
||||
FlashSetup(FLASHMEM_SPIBAUDRATE);
|
||||
|
||||
StartTicks();
|
||||
StartTicks();
|
||||
|
||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) {
|
||||
StopTicks();
|
||||
return false;
|
||||
}
|
||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) {
|
||||
StopTicks();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void FlashSetup(uint32_t baudrate){
|
||||
//WDT_DISABLE
|
||||
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
|
||||
|
||||
// PA10 -> SPI_NCS2 chip select (FLASHMEM)
|
||||
// PA11 -> SPI_NCS0 chip select (FPGA)
|
||||
// PA12 -> SPI_MISO Master-In Slave-Out
|
||||
// PA13 -> SPI_MOSI Master-Out Slave-In
|
||||
// PA14 -> SPI_SPCK Serial Clock
|
||||
// PA10 -> SPI_NCS2 chip select (FLASHMEM)
|
||||
// PA11 -> SPI_NCS0 chip select (FPGA)
|
||||
// PA12 -> SPI_MISO Master-In Slave-Out
|
||||
// PA13 -> SPI_MOSI Master-Out Slave-In
|
||||
// PA14 -> SPI_SPCK Serial Clock
|
||||
|
||||
// Disable PIO control of the following pins, allows use by the SPI peripheral
|
||||
AT91C_BASE_PIOA->PIO_PDR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
|
||||
// Disable PIO control of the following pins, allows use by the SPI peripheral
|
||||
AT91C_BASE_PIOA->PIO_PDR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
|
||||
|
||||
// Pull-up Enable
|
||||
AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
|
||||
// Pull-up Enable
|
||||
AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
|
||||
|
||||
// Peripheral A
|
||||
AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK);
|
||||
// Peripheral A
|
||||
AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK);
|
||||
|
||||
// Peripheral B
|
||||
AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
|
||||
// Peripheral B
|
||||
AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
|
||||
|
||||
//enable the SPI Peripheral clock
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
||||
//enable the SPI Peripheral clock
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
||||
|
||||
|
||||
//reset spi needs double SWRST, see atmel's errata on this case
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
|
||||
//reset spi needs double SWRST, see atmel's errata on this case
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
|
||||
|
||||
// Enable SPI
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
||||
// Enable SPI
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
||||
|
||||
// NPCS2 Mode 0
|
||||
AT91C_BASE_SPI->SPI_MR =
|
||||
(0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT:
|
||||
// If DLYBCS is less than or equal to six, six MCK periods
|
||||
// will be inserted by default.
|
||||
SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10)
|
||||
( 0 << 7) | // Disable LLB (1=MOSI2MISO test mode)
|
||||
( 1 << 4) | // Disable ModeFault Protection
|
||||
( 0 << 3) | // makes spi operate at MCK (1 is MCK/2)
|
||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
||||
AT91C_SPI_MSTR; // Master Mode
|
||||
// NPCS2 Mode 0
|
||||
AT91C_BASE_SPI->SPI_MR =
|
||||
(0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT:
|
||||
// If DLYBCS is less than or equal to six, six MCK periods
|
||||
// will be inserted by default.
|
||||
SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10)
|
||||
( 0 << 7) | // Disable LLB (1=MOSI2MISO test mode)
|
||||
( 1 << 4) | // Disable ModeFault Protection
|
||||
( 0 << 3) | // makes spi operate at MCK (1 is MCK/2)
|
||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
||||
AT91C_SPI_MSTR; // Master Mode
|
||||
|
||||
uint8_t csaat = 1;
|
||||
uint32_t dlybct = 0;
|
||||
uint8_t csaat = 1;
|
||||
uint32_t dlybct = 0;
|
||||
if (baudrate > FLASH_MINFAST) {
|
||||
baudrate = FLASH_FASTBAUD;
|
||||
//csaat = 0;
|
||||
dlybct = 1500;
|
||||
}
|
||||
baudrate = FLASH_FASTBAUD;
|
||||
//csaat = 0;
|
||||
dlybct = 1500;
|
||||
}
|
||||
|
||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||
SPI_DLYBCT(dlybct,MCK) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||
SPI_DLYBS(0,MCK) | // Delay Beforce SPCK CLock
|
||||
SPI_SCBR(baudrate,MCK) | // SPI Baudrate Selection
|
||||
AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits)
|
||||
//AT91C_SPI_CSAAT | // Chip Select inactive after transfer
|
||||
// 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1
|
||||
// If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on
|
||||
// the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been
|
||||
// transferred in the shifter. This can imply for example, that the second data is sent twice.
|
||||
// COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay
|
||||
( csaat << 3) |
|
||||
/* Spi modes:
|
||||
Mode CPOL CPHA NCPHA
|
||||
0 0 0 1 clock normally low read on rising edge
|
||||
1 0 1 0 clock normally low read on falling edge
|
||||
2 1 0 1 clock normally high read on falling edge
|
||||
3 1 1 0 clock normally high read on rising edge
|
||||
However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI
|
||||
master mode the ATSAM7S512/256/128/64/321/32 does not sample the data
|
||||
(MISO) on the opposite edge where data clocks out (MOSI) but the same
|
||||
edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3
|
||||
shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and
|
||||
that the data changes sometime after the rising edge (about 2 ns). To
|
||||
be consistent with normal SPI operation, it is probably safe to say
|
||||
that the data changes on the falling edge and should be sampled on the
|
||||
rising edge. Therefore, it appears that NCPHA should be treated the
|
||||
same as CPHA. Thus:
|
||||
Mode CPOL CPHA NCPHA
|
||||
0 0 0 0 clock normally low read on rising edge
|
||||
1 0 1 1 clock normally low read on falling edge
|
||||
2 1 0 0 clock normally high read on falling edge
|
||||
3 1 1 1 clock normally high read on rising edge
|
||||
*/
|
||||
( 0 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||
SPI_DLYBCT(dlybct,MCK)| // Delay between Consecutive Transfers (32 MCK periods)
|
||||
SPI_DLYBS(0,MCK) | // Delay Beforce SPCK CLock
|
||||
SPI_SCBR(baudrate,MCK)| // SPI Baudrate Selection
|
||||
AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits)
|
||||
//AT91C_SPI_CSAAT | // Chip Select inactive after transfer
|
||||
// 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1
|
||||
// If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on
|
||||
// the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been
|
||||
// transferred in the shifter. This can imply for example, that the second data is sent twice.
|
||||
// COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay
|
||||
( csaat << 3) |
|
||||
/* Spi modes:
|
||||
Mode CPOL CPHA NCPHA
|
||||
0 0 0 1 clock normally low read on rising edge
|
||||
1 0 1 0 clock normally low read on falling edge
|
||||
2 1 0 1 clock normally high read on falling edge
|
||||
3 1 1 0 clock normally high read on rising edge
|
||||
However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI
|
||||
master mode the ATSAM7S512/256/128/64/321/32 does not sample the data
|
||||
(MISO) on the opposite edge where data clocks out (MOSI) but the same
|
||||
edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3
|
||||
shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and
|
||||
that the data changes sometime after the rising edge (about 2 ns). To
|
||||
be consistent with normal SPI operation, it is probably safe to say
|
||||
that the data changes on the falling edge and should be sampled on the
|
||||
rising edge. Therefore, it appears that NCPHA should be treated the
|
||||
same as CPHA. Thus:
|
||||
Mode CPOL CPHA NCPHA
|
||||
0 0 0 0 clock normally low read on rising edge
|
||||
1 0 1 1 clock normally low read on falling edge
|
||||
2 1 0 0 clock normally high read on falling edge
|
||||
3 1 1 1 clock normally high read on rising edge
|
||||
*/
|
||||
( 0 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
|
||||
// read first, empty buffer
|
||||
if (AT91C_BASE_SPI->SPI_RDR == 0) {};
|
||||
// read first, empty buffer
|
||||
if (AT91C_BASE_SPI->SPI_RDR == 0) {};
|
||||
}
|
||||
|
||||
void FlashStop(void) {
|
||||
//Bof
|
||||
//* Reset all the Chip Select register
|
||||
//Bof
|
||||
//* Reset all the Chip Select register
|
||||
AT91C_BASE_SPI->SPI_CSR[0] = 0;
|
||||
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
||||
AT91C_BASE_SPI->SPI_CSR[2] = 0;
|
||||
|
@ -141,164 +141,164 @@ void FlashStop(void) {
|
|||
// Disable all interrupts
|
||||
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
|
||||
|
||||
// SPI disable
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
|
||||
// SPI disable
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
|
||||
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("FlashStop");
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("FlashStop");
|
||||
|
||||
StopTicks();
|
||||
StopTicks();
|
||||
}
|
||||
|
||||
// send one byte over SPI
|
||||
// send one byte over SPI
|
||||
uint16_t FlashSendByte(uint32_t data) {
|
||||
|
||||
// wait until SPI is ready for transfer
|
||||
//if you are checking for incoming data returned then the TXEMPTY flag is redundant
|
||||
//while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {};
|
||||
// wait until SPI is ready for transfer
|
||||
//if you are checking for incoming data returned then the TXEMPTY flag is redundant
|
||||
//while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {};
|
||||
|
||||
// send the data
|
||||
AT91C_BASE_SPI->SPI_TDR = data;
|
||||
// send the data
|
||||
AT91C_BASE_SPI->SPI_TDR = data;
|
||||
|
||||
//while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){};
|
||||
|
||||
// wait recive transfer is complete
|
||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0){};
|
||||
// wait recive transfer is complete
|
||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0){};
|
||||
|
||||
// reading incoming data
|
||||
return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF);
|
||||
// reading incoming data
|
||||
return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF);
|
||||
}
|
||||
|
||||
// send last byte over SPI
|
||||
// send last byte over SPI
|
||||
uint16_t FlashSendLastByte(uint32_t data) {
|
||||
return FlashSendByte(data | AT91C_SPI_LASTXFER);
|
||||
return FlashSendByte(data | AT91C_SPI_LASTXFER);
|
||||
}
|
||||
|
||||
// read state register 1
|
||||
// read state register 1
|
||||
uint8_t Flash_ReadStat1(void) {
|
||||
FlashSendByte(READSTAT1);
|
||||
return FlashSendLastByte(0xFF);
|
||||
FlashSendByte(READSTAT1);
|
||||
return FlashSendLastByte(0xFF);
|
||||
}
|
||||
|
||||
bool Flash_CheckBusy(uint32_t timeout)
|
||||
{
|
||||
WaitUS(WINBOND_WRITE_DELAY);
|
||||
StartCountUS();
|
||||
uint32_t _time = GetCountUS();
|
||||
WaitUS(WINBOND_WRITE_DELAY);
|
||||
StartCountUS();
|
||||
uint32_t _time = GetCountUS();
|
||||
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Checkbusy in...");
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Checkbusy in...");
|
||||
|
||||
do
|
||||
{
|
||||
if (!(Flash_ReadStat1() & BUSY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} while ((GetCountUS() - _time) < timeout);
|
||||
do
|
||||
{
|
||||
if (!(Flash_ReadStat1() & BUSY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} while ((GetCountUS() - _time) < timeout);
|
||||
|
||||
if (timeout <= (GetCountUS() - _time))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (timeout <= (GetCountUS() - _time))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// read ID out
|
||||
uint8_t Flash_ReadID(void) {
|
||||
|
||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||
|
||||
// Manufacture ID / device ID
|
||||
FlashSendByte(ID);
|
||||
FlashSendByte(0x00);
|
||||
FlashSendByte(0x00);
|
||||
FlashSendByte(0x00);
|
||||
// Manufacture ID / device ID
|
||||
FlashSendByte(ID);
|
||||
FlashSendByte(0x00);
|
||||
FlashSendByte(0x00);
|
||||
FlashSendByte(0x00);
|
||||
|
||||
uint8_t man_id = FlashSendByte(0xFF);
|
||||
uint8_t dev_id = FlashSendLastByte(0xFF);
|
||||
uint8_t dev_id = FlashSendLastByte(0xFF);
|
||||
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash ReadID | Man ID %02x | Device ID %02x", man_id, dev_id);
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash ReadID | Man ID %02x | Device ID %02x", man_id, dev_id);
|
||||
|
||||
if ( (man_id == WINBOND_MANID ) && (dev_id == WINBOND_DEVID) )
|
||||
return dev_id;
|
||||
if ( (man_id == WINBOND_MANID ) && (dev_id == WINBOND_DEVID) )
|
||||
return dev_id;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read unique id for chip.
|
||||
void Flash_UniqueID(uint8_t *uid) {
|
||||
|
||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
|
||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
|
||||
|
||||
// reading unique serial number
|
||||
FlashSendByte(UNIQUE_ID);
|
||||
FlashSendByte(0xFF);
|
||||
FlashSendByte(0xFF);
|
||||
FlashSendByte(0xFF);
|
||||
FlashSendByte(0xFF);
|
||||
// reading unique serial number
|
||||
FlashSendByte(UNIQUE_ID);
|
||||
FlashSendByte(0xFF);
|
||||
FlashSendByte(0xFF);
|
||||
FlashSendByte(0xFF);
|
||||
FlashSendByte(0xFF);
|
||||
|
||||
uid[7] = FlashSendByte(0xFF);
|
||||
uid[6] = FlashSendByte(0xFF);
|
||||
uid[5] = FlashSendByte(0xFF);
|
||||
uid[4] = FlashSendByte(0xFF);
|
||||
uid[7] = FlashSendByte(0xFF);
|
||||
uid[6] = FlashSendByte(0xFF);
|
||||
uid[5] = FlashSendByte(0xFF);
|
||||
uid[4] = FlashSendByte(0xFF);
|
||||
uid[3] = FlashSendByte(0xFF);
|
||||
uid[2] = FlashSendByte(0xFF);
|
||||
uid[1] = FlashSendByte(0xFF);
|
||||
uid[0] = FlashSendLastByte(0xFF);
|
||||
uid[2] = FlashSendByte(0xFF);
|
||||
uid[1] = FlashSendByte(0xFF);
|
||||
uid[0] = FlashSendLastByte(0xFF);
|
||||
}
|
||||
|
||||
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||
|
||||
if (!FlashInit()) return 0;
|
||||
if (!FlashInit()) return 0;
|
||||
|
||||
// length should never be zero
|
||||
if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||
// length should never be zero
|
||||
if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||
|
||||
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
||||
|
||||
FlashSendByte(cmd);
|
||||
Flash_TransferAdresse(address);
|
||||
FlashSendByte(cmd);
|
||||
Flash_TransferAdresse(address);
|
||||
|
||||
if (FASTFLASH){
|
||||
FlashSendByte(DUMMYBYTE);
|
||||
}
|
||||
if (FASTFLASH){
|
||||
FlashSendByte(DUMMYBYTE);
|
||||
}
|
||||
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
out[i] = FlashSendByte(0xFF);
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
out[i] = FlashSendByte(0xFF);
|
||||
|
||||
out[i] = FlashSendLastByte(0xFF);
|
||||
FlashStop();
|
||||
return len;
|
||||
out[i] = FlashSendLastByte(0xFF);
|
||||
FlashStop();
|
||||
return len;
|
||||
}
|
||||
|
||||
void Flash_TransferAdresse(uint32_t address){
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
}
|
||||
|
||||
/* This ensure we can ReadData without having to cycle through initialization everytime */
|
||||
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
||||
|
||||
// length should never be zero
|
||||
if (!len) return 0;
|
||||
// length should never be zero
|
||||
if (!len) return 0;
|
||||
|
||||
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
||||
|
||||
FlashSendByte(cmd);
|
||||
Flash_TransferAdresse(address);
|
||||
FlashSendByte(cmd);
|
||||
Flash_TransferAdresse(address);
|
||||
|
||||
if (FASTFLASH){
|
||||
FlashSendByte(DUMMYBYTE);
|
||||
}
|
||||
FlashSendByte(DUMMYBYTE);
|
||||
}
|
||||
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
out[i] = FlashSendByte(0xFF);
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
out[i] = FlashSendByte(0xFF);
|
||||
|
||||
out[i] = FlashSendLastByte(0xFF);
|
||||
return len;
|
||||
out[i] = FlashSendLastByte(0xFF);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
@ -307,89 +307,89 @@ uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
|||
// if len > 256, it might wrap around and overwrite pos 0.
|
||||
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||
|
||||
// length should never be zero
|
||||
if (!len)
|
||||
return 0;
|
||||
// length should never be zero
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
// Max 256 bytes write
|
||||
if (((address & 0xFF) + len) > 256) {
|
||||
Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
||||
return 0;
|
||||
}
|
||||
// Max 256 bytes write
|
||||
if (((address & 0xFF) + len) > 256) {
|
||||
Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// out-of-range
|
||||
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
||||
Dbprintf("Flash_WriteData, block out-of-range");
|
||||
return 0;
|
||||
}
|
||||
// out-of-range
|
||||
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
||||
Dbprintf("Flash_WriteData, block out-of-range");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!FlashInit()) {
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||
return 0;
|
||||
}
|
||||
if (!FlashInit()) {
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
Flash_WriteEnable();
|
||||
Flash_WriteEnable();
|
||||
|
||||
FlashSendByte(PAGEPROG);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
FlashSendByte(PAGEPROG);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
FlashSendByte(in[i]);
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
FlashSendByte(in[i]);
|
||||
|
||||
FlashSendLastByte(in[i]);
|
||||
FlashSendLastByte(in[i]);
|
||||
|
||||
FlashStop();
|
||||
return len;
|
||||
FlashStop();
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
// length should never be zero
|
||||
// Max 256 bytes write
|
||||
// Max 256 bytes write
|
||||
// out-of-range
|
||||
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (((address & 0xFF) + len) > 256) {
|
||||
Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
||||
return 0;
|
||||
}
|
||||
if (((address & 0xFF) + len) > 256) {
|
||||
Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
||||
Dbprintf("Flash_WriteDataCont, block out-of-range");
|
||||
return 0;
|
||||
}
|
||||
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
||||
Dbprintf("Flash_WriteDataCont, block out-of-range");
|
||||
return 0;
|
||||
}
|
||||
|
||||
FlashSendByte(PAGEPROG);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
FlashSendByte(PAGEPROG);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendByte((address >> 0) & 0xFF);
|
||||
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
FlashSendByte(in[i]);
|
||||
uint16_t i = 0;
|
||||
for (; i < (len - 1); i++)
|
||||
FlashSendByte(in[i]);
|
||||
|
||||
FlashSendLastByte(in[i]);
|
||||
return len;
|
||||
FlashSendLastByte(in[i]);
|
||||
return len;
|
||||
}
|
||||
|
||||
// assumes valid start 256 based 00 address
|
||||
//
|
||||
uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) {
|
||||
|
||||
bool isok;
|
||||
uint16_t res, bytes_sent = 0, bytes_remaining = len;
|
||||
bool isok;
|
||||
uint16_t res, bytes_sent = 0, bytes_remaining = len;
|
||||
uint8_t buf[FLASH_MEM_BLOCK_SIZE];
|
||||
while (bytes_remaining > 0) {
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable();
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable();
|
||||
|
||||
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
||||
|
||||
|
@ -397,85 +397,85 @@ uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) {
|
|||
|
||||
res = Flash_WriteDataCont(address + bytes_sent, buf, bytes_in_packet);
|
||||
|
||||
bytes_remaining -= bytes_in_packet;
|
||||
bytes_remaining -= bytes_in_packet;
|
||||
bytes_sent += bytes_in_packet;
|
||||
|
||||
isok = (res == bytes_in_packet);
|
||||
|
||||
if (!isok)
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
FlashStop();
|
||||
return len;
|
||||
FlashStop();
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
bool Flash_WipeMemoryPage(uint8_t page) {
|
||||
if (!FlashInit()) {
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||
return false;
|
||||
}
|
||||
Flash_ReadStat1();
|
||||
if (!FlashInit()) {
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||
return false;
|
||||
}
|
||||
Flash_ReadStat1();
|
||||
|
||||
// Each block is 64Kb. One block erase takes 1s ( 1000ms )
|
||||
Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
// Each block is 64Kb. One block erase takes 1s ( 1000ms )
|
||||
Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
FlashStop();
|
||||
return true;
|
||||
FlashStop();
|
||||
return true;
|
||||
}
|
||||
// Wipes flash memory completely, fills with 0xFF
|
||||
bool Flash_WipeMemory() {
|
||||
if (!FlashInit()) {
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||
return false;
|
||||
}
|
||||
Flash_ReadStat1();
|
||||
if (!FlashInit()) {
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||
return false;
|
||||
}
|
||||
Flash_ReadStat1();
|
||||
|
||||
// Each block is 64Kb. Four blocks
|
||||
// one block erase takes 1s ( 1000ms )
|
||||
Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
// Each block is 64Kb. Four blocks
|
||||
// one block erase takes 1s ( 1000ms )
|
||||
Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
|
||||
FlashStop();
|
||||
return true;
|
||||
FlashStop();
|
||||
return true;
|
||||
}
|
||||
|
||||
// enable the flash write
|
||||
// enable the flash write
|
||||
void Flash_WriteEnable() {
|
||||
FlashSendLastByte(WRITEENABLE);
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash Write enabled");
|
||||
FlashSendLastByte(WRITEENABLE);
|
||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash Write enabled");
|
||||
}
|
||||
|
||||
// erase 4K at one time
|
||||
// erase 4K at one time
|
||||
// execution time: 0.8ms / 800us
|
||||
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
||||
|
||||
if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false;
|
||||
if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false;
|
||||
|
||||
FlashSendByte(SECTORERASE);
|
||||
FlashSendByte(block);
|
||||
FlashSendByte(sector << 4);
|
||||
FlashSendLastByte(00);
|
||||
return true;
|
||||
FlashSendByte(SECTORERASE);
|
||||
FlashSendByte(block);
|
||||
FlashSendByte(sector << 4);
|
||||
FlashSendLastByte(00);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
// erase 32K at one time
|
||||
// erase 32K at one time
|
||||
// execution time: 0,3s / 300ms
|
||||
bool Flash_Erase32k(uint32_t address) {
|
||||
if (address & (32*1024 - 1)) {
|
||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
|
||||
return false;
|
||||
}
|
||||
FlashSendByte(BLOCK32ERASE);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendLastByte((address >> 0) & 0xFF);
|
||||
return true;
|
||||
if (address & (32*1024 - 1)) {
|
||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
|
||||
return false;
|
||||
}
|
||||
FlashSendByte(BLOCK32ERASE);
|
||||
FlashSendByte((address >> 16) & 0xFF);
|
||||
FlashSendByte((address >> 8) & 0xFF);
|
||||
FlashSendLastByte((address >> 0) & 0xFF);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -489,52 +489,52 @@ bool Flash_Erase32k(uint32_t address) {
|
|||
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
||||
bool Flash_Erase64k(uint8_t block) {
|
||||
|
||||
if (block > MAX_BLOCKS) return false;
|
||||
if (block > MAX_BLOCKS) return false;
|
||||
|
||||
FlashSendByte(BLOCK64ERASE);
|
||||
FlashSendByte(block);
|
||||
FlashSendByte(0x00);
|
||||
FlashSendLastByte(0x00);
|
||||
return true;
|
||||
FlashSendByte(BLOCK64ERASE);
|
||||
FlashSendByte(block);
|
||||
FlashSendByte(0x00);
|
||||
FlashSendLastByte(0x00);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Erase chip
|
||||
// Erase chip
|
||||
void Flash_EraseChip(void) {
|
||||
FlashSendLastByte(CHIPERASE);
|
||||
FlashSendLastByte(CHIPERASE);
|
||||
}
|
||||
|
||||
void Flashmem_print_status(void) {
|
||||
DbpString("Flash memory");
|
||||
Dbprintf(" Baudrate................%dMHz",FLASHMEM_SPIBAUDRATE/1000000);
|
||||
DbpString("Flash memory");
|
||||
Dbprintf(" Baudrate................%dMHz",FLASHMEM_SPIBAUDRATE/1000000);
|
||||
|
||||
if (!FlashInit()) {
|
||||
DbpString(" Init....................FAIL");
|
||||
return;
|
||||
}
|
||||
DbpString(" Init....................OK");
|
||||
if (!FlashInit()) {
|
||||
DbpString(" Init....................FAIL");
|
||||
return;
|
||||
}
|
||||
DbpString(" Init....................OK");
|
||||
|
||||
uint8_t dev_id = Flash_ReadID();
|
||||
switch (dev_id) {
|
||||
case 0x11 :
|
||||
DbpString(" Memory size.............2 mbits / 256kb");
|
||||
break;
|
||||
case 0x10 :
|
||||
DbpString(" Memory size..... .......1 mbits / 128kb");
|
||||
break;
|
||||
case 0x05 :
|
||||
DbpString(" Memory size.............512 kbits / 64kb");
|
||||
break;
|
||||
default :
|
||||
DbpString(" Device ID............... --> Unknown <--");
|
||||
break;
|
||||
}
|
||||
uint8_t dev_id = Flash_ReadID();
|
||||
switch (dev_id) {
|
||||
case 0x11 :
|
||||
DbpString(" Memory size.............2 mbits / 256kb");
|
||||
break;
|
||||
case 0x10 :
|
||||
DbpString(" Memory size..... .......1 mbits / 128kb");
|
||||
break;
|
||||
case 0x05 :
|
||||
DbpString(" Memory size.............512 kbits / 64kb");
|
||||
break;
|
||||
default :
|
||||
DbpString(" Device ID............... --> Unknown <--");
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
||||
Flash_UniqueID(uid);
|
||||
Dbprintf(" Unique ID...............0x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
uid[7], uid[6], uid[5], uid[4],
|
||||
uid[3], uid[2], uid[1], uid[0]
|
||||
);
|
||||
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
||||
Flash_UniqueID(uid);
|
||||
Dbprintf(" Unique ID...............0x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
uid[7], uid[6], uid[5], uid[4],
|
||||
uid[3], uid[2], uid[1], uid[0]
|
||||
);
|
||||
|
||||
FlashStop();
|
||||
FlashStop();
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||
// Common Instructions //
|
||||
// Common Instructions //
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||
#ifndef __FLASHMEM_H
|
||||
#define __FLASHMEM_H
|
||||
|
@ -32,74 +32,74 @@
|
|||
#include "apps.h"
|
||||
#include "ticks.h"
|
||||
|
||||
// Used Command
|
||||
#define ID 0x90
|
||||
#define MANID 0x90
|
||||
#define JEDECID 0x9F
|
||||
// Used Command
|
||||
#define ID 0x90
|
||||
#define MANID 0x90
|
||||
#define JEDECID 0x9F
|
||||
|
||||
#define READSTAT1 0x05
|
||||
#define READSTAT2 0x35
|
||||
#define WRITESTAT 0x01
|
||||
#define READSTAT1 0x05
|
||||
#define READSTAT2 0x35
|
||||
#define WRITESTAT 0x01
|
||||
|
||||
#define WRITEDISABLE 0x04
|
||||
#define WRITEENABLE 0x06
|
||||
#define WRITEDISABLE 0x04
|
||||
#define WRITEENABLE 0x06
|
||||
|
||||
#define READDATA 0x03
|
||||
#define FASTREAD 0x0B
|
||||
#define PAGEPROG 0x02
|
||||
#define READDATA 0x03
|
||||
#define FASTREAD 0x0B
|
||||
#define PAGEPROG 0x02
|
||||
|
||||
#define SECTORERASE 0x20
|
||||
#define BLOCK32ERASE 0x52
|
||||
#define BLOCK64ERASE 0xD8
|
||||
#define CHIPERASE 0xC7
|
||||
#define SECTORERASE 0x20
|
||||
#define BLOCK32ERASE 0x52
|
||||
#define BLOCK64ERASE 0xD8
|
||||
#define CHIPERASE 0xC7
|
||||
|
||||
#define UNIQUE_ID 0x4B
|
||||
#define UNIQUE_ID 0x4B
|
||||
|
||||
// Not used or not support command
|
||||
#define RELEASE 0xAB
|
||||
#define POWERDOWN 0xB9
|
||||
#define SUSPEND 0x75
|
||||
#define RESUME 0x7A
|
||||
// Not used or not support command
|
||||
#define RELEASE 0xAB
|
||||
#define POWERDOWN 0xB9
|
||||
#define SUSPEND 0x75
|
||||
#define RESUME 0x7A
|
||||
|
||||
#define BUSY_TIMEOUT 1000000000L
|
||||
#define BUSY_TIMEOUT 1000000000L
|
||||
|
||||
#define WINBOND_MANID 0xEF
|
||||
#define WINBOND_DEVID 0x11
|
||||
#define PAGESIZE 0x100
|
||||
#define WINBOND_MANID 0xEF
|
||||
#define WINBOND_DEVID 0x11
|
||||
#define PAGESIZE 0x100
|
||||
#define WINBOND_WRITE_DELAY 0x02
|
||||
|
||||
#define SPI_CLK 48000000
|
||||
#define SPI_CLK 48000000
|
||||
|
||||
#define BUSY 0x01
|
||||
#define WRTEN 0x02
|
||||
#define SUS 0x40
|
||||
#define BUSY 0x01
|
||||
#define WRTEN 0x02
|
||||
#define SUS 0x40
|
||||
|
||||
#define DUMMYBYTE 0xEE
|
||||
#define NULLBYTE 0x00
|
||||
#define NULLINT 0x0000
|
||||
#define NO_CONTINUE 0x00
|
||||
#define PASS 0x01
|
||||
#define FAIL 0x00
|
||||
#define maxAddress capacity
|
||||
#define DUMMYBYTE 0xEE
|
||||
#define NULLBYTE 0x00
|
||||
#define NULLINT 0x0000
|
||||
#define NO_CONTINUE 0x00
|
||||
#define PASS 0x01
|
||||
#define FAIL 0x00
|
||||
#define maxAddress capacity
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||
// List of Error codes //
|
||||
// List of Error codes //
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||
#define SUCCESS 0x00
|
||||
#define CALLBEGIN 0x01
|
||||
#define UNKNOWNCHIP 0x02
|
||||
#define UNKNOWNCAP 0x03
|
||||
#define CHIPBUSY 0x04
|
||||
#define OUTOFBOUNDS 0x05
|
||||
#define CANTENWRITE 0x06
|
||||
#define PREVWRITTEN 0x07
|
||||
#define LOWRAM 0x08
|
||||
#define NOSUSPEND 0x09
|
||||
#define UNKNOWNERROR 0xFF
|
||||
#define SUCCESS 0x00
|
||||
#define CALLBEGIN 0x01
|
||||
#define UNKNOWNCHIP 0x02
|
||||
#define UNKNOWNCAP 0x03
|
||||
#define CHIPBUSY 0x04
|
||||
#define OUTOFBOUNDS 0x05
|
||||
#define CANTENWRITE 0x06
|
||||
#define PREVWRITTEN 0x07
|
||||
#define LOWRAM 0x08
|
||||
#define NOSUSPEND 0x09
|
||||
#define UNKNOWNERROR 0xFF
|
||||
|
||||
// List of blocks
|
||||
#define MAX_BLOCKS 4
|
||||
#define MAX_SECTORS 16
|
||||
#define MAX_BLOCKS 4
|
||||
#define MAX_SECTORS 16
|
||||
|
||||
|
||||
|
||||
|
|
582
armsrc/fonts.c
582
armsrc/fonts.c
|
@ -7,302 +7,302 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char FONT6x8[97][8] = {
|
||||
{0x06,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
||||
{0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00}, // !
|
||||
{0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00}, // "
|
||||
{0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00}, // #
|
||||
{0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00}, // $
|
||||
{0xC0,0xC8,0x10,0x20,0x40,0x98,0x18,0x00}, // %
|
||||
{0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68,0x00}, // &
|
||||
{0x30,0x30,0x20,0x40,0x00,0x00,0x00,0x00}, // '
|
||||
{0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00}, // (
|
||||
{0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00}, // )
|
||||
{0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00}, // *
|
||||
{0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00}, // +
|
||||
{0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40}, // ,
|
||||
{0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00}, // -
|
||||
{0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00}, // .
|
||||
{0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00}, // /
|
||||
{0x70,0x88,0x88,0xA8,0x88,0x88,0x70,0x00}, // 0
|
||||
{0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00}, // 1
|
||||
{0x70,0x88,0x08,0x70,0x80,0x80,0xF8,0x00}, // 2
|
||||
{0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x00}, // 3
|
||||
{0x10,0x30,0x50,0x90,0xF8,0x10,0x10,0x00}, // 4
|
||||
{0xF8,0x80,0xF0,0x08,0x08,0x88,0x70,0x00}, // 5
|
||||
{0x38,0x40,0x80,0xF0,0x88,0x88,0x70,0x00}, // 6
|
||||
{0xF8,0x08,0x08,0x10,0x20,0x40,0x80,0x00}, // 7
|
||||
{0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00}, // 8
|
||||
{0x70,0x88,0x88,0x78,0x08,0x10,0xE0,0x00}, // 9
|
||||
{0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x00}, // :
|
||||
{0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x00}, // ;
|
||||
{0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00}, // <
|
||||
{0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00}, // =
|
||||
{0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00}, // >
|
||||
{0x70,0x88,0x08,0x30,0x20,0x00,0x20,0x00}, // ?
|
||||
{0x70,0x88,0xA8,0xB8,0xB0,0x80,0x78,0x00}, // @
|
||||
{0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00}, // A
|
||||
{0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00}, // B
|
||||
{0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00}, // C
|
||||
{0xF0,0x88,0x88,0x88,0x88,0x88,0xF0,0x00}, // D
|
||||
{0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00}, // E
|
||||
{0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00}, // F
|
||||
{0x78,0x88,0x80,0x80,0x98,0x88,0x78,0x00}, // G
|
||||
{0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00}, // H
|
||||
{0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // I
|
||||
{0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00}, // J
|
||||
{0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00}, // K
|
||||
{0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00}, // L
|
||||
{0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x00}, // M
|
||||
{0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00}, // N
|
||||
{0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // O
|
||||
{0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00}, // P
|
||||
{0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00}, // Q
|
||||
{0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x00}, // R
|
||||
{0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00}, // S
|
||||
{0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x00}, // T
|
||||
{0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // U
|
||||
{0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00}, // V
|
||||
{0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00}, // W
|
||||
{0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00}, // X
|
||||
{0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00}, // Y
|
||||
{0xF8,0x08,0x10,0x70,0x40,0x80,0xF8,0x00}, // Z
|
||||
{0x78,0x40,0x40,0x40,0x40,0x40,0x78,0x00}, // [
|
||||
{0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00}, // backslash
|
||||
{0x78,0x08,0x08,0x08,0x08,0x08,0x78,0x00}, // ]
|
||||
{0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00}, // ^
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00}, // _
|
||||
{0x60,0x60,0x20,0x10,0x00,0x00,0x00,0x00}, // `
|
||||
{0x00,0x00,0x60,0x10,0x70,0x90,0x78,0x00}, // a
|
||||
{0x80,0x80,0xB0,0xC8,0x88,0xC8,0xB0,0x00}, // b
|
||||
{0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00}, // c
|
||||
{0x08,0x08,0x68,0x98,0x88,0x98,0x68,0x00}, // d
|
||||
{0x00,0x00,0x70,0x88,0xF8,0x80,0x70,0x00}, // e
|
||||
{0x10,0x28,0x20,0x70,0x20,0x20,0x20,0x00}, // f
|
||||
{0x00,0x00,0x70,0x98,0x98,0x68,0x08,0x70}, // g
|
||||
{0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x00}, // h
|
||||
{0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00}, // i
|
||||
{0x10,0x00,0x10,0x10,0x10,0x90,0x60,0x00}, // j
|
||||
{0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x00}, // k
|
||||
{0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // l
|
||||
{0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x00}, // m
|
||||
{0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x00}, // n
|
||||
{0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00}, // o
|
||||
{0x00,0x00,0xB0,0xC8,0xC8,0xB0,0x80,0x80}, // p
|
||||
{0x00,0x00,0x68,0x98,0x98,0x68,0x08,0x08}, // q
|
||||
{0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x00}, // r
|
||||
{0x00,0x00,0x78,0x80,0x70,0x08,0xF0,0x00}, // s
|
||||
{0x20,0x20,0xF8,0x20,0x20,0x28,0x10,0x00}, // t
|
||||
{0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00}, // u
|
||||
{0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00}, // v
|
||||
{0x00,0x00,0x88,0x88,0xA8,0xA8,0x50,0x00}, // w
|
||||
{0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00}, // x
|
||||
{0x00,0x00,0x88,0x88,0x78,0x08,0x88,0x70}, // y
|
||||
{0x00,0x00,0xF8,0x10,0x20,0x40,0xF8,0x00}, // z
|
||||
{0x10,0x20,0x20,0x40,0x20,0x20,0x10,0x00}, // {
|
||||
{0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00}, // |
|
||||
{0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00}, // }
|
||||
{0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00}, // ~
|
||||
{0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00} // DEL
|
||||
{0x06,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
||||
{0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00}, // !
|
||||
{0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00}, // "
|
||||
{0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00}, // #
|
||||
{0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00}, // $
|
||||
{0xC0,0xC8,0x10,0x20,0x40,0x98,0x18,0x00}, // %
|
||||
{0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68,0x00}, // &
|
||||
{0x30,0x30,0x20,0x40,0x00,0x00,0x00,0x00}, // '
|
||||
{0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00}, // (
|
||||
{0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00}, // )
|
||||
{0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00}, // *
|
||||
{0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00}, // +
|
||||
{0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40}, // ,
|
||||
{0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00}, // -
|
||||
{0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00}, // .
|
||||
{0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00}, // /
|
||||
{0x70,0x88,0x88,0xA8,0x88,0x88,0x70,0x00}, // 0
|
||||
{0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00}, // 1
|
||||
{0x70,0x88,0x08,0x70,0x80,0x80,0xF8,0x00}, // 2
|
||||
{0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x00}, // 3
|
||||
{0x10,0x30,0x50,0x90,0xF8,0x10,0x10,0x00}, // 4
|
||||
{0xF8,0x80,0xF0,0x08,0x08,0x88,0x70,0x00}, // 5
|
||||
{0x38,0x40,0x80,0xF0,0x88,0x88,0x70,0x00}, // 6
|
||||
{0xF8,0x08,0x08,0x10,0x20,0x40,0x80,0x00}, // 7
|
||||
{0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00}, // 8
|
||||
{0x70,0x88,0x88,0x78,0x08,0x10,0xE0,0x00}, // 9
|
||||
{0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x00}, // :
|
||||
{0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x00}, // ;
|
||||
{0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00}, // <
|
||||
{0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00}, // =
|
||||
{0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00}, // >
|
||||
{0x70,0x88,0x08,0x30,0x20,0x00,0x20,0x00}, // ?
|
||||
{0x70,0x88,0xA8,0xB8,0xB0,0x80,0x78,0x00}, // @
|
||||
{0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00}, // A
|
||||
{0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00}, // B
|
||||
{0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00}, // C
|
||||
{0xF0,0x88,0x88,0x88,0x88,0x88,0xF0,0x00}, // D
|
||||
{0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00}, // E
|
||||
{0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00}, // F
|
||||
{0x78,0x88,0x80,0x80,0x98,0x88,0x78,0x00}, // G
|
||||
{0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00}, // H
|
||||
{0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // I
|
||||
{0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00}, // J
|
||||
{0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00}, // K
|
||||
{0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00}, // L
|
||||
{0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x00}, // M
|
||||
{0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00}, // N
|
||||
{0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // O
|
||||
{0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00}, // P
|
||||
{0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00}, // Q
|
||||
{0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x00}, // R
|
||||
{0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00}, // S
|
||||
{0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x00}, // T
|
||||
{0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // U
|
||||
{0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00}, // V
|
||||
{0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00}, // W
|
||||
{0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00}, // X
|
||||
{0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00}, // Y
|
||||
{0xF8,0x08,0x10,0x70,0x40,0x80,0xF8,0x00}, // Z
|
||||
{0x78,0x40,0x40,0x40,0x40,0x40,0x78,0x00}, // [
|
||||
{0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00}, // backslash
|
||||
{0x78,0x08,0x08,0x08,0x08,0x08,0x78,0x00}, // ]
|
||||
{0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00}, // ^
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00}, // _
|
||||
{0x60,0x60,0x20,0x10,0x00,0x00,0x00,0x00}, // `
|
||||
{0x00,0x00,0x60,0x10,0x70,0x90,0x78,0x00}, // a
|
||||
{0x80,0x80,0xB0,0xC8,0x88,0xC8,0xB0,0x00}, // b
|
||||
{0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00}, // c
|
||||
{0x08,0x08,0x68,0x98,0x88,0x98,0x68,0x00}, // d
|
||||
{0x00,0x00,0x70,0x88,0xF8,0x80,0x70,0x00}, // e
|
||||
{0x10,0x28,0x20,0x70,0x20,0x20,0x20,0x00}, // f
|
||||
{0x00,0x00,0x70,0x98,0x98,0x68,0x08,0x70}, // g
|
||||
{0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x00}, // h
|
||||
{0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00}, // i
|
||||
{0x10,0x00,0x10,0x10,0x10,0x90,0x60,0x00}, // j
|
||||
{0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x00}, // k
|
||||
{0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // l
|
||||
{0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x00}, // m
|
||||
{0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x00}, // n
|
||||
{0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00}, // o
|
||||
{0x00,0x00,0xB0,0xC8,0xC8,0xB0,0x80,0x80}, // p
|
||||
{0x00,0x00,0x68,0x98,0x98,0x68,0x08,0x08}, // q
|
||||
{0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x00}, // r
|
||||
{0x00,0x00,0x78,0x80,0x70,0x08,0xF0,0x00}, // s
|
||||
{0x20,0x20,0xF8,0x20,0x20,0x28,0x10,0x00}, // t
|
||||
{0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00}, // u
|
||||
{0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00}, // v
|
||||
{0x00,0x00,0x88,0x88,0xA8,0xA8,0x50,0x00}, // w
|
||||
{0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00}, // x
|
||||
{0x00,0x00,0x88,0x88,0x78,0x08,0x88,0x70}, // y
|
||||
{0x00,0x00,0xF8,0x10,0x20,0x40,0xF8,0x00}, // z
|
||||
{0x10,0x20,0x20,0x40,0x20,0x20,0x10,0x00}, // {
|
||||
{0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00}, // |
|
||||
{0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00}, // }
|
||||
{0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00}, // ~
|
||||
{0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00} // DEL
|
||||
};
|
||||
/*
|
||||
const char FONT8x8F[97][8] = {
|
||||
{0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
||||
{0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
|
||||
{0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
|
||||
{0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
|
||||
{0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
|
||||
{0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
|
||||
{0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
|
||||
{0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
|
||||
{0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
|
||||
{0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
|
||||
{0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
|
||||
{0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
|
||||
{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
|
||||
{0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // /
|
||||
{0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0
|
||||
{0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
|
||||
{0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
|
||||
{0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
|
||||
{0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
|
||||
{0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
|
||||
{0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
|
||||
{0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
|
||||
{0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
|
||||
{0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
|
||||
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
|
||||
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
|
||||
{0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
|
||||
{0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
|
||||
{0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
|
||||
{0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
|
||||
{0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @
|
||||
{0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
|
||||
{0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
|
||||
{0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
|
||||
{0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
|
||||
{0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
|
||||
{0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
|
||||
{0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
|
||||
{0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
|
||||
{0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
|
||||
{0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
|
||||
{0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
|
||||
{0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
|
||||
{0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
|
||||
{0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
|
||||
{0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
|
||||
{0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P
|
||||
{0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
|
||||
{0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
|
||||
{0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
|
||||
{0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
|
||||
{0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
|
||||
{0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
|
||||
{0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
|
||||
{0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
|
||||
{0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
|
||||
{0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
|
||||
{0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
|
||||
{0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // backslash
|
||||
{0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
|
||||
{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
|
||||
{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // `
|
||||
{0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
|
||||
{0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
|
||||
{0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
|
||||
{0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
|
||||
{0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
|
||||
{0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
|
||||
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
|
||||
{0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
|
||||
{0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
|
||||
{0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
|
||||
{0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
|
||||
{0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
|
||||
{0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
|
||||
{0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
|
||||
{0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
|
||||
{0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
|
||||
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
|
||||
{0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
|
||||
{0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
|
||||
{0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
|
||||
{0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
|
||||
{0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
|
||||
{0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
|
||||
{0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
|
||||
{0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
|
||||
{0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
|
||||
{0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
|
||||
{0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
|
||||
{0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
|
||||
{0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
|
||||
{0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00} // DEL
|
||||
{0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
||||
{0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
|
||||
{0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
|
||||
{0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
|
||||
{0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
|
||||
{0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
|
||||
{0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
|
||||
{0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
|
||||
{0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
|
||||
{0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
|
||||
{0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
|
||||
{0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
|
||||
{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
|
||||
{0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // /
|
||||
{0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0
|
||||
{0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
|
||||
{0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
|
||||
{0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
|
||||
{0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
|
||||
{0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
|
||||
{0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
|
||||
{0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
|
||||
{0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
|
||||
{0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
|
||||
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
|
||||
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
|
||||
{0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
|
||||
{0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
|
||||
{0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
|
||||
{0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
|
||||
{0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @
|
||||
{0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
|
||||
{0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
|
||||
{0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
|
||||
{0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
|
||||
{0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
|
||||
{0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
|
||||
{0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
|
||||
{0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
|
||||
{0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
|
||||
{0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
|
||||
{0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
|
||||
{0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
|
||||
{0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
|
||||
{0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
|
||||
{0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
|
||||
{0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P
|
||||
{0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
|
||||
{0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
|
||||
{0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
|
||||
{0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
|
||||
{0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
|
||||
{0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
|
||||
{0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
|
||||
{0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
|
||||
{0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
|
||||
{0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
|
||||
{0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
|
||||
{0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // backslash
|
||||
{0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
|
||||
{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
|
||||
{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // `
|
||||
{0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
|
||||
{0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
|
||||
{0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
|
||||
{0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
|
||||
{0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
|
||||
{0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
|
||||
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
|
||||
{0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
|
||||
{0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
|
||||
{0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
|
||||
{0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
|
||||
{0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
|
||||
{0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
|
||||
{0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
|
||||
{0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
|
||||
{0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
|
||||
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
|
||||
{0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
|
||||
{0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
|
||||
{0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
|
||||
{0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
|
||||
{0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
|
||||
{0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
|
||||
{0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
|
||||
{0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
|
||||
{0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
|
||||
{0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
|
||||
{0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
|
||||
{0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
|
||||
{0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
|
||||
{0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00} // DEL
|
||||
};
|
||||
|
||||
const char FONT8x16[97][16] = {
|
||||
{0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
||||
{0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // !
|
||||
{0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // "
|
||||
{0x00,0x00,0x00,0x36,0x36,0x7F,0x36,0x36,0x36,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, // #
|
||||
{0x0C,0x0C,0x3E,0x63,0x61,0x60,0x3E,0x03,0x03,0x43,0x63,0x3E,0x0C,0x0C,0x00,0x00}, // $
|
||||
{0x00,0x00,0x00,0x00,0x00,0x61,0x63,0x06,0x0C,0x18,0x33,0x63,0x00,0x00,0x00,0x00}, // %
|
||||
{0x00,0x00,0x00,0x1C,0x36,0x36,0x1C,0x3B,0x6E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // &
|
||||
{0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // '
|
||||
{0x00,0x00,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x00,0x00,0x00,0x00}, // (
|
||||
{0x00,0x00,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x00,0x00,0x00,0x00}, // )
|
||||
{0x00,0x00,0x00,0x00,0x42,0x66,0x3C,0xFF,0x3C,0x66,0x42,0x00,0x00,0x00,0x00,0x00}, // *
|
||||
{0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, // +
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, // ,
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // -
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // .
|
||||
{0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00}, // /
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x63,0x6B,0x6B,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 0
|
||||
{0x00,0x00,0x0C,0x1C,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3F,0x00,0x00,0x00,0x00}, // 1
|
||||
{0x00,0x00,0x3E,0x63,0x03,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, // 2
|
||||
{0x00,0x00,0x3E,0x63,0x03,0x03,0x1E,0x03,0x03,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, // 3
|
||||
{0x00,0x00,0x06,0x0E,0x1E,0x36,0x66,0x66,0x7F,0x06,0x06,0x0F,0x00,0x00,0x00,0x00}, // 4
|
||||
{0x00,0x00,0x7F,0x60,0x60,0x60,0x7E,0x03,0x03,0x63,0x73,0x3E,0x00,0x00,0x00,0x00}, // 5
|
||||
{0x00,0x00,0x1C,0x30,0x60,0x60,0x7E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 6
|
||||
{0x00,0x00,0x7F,0x63,0x03,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x00,0x00}, // 7
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x63,0x3E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 8
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x3F,0x03,0x03,0x06,0x3C,0x00,0x00,0x00,0x00}, // 9
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // :
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, // ;
|
||||
{0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00}, // <
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00}, // =
|
||||
{0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00}, // >
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x06,0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00}, // ?
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x6F,0x6B,0x6B,0x6E,0x60,0x60,0x3E,0x00,0x00,0x00,0x00}, // @
|
||||
{0x00,0x00,0x08,0x1C,0x36,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // A
|
||||
{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x33,0x33,0x33,0x33,0x7E,0x00,0x00,0x00,0x00}, // B
|
||||
{0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1E,0x00,0x00,0x00,0x00}, // C
|
||||
{0x00,0x00,0x7C,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7C,0x00,0x00,0x00,0x00}, // D
|
||||
{0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, // E
|
||||
{0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // F
|
||||
{0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x6F,0x63,0x63,0x37,0x1D,0x00,0x00,0x00,0x00}, // G
|
||||
{0x00,0x00,0x63,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // H
|
||||
{0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // I
|
||||
{0x00,0x00,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00,0x00,0x00}, // J
|
||||
{0x00,0x00,0x73,0x33,0x36,0x36,0x3C,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // K
|
||||
{0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, // L
|
||||
{0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // M
|
||||
{0x00,0x00,0x63,0x63,0x73,0x7B,0x7F,0x6F,0x67,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // N
|
||||
{0x00,0x00,0x1C,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x00,0x00,0x00,0x00}, // O
|
||||
{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // P
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x63,0x6B,0x6F,0x3E,0x06,0x07,0x00,0x00}, // Q
|
||||
{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // R
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x30,0x1C,0x06,0x03,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // S
|
||||
{0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // T
|
||||
{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // U
|
||||
{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x08,0x00,0x00,0x00,0x00}, // V
|
||||
{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, // W
|
||||
{0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00}, // X
|
||||
{0x00,0x00,0xC3,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // Y
|
||||
{0x00,0x00,0x7F,0x63,0x43,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, // Z
|
||||
{0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00}, // [
|
||||
{0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00}, // backslash
|
||||
{0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00}, // ]
|
||||
{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ^
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00}, // _
|
||||
{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // `
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3C,0x46,0x06,0x3E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // a
|
||||
{0x00,0x00,0x70,0x30,0x30,0x3C,0x36,0x33,0x33,0x33,0x33,0x6E,0x00,0x00,0x00,0x00}, // b
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, // c
|
||||
{0x00,0x00,0x0E,0x06,0x06,0x1E,0x36,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // d
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x7E,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, // e
|
||||
{0x00,0x00,0x1C,0x36,0x32,0x30,0x7C,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // f
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,0x00}, // g
|
||||
{0x00,0x00,0x70,0x30,0x30,0x36,0x3B,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // h
|
||||
{0x00,0x00,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, // i
|
||||
{0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00}, // j
|
||||
{0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3C,0x36,0x33,0x73,0x00,0x00,0x00,0x00}, // k
|
||||
{0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, // l
|
||||
{0x00,0x00,0x00,0x00,0x00,0x6E,0x7F,0x6B,0x6B,0x6B,0x6B,0x6B,0x00,0x00,0x00,0x00}, // m
|
||||
{0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00}, // n
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // o
|
||||
{0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x3E,0x30,0x30,0x78,0x00,0x00}, // p
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x06,0x0F,0x00,0x00}, // q
|
||||
{0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // r
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x38,0x0E,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, // s
|
||||
{0x00,0x00,0x08,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x1B,0x0E,0x00,0x00,0x00,0x00}, // t
|
||||
{0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // u
|
||||
{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1C,0x1C,0x08,0x00,0x00,0x00,0x00}, // v
|
||||
{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x00,0x00,0x00,0x00}, // w
|
||||
{0x00,0x00,0x00,0x00,0x00,0x63,0x36,0x1C,0x1C,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // x
|
||||
{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x3F,0x03,0x06,0x3C,0x00,0x00}, // y
|
||||
{0x00,0x00,0x00,0x00,0x00,0x7F,0x66,0x0C,0x18,0x30,0x63,0x7F,0x00,0x00,0x00,0x00}, // z
|
||||
{0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00}, // {
|
||||
{0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00}, // |
|
||||
{0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00}, // }
|
||||
{0x00,0x00,0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
|
||||
{0x00,0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // DEL
|
||||
{0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
||||
{0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // !
|
||||
{0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // "
|
||||
{0x00,0x00,0x00,0x36,0x36,0x7F,0x36,0x36,0x36,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, // #
|
||||
{0x0C,0x0C,0x3E,0x63,0x61,0x60,0x3E,0x03,0x03,0x43,0x63,0x3E,0x0C,0x0C,0x00,0x00}, // $
|
||||
{0x00,0x00,0x00,0x00,0x00,0x61,0x63,0x06,0x0C,0x18,0x33,0x63,0x00,0x00,0x00,0x00}, // %
|
||||
{0x00,0x00,0x00,0x1C,0x36,0x36,0x1C,0x3B,0x6E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // &
|
||||
{0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // '
|
||||
{0x00,0x00,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x00,0x00,0x00,0x00}, // (
|
||||
{0x00,0x00,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x00,0x00,0x00,0x00}, // )
|
||||
{0x00,0x00,0x00,0x00,0x42,0x66,0x3C,0xFF,0x3C,0x66,0x42,0x00,0x00,0x00,0x00,0x00}, // *
|
||||
{0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00}, // +
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, // ,
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // -
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // .
|
||||
{0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00}, // /
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x63,0x6B,0x6B,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 0
|
||||
{0x00,0x00,0x0C,0x1C,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3F,0x00,0x00,0x00,0x00}, // 1
|
||||
{0x00,0x00,0x3E,0x63,0x03,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, // 2
|
||||
{0x00,0x00,0x3E,0x63,0x03,0x03,0x1E,0x03,0x03,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, // 3
|
||||
{0x00,0x00,0x06,0x0E,0x1E,0x36,0x66,0x66,0x7F,0x06,0x06,0x0F,0x00,0x00,0x00,0x00}, // 4
|
||||
{0x00,0x00,0x7F,0x60,0x60,0x60,0x7E,0x03,0x03,0x63,0x73,0x3E,0x00,0x00,0x00,0x00}, // 5
|
||||
{0x00,0x00,0x1C,0x30,0x60,0x60,0x7E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 6
|
||||
{0x00,0x00,0x7F,0x63,0x03,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x00,0x00}, // 7
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x63,0x3E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // 8
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x3F,0x03,0x03,0x06,0x3C,0x00,0x00,0x00,0x00}, // 9
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, // :
|
||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00}, // ;
|
||||
{0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00}, // <
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00}, // =
|
||||
{0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00}, // >
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x06,0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00}, // ?
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x6F,0x6B,0x6B,0x6E,0x60,0x60,0x3E,0x00,0x00,0x00,0x00}, // @
|
||||
{0x00,0x00,0x08,0x1C,0x36,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // A
|
||||
{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x33,0x33,0x33,0x33,0x7E,0x00,0x00,0x00,0x00}, // B
|
||||
{0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1E,0x00,0x00,0x00,0x00}, // C
|
||||
{0x00,0x00,0x7C,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7C,0x00,0x00,0x00,0x00}, // D
|
||||
{0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, // E
|
||||
{0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // F
|
||||
{0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x6F,0x63,0x63,0x37,0x1D,0x00,0x00,0x00,0x00}, // G
|
||||
{0x00,0x00,0x63,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // H
|
||||
{0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // I
|
||||
{0x00,0x00,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00,0x00,0x00}, // J
|
||||
{0x00,0x00,0x73,0x33,0x36,0x36,0x3C,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // K
|
||||
{0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00}, // L
|
||||
{0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // M
|
||||
{0x00,0x00,0x63,0x63,0x73,0x7B,0x7F,0x6F,0x67,0x63,0x63,0x63,0x00,0x00,0x00,0x00}, // N
|
||||
{0x00,0x00,0x1C,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x00,0x00,0x00,0x00}, // O
|
||||
{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // P
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x63,0x6B,0x6F,0x3E,0x06,0x07,0x00,0x00}, // Q
|
||||
{0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // R
|
||||
{0x00,0x00,0x3E,0x63,0x63,0x30,0x1C,0x06,0x03,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // S
|
||||
{0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // T
|
||||
{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // U
|
||||
{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x08,0x00,0x00,0x00,0x00}, // V
|
||||
{0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x36,0x00,0x00,0x00,0x00}, // W
|
||||
{0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00}, // X
|
||||
{0x00,0x00,0xC3,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, // Y
|
||||
{0x00,0x00,0x7F,0x63,0x43,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00}, // Z
|
||||
{0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00}, // [
|
||||
{0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00}, // backslash
|
||||
{0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00}, // ]
|
||||
{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ^
|
||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00}, // _
|
||||
{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // `
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3C,0x46,0x06,0x3E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // a
|
||||
{0x00,0x00,0x70,0x30,0x30,0x3C,0x36,0x33,0x33,0x33,0x33,0x6E,0x00,0x00,0x00,0x00}, // b
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, // c
|
||||
{0x00,0x00,0x0E,0x06,0x06,0x1E,0x36,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // d
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x7E,0x60,0x63,0x3E,0x00,0x00,0x00,0x00}, // e
|
||||
{0x00,0x00,0x1C,0x36,0x32,0x30,0x7C,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // f
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,0x00}, // g
|
||||
{0x00,0x00,0x70,0x30,0x30,0x36,0x3B,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00}, // h
|
||||
{0x00,0x00,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, // i
|
||||
{0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00}, // j
|
||||
{0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3C,0x36,0x33,0x73,0x00,0x00,0x00,0x00}, // k
|
||||
{0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00}, // l
|
||||
{0x00,0x00,0x00,0x00,0x00,0x6E,0x7F,0x6B,0x6B,0x6B,0x6B,0x6B,0x00,0x00,0x00,0x00}, // m
|
||||
{0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00}, // n
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00}, // o
|
||||
{0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x3E,0x30,0x30,0x78,0x00,0x00}, // p
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x06,0x0F,0x00,0x00}, // q
|
||||
{0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00}, // r
|
||||
{0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x38,0x0E,0x03,0x63,0x3E,0x00,0x00,0x00,0x00}, // s
|
||||
{0x00,0x00,0x08,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x1B,0x0E,0x00,0x00,0x00,0x00}, // t
|
||||
{0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00}, // u
|
||||
{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1C,0x1C,0x08,0x00,0x00,0x00,0x00}, // v
|
||||
{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x00,0x00,0x00,0x00}, // w
|
||||
{0x00,0x00,0x00,0x00,0x00,0x63,0x36,0x1C,0x1C,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // x
|
||||
{0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x3F,0x03,0x06,0x3C,0x00,0x00}, // y
|
||||
{0x00,0x00,0x00,0x00,0x00,0x7F,0x66,0x0C,0x18,0x30,0x63,0x7F,0x00,0x00,0x00,0x00}, // z
|
||||
{0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00}, // {
|
||||
{0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00}, // |
|
||||
{0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00}, // }
|
||||
{0x00,0x00,0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
|
||||
{0x00,0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // DEL
|
||||
};
|
||||
*/
|
||||
|
|
|
@ -21,7 +21,7 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end;
|
|||
static uint8_t *fpga_image_ptr = NULL;
|
||||
static uint32_t uncompressed_bytes_cnt;
|
||||
|
||||
#define OUTPUT_BUFFER_LEN 80
|
||||
#define OUTPUT_BUFFER_LEN 80
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Set up the Serial Peripheral Interface as master
|
||||
|
@ -29,7 +29,7 @@ static uint32_t uncompressed_bytes_cnt;
|
|||
// May also be used to write to other SPI attached devices like an LCD
|
||||
//-----------------------------------------------------------------------------
|
||||
static void DisableSpi(void) {
|
||||
//* Reset all the Chip Select register
|
||||
//* Reset all the Chip Select register
|
||||
AT91C_BASE_SPI->SPI_CSR[0] = 0;
|
||||
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
||||
AT91C_BASE_SPI->SPI_CSR[2] = 0;
|
||||
|
@ -41,77 +41,77 @@ static void DisableSpi(void) {
|
|||
// Disable all interrupts
|
||||
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
|
||||
|
||||
// SPI disable
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
|
||||
// SPI disable
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
|
||||
}
|
||||
|
||||
void SetupSpi(int mode) {
|
||||
// PA1 -> SPI_NCS3 chip select (MEM)
|
||||
// PA10 -> SPI_NCS2 chip select (LCD)
|
||||
// PA11 -> SPI_NCS0 chip select (FPGA)
|
||||
// PA12 -> SPI_MISO Master-In Slave-Out
|
||||
// PA13 -> SPI_MOSI Master-Out Slave-In
|
||||
// PA14 -> SPI_SPCK Serial Clock
|
||||
// PA1 -> SPI_NCS3 chip select (MEM)
|
||||
// PA10 -> SPI_NCS2 chip select (LCD)
|
||||
// PA11 -> SPI_NCS0 chip select (FPGA)
|
||||
// PA12 -> SPI_MISO Master-In Slave-Out
|
||||
// PA13 -> SPI_MOSI Master-Out Slave-In
|
||||
// PA14 -> SPI_SPCK Serial Clock
|
||||
|
||||
// Disable PIO control of the following pins, allows use by the SPI peripheral
|
||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK;
|
||||
// Disable PIO control of the following pins, allows use by the SPI peripheral
|
||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK;
|
||||
|
||||
// Peripheral A
|
||||
AT91C_BASE_PIOA->PIO_ASR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK;
|
||||
// Peripheral A
|
||||
AT91C_BASE_PIOA->PIO_ASR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK;
|
||||
|
||||
// Peripheral B
|
||||
//AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
|
||||
// Peripheral B
|
||||
//AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
|
||||
|
||||
//enable the SPI Peripheral clock
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
||||
// Enable SPI
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
||||
//enable the SPI Peripheral clock
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
||||
// Enable SPI
|
||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
||||
|
||||
switch (mode) {
|
||||
case SPI_FPGA_MODE:
|
||||
AT91C_BASE_SPI->SPI_MR =
|
||||
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
||||
(0xE << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
|
||||
( 0 << 7) | // Local Loopback Disabled
|
||||
AT91C_SPI_MODFDIS | // Mode Fault Detection disabled
|
||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
||||
AT91C_SPI_MSTR; // Master Mode
|
||||
switch (mode) {
|
||||
case SPI_FPGA_MODE:
|
||||
AT91C_BASE_SPI->SPI_MR =
|
||||
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
||||
(0xE << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
|
||||
( 0 << 7) | // Local Loopback Disabled
|
||||
AT91C_SPI_MODFDIS | // Mode Fault Detection disabled
|
||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
||||
AT91C_SPI_MSTR; // Master Mode
|
||||
|
||||
AT91C_BASE_SPI->SPI_CSR[0] =
|
||||
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
||||
AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits)
|
||||
( 0 << 3) | // Chip Select inactive after transfer
|
||||
AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
break;
|
||||
AT91C_BASE_SPI->SPI_CSR[0] =
|
||||
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
||||
AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits)
|
||||
( 0 << 3) | // Chip Select inactive after transfer
|
||||
AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
break;
|
||||
/*
|
||||
case SPI_LCD_MODE:
|
||||
AT91C_BASE_SPI->SPI_MR =
|
||||
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
||||
(0xB << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
|
||||
( 0 << 7) | // Local Loopback Disabled
|
||||
( 1 << 4) | // Mode Fault Detection disabled
|
||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||
( 0 << 1) | // Fixed Peripheral Select
|
||||
( 1 << 0); // Master Mode
|
||||
case SPI_LCD_MODE:
|
||||
AT91C_BASE_SPI->SPI_MR =
|
||||
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
||||
(0xB << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
|
||||
( 0 << 7) | // Local Loopback Disabled
|
||||
( 1 << 4) | // Mode Fault Detection disabled
|
||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||
( 0 << 1) | // Fixed Peripheral Select
|
||||
( 1 << 0); // Master Mode
|
||||
|
||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
||||
AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits)
|
||||
( 0 << 3) | // Chip Select inactive after transfer
|
||||
( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
break;
|
||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
||||
AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits)
|
||||
( 0 << 3) | // Chip Select inactive after transfer
|
||||
( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
DisableSpi();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DisableSpi();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -119,35 +119,35 @@ void SetupSpi(int mode) {
|
|||
// always use when we are talking to the FPGA. Both RX and TX are enabled.
|
||||
//-----------------------------------------------------------------------------
|
||||
void FpgaSetupSsc(void) {
|
||||
// First configure the GPIOs, and get ourselves a clock.
|
||||
AT91C_BASE_PIOA->PIO_ASR =
|
||||
GPIO_SSC_FRAME |
|
||||
GPIO_SSC_DIN |
|
||||
GPIO_SSC_DOUT |
|
||||
GPIO_SSC_CLK;
|
||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
|
||||
// First configure the GPIOs, and get ourselves a clock.
|
||||
AT91C_BASE_PIOA->PIO_ASR =
|
||||
GPIO_SSC_FRAME |
|
||||
GPIO_SSC_DIN |
|
||||
GPIO_SSC_DOUT |
|
||||
GPIO_SSC_CLK;
|
||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
|
||||
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SSC);
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SSC);
|
||||
|
||||
// Now set up the SSC proper, starting from a known state.
|
||||
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
|
||||
// Now set up the SSC proper, starting from a known state.
|
||||
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
|
||||
|
||||
// RX clock comes from TX clock, RX starts when TX starts, data changes
|
||||
// on RX clock rising edge, sampled on falling edge
|
||||
AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1);
|
||||
// RX clock comes from TX clock, RX starts when TX starts, data changes
|
||||
// on RX clock rising edge, sampled on falling edge
|
||||
AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1);
|
||||
|
||||
// 8 bits per transfer, no loopback, MSB first, 1 transfer per sync
|
||||
// pulse, no output sync
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
// 8 bits per transfer, no loopback, MSB first, 1 transfer per sync
|
||||
// pulse, no output sync
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
|
||||
// clock comes from TK pin, no clock output, outputs change on falling
|
||||
// edge of TK, sample on rising edge of TK, start on positive-going edge of sync
|
||||
AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5);
|
||||
// clock comes from TK pin, no clock output, outputs change on falling
|
||||
// edge of TK, sample on rising edge of TK, start on positive-going edge of sync
|
||||
AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5);
|
||||
|
||||
// tx framing is the same as the rx framing
|
||||
AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR;
|
||||
// tx framing is the same as the rx framing
|
||||
AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR;
|
||||
|
||||
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
|
||||
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -157,15 +157,15 @@ void FpgaSetupSsc(void) {
|
|||
// is in apps.h, because it should be inlined, for speed.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool FpgaSetupSscDma(uint8_t *buf, int len) {
|
||||
if (buf == NULL) return false;
|
||||
if (buf == NULL) return false;
|
||||
|
||||
FpgaDisableSscDma();
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address
|
||||
AT91C_BASE_PDC_SSC->PDC_RCR = len; // transfer this many bytes
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf; // next transfer to same memory address
|
||||
AT91C_BASE_PDC_SSC->PDC_RNCR = len; // ... with same number of bytes
|
||||
FpgaEnableSscDma();
|
||||
return true;
|
||||
FpgaDisableSscDma();
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address
|
||||
AT91C_BASE_PDC_SSC->PDC_RCR = len; // transfer this many bytes
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf; // next transfer to same memory address
|
||||
AT91C_BASE_PDC_SSC->PDC_RNCR = len; // ... with same number of bytes
|
||||
FpgaEnableSscDma();
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -173,20 +173,20 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) {
|
|||
// each call.
|
||||
//----------------------------------------------------------------------------
|
||||
static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
|
||||
compressed_fpga_stream->next_out = output_buffer;
|
||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
||||
fpga_image_ptr = output_buffer;
|
||||
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
|
||||
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
|
||||
compressed_fpga_stream->next_out = output_buffer;
|
||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
||||
fpga_image_ptr = output_buffer;
|
||||
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
|
||||
|
||||
if (res != Z_OK)
|
||||
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
|
||||
if (res != Z_OK)
|
||||
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
|
||||
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
uncompressed_bytes_cnt++;
|
||||
return *fpga_image_ptr++;
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
uncompressed_bytes_cnt++;
|
||||
return *fpga_image_ptr++;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -195,140 +195,140 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8
|
|||
// 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
|
||||
//----------------------------------------------------------------------------
|
||||
static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||
while((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) {
|
||||
// skip undesired data belonging to other bitstream_versions
|
||||
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
||||
}
|
||||
while((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) {
|
||||
// skip undesired data belonging to other bitstream_versions
|
||||
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
||||
}
|
||||
|
||||
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
||||
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
||||
}
|
||||
|
||||
static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size) {
|
||||
return BigBuf_malloc(items*size);
|
||||
return BigBuf_malloc(items*size);
|
||||
}
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
static void fpga_inflate_free(voidpf opaque, voidpf address) {
|
||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Initialize decompression of the respective (HF or LF) FPGA stream
|
||||
//----------------------------------------------------------------------------
|
||||
static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
|
||||
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
|
||||
|
||||
uncompressed_bytes_cnt = 0;
|
||||
uncompressed_bytes_cnt = 0;
|
||||
|
||||
// initialize z_stream structure for inflate:
|
||||
compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start;
|
||||
compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
|
||||
compressed_fpga_stream->next_out = output_buffer;
|
||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
||||
compressed_fpga_stream->zalloc = &fpga_inflate_malloc;
|
||||
compressed_fpga_stream->zfree = &fpga_inflate_free;
|
||||
// initialize z_stream structure for inflate:
|
||||
compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start;
|
||||
compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
|
||||
compressed_fpga_stream->next_out = output_buffer;
|
||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
||||
compressed_fpga_stream->zalloc = &fpga_inflate_malloc;
|
||||
compressed_fpga_stream->zfree = &fpga_inflate_free;
|
||||
|
||||
inflateInit2(compressed_fpga_stream, 0);
|
||||
inflateInit2(compressed_fpga_stream, 0);
|
||||
|
||||
fpga_image_ptr = output_buffer;
|
||||
fpga_image_ptr = output_buffer;
|
||||
|
||||
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++)
|
||||
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++)
|
||||
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||
|
||||
// Check for a valid .bit file (starts with bitparse_fixed_header)
|
||||
if (memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0)
|
||||
return true;
|
||||
// Check for a valid .bit file (starts with bitparse_fixed_header)
|
||||
if (memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void DownloadFPGA_byte( uint8_t w) {
|
||||
#define SEND_BIT(x) { if(w & (1<<x) ) HIGH(GPIO_FPGA_DIN); else LOW(GPIO_FPGA_DIN); HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); }
|
||||
SEND_BIT(7);
|
||||
SEND_BIT(6);
|
||||
SEND_BIT(5);
|
||||
SEND_BIT(4);
|
||||
SEND_BIT(3);
|
||||
SEND_BIT(2);
|
||||
SEND_BIT(1);
|
||||
SEND_BIT(0);
|
||||
SEND_BIT(7);
|
||||
SEND_BIT(6);
|
||||
SEND_BIT(5);
|
||||
SEND_BIT(4);
|
||||
SEND_BIT(3);
|
||||
SEND_BIT(2);
|
||||
SEND_BIT(1);
|
||||
SEND_BIT(0);
|
||||
}
|
||||
|
||||
// Download the fpga image starting at current stream position with length FpgaImageLen bytes
|
||||
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||
int i = 0;
|
||||
int i = 0;
|
||||
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON;
|
||||
HIGH(GPIO_FPGA_ON); // ensure everything is powered on
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON;
|
||||
HIGH(GPIO_FPGA_ON); // ensure everything is powered on
|
||||
|
||||
SpinDelay(50);
|
||||
SpinDelay(50);
|
||||
|
||||
LED_D_ON();
|
||||
LED_D_ON();
|
||||
|
||||
// These pins are inputs
|
||||
// These pins are inputs
|
||||
AT91C_BASE_PIOA->PIO_ODR =
|
||||
GPIO_FPGA_NINIT |
|
||||
GPIO_FPGA_DONE;
|
||||
// PIO controls the following pins
|
||||
GPIO_FPGA_NINIT |
|
||||
GPIO_FPGA_DONE;
|
||||
// PIO controls the following pins
|
||||
AT91C_BASE_PIOA->PIO_PER =
|
||||
GPIO_FPGA_NINIT |
|
||||
GPIO_FPGA_DONE;
|
||||
// Enable pull-ups
|
||||
AT91C_BASE_PIOA->PIO_PPUER =
|
||||
GPIO_FPGA_NINIT |
|
||||
GPIO_FPGA_DONE;
|
||||
GPIO_FPGA_NINIT |
|
||||
GPIO_FPGA_DONE;
|
||||
// Enable pull-ups
|
||||
AT91C_BASE_PIOA->PIO_PPUER =
|
||||
GPIO_FPGA_NINIT |
|
||||
GPIO_FPGA_DONE;
|
||||
|
||||
// setup initial logic state
|
||||
HIGH(GPIO_FPGA_NPROGRAM);
|
||||
LOW(GPIO_FPGA_CCLK);
|
||||
LOW(GPIO_FPGA_DIN);
|
||||
// These pins are outputs
|
||||
AT91C_BASE_PIOA->PIO_OER =
|
||||
GPIO_FPGA_NPROGRAM |
|
||||
GPIO_FPGA_CCLK |
|
||||
GPIO_FPGA_DIN;
|
||||
// setup initial logic state
|
||||
HIGH(GPIO_FPGA_NPROGRAM);
|
||||
LOW(GPIO_FPGA_CCLK);
|
||||
LOW(GPIO_FPGA_DIN);
|
||||
// These pins are outputs
|
||||
AT91C_BASE_PIOA->PIO_OER =
|
||||
GPIO_FPGA_NPROGRAM |
|
||||
GPIO_FPGA_CCLK |
|
||||
GPIO_FPGA_DIN;
|
||||
|
||||
// enter FPGA configuration mode
|
||||
LOW(GPIO_FPGA_NPROGRAM);
|
||||
SpinDelay(50);
|
||||
HIGH(GPIO_FPGA_NPROGRAM);
|
||||
// enter FPGA configuration mode
|
||||
LOW(GPIO_FPGA_NPROGRAM);
|
||||
SpinDelay(50);
|
||||
HIGH(GPIO_FPGA_NPROGRAM);
|
||||
|
||||
i = 100000;
|
||||
// wait for FPGA ready to accept data signal
|
||||
while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) {
|
||||
i--;
|
||||
}
|
||||
i = 100000;
|
||||
// wait for FPGA ready to accept data signal
|
||||
while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) {
|
||||
i--;
|
||||
}
|
||||
|
||||
// crude error indicator, leave both red LEDs on and return
|
||||
if (i==0){
|
||||
LED_C_ON();
|
||||
LED_D_ON();
|
||||
return;
|
||||
}
|
||||
// crude error indicator, leave both red LEDs on and return
|
||||
if (i==0){
|
||||
LED_C_ON();
|
||||
LED_D_ON();
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < FpgaImageLen; i++) {
|
||||
int b = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||
if (b < 0) {
|
||||
Dbprintf("Error %d during FpgaDownload", b);
|
||||
break;
|
||||
}
|
||||
DownloadFPGA_byte(b);
|
||||
}
|
||||
for (i = 0; i < FpgaImageLen; i++) {
|
||||
int b = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||
if (b < 0) {
|
||||
Dbprintf("Error %d during FpgaDownload", b);
|
||||
break;
|
||||
}
|
||||
DownloadFPGA_byte(b);
|
||||
}
|
||||
|
||||
// continue to clock FPGA until ready signal goes high
|
||||
i = 100000;
|
||||
while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) {
|
||||
HIGH(GPIO_FPGA_CCLK);
|
||||
LOW(GPIO_FPGA_CCLK);
|
||||
}
|
||||
// crude error indicator, leave both red LEDs on and return
|
||||
if (i==0){
|
||||
LED_C_ON();
|
||||
LED_D_ON();
|
||||
return;
|
||||
}
|
||||
LED_D_OFF();
|
||||
// continue to clock FPGA until ready signal goes high
|
||||
i = 100000;
|
||||
while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) {
|
||||
HIGH(GPIO_FPGA_CCLK);
|
||||
LOW(GPIO_FPGA_CCLK);
|
||||
}
|
||||
// crude error indicator, leave both red LEDs on and return
|
||||
if (i==0){
|
||||
LED_C_ON();
|
||||
LED_D_ON();
|
||||
return;
|
||||
}
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
/* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence
|
||||
|
@ -338,48 +338,48 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp
|
|||
* length.
|
||||
*/
|
||||
static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
||||
int result = 0;
|
||||
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
||||
uint16_t numbytes = 0;
|
||||
while(numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) {
|
||||
char current_name = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||
numbytes++;
|
||||
uint32_t current_length = 0;
|
||||
if (current_name < 'a' || current_name > 'e') {
|
||||
/* Strange section name, abort */
|
||||
break;
|
||||
}
|
||||
current_length = 0;
|
||||
switch (current_name) {
|
||||
case 'e':
|
||||
/* Four byte length field */
|
||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 24;
|
||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 16;
|
||||
numbytes += 2;
|
||||
default: /* Fall through, two byte length field */
|
||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 8;
|
||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0;
|
||||
numbytes += 2;
|
||||
}
|
||||
int result = 0;
|
||||
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
||||
uint16_t numbytes = 0;
|
||||
while(numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) {
|
||||
char current_name = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||
numbytes++;
|
||||
uint32_t current_length = 0;
|
||||
if (current_name < 'a' || current_name > 'e') {
|
||||
/* Strange section name, abort */
|
||||
break;
|
||||
}
|
||||
current_length = 0;
|
||||
switch (current_name) {
|
||||
case 'e':
|
||||
/* Four byte length field */
|
||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 24;
|
||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 16;
|
||||
numbytes += 2;
|
||||
default: /* Fall through, two byte length field */
|
||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 8;
|
||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0;
|
||||
numbytes += 2;
|
||||
}
|
||||
|
||||
if (current_name != 'e' && current_length > 255) {
|
||||
/* Maybe a parse error */
|
||||
break;
|
||||
}
|
||||
if (current_name != 'e' && current_length > 255) {
|
||||
/* Maybe a parse error */
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_name == section_name) {
|
||||
/* Found it */
|
||||
*section_length = current_length;
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
if (current_name == section_name) {
|
||||
/* Found it */
|
||||
*section_length = current_length;
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) {
|
||||
get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||
numbytes++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) {
|
||||
get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||
numbytes++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -388,34 +388,34 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3
|
|||
//----------------------------------------------------------------------------
|
||||
void FpgaDownloadAndGo(int bitstream_version) {
|
||||
|
||||
// check whether or not the bitstream is already loaded
|
||||
if (downloaded_bitstream == bitstream_version)
|
||||
return;
|
||||
// check whether or not the bitstream is already loaded
|
||||
if (downloaded_bitstream == bitstream_version)
|
||||
return;
|
||||
|
||||
z_stream compressed_fpga_stream;
|
||||
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
|
||||
z_stream compressed_fpga_stream;
|
||||
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
|
||||
|
||||
bool verbose = (MF_DBGLEVEL > 3);
|
||||
bool verbose = (MF_DBGLEVEL > 3);
|
||||
|
||||
// make sure that we have enough memory to decompress
|
||||
BigBuf_free(); BigBuf_Clear_ext(verbose);
|
||||
// make sure that we have enough memory to decompress
|
||||
BigBuf_free(); BigBuf_Clear_ext(verbose);
|
||||
|
||||
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
|
||||
return;
|
||||
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
|
||||
return;
|
||||
|
||||
uint32_t bitstream_length;
|
||||
if (bitparse_find_section(bitstream_version, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {
|
||||
DownloadFPGA(bitstream_version, bitstream_length, &compressed_fpga_stream, output_buffer);
|
||||
downloaded_bitstream = bitstream_version;
|
||||
}
|
||||
uint32_t bitstream_length;
|
||||
if (bitparse_find_section(bitstream_version, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {
|
||||
DownloadFPGA(bitstream_version, bitstream_length, &compressed_fpga_stream, output_buffer);
|
||||
downloaded_bitstream = bitstream_version;
|
||||
}
|
||||
|
||||
inflateEnd(&compressed_fpga_stream);
|
||||
inflateEnd(&compressed_fpga_stream);
|
||||
|
||||
// turn off antenna
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
// turn off antenna
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -424,10 +424,10 @@ void FpgaDownloadAndGo(int bitstream_version) {
|
|||
// where C is the 4 bit command and D is the 12 bit data
|
||||
//-----------------------------------------------------------------------------
|
||||
void FpgaSendCommand(uint16_t cmd, uint16_t v) {
|
||||
SetupSpi(SPI_FPGA_MODE);
|
||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
|
||||
AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data
|
||||
while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF)) {}; // wait till transfer is complete
|
||||
SetupSpi(SPI_FPGA_MODE);
|
||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
|
||||
AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data
|
||||
while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF)) {}; // wait till transfer is complete
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Write the FPGA setup word (that determines what mode the logic is in, read
|
||||
|
@ -435,7 +435,7 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v) {
|
|||
// avoid changing this function's occurence everywhere in the source code.
|
||||
//-----------------------------------------------------------------------------
|
||||
void FpgaWriteConfWord(uint8_t v) {
|
||||
FpgaSendCommand(FPGA_CMD_SET_CONFREG, v);
|
||||
FpgaSendCommand(FPGA_CMD_SET_CONFREG, v);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -444,35 +444,35 @@ void FpgaWriteConfWord(uint8_t v) {
|
|||
// the samples from the ADC always flow through the FPGA.
|
||||
//-----------------------------------------------------------------------------
|
||||
void SetAdcMuxFor(uint32_t whichGpio) {
|
||||
AT91C_BASE_PIOA->PIO_OER =
|
||||
GPIO_MUXSEL_HIPKD |
|
||||
GPIO_MUXSEL_LOPKD |
|
||||
GPIO_MUXSEL_LORAW |
|
||||
GPIO_MUXSEL_HIRAW;
|
||||
AT91C_BASE_PIOA->PIO_OER =
|
||||
GPIO_MUXSEL_HIPKD |
|
||||
GPIO_MUXSEL_LOPKD |
|
||||
GPIO_MUXSEL_LORAW |
|
||||
GPIO_MUXSEL_HIRAW;
|
||||
|
||||
AT91C_BASE_PIOA->PIO_PER =
|
||||
GPIO_MUXSEL_HIPKD |
|
||||
GPIO_MUXSEL_LOPKD |
|
||||
GPIO_MUXSEL_LORAW |
|
||||
GPIO_MUXSEL_HIRAW;
|
||||
AT91C_BASE_PIOA->PIO_PER =
|
||||
GPIO_MUXSEL_HIPKD |
|
||||
GPIO_MUXSEL_LOPKD |
|
||||
GPIO_MUXSEL_LORAW |
|
||||
GPIO_MUXSEL_HIRAW;
|
||||
|
||||
LOW(GPIO_MUXSEL_HIPKD);
|
||||
LOW(GPIO_MUXSEL_LOPKD);
|
||||
LOW(GPIO_MUXSEL_HIPKD);
|
||||
LOW(GPIO_MUXSEL_LOPKD);
|
||||
#ifndef WITH_FPC
|
||||
LOW(GPIO_MUXSEL_HIRAW);
|
||||
LOW(GPIO_MUXSEL_LORAW);
|
||||
LOW(GPIO_MUXSEL_HIRAW);
|
||||
LOW(GPIO_MUXSEL_LORAW);
|
||||
#endif
|
||||
|
||||
HIGH(whichGpio);
|
||||
HIGH(whichGpio);
|
||||
}
|
||||
|
||||
void Fpga_print_status(void) {
|
||||
Dbprintf("Currently loaded FPGA image");
|
||||
Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream-1]);
|
||||
Dbprintf("Currently loaded FPGA image");
|
||||
Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream-1]);
|
||||
}
|
||||
|
||||
int FpgaGetCurrent(void) {
|
||||
return downloaded_bitstream;
|
||||
return downloaded_bitstream;
|
||||
}
|
||||
|
||||
// Turns off the antenna,
|
||||
|
@ -480,10 +480,10 @@ int FpgaGetCurrent(void) {
|
|||
// if HF, Disable SSC DMA
|
||||
// turn off trace and leds off.
|
||||
void switch_off(void) {
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("switch_off");
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
if (downloaded_bitstream == FPGA_BITSTREAM_HF )
|
||||
FpgaDisableSscDma();
|
||||
set_tracing(false);
|
||||
LEDsoff();
|
||||
if (MF_DBGLEVEL > 3) Dbprintf("switch_off");
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
if (downloaded_bitstream == FPGA_BITSTREAM_HF )
|
||||
FpgaDisableSscDma();
|
||||
set_tracing(false);
|
||||
LEDsoff();
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
#include <stdbool.h>
|
||||
#include "apps.h"
|
||||
#include "fpga.h"
|
||||
#include "common.h" // standard definitions
|
||||
#include "proxmark3.h" // common area
|
||||
#include "common.h" // standard definitions
|
||||
#include "proxmark3.h" // common area
|
||||
#include "string.h"
|
||||
#include "BigBuf.h" // bigbuf mem
|
||||
#include "zlib.h" // uncompress
|
||||
#include "BigBuf.h" // bigbuf mem
|
||||
#include "zlib.h" // uncompress
|
||||
|
||||
|
||||
void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
||||
|
@ -32,7 +32,7 @@ void SetupSpi(int mode);
|
|||
bool FpgaSetupSscDma(uint8_t *buf, int len);
|
||||
void Fpga_print_status(void);
|
||||
int FpgaGetCurrent(void);
|
||||
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||
void SetAdcMuxFor(uint32_t whichGpio);
|
||||
|
||||
|
@ -45,56 +45,56 @@ extern void switch_off(void);
|
|||
//#define FPGA_BITSTREAM_FELICA 3
|
||||
|
||||
// Definitions for the FPGA commands.
|
||||
#define FPGA_CMD_SET_CONFREG (1<<12)
|
||||
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
||||
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
|
||||
#define FPGA_CMD_SET_CONFREG (1<<12)
|
||||
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
||||
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
|
||||
// Definitions for the FPGA configuration word.
|
||||
// LF
|
||||
#define FPGA_MAJOR_MODE_LF_ADC (0<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_ADC (0<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
|
||||
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5)
|
||||
// HF
|
||||
#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_FELICA (5<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_READER_TX (0<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5)
|
||||
#define FPGA_MAJOR_MODE_HF_FELICA (5<<5)
|
||||
// BOTH
|
||||
#define FPGA_MAJOR_MODE_OFF_LF (6<<5)
|
||||
#define FPGA_MAJOR_MODE_OFF (7<<5)
|
||||
#define FPGA_MAJOR_MODE_OFF_LF (6<<5)
|
||||
#define FPGA_MAJOR_MODE_OFF (7<<5)
|
||||
|
||||
// Options for LF_ADC
|
||||
#define FPGA_LF_ADC_READER_FIELD (1<<0)
|
||||
#define FPGA_LF_ADC_READER_FIELD (1<<0)
|
||||
// Options for LF_EDGE_DETECT
|
||||
#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1
|
||||
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
|
||||
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
|
||||
#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1
|
||||
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
|
||||
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
|
||||
// Options for the HF reader, tx to tag
|
||||
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
|
||||
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
|
||||
// Options for the HF reader, correlating against rx from tag
|
||||
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
|
||||
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
||||
#define FPGA_HF_READER_RX_XCORR_QUARTER (1<<2)
|
||||
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
|
||||
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
||||
#define FPGA_HF_READER_RX_XCORR_QUARTER (1<<2)
|
||||
// Options for the HF simulated tag, how to modulate
|
||||
#define FPGA_HF_SIMULATOR_NO_MODULATION 0x0 // 0000
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_BPSK 0x1 // 0001
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_212K 0x2 // 0010
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K 0x4 // 0100
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5 // 0101
|
||||
#define FPGA_HF_SIMULATOR_NO_MODULATION 0x0 // 0000
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_BPSK 0x1 // 0001
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_212K 0x2 // 0010
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K 0x4 // 0100
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5 // 0101
|
||||
// no 848K
|
||||
|
||||
// Options for ISO14443A
|
||||
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
|
||||
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
|
||||
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
|
||||
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
|
||||
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
||||
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
|
||||
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
|
||||
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
|
||||
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
|
||||
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
||||
|
||||
//options for Felica.
|
||||
#define FPGA_MAJOR_MODE_ISO18092 (5<<5) // 01010 0000
|
||||
#define FPGA_MAJOR_MODE_ISO18092 (5<<5) // 01010 0000
|
||||
#define FPGA_HF_ISO18092_FLAG_NOMOD (1<<0) // 0001 disable modulation module
|
||||
#define FPGA_HF_ISO18092_FLAG_424K (2<<0) // 0010 should enable 414k mode (untested). No autodetect
|
||||
#define FPGA_HF_ISO18092_FLAG_READER (4<<0) // 0100 enables antenna power, to act as a reader instead of tag
|
||||
#define FPGA_HF_ISO18092_FLAG_READER (4<<0) // 0100 enables antenna power, to act as a reader instead of tag
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -2,79 +2,79 @@
|
|||
#include "apps.h"
|
||||
#include "BigBuf.h"
|
||||
#include "util.h"
|
||||
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||
|
||||
static void RAMFUNC optimizedSnoop(void);
|
||||
|
||||
static void RAMFUNC optimizedSnoop(void)
|
||||
{
|
||||
int n = BigBuf_max_traceLen() / sizeof(uint16_t); // take all memory
|
||||
int n = BigBuf_max_traceLen() / sizeof(uint16_t); // take all memory
|
||||
|
||||
uint16_t *dest = (uint16_t *)BigBuf_get_addr();
|
||||
uint16_t *dest = (uint16_t *)BigBuf_get_addr();
|
||||
uint16_t *destend = dest + n-1;
|
||||
|
||||
// Reading data loop
|
||||
while(dest <= destend) {
|
||||
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
*dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
// Reading data loop
|
||||
while(dest <= destend) {
|
||||
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
*dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
||||
dest++;
|
||||
}
|
||||
}
|
||||
//setting tracelen - important! it was set by buffer overflow before
|
||||
set_tracelen( BigBuf_max_traceLen());
|
||||
}
|
||||
|
||||
void HfSnoop(int samplesToSkip, int triggersToSkip)
|
||||
{
|
||||
BigBuf_free(); BigBuf_Clear();
|
||||
BigBuf_free(); BigBuf_Clear();
|
||||
|
||||
Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
|
||||
int trigger_cnt = 0;
|
||||
Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
|
||||
int trigger_cnt = 0;
|
||||
|
||||
LED_D_ON();
|
||||
LED_D_ON();
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Set up the synchronous serial port
|
||||
FpgaSetupSsc();
|
||||
// Set up the synchronous serial port
|
||||
FpgaSetupSsc();
|
||||
|
||||
// Setting Frame Mode For better performance on high speed data transfer.
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16);
|
||||
// Setting Frame Mode For better performance on high speed data transfer.
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
|
||||
SpinDelay(100);
|
||||
|
||||
uint16_t r = 0;
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||
WDT_HIT();
|
||||
uint16_t r = 0;
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||
WDT_HIT();
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
r = (uint16_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
r = MAX(r & 0xff, r >> 8);
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
r = (uint16_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
r = MAX(r & 0xff, r >> 8);
|
||||
if (r >= 180) { // 0xB4 ??
|
||||
if (++trigger_cnt > triggersToSkip)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!BUTTON_PRESS()) {
|
||||
int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0
|
||||
while(waitcount != 0) {
|
||||
if (!BUTTON_PRESS()) {
|
||||
int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0
|
||||
while(waitcount != 0) {
|
||||
|
||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY))
|
||||
waitcount--;
|
||||
}
|
||||
optimizedSnoop();
|
||||
Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r);
|
||||
}
|
||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY))
|
||||
waitcount--;
|
||||
}
|
||||
optimizedSnoop();
|
||||
Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r);
|
||||
}
|
||||
|
||||
//Resetting Frame mode (First set in fpgaloader.c)
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
//Resetting Frame mode (First set in fpgaloader.c)
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
|
||||
DbpString("HF Snoop end");
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
DbpString("HF Snoop end");
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
|
2722
armsrc/hitag2.c
2722
armsrc/hitag2.c
File diff suppressed because it is too large
Load diff
3524
armsrc/hitagS.c
3524
armsrc/hitagS.c
File diff suppressed because it is too large
Load diff
3196
armsrc/iclass.c
3196
armsrc/iclass.c
File diff suppressed because it is too large
Load diff
5317
armsrc/iso14443a.c
5317
armsrc/iso14443a.c
File diff suppressed because it is too large
Load diff
|
@ -31,66 +31,66 @@ extern "C" {
|
|||
#include "mifare.h" // structs
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
DEMOD_UNSYNCD,
|
||||
// DEMOD_HALF_SYNCD,
|
||||
// DEMOD_MOD_FIRST_HALF,
|
||||
// DEMOD_NOMOD_FIRST_HALF,
|
||||
DEMOD_MANCHESTER_DATA
|
||||
} state;
|
||||
uint16_t twoBits;
|
||||
uint16_t highCnt;
|
||||
uint16_t bitCount;
|
||||
uint16_t collisionPos;
|
||||
uint16_t syncBit;
|
||||
uint8_t parityBits;
|
||||
uint8_t parityLen;
|
||||
uint16_t shiftReg;
|
||||
uint16_t samples;
|
||||
uint16_t len;
|
||||
uint32_t startTime, endTime;
|
||||
uint8_t *output;
|
||||
uint8_t *parity;
|
||||
enum {
|
||||
DEMOD_UNSYNCD,
|
||||
// DEMOD_HALF_SYNCD,
|
||||
// DEMOD_MOD_FIRST_HALF,
|
||||
// DEMOD_NOMOD_FIRST_HALF,
|
||||
DEMOD_MANCHESTER_DATA
|
||||
} state;
|
||||
uint16_t twoBits;
|
||||
uint16_t highCnt;
|
||||
uint16_t bitCount;
|
||||
uint16_t collisionPos;
|
||||
uint16_t syncBit;
|
||||
uint8_t parityBits;
|
||||
uint8_t parityLen;
|
||||
uint16_t shiftReg;
|
||||
uint16_t samples;
|
||||
uint16_t len;
|
||||
uint32_t startTime, endTime;
|
||||
uint8_t *output;
|
||||
uint8_t *parity;
|
||||
} tDemod;
|
||||
/*
|
||||
typedef enum {
|
||||
MOD_NOMOD = 0,
|
||||
MOD_SECOND_HALF,
|
||||
MOD_FIRST_HALF,
|
||||
MOD_BOTH_HALVES
|
||||
} Modulation_t;
|
||||
MOD_NOMOD = 0,
|
||||
MOD_SECOND_HALF,
|
||||
MOD_FIRST_HALF,
|
||||
MOD_BOTH_HALVES
|
||||
} Modulation_t;
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
STATE_UNSYNCD,
|
||||
STATE_START_OF_COMMUNICATION,
|
||||
STATE_MILLER_X,
|
||||
STATE_MILLER_Y,
|
||||
STATE_MILLER_Z,
|
||||
// DROP_NONE,
|
||||
// DROP_FIRST_HALF,
|
||||
} state;
|
||||
uint16_t shiftReg;
|
||||
int16_t bitCount;
|
||||
uint16_t len;
|
||||
//uint16_t byteCntMax;
|
||||
uint16_t posCnt;
|
||||
uint16_t syncBit;
|
||||
uint8_t parityBits;
|
||||
uint8_t parityLen;
|
||||
uint32_t fourBits;
|
||||
uint32_t startTime, endTime;
|
||||
enum {
|
||||
STATE_UNSYNCD,
|
||||
STATE_START_OF_COMMUNICATION,
|
||||
STATE_MILLER_X,
|
||||
STATE_MILLER_Y,
|
||||
STATE_MILLER_Z,
|
||||
// DROP_NONE,
|
||||
// DROP_FIRST_HALF,
|
||||
} state;
|
||||
uint16_t shiftReg;
|
||||
int16_t bitCount;
|
||||
uint16_t len;
|
||||
//uint16_t byteCntMax;
|
||||
uint16_t posCnt;
|
||||
uint16_t syncBit;
|
||||
uint8_t parityBits;
|
||||
uint8_t parityLen;
|
||||
uint32_t fourBits;
|
||||
uint32_t startTime, endTime;
|
||||
uint8_t *output;
|
||||
uint8_t *parity;
|
||||
uint8_t *parity;
|
||||
} tUart;
|
||||
|
||||
#ifndef AddCrc14A
|
||||
# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1)
|
||||
# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1)
|
||||
#endif
|
||||
|
||||
#ifndef AddCrc14B
|
||||
# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1)
|
||||
# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1)
|
||||
#endif
|
||||
|
||||
extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
|
||||
|
@ -129,7 +129,7 @@ extern int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool co
|
|||
extern int EmSendPrecompiledCmd(tag_response_info_t *response_info);
|
||||
|
||||
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
|
||||
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
|
||||
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
|
||||
|
||||
//extern bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *buffer_size);
|
||||
|
||||
|
|
2218
armsrc/iso14443b.c
2218
armsrc/iso14443b.c
File diff suppressed because it is too large
Load diff
|
@ -18,7 +18,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "proxmark3.h"
|
||||
#include "common.h" // access to global variable: MF_DBGLEVEL
|
||||
#include "common.h" // access to global variable: MF_DBGLEVEL
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
|
@ -27,11 +27,11 @@ extern "C" {
|
|||
#include "protocols.h"
|
||||
|
||||
#ifndef AddCrc14A
|
||||
# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1)
|
||||
# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1)
|
||||
#endif
|
||||
|
||||
#ifndef AddCrc14B
|
||||
# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1)
|
||||
# define AddCrc14B(data, len) compute_crc(CRC_14443_B, (data), (len), (data)+(len), (data)+(len)+1)
|
||||
#endif
|
||||
|
||||
extern void SendRawCommand14443B_Ex(UsbCommand *c);
|
||||
|
@ -45,13 +45,13 @@ extern void WaitForFpgaDelayQueueIsEmpty( uint16_t delay );
|
|||
extern void ClearFpgaShiftingRegisters(void);
|
||||
|
||||
// States for 14B SIM command
|
||||
#define SIM_NOFIELD 0
|
||||
#define SIM_IDLE 1
|
||||
#define SIM_HALTED 2
|
||||
#define SIM_SELECTING 3
|
||||
#define SIM_HALTING 4
|
||||
#define SIM_NOFIELD 0
|
||||
#define SIM_IDLE 1
|
||||
#define SIM_HALTED 2
|
||||
#define SIM_SELECTING 3
|
||||
#define SIM_HALTING 4
|
||||
#define SIM_ACKNOWLEDGE 5
|
||||
#define SIM_WORK 6
|
||||
#define SIM_WORK 6
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
1298
armsrc/iso15693.c
1298
armsrc/iso15693.c
File diff suppressed because it is too large
Load diff
2981
armsrc/lfops.c
2981
armsrc/lfops.c
File diff suppressed because it is too large
Load diff
|
@ -10,21 +10,21 @@
|
|||
|
||||
/*
|
||||
Default LF config is set to:
|
||||
decimation = 1 (we keep 1 out of 1 samples)
|
||||
bits_per_sample = 8
|
||||
averaging = YES
|
||||
divisor = 95 (125khz)
|
||||
trigger_threshold = 0
|
||||
*/
|
||||
decimation = 1 (we keep 1 out of 1 samples)
|
||||
bits_per_sample = 8
|
||||
averaging = YES
|
||||
divisor = 95 (125khz)
|
||||
trigger_threshold = 0
|
||||
*/
|
||||
sample_config config = { 1, 8, 1, 95, 0 } ;
|
||||
|
||||
void printConfig() {
|
||||
Dbprintf("LF Sampling config");
|
||||
Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor+1));
|
||||
Dbprintf(" [b] bps.................%d", config.bits_per_sample);
|
||||
Dbprintf(" [d] decimation..........%d", config.decimation);
|
||||
Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No");
|
||||
Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold);
|
||||
Dbprintf("LF Sampling config");
|
||||
Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor+1));
|
||||
Dbprintf(" [b] bps.................%d", config.bits_per_sample);
|
||||
Dbprintf(" [d] decimation..........%d", config.decimation);
|
||||
Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No");
|
||||
Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,25 +39,25 @@ void printConfig() {
|
|||
* @param sc
|
||||
*/
|
||||
void setSamplingConfig(sample_config *sc) {
|
||||
if(sc->divisor != 0) config.divisor = sc->divisor;
|
||||
if(sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample;
|
||||
if(sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold;
|
||||
if(sc->divisor != 0) config.divisor = sc->divisor;
|
||||
if(sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample;
|
||||
if(sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold;
|
||||
|
||||
config.decimation = (sc->decimation != 0) ? sc->decimation : 1;
|
||||
config.averaging = sc->averaging;
|
||||
if(config.bits_per_sample > 8) config.bits_per_sample = 8;
|
||||
config.decimation = (sc->decimation != 0) ? sc->decimation : 1;
|
||||
config.averaging = sc->averaging;
|
||||
if(config.bits_per_sample > 8) config.bits_per_sample = 8;
|
||||
|
||||
printConfig();
|
||||
printConfig();
|
||||
}
|
||||
|
||||
sample_config* getSamplingConfig() {
|
||||
return &config;
|
||||
return &config;
|
||||
}
|
||||
|
||||
struct BitstreamOut {
|
||||
uint8_t * buffer;
|
||||
uint32_t numbits;
|
||||
uint32_t position;
|
||||
uint8_t * buffer;
|
||||
uint32_t numbits;
|
||||
uint32_t position;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -66,39 +66,39 @@ struct BitstreamOut {
|
|||
* @param bit
|
||||
*/
|
||||
void pushBit( BitstreamOut* stream, uint8_t bit) {
|
||||
int bytepos = stream->position >> 3; // divide by 8
|
||||
int bitpos = stream->position & 7;
|
||||
*(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos);
|
||||
stream->position++;
|
||||
stream->numbits++;
|
||||
int bytepos = stream->position >> 3; // divide by 8
|
||||
int bitpos = stream->position & 7;
|
||||
*(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos);
|
||||
stream->position++;
|
||||
stream->numbits++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
|
||||
* if not already loaded, sets divisor and starts up the antenna.
|
||||
* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz
|
||||
* 0 or 95 ==> 125 KHz
|
||||
* 0 or 95 ==> 125 KHz
|
||||
*
|
||||
**/
|
||||
void LFSetupFPGAForADC(int divisor, bool lf_field) {
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
else if (divisor == 0)
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
else
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
else if (divisor == 0)
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
else
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
|
||||
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
// 50ms for the resonant antenna to settle.
|
||||
SpinDelay(50);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
// start a 1.5ticks is 1us
|
||||
StartTicks();
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
// 50ms for the resonant antenna to settle.
|
||||
SpinDelay(50);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
// start a 1.5ticks is 1us
|
||||
StartTicks();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,97 +118,97 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) {
|
|||
*/
|
||||
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after) {
|
||||
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen();
|
||||
|
||||
if (bits_per_sample < 1) bits_per_sample = 1;
|
||||
if (bits_per_sample > 8) bits_per_sample = 8;
|
||||
if (bits_per_sample < 1) bits_per_sample = 1;
|
||||
if (bits_per_sample > 8) bits_per_sample = 8;
|
||||
|
||||
if (decimation < 1) decimation = 1;
|
||||
if (decimation < 1) decimation = 1;
|
||||
|
||||
// use a bit stream to handle the output
|
||||
BitstreamOut data = { dest , 0, 0};
|
||||
int sample_counter = 0;
|
||||
uint8_t sample = 0;
|
||||
// use a bit stream to handle the output
|
||||
BitstreamOut data = { dest , 0, 0};
|
||||
int sample_counter = 0;
|
||||
uint8_t sample = 0;
|
||||
|
||||
// if we want to do averaging
|
||||
uint32_t sample_sum =0 ;
|
||||
uint32_t sample_total_numbers = 0;
|
||||
uint32_t sample_total_saved = 0;
|
||||
uint32_t cancel_counter = 0;
|
||||
// if we want to do averaging
|
||||
uint32_t sample_sum =0 ;
|
||||
uint32_t sample_total_numbers = 0;
|
||||
uint32_t sample_total_saved = 0;
|
||||
uint32_t cancel_counter = 0;
|
||||
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||
WDT_HIT();
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||
WDT_HIT();
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
|
||||
// Testpoint 8 (TP8) can be used to trigger oscilliscope
|
||||
LED_D_OFF();
|
||||
// Testpoint 8 (TP8) can be used to trigger oscilliscope
|
||||
LED_D_OFF();
|
||||
|
||||
// threshold either high or low values 128 = center 0. if trigger = 178
|
||||
if ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) {
|
||||
if (cancel_after > 0) {
|
||||
cancel_counter++;
|
||||
if (cancel_after == cancel_counter)
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// threshold either high or low values 128 = center 0. if trigger = 178
|
||||
if ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) {
|
||||
if (cancel_after > 0) {
|
||||
cancel_counter++;
|
||||
if (cancel_after == cancel_counter)
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
trigger_threshold = 0;
|
||||
sample_total_numbers++;
|
||||
trigger_threshold = 0;
|
||||
sample_total_numbers++;
|
||||
|
||||
if (averaging)
|
||||
sample_sum += sample;
|
||||
if (averaging)
|
||||
sample_sum += sample;
|
||||
|
||||
// check decimation
|
||||
if (decimation > 1) {
|
||||
sample_counter++;
|
||||
if (sample_counter < decimation) continue;
|
||||
sample_counter = 0;
|
||||
}
|
||||
// check decimation
|
||||
if (decimation > 1) {
|
||||
sample_counter++;
|
||||
if (sample_counter < decimation) continue;
|
||||
sample_counter = 0;
|
||||
}
|
||||
|
||||
// averaging
|
||||
if (averaging && decimation > 1) {
|
||||
sample = sample_sum / decimation;
|
||||
sample_sum =0;
|
||||
}
|
||||
// averaging
|
||||
if (averaging && decimation > 1) {
|
||||
sample = sample_sum / decimation;
|
||||
sample_sum =0;
|
||||
}
|
||||
|
||||
// store the sample
|
||||
sample_total_saved ++;
|
||||
if (bits_per_sample == 8) {
|
||||
dest[sample_total_saved-1] = sample;
|
||||
// store the sample
|
||||
sample_total_saved ++;
|
||||
if (bits_per_sample == 8) {
|
||||
dest[sample_total_saved-1] = sample;
|
||||
|
||||
// Get the return value correct
|
||||
data.numbits = sample_total_saved << 3;
|
||||
if (sample_total_saved >= bufsize) break;
|
||||
// Get the return value correct
|
||||
data.numbits = sample_total_saved << 3;
|
||||
if (sample_total_saved >= bufsize) break;
|
||||
|
||||
} else {
|
||||
pushBit(&data, sample & 0x80);
|
||||
if (bits_per_sample > 1) pushBit(&data, sample & 0x40);
|
||||
if (bits_per_sample > 2) pushBit(&data, sample & 0x20);
|
||||
if (bits_per_sample > 3) pushBit(&data, sample & 0x10);
|
||||
if (bits_per_sample > 4) pushBit(&data, sample & 0x08);
|
||||
if (bits_per_sample > 5) pushBit(&data, sample & 0x04);
|
||||
if (bits_per_sample > 6) pushBit(&data, sample & 0x02);
|
||||
} else {
|
||||
pushBit(&data, sample & 0x80);
|
||||
if (bits_per_sample > 1) pushBit(&data, sample & 0x40);
|
||||
if (bits_per_sample > 2) pushBit(&data, sample & 0x20);
|
||||
if (bits_per_sample > 3) pushBit(&data, sample & 0x10);
|
||||
if (bits_per_sample > 4) pushBit(&data, sample & 0x08);
|
||||
if (bits_per_sample > 5) pushBit(&data, sample & 0x04);
|
||||
if (bits_per_sample > 6) pushBit(&data, sample & 0x02);
|
||||
|
||||
if ((data.numbits >> 3) + 1 >= bufsize) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((data.numbits >> 3) + 1 >= bufsize) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
Dbprintf("Done, saved %d out of %d seen samples at %d bits/sample", sample_total_saved, sample_total_numbers, bits_per_sample);
|
||||
Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
|
||||
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
}
|
||||
if (!silent) {
|
||||
Dbprintf("Done, saved %d out of %d seen samples at %d bits/sample", sample_total_saved, sample_total_numbers, bits_per_sample);
|
||||
Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
|
||||
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
}
|
||||
|
||||
// Ensure that DC offset removal and noise check is performed for any device-side processing
|
||||
removeSignalOffset(dest, bufsize);
|
||||
computeSignalProperties(dest, bufsize);
|
||||
// Ensure that DC offset removal and noise check is performed for any device-side processing
|
||||
removeSignalOffset(dest, bufsize);
|
||||
computeSignalProperties(dest, bufsize);
|
||||
|
||||
return data.numbits;
|
||||
return data.numbits;
|
||||
}
|
||||
/**
|
||||
* @brief Does sample acquisition, ignoring the config values set in the sample_config.
|
||||
|
@ -219,27 +219,27 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
|||
* @return number of bits sampled
|
||||
*/
|
||||
uint32_t DoAcquisition_default(int trigger_threshold, bool silent) {
|
||||
return DoAcquisition(1, 8, 0,trigger_threshold, silent, 0, 0);
|
||||
return DoAcquisition(1, 8, 0,trigger_threshold, silent, 0, 0);
|
||||
}
|
||||
uint32_t DoAcquisition_config( bool silent, int sample_size) {
|
||||
return DoAcquisition(config.decimation
|
||||
,config.bits_per_sample
|
||||
,config.averaging
|
||||
,config.trigger_threshold
|
||||
,silent
|
||||
,sample_size
|
||||
,0);
|
||||
return DoAcquisition(config.decimation
|
||||
,config.bits_per_sample
|
||||
,config.averaging
|
||||
,config.trigger_threshold
|
||||
,silent
|
||||
,sample_size
|
||||
,0);
|
||||
}
|
||||
|
||||
uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after) {
|
||||
return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after);
|
||||
return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after);
|
||||
}
|
||||
|
||||
uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
|
||||
if (!silent)
|
||||
printConfig();
|
||||
LFSetupFPGAForADC(config.divisor, activeField);
|
||||
return DoAcquisition_config(silent, sample_size);
|
||||
if (!silent)
|
||||
printConfig();
|
||||
LFSetupFPGAForADC(config.divisor, activeField);
|
||||
return DoAcquisition_config(silent, sample_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -247,20 +247,20 @@ uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
|
|||
* @return number of bits sampled
|
||||
**/
|
||||
uint32_t SampleLF(bool printCfg, int sample_size) {
|
||||
BigBuf_Clear_ext(false);
|
||||
uint32_t ret = ReadLF(true, printCfg, sample_size);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
return ret;
|
||||
BigBuf_Clear_ext(false);
|
||||
uint32_t ret = ReadLF(true, printCfg, sample_size);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
|
||||
* @return number of bits sampled
|
||||
**/
|
||||
uint32_t SnoopLF() {
|
||||
BigBuf_Clear_ext(false);
|
||||
uint32_t ret = ReadLF(false, true, 0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
return ret;
|
||||
BigBuf_Clear_ext(false);
|
||||
uint32_t ret = ReadLF(false, true, 0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,61 +269,61 @@ uint32_t SnoopLF() {
|
|||
**/
|
||||
void doT55x7Acquisition(size_t sample_size) {
|
||||
|
||||
#define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph
|
||||
#define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph
|
||||
#define T55xx_READ_TOL 5
|
||||
#define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph
|
||||
#define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph
|
||||
#define T55xx_READ_TOL 5
|
||||
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
uint16_t bufsize = BigBuf_max_traceLen();
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
uint16_t bufsize = BigBuf_max_traceLen();
|
||||
|
||||
if ( bufsize > sample_size )
|
||||
bufsize = sample_size;
|
||||
if ( bufsize > sample_size )
|
||||
bufsize = sample_size;
|
||||
|
||||
uint8_t curSample = 0, lastSample = 0;
|
||||
uint16_t i = 0, skipCnt = 0;
|
||||
bool startFound = false;
|
||||
bool highFound = false;
|
||||
bool lowFound = false;
|
||||
uint8_t curSample = 0, lastSample = 0;
|
||||
uint16_t i = 0, skipCnt = 0;
|
||||
bool startFound = false;
|
||||
bool highFound = false;
|
||||
bool lowFound = false;
|
||||
|
||||
while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) {
|
||||
WDT_HIT();
|
||||
while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) {
|
||||
WDT_HIT();
|
||||
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
|
||||
// skip until the first high sample above threshold
|
||||
if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) {
|
||||
//if (curSample > lastSample)
|
||||
// lastSample = curSample;
|
||||
highFound = true;
|
||||
} else if (!highFound) {
|
||||
skipCnt++;
|
||||
continue;
|
||||
}
|
||||
// skip until the first low sample below threshold
|
||||
if (!startFound && curSample < T55xx_READ_LOWER_THRESHOLD) {
|
||||
//if (curSample > lastSample)
|
||||
lastSample = curSample;
|
||||
lowFound = true;
|
||||
} else if (!lowFound) {
|
||||
skipCnt++;
|
||||
continue;
|
||||
}
|
||||
// skip until the first high sample above threshold
|
||||
if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) {
|
||||
//if (curSample > lastSample)
|
||||
// lastSample = curSample;
|
||||
highFound = true;
|
||||
} else if (!highFound) {
|
||||
skipCnt++;
|
||||
continue;
|
||||
}
|
||||
// skip until the first low sample below threshold
|
||||
if (!startFound && curSample < T55xx_READ_LOWER_THRESHOLD) {
|
||||
//if (curSample > lastSample)
|
||||
lastSample = curSample;
|
||||
lowFound = true;
|
||||
} else if (!lowFound) {
|
||||
skipCnt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip until first high samples begin to change
|
||||
if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL){
|
||||
// if just found start - recover last sample
|
||||
if (!startFound) {
|
||||
dest[i++] = lastSample;
|
||||
startFound = true;
|
||||
}
|
||||
// collect samples
|
||||
dest[i++] = curSample;
|
||||
}
|
||||
}
|
||||
}
|
||||
// skip until first high samples begin to change
|
||||
if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL){
|
||||
// if just found start - recover last sample
|
||||
if (!startFound) {
|
||||
dest[i++] = lastSample;
|
||||
startFound = true;
|
||||
}
|
||||
// collect samples
|
||||
dest[i++] = curSample;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* acquisition of Cotag LF signal. Similart to other LF, since the Cotag has such long datarate RF/384
|
||||
|
@ -339,117 +339,117 @@ void doT55x7Acquisition(size_t sample_size) {
|
|||
#endif
|
||||
void doCotagAcquisition(size_t sample_size) {
|
||||
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
uint16_t bufsize = BigBuf_max_traceLen();
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
uint16_t bufsize = BigBuf_max_traceLen();
|
||||
|
||||
if ( bufsize > sample_size )
|
||||
bufsize = sample_size;
|
||||
if ( bufsize > sample_size )
|
||||
bufsize = sample_size;
|
||||
|
||||
dest[0] = 0;
|
||||
uint8_t sample = 0, firsthigh = 0, firstlow = 0;
|
||||
uint16_t i = 0;
|
||||
uint16_t noise_counter = 0;
|
||||
dest[0] = 0;
|
||||
uint8_t sample = 0, firsthigh = 0, firstlow = 0;
|
||||
uint16_t i = 0;
|
||||
uint16_t noise_counter = 0;
|
||||
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
||||
WDT_HIT();
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
||||
WDT_HIT();
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
|
||||
// find first peak
|
||||
if ( !firsthigh ) {
|
||||
if (sample < COTAG_ONE_THRESHOLD) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firsthigh = 1;
|
||||
}
|
||||
if ( !firstlow ){
|
||||
if (sample > COTAG_ZERO_THRESHOLD ) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firstlow = 1;
|
||||
}
|
||||
// find first peak
|
||||
if ( !firsthigh ) {
|
||||
if (sample < COTAG_ONE_THRESHOLD) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firsthigh = 1;
|
||||
}
|
||||
if ( !firstlow ){
|
||||
if (sample > COTAG_ZERO_THRESHOLD ) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firstlow = 1;
|
||||
}
|
||||
|
||||
++i;
|
||||
++i;
|
||||
|
||||
if ( sample > COTAG_ONE_THRESHOLD)
|
||||
dest[i] = 255;
|
||||
else if ( sample < COTAG_ZERO_THRESHOLD)
|
||||
dest[i] = 0;
|
||||
else
|
||||
dest[i] = dest[i-1];
|
||||
}
|
||||
}
|
||||
if ( sample > COTAG_ONE_THRESHOLD)
|
||||
dest[i] = 255;
|
||||
else if ( sample < COTAG_ZERO_THRESHOLD)
|
||||
dest[i] = 0;
|
||||
else
|
||||
dest[i] = dest[i-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t doCotagAcquisitionManchester() {
|
||||
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
uint16_t bufsize = BigBuf_max_traceLen();
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
uint16_t bufsize = BigBuf_max_traceLen();
|
||||
|
||||
if ( bufsize > COTAG_BITS )
|
||||
bufsize = COTAG_BITS;
|
||||
if ( bufsize > COTAG_BITS )
|
||||
bufsize = COTAG_BITS;
|
||||
|
||||
dest[0] = 0;
|
||||
uint8_t sample = 0, firsthigh = 0, firstlow = 0;
|
||||
uint16_t sample_counter = 0, period = 0;
|
||||
uint8_t curr = 0, prev = 0;
|
||||
uint16_t noise_counter = 0;
|
||||
dest[0] = 0;
|
||||
uint8_t sample = 0, firsthigh = 0, firstlow = 0;
|
||||
uint16_t sample_counter = 0, period = 0;
|
||||
uint8_t curr = 0, prev = 0;
|
||||
uint16_t noise_counter = 0;
|
||||
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
||||
WDT_HIT();
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
||||
WDT_HIT();
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
|
||||
// find first peak
|
||||
if ( !firsthigh ) {
|
||||
if (sample < COTAG_ONE_THRESHOLD) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firsthigh = 1;
|
||||
}
|
||||
// find first peak
|
||||
if ( !firsthigh ) {
|
||||
if (sample < COTAG_ONE_THRESHOLD) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firsthigh = 1;
|
||||
}
|
||||
|
||||
if ( !firstlow ){
|
||||
if (sample > COTAG_ZERO_THRESHOLD ) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firstlow = 1;
|
||||
}
|
||||
if ( !firstlow ){
|
||||
if (sample > COTAG_ZERO_THRESHOLD ) {
|
||||
noise_counter++;
|
||||
continue;
|
||||
}
|
||||
noise_counter = 0;
|
||||
firstlow = 1;
|
||||
}
|
||||
|
||||
// set sample 255, 0, or previous
|
||||
if ( sample > COTAG_ONE_THRESHOLD){
|
||||
prev = curr;
|
||||
curr = 1;
|
||||
}
|
||||
else if ( sample < COTAG_ZERO_THRESHOLD) {
|
||||
prev = curr;
|
||||
curr = 0;
|
||||
}
|
||||
else {
|
||||
curr = prev;
|
||||
}
|
||||
// set sample 255, 0, or previous
|
||||
if ( sample > COTAG_ONE_THRESHOLD){
|
||||
prev = curr;
|
||||
curr = 1;
|
||||
}
|
||||
else if ( sample < COTAG_ZERO_THRESHOLD) {
|
||||
prev = curr;
|
||||
curr = 0;
|
||||
}
|
||||
else {
|
||||
curr = prev;
|
||||
}
|
||||
|
||||
// full T1 periods,
|
||||
if ( period > 0 ) {
|
||||
--period;
|
||||
continue;
|
||||
}
|
||||
// full T1 periods,
|
||||
if ( period > 0 ) {
|
||||
--period;
|
||||
continue;
|
||||
}
|
||||
|
||||
dest[sample_counter] = curr;
|
||||
++sample_counter;
|
||||
period = COTAG_T1;
|
||||
}
|
||||
}
|
||||
return sample_counter;
|
||||
dest[sample_counter] = curr;
|
||||
++sample_counter;
|
||||
period = COTAG_T1;
|
||||
}
|
||||
}
|
||||
return sample_counter;
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||
#include "ticks.h" // for StartTicks
|
||||
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||
#include "ticks.h" // for StartTicks
|
||||
|
||||
typedef struct BitstreamOut BitstreamOut;
|
||||
|
||||
|
@ -60,7 +60,7 @@ uint32_t DoAcquisition_config(bool silent, int sample_size);
|
|||
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
|
||||
* if not already loaded, sets divisor and starts up the antenna.
|
||||
* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz
|
||||
* 0 or 95 ==> 125 KHz
|
||||
* 0 or 95 ==> 125 KHz
|
||||
*
|
||||
**/
|
||||
void LFSetupFPGAForADC(int divisor, bool lf_field);
|
||||
|
|
2936
armsrc/mifarecmd.c
2936
armsrc/mifarecmd.c
File diff suppressed because it is too large
Load diff
|
@ -18,189 +18,189 @@ static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
|
|||
|
||||
bool InitDesfireCard(){
|
||||
|
||||
iso14a_card_select_t card;
|
||||
iso14a_card_select_t card;
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
set_tracing(true);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
set_tracing(true);
|
||||
|
||||
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
|
||||
OnError(1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
|
||||
OnError(1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ARG0 flag enums
|
||||
enum {
|
||||
NONE = 0x00,
|
||||
INIT = 0x01,
|
||||
DISCONNECT = 0x02,
|
||||
CLEARTRACE = 0x04,
|
||||
BAR = 0x08,
|
||||
NONE = 0x00,
|
||||
INIT = 0x01,
|
||||
DISCONNECT = 0x02,
|
||||
CLEARTRACE = 0x04,
|
||||
BAR = 0x08,
|
||||
} CmdOptions ;
|
||||
|
||||
void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
|
||||
|
||||
/* ARG0 contains flags.
|
||||
0x01 = init card.
|
||||
0x02 = Disconnect
|
||||
0x03
|
||||
*/
|
||||
uint8_t flags = arg0;
|
||||
size_t datalen = arg1;
|
||||
uint8_t resp[RECEIVE_SIZE];
|
||||
memset(resp,0,sizeof(resp));
|
||||
/* ARG0 contains flags.
|
||||
0x01 = init card.
|
||||
0x02 = Disconnect
|
||||
0x03
|
||||
*/
|
||||
uint8_t flags = arg0;
|
||||
size_t datalen = arg1;
|
||||
uint8_t resp[RECEIVE_SIZE];
|
||||
memset(resp,0,sizeof(resp));
|
||||
|
||||
if (MF_DBGLEVEL >= 4) {
|
||||
Dbprintf(" flags : %02X", flags);
|
||||
Dbprintf(" len : %02X", datalen);
|
||||
print_result(" RX : ", datain, datalen);
|
||||
}
|
||||
if (MF_DBGLEVEL >= 4) {
|
||||
Dbprintf(" flags : %02X", flags);
|
||||
Dbprintf(" len : %02X", datalen);
|
||||
print_result(" RX : ", datain, datalen);
|
||||
}
|
||||
|
||||
if ( flags & CLEARTRACE )
|
||||
clear_trace();
|
||||
if ( flags & CLEARTRACE )
|
||||
clear_trace();
|
||||
|
||||
if ( flags & INIT ){
|
||||
if ( !InitDesfireCard() )
|
||||
return;
|
||||
}
|
||||
if ( flags & INIT ){
|
||||
if ( !InitDesfireCard() )
|
||||
return;
|
||||
}
|
||||
|
||||
int len = DesfireAPDU(datain, datalen, resp);
|
||||
if (MF_DBGLEVEL >= 4)
|
||||
print_result("ERR <--: ", resp, len);
|
||||
int len = DesfireAPDU(datain, datalen, resp);
|
||||
if (MF_DBGLEVEL >= 4)
|
||||
print_result("ERR <--: ", resp, len);
|
||||
|
||||
if ( !len ) {
|
||||
OnError(2);
|
||||
return;
|
||||
}
|
||||
if ( !len ) {
|
||||
OnError(2);
|
||||
return;
|
||||
}
|
||||
|
||||
// reset the pcb_blocknum,
|
||||
pcb_blocknum = 0;
|
||||
// reset the pcb_blocknum,
|
||||
pcb_blocknum = 0;
|
||||
|
||||
if ( flags & DISCONNECT )
|
||||
OnSuccess();
|
||||
if ( flags & DISCONNECT )
|
||||
OnSuccess();
|
||||
|
||||
cmd_send(CMD_ACK,1,len,0,resp,len);
|
||||
cmd_send(CMD_ACK,1,len,0,resp,len);
|
||||
}
|
||||
|
||||
void MifareDesfireGetInformation(){
|
||||
|
||||
int len = 0;
|
||||
iso14a_card_select_t card;
|
||||
uint8_t resp[USB_CMD_DATA_SIZE] = {0x00};
|
||||
uint8_t dataout[USB_CMD_DATA_SIZE] = {0x00};
|
||||
int len = 0;
|
||||
iso14a_card_select_t card;
|
||||
uint8_t resp[USB_CMD_DATA_SIZE] = {0x00};
|
||||
uint8_t dataout[USB_CMD_DATA_SIZE] = {0x00};
|
||||
|
||||
/*
|
||||
1 = PCB 1
|
||||
2 = cid 2
|
||||
3 = desfire command 3
|
||||
4-5 = crc 4 key
|
||||
5-6 crc
|
||||
PCB == 0x0A because sending CID byte.
|
||||
CID == 0x00 first card?
|
||||
*/
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
/*
|
||||
1 = PCB 1
|
||||
2 = cid 2
|
||||
3 = desfire command 3
|
||||
4-5 = crc 4 key
|
||||
5-6 crc
|
||||
PCB == 0x0A because sending CID byte.
|
||||
CID == 0x00 first card?
|
||||
*/
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
// card select - information
|
||||
if ( !iso14443a_select_card(NULL, &card, NULL, true, 0, false) ) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
|
||||
OnError(1);
|
||||
return;
|
||||
}
|
||||
// card select - information
|
||||
if ( !iso14443a_select_card(NULL, &card, NULL, true, 0, false) ) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
|
||||
OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( card.uidlen != 7 ) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Wrong UID size. Expected 7byte got %d", card.uidlen);
|
||||
OnError(2);
|
||||
return;
|
||||
}
|
||||
if ( card.uidlen != 7 ) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Wrong UID size. Expected 7byte got %d", card.uidlen);
|
||||
OnError(2);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(dataout, card.uid, 7);
|
||||
memcpy(dataout, card.uid, 7);
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
uint8_t cmd[] = {GET_VERSION};
|
||||
size_t cmd_len = sizeof(cmd);
|
||||
uint8_t cmd[] = {GET_VERSION};
|
||||
size_t cmd_len = sizeof(cmd);
|
||||
|
||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||
if ( !len ) {
|
||||
print_result("ERROR <--: ", resp, len);
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||
if ( !len ) {
|
||||
print_result("ERROR <--: ", resp, len);
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
|
||||
LED_A_OFF();
|
||||
LED_B_ON();
|
||||
memcpy(dataout+7,resp+3,7);
|
||||
LED_A_OFF();
|
||||
LED_B_ON();
|
||||
memcpy(dataout+7,resp+3,7);
|
||||
|
||||
// ADDITION_FRAME 1
|
||||
cmd[0] = ADDITIONAL_FRAME;
|
||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||
if ( !len ) {
|
||||
print_result("ERROR <--: ", resp, len);
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
// ADDITION_FRAME 1
|
||||
cmd[0] = ADDITIONAL_FRAME;
|
||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||
if ( !len ) {
|
||||
print_result("ERROR <--: ", resp, len);
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
|
||||
LED_B_OFF();
|
||||
LED_C_ON();
|
||||
memcpy(dataout+7+7,resp+3,7);
|
||||
LED_B_OFF();
|
||||
LED_C_ON();
|
||||
memcpy(dataout+7+7,resp+3,7);
|
||||
|
||||
// ADDITION_FRAME 2
|
||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||
if ( !len ) {
|
||||
print_result("ERROR <--: ", resp, len);
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
// ADDITION_FRAME 2
|
||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||
if ( !len ) {
|
||||
print_result("ERROR <--: ", resp, len);
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(dataout+7+7+7,resp+3,14);
|
||||
memcpy(dataout+7+7+7,resp+3,14);
|
||||
|
||||
cmd_send(CMD_ACK,1,0,0,dataout,sizeof(dataout));
|
||||
cmd_send(CMD_ACK,1,0,0,dataout,sizeof(dataout));
|
||||
|
||||
// reset the pcb_blocknum,
|
||||
pcb_blocknum = 0;
|
||||
OnSuccess();
|
||||
// reset the pcb_blocknum,
|
||||
pcb_blocknum = 0;
|
||||
OnSuccess();
|
||||
}
|
||||
|
||||
void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){
|
||||
|
||||
int len = 0;
|
||||
//uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
|
||||
uint8_t PICC_MASTER_KEY16[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
|
||||
uint8_t null_key_data8[8] = {0x00};
|
||||
//uint8_t null_key_data16[16] = {0x00};
|
||||
//uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
|
||||
//uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
|
||||
int len = 0;
|
||||
//uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
|
||||
uint8_t PICC_MASTER_KEY16[16] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f };
|
||||
uint8_t null_key_data8[8] = {0x00};
|
||||
//uint8_t null_key_data16[16] = {0x00};
|
||||
//uint8_t new_key_data8[8] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
|
||||
//uint8_t new_key_data16[16] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
|
||||
|
||||
uint8_t resp[256] = {0x00};
|
||||
uint8_t IV[16] = {0x00};
|
||||
uint8_t resp[256] = {0x00};
|
||||
uint8_t IV[16] = {0x00};
|
||||
|
||||
size_t datalen = datain[0];
|
||||
size_t datalen = datain[0];
|
||||
|
||||
uint8_t cmd[40] = {0x00};
|
||||
uint8_t encRndB[16] = {0x00};
|
||||
uint8_t decRndB[16] = {0x00};
|
||||
uint8_t nonce[16] = {0x00};
|
||||
uint8_t both[32] = {0x00};
|
||||
uint8_t encBoth[32] = {0x00};
|
||||
uint8_t cmd[40] = {0x00};
|
||||
uint8_t encRndB[16] = {0x00};
|
||||
uint8_t decRndB[16] = {0x00};
|
||||
uint8_t nonce[16] = {0x00};
|
||||
uint8_t both[32] = {0x00};
|
||||
uint8_t encBoth[32] = {0x00};
|
||||
|
||||
InitDesfireCard();
|
||||
InitDesfireCard();
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
// 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
|
||||
// 4 olika crypto algo DES, 3DES, 3K3DES, AES
|
||||
// 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO
|
||||
// 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
|
||||
// 4 olika crypto algo DES, 3DES, 3K3DES, AES
|
||||
// 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO
|
||||
|
||||
// des, nyckel 0,
|
||||
switch (mode){
|
||||
// des, nyckel 0,
|
||||
switch (mode){
|
||||
case 1:{
|
||||
uint8_t keybytes[16];
|
||||
uint8_t RndA[8] = {0x00};
|
||||
|
@ -416,83 +416,83 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain
|
|||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
//SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
|
||||
break;
|
||||
case 3:{
|
||||
break;
|
||||
case 2:
|
||||
//SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
|
||||
break;
|
||||
case 3:{
|
||||
|
||||
//defaultkey
|
||||
uint8_t keybytes[16] = {0x00};
|
||||
if (datain[1] == 0xff){
|
||||
memcpy(keybytes,PICC_MASTER_KEY16,16);
|
||||
} else{
|
||||
memcpy(keybytes, datain+1, datalen);
|
||||
}
|
||||
//defaultkey
|
||||
uint8_t keybytes[16] = {0x00};
|
||||
if (datain[1] == 0xff){
|
||||
memcpy(keybytes,PICC_MASTER_KEY16,16);
|
||||
} else{
|
||||
memcpy(keybytes, datain+1, datalen);
|
||||
}
|
||||
|
||||
struct desfire_key defaultkey = {0x00};
|
||||
desfirekey_t key = &defaultkey;
|
||||
Desfire_aes_key_new( keybytes, key);
|
||||
struct desfire_key defaultkey = {0x00};
|
||||
desfirekey_t key = &defaultkey;
|
||||
Desfire_aes_key_new( keybytes, key);
|
||||
|
||||
AesCtx ctx;
|
||||
if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){
|
||||
if( MF_DBGLEVEL >= 4) {
|
||||
DbpString("AES context failed to init");
|
||||
}
|
||||
OnError(7);
|
||||
return;
|
||||
}
|
||||
AesCtx ctx;
|
||||
if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){
|
||||
if( MF_DBGLEVEL >= 4) {
|
||||
DbpString("AES context failed to init");
|
||||
}
|
||||
OnError(7);
|
||||
return;
|
||||
}
|
||||
|
||||
cmd[0] = AUTHENTICATE_AES;
|
||||
cmd[1] = 0x00; //keynumber
|
||||
len = DesfireAPDU(cmd, 2, resp);
|
||||
if ( !len ) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) {
|
||||
DbpString("Authentication failed. Card timeout.");
|
||||
}
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy( encRndB, resp+3, 16);
|
||||
|
||||
// dekryptera tagnonce.
|
||||
AesDecrypt(&ctx, encRndB, decRndB, 16);
|
||||
rol(decRndB,16);
|
||||
memcpy(both, nonce,16);
|
||||
memcpy(both+16, decRndB ,16 );
|
||||
AesEncrypt(&ctx, both, encBoth, 32 );
|
||||
|
||||
cmd[0] = ADDITIONAL_FRAME;
|
||||
memcpy(cmd+1, encBoth, 32 );
|
||||
|
||||
len = DesfireAPDU(cmd, 33, resp); // 1 + 32 == 33
|
||||
if ( !len ) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) {
|
||||
DbpString("Authentication failed. Card timeout.");
|
||||
}
|
||||
cmd[0] = AUTHENTICATE_AES;
|
||||
cmd[1] = 0x00; //keynumber
|
||||
len = DesfireAPDU(cmd, 2, resp);
|
||||
if ( !len ) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) {
|
||||
DbpString("Authentication failed. Card timeout.");
|
||||
}
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( resp[2] == 0x00 ){
|
||||
// Create AES Session key
|
||||
struct desfire_key sessionKey = {0};
|
||||
desfirekey_t skey = &sessionKey;
|
||||
Desfire_session_key_new( nonce, decRndB , key, skey );
|
||||
print_result("SESSION : ", skey->data, 16);
|
||||
} else {
|
||||
DbpString("Authentication failed.");
|
||||
OnError(7);
|
||||
return;
|
||||
}
|
||||
memcpy( encRndB, resp+3, 16);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
// dekryptera tagnonce.
|
||||
AesDecrypt(&ctx, encRndB, decRndB, 16);
|
||||
rol(decRndB,16);
|
||||
memcpy(both, nonce,16);
|
||||
memcpy(both+16, decRndB ,16 );
|
||||
AesEncrypt(&ctx, both, encBoth, 32 );
|
||||
|
||||
OnSuccess();
|
||||
cmd_send(CMD_ACK,1,len,0,resp,len);
|
||||
cmd[0] = ADDITIONAL_FRAME;
|
||||
memcpy(cmd+1, encBoth, 32 );
|
||||
|
||||
len = DesfireAPDU(cmd, 33, resp); // 1 + 32 == 33
|
||||
if ( !len ) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) {
|
||||
DbpString("Authentication failed. Card timeout.");
|
||||
}
|
||||
OnError(3);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( resp[2] == 0x00 ){
|
||||
// Create AES Session key
|
||||
struct desfire_key sessionKey = {0};
|
||||
desfirekey_t skey = &sessionKey;
|
||||
Desfire_session_key_new( nonce, decRndB , key, skey );
|
||||
print_result("SESSION : ", skey->data, 16);
|
||||
} else {
|
||||
DbpString("Authentication failed.");
|
||||
OnError(7);
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OnSuccess();
|
||||
cmd_send(CMD_ACK,1,len,0,resp,len);
|
||||
}
|
||||
|
||||
// 3 olika ISO sätt att skicka data till DESFIRE (direkt, inkapslat, inkapslat ISO)
|
||||
|
@ -501,71 +501,71 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain
|
|||
// dataout = pointer to response data array
|
||||
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
|
||||
|
||||
size_t len = 0;
|
||||
size_t wrappedLen = 0;
|
||||
uint8_t wCmd[USB_CMD_DATA_SIZE] = {0x00};
|
||||
uint8_t resp[MAX_FRAME_SIZE];
|
||||
size_t len = 0;
|
||||
size_t wrappedLen = 0;
|
||||
uint8_t wCmd[USB_CMD_DATA_SIZE] = {0x00};
|
||||
uint8_t resp[MAX_FRAME_SIZE];
|
||||
uint8_t par[MAX_PARITY_SIZE];
|
||||
|
||||
wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
|
||||
wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
|
||||
|
||||
if (MF_DBGLEVEL >= 4)
|
||||
print_result("WCMD <--: ", wCmd, wrappedLen);
|
||||
if (MF_DBGLEVEL >= 4)
|
||||
print_result("WCMD <--: ", wCmd, wrappedLen);
|
||||
|
||||
ReaderTransmit( wCmd, wrappedLen, NULL);
|
||||
ReaderTransmit( wCmd, wrappedLen, NULL);
|
||||
|
||||
len = ReaderReceive(resp, par);
|
||||
if ( !len ) {
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("fukked");
|
||||
return false; //DATA LINK ERROR
|
||||
}
|
||||
// if we received an I- or R(ACK)-Block with a block number equal to the
|
||||
// current block number, toggle the current block number
|
||||
else if (len >= 4 // PCB+CID+CRC = 4 bytes
|
||||
&& ((resp[0] & 0xC0) == 0 // I-Block
|
||||
|| (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
|
||||
&& (resp[0] & 0x01) == pcb_blocknum) // equal block numbers
|
||||
{
|
||||
pcb_blocknum ^= 1; //toggle next block
|
||||
}
|
||||
len = ReaderReceive(resp, par);
|
||||
if ( !len ) {
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("fukked");
|
||||
return false; //DATA LINK ERROR
|
||||
}
|
||||
// if we received an I- or R(ACK)-Block with a block number equal to the
|
||||
// current block number, toggle the current block number
|
||||
else if (len >= 4 // PCB+CID+CRC = 4 bytes
|
||||
&& ((resp[0] & 0xC0) == 0 // I-Block
|
||||
|| (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
|
||||
&& (resp[0] & 0x01) == pcb_blocknum) // equal block numbers
|
||||
{
|
||||
pcb_blocknum ^= 1; //toggle next block
|
||||
}
|
||||
|
||||
memcpy(dataout, resp, len);
|
||||
return len;
|
||||
memcpy(dataout, resp, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
// CreateAPDU
|
||||
size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){
|
||||
|
||||
size_t cmdlen = MIN(len+4, USB_CMD_DATA_SIZE-1);
|
||||
size_t cmdlen = MIN(len+4, USB_CMD_DATA_SIZE-1);
|
||||
|
||||
uint8_t cmd[cmdlen];
|
||||
memset(cmd, 0, cmdlen);
|
||||
uint8_t cmd[cmdlen];
|
||||
memset(cmd, 0, cmdlen);
|
||||
|
||||
cmd[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar //
|
||||
cmd[0] |= pcb_blocknum; // OR the block number into the PCB
|
||||
cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards
|
||||
cmd[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar //
|
||||
cmd[0] |= pcb_blocknum; // OR the block number into the PCB
|
||||
cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards
|
||||
|
||||
memcpy(cmd+2, datain, len);
|
||||
AddCrc14A(cmd, len+2);
|
||||
memcpy(cmd+2, datain, len);
|
||||
AddCrc14A(cmd, len+2);
|
||||
|
||||
memcpy(dataout, cmd, cmdlen);
|
||||
memcpy(dataout, cmd, cmdlen);
|
||||
|
||||
return cmdlen;
|
||||
return cmdlen;
|
||||
}
|
||||
|
||||
// crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */
|
||||
// crc_update(&desfire_crc32, addr, addr_sz);
|
||||
// crc_update(&desfire_crc32, byte, 8);
|
||||
// uint32_t crc = crc_finish(&desfire_crc32);
|
||||
// crc_update(&desfire_crc32, 0, 1); /* CMD_WRITE */
|
||||
// crc_update(&desfire_crc32, addr, addr_sz);
|
||||
// crc_update(&desfire_crc32, byte, 8);
|
||||
// uint32_t crc = crc_finish(&desfire_crc32);
|
||||
|
||||
void OnSuccess(){
|
||||
pcb_blocknum = 0;
|
||||
ReaderTransmit(deselect_cmd, 3 , NULL);
|
||||
mifare_ultra_halt();
|
||||
switch_off();
|
||||
pcb_blocknum = 0;
|
||||
ReaderTransmit(deselect_cmd, 3 , NULL);
|
||||
mifare_ultra_halt();
|
||||
switch_off();
|
||||
}
|
||||
|
||||
void OnError(uint8_t reason){
|
||||
cmd_send(CMD_ACK,0,reason,0,0,0);
|
||||
OnSuccess();
|
||||
cmd_send(CMD_ACK,0,reason,0,0,0);
|
||||
OnSuccess();
|
||||
}
|
||||
|
|
|
@ -25,300 +25,300 @@ static uint32_t timerData = 0;
|
|||
//-----------------------------------------------------------------------------
|
||||
// "hf mf sniff"
|
||||
void RAMFUNC SniffMifare(uint8_t param) {
|
||||
// param:
|
||||
// bit 0 - trigger from first card answer
|
||||
// bit 1 - trigger from first reader 7-bit request
|
||||
// param:
|
||||
// bit 0 - trigger from first card answer
|
||||
// bit 1 - trigger from first reader 7-bit request
|
||||
|
||||
// C(red) A(yellow) B(green)
|
||||
LEDsoff();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
|
||||
// C(red) A(yellow) B(green)
|
||||
LEDsoff();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
|
||||
|
||||
// Allocate memory from BigBuf for some buffers
|
||||
// free all previous allocations first
|
||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
// Allocate memory from BigBuf for some buffers
|
||||
// free all previous allocations first
|
||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||
uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||
uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
||||
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t receivedResp[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||
uint8_t receivedRespPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t receivedResp[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||
uint8_t receivedRespPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
||||
|
||||
// allocate the DMA buffer, used to stream samples from the FPGA
|
||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
uint8_t *data = dmaBuf;
|
||||
uint8_t previous_data = 0;
|
||||
int maxDataLen = 0;
|
||||
int dataLen = 0;
|
||||
bool ReaderIsActive = false;
|
||||
bool TagIsActive = false;
|
||||
// allocate the DMA buffer, used to stream samples from the FPGA
|
||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
uint8_t *data = dmaBuf;
|
||||
uint8_t previous_data = 0;
|
||||
int maxDataLen = 0;
|
||||
int dataLen = 0;
|
||||
bool ReaderIsActive = false;
|
||||
bool TagIsActive = false;
|
||||
|
||||
// We won't start recording the frames that we acquire until we trigger;
|
||||
// a good trigger condition to get started is probably when we see a
|
||||
// response from the tag.
|
||||
// triggered == false -- to wait first for card
|
||||
//bool triggered = !(param & 0x03);
|
||||
// We won't start recording the frames that we acquire until we trigger;
|
||||
// a good trigger condition to get started is probably when we see a
|
||||
// response from the tag.
|
||||
// triggered == false -- to wait first for card
|
||||
//bool triggered = !(param & 0x03);
|
||||
|
||||
|
||||
// Set up the demodulator for tag -> reader responses.
|
||||
DemodInit(receivedResp, receivedRespPar);
|
||||
// Set up the demodulator for tag -> reader responses.
|
||||
DemodInit(receivedResp, receivedRespPar);
|
||||
|
||||
// Set up the demodulator for the reader -> tag commands
|
||||
UartInit(receivedCmd, receivedCmdPar);
|
||||
// Set up the demodulator for the reader -> tag commands
|
||||
UartInit(receivedCmd, receivedCmdPar);
|
||||
|
||||
// Setup and start DMA.
|
||||
// set transfer address and number of bytes. Start transfer.
|
||||
if ( !FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE) ){
|
||||
if (MF_DBGLEVEL > 1) Dbprintf("[!] FpgaSetupSscDma failed. Exiting");
|
||||
return;
|
||||
}
|
||||
// Setup and start DMA.
|
||||
// set transfer address and number of bytes. Start transfer.
|
||||
if ( !FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE) ){
|
||||
if (MF_DBGLEVEL > 1) Dbprintf("[!] FpgaSetupSscDma failed. Exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
tUart* uart = GetUart();
|
||||
tDemod* demod = GetDemod();
|
||||
tUart* uart = GetUart();
|
||||
tDemod* demod = GetDemod();
|
||||
|
||||
MfSniffInit();
|
||||
MfSniffInit();
|
||||
|
||||
uint32_t sniffCounter = 0;
|
||||
uint32_t sniffCounter = 0;
|
||||
// loop and listen
|
||||
while (!BUTTON_PRESS()) {
|
||||
WDT_HIT();
|
||||
LED_A_ON();
|
||||
while (!BUTTON_PRESS()) {
|
||||
WDT_HIT();
|
||||
LED_A_ON();
|
||||
/*
|
||||
if ((sniffCounter & 0x0000FFFF) == 0) { // from time to time
|
||||
// check if a transaction is completed (timeout after 2000ms).
|
||||
// if yes, stop the DMA transfer and send what we have so far to the client
|
||||
if (BigBuf_get_traceLen()) {
|
||||
MfSniffSend();
|
||||
// Reset everything - we missed some sniffed data anyway while the DMA was stopped
|
||||
sniffCounter = 0;
|
||||
dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
data = dmaBuf;
|
||||
maxDataLen = 0;
|
||||
ReaderIsActive = false;
|
||||
TagIsActive = false;
|
||||
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
|
||||
}
|
||||
}
|
||||
*/
|
||||
if ((sniffCounter & 0x0000FFFF) == 0) { // from time to time
|
||||
// check if a transaction is completed (timeout after 2000ms).
|
||||
// if yes, stop the DMA transfer and send what we have so far to the client
|
||||
if (BigBuf_get_traceLen()) {
|
||||
MfSniffSend();
|
||||
// Reset everything - we missed some sniffed data anyway while the DMA was stopped
|
||||
sniffCounter = 0;
|
||||
dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||
data = dmaBuf;
|
||||
maxDataLen = 0;
|
||||
ReaderIsActive = false;
|
||||
TagIsActive = false;
|
||||
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// number of bytes we have processed so far
|
||||
int register readBufDataP = data - dmaBuf;
|
||||
// number of bytes already transferred
|
||||
int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
|
||||
if (readBufDataP <= dmaBufDataP) // we are processing the same block of data which is currently being transferred
|
||||
dataLen = dmaBufDataP - readBufDataP; // number of bytes still to be processed
|
||||
else
|
||||
dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; // number of bytes still to be processed
|
||||
// number of bytes we have processed so far
|
||||
int register readBufDataP = data - dmaBuf;
|
||||
// number of bytes already transferred
|
||||
int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
|
||||
if (readBufDataP <= dmaBufDataP) // we are processing the same block of data which is currently being transferred
|
||||
dataLen = dmaBufDataP - readBufDataP; // number of bytes still to be processed
|
||||
else
|
||||
dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; // number of bytes still to be processed
|
||||
|
||||
// test for length of buffer
|
||||
if (dataLen > maxDataLen) { // we are more behind than ever...
|
||||
maxDataLen = dataLen;
|
||||
if (dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||
Dbprintf("[!] blew circular buffer! | datalen %u", dataLen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dataLen < 1) continue;
|
||||
// test for length of buffer
|
||||
if (dataLen > maxDataLen) { // we are more behind than ever...
|
||||
maxDataLen = dataLen;
|
||||
if (dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||
Dbprintf("[!] blew circular buffer! | datalen %u", dataLen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dataLen < 1) continue;
|
||||
|
||||
// primary buffer was stopped ( <-- we lost data!
|
||||
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
|
||||
Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
|
||||
}
|
||||
// secondary buffer sets as primary, secondary buffer was stopped
|
||||
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
|
||||
}
|
||||
// primary buffer was stopped ( <-- we lost data!
|
||||
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
|
||||
Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
|
||||
}
|
||||
// secondary buffer sets as primary, secondary buffer was stopped
|
||||
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
LED_A_OFF();
|
||||
LED_A_OFF();
|
||||
|
||||
// Need two samples to feed Miller and Manchester-Decoder
|
||||
if (sniffCounter & 0x01) {
|
||||
// Need two samples to feed Miller and Manchester-Decoder
|
||||
if (sniffCounter & 0x01) {
|
||||
|
||||
// no need to try decoding tag data if the reader is sending
|
||||
if (!TagIsActive) {
|
||||
uint8_t readerbyte = (previous_data & 0xF0) | (*data >> 4);
|
||||
if (MillerDecoding(readerbyte, (sniffCounter-1)*4)) {
|
||||
LogTrace(receivedCmd, uart->len, 0, 0, NULL, true);
|
||||
DemodReset();
|
||||
UartReset();
|
||||
}
|
||||
ReaderIsActive = (uart->state != STATE_UNSYNCD);
|
||||
}
|
||||
// no need to try decoding tag data if the reader is sending
|
||||
if (!TagIsActive) {
|
||||
uint8_t readerbyte = (previous_data & 0xF0) | (*data >> 4);
|
||||
if (MillerDecoding(readerbyte, (sniffCounter-1)*4)) {
|
||||
LogTrace(receivedCmd, uart->len, 0, 0, NULL, true);
|
||||
DemodReset();
|
||||
UartReset();
|
||||
}
|
||||
ReaderIsActive = (uart->state != STATE_UNSYNCD);
|
||||
}
|
||||
|
||||
// no need to try decoding tag data if the reader is sending
|
||||
if (!ReaderIsActive) {
|
||||
uint8_t tagbyte = (previous_data << 4) | (*data & 0x0F);
|
||||
if (ManchesterDecoding(tagbyte, 0, (sniffCounter-1)*4)) {
|
||||
LogTrace(receivedResp, demod->len, 0, 0, NULL, false);
|
||||
DemodReset();
|
||||
UartReset();
|
||||
}
|
||||
TagIsActive = (demod->state != DEMOD_UNSYNCD);
|
||||
}
|
||||
}
|
||||
previous_data = *data;
|
||||
sniffCounter++;
|
||||
data++;
|
||||
// no need to try decoding tag data if the reader is sending
|
||||
if (!ReaderIsActive) {
|
||||
uint8_t tagbyte = (previous_data << 4) | (*data & 0x0F);
|
||||
if (ManchesterDecoding(tagbyte, 0, (sniffCounter-1)*4)) {
|
||||
LogTrace(receivedResp, demod->len, 0, 0, NULL, false);
|
||||
DemodReset();
|
||||
UartReset();
|
||||
}
|
||||
TagIsActive = (demod->state != DEMOD_UNSYNCD);
|
||||
}
|
||||
}
|
||||
previous_data = *data;
|
||||
sniffCounter++;
|
||||
data++;
|
||||
|
||||
if (data == dmaBuf + DMA_BUFFER_SIZE)
|
||||
data = dmaBuf;
|
||||
if (data == dmaBuf + DMA_BUFFER_SIZE)
|
||||
data = dmaBuf;
|
||||
|
||||
} // main cycle
|
||||
} // main cycle
|
||||
|
||||
MfSniffEnd();
|
||||
switch_off();
|
||||
MfSniffEnd();
|
||||
switch_off();
|
||||
}
|
||||
|
||||
void MfSniffInit(void){
|
||||
memset(sniffUID, 0x00, sizeof(sniffUID));
|
||||
memset(sniffATQA, 0x00, sizeof(sniffATQA));
|
||||
memset(sniffBuf, 0x00, sizeof(sniffBuf));
|
||||
sniffSAK = 0;
|
||||
sniffUIDType = SNF_UID_4;
|
||||
timerData = 0;
|
||||
memset(sniffUID, 0x00, sizeof(sniffUID));
|
||||
memset(sniffATQA, 0x00, sizeof(sniffATQA));
|
||||
memset(sniffBuf, 0x00, sizeof(sniffBuf));
|
||||
sniffSAK = 0;
|
||||
sniffUIDType = SNF_UID_4;
|
||||
timerData = 0;
|
||||
}
|
||||
|
||||
void MfSniffEnd(void){
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
LED_B_OFF();
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
LED_B_OFF();
|
||||
}
|
||||
|
||||
/*
|
||||
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader) {
|
||||
|
||||
// reset on 7-Bit commands from reader
|
||||
if (reader && (len == 1) && (bitCnt == 7)) {
|
||||
sniffState = SNF_INIT;
|
||||
}
|
||||
// reset on 7-Bit commands from reader
|
||||
if (reader && (len == 1) && (bitCnt == 7)) {
|
||||
sniffState = SNF_INIT;
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch (sniffState) {
|
||||
case SNF_INIT:{
|
||||
// REQA,WUPA or MAGICWUP from reader
|
||||
if ((len == 1) && (reader) && (bitCnt == 7) ) {
|
||||
MfSniffInit();
|
||||
sniffState = (data[0] == MIFARE_MAGICWUPC1) ? SNF_MAGIC_WUPC2 : SNF_ATQA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_MAGIC_WUPC2: {
|
||||
if ((len == 1) && (reader) && (data[0] == MIFARE_MAGICWUPC2) ) {
|
||||
sniffState = SNF_CARD_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_ATQA:{
|
||||
// ATQA from tag
|
||||
if ((!reader) && (len == 2)) {
|
||||
sniffATQA[0] = data[0];
|
||||
sniffATQA[1] = data[1];
|
||||
sniffState = SNF_UID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_UID: {
|
||||
switch (sniffState) {
|
||||
case SNF_INIT:{
|
||||
// REQA,WUPA or MAGICWUP from reader
|
||||
if ((len == 1) && (reader) && (bitCnt == 7) ) {
|
||||
MfSniffInit();
|
||||
sniffState = (data[0] == MIFARE_MAGICWUPC1) ? SNF_MAGIC_WUPC2 : SNF_ATQA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_MAGIC_WUPC2: {
|
||||
if ((len == 1) && (reader) && (data[0] == MIFARE_MAGICWUPC2) ) {
|
||||
sniffState = SNF_CARD_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_ATQA:{
|
||||
// ATQA from tag
|
||||
if ((!reader) && (len == 2)) {
|
||||
sniffATQA[0] = data[0];
|
||||
sniffATQA[1] = data[1];
|
||||
sniffState = SNF_UID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_UID: {
|
||||
|
||||
if ( !reader ) break;
|
||||
if ( len != 9 ) break;
|
||||
if ( !CheckCrc14443(CRC_14443_A, data, 9)) break;
|
||||
if ( data[1] != 0x70 ) break;
|
||||
if ( !reader ) break;
|
||||
if ( len != 9 ) break;
|
||||
if ( !CheckCrc14443(CRC_14443_A, data, 9)) break;
|
||||
if ( data[1] != 0x70 ) break;
|
||||
|
||||
Dbprintf("[!] UID | %x", data[0]);
|
||||
Dbprintf("[!] UID | %x", data[0]);
|
||||
|
||||
if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT)) {
|
||||
// UID_4 - select 4 Byte UID from reader
|
||||
memcpy(sniffUID, data+2, 4);
|
||||
sniffUIDType = SNF_UID_4;
|
||||
sniffState = SNF_SAK;
|
||||
} else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2)) {
|
||||
// UID_7 - Select 2nd part of 7 Byte UID
|
||||
if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT)) {
|
||||
// UID_4 - select 4 Byte UID from reader
|
||||
memcpy(sniffUID, data+2, 4);
|
||||
sniffUIDType = SNF_UID_4;
|
||||
sniffState = SNF_SAK;
|
||||
} else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2)) {
|
||||
// UID_7 - Select 2nd part of 7 Byte UID
|
||||
|
||||
// get rid of 0x88
|
||||
sniffUID[0] = sniffUID[1];
|
||||
sniffUID[1] = sniffUID[2];
|
||||
sniffUID[2] = sniffUID[3];
|
||||
//new uid bytes
|
||||
memcpy(sniffUID+3, data+2, 4);
|
||||
sniffUIDType = SNF_UID_7;
|
||||
sniffState = SNF_SAK;
|
||||
} else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3)) {
|
||||
// UID_10 - Select 3nd part of 10 Byte UID
|
||||
// 3+3+4 = 10.
|
||||
// get ride of previous 0x88
|
||||
sniffUID[3] = sniffUID[4];
|
||||
sniffUID[4] = sniffUID[5];
|
||||
sniffUID[5] = sniffUID[6];
|
||||
// new uid bytes
|
||||
memcpy(sniffUID+6, data+2, 4);
|
||||
sniffUIDType = SNF_UID_10;
|
||||
sniffState = SNF_SAK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_SAK:{
|
||||
// SAK from card?
|
||||
if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) {
|
||||
sniffSAK = data[0];
|
||||
// CL2 UID part to be expected
|
||||
if (( sniffSAK == 0x04) && (sniffUIDType == SNF_UID_4)) {
|
||||
sniffState = SNF_UID;
|
||||
// CL3 UID part to be expected
|
||||
} else if ((sniffSAK == 0x04) && (sniffUIDType == SNF_UID_7)) {
|
||||
sniffState = SNF_UID;
|
||||
} else {
|
||||
// select completed
|
||||
sniffState = SNF_CARD_IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_CARD_IDLE:{ // trace the card select sequence
|
||||
sniffBuf[0] = 0xFF;
|
||||
sniffBuf[1] = 0xFF;
|
||||
memcpy(sniffBuf + 2, sniffUID, sizeof(sniffUID));
|
||||
memcpy(sniffBuf + 12, sniffATQA, sizeof(sniffATQA));
|
||||
sniffBuf[14] = sniffSAK;
|
||||
sniffBuf[15] = 0xFF;
|
||||
sniffBuf[16] = 0xFF;
|
||||
LogTrace(sniffBuf, sizeof(sniffBuf), 0, 0, NULL, true);
|
||||
sniffState = SNF_CARD_CMD;
|
||||
} // intentionally no break;
|
||||
case SNF_CARD_CMD:{
|
||||
LogTrace(data, len, 0, 0, NULL, reader);
|
||||
timerData = GetTickCount();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sniffState = SNF_INIT;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
// get rid of 0x88
|
||||
sniffUID[0] = sniffUID[1];
|
||||
sniffUID[1] = sniffUID[2];
|
||||
sniffUID[2] = sniffUID[3];
|
||||
//new uid bytes
|
||||
memcpy(sniffUID+3, data+2, 4);
|
||||
sniffUIDType = SNF_UID_7;
|
||||
sniffState = SNF_SAK;
|
||||
} else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3)) {
|
||||
// UID_10 - Select 3nd part of 10 Byte UID
|
||||
// 3+3+4 = 10.
|
||||
// get ride of previous 0x88
|
||||
sniffUID[3] = sniffUID[4];
|
||||
sniffUID[4] = sniffUID[5];
|
||||
sniffUID[5] = sniffUID[6];
|
||||
// new uid bytes
|
||||
memcpy(sniffUID+6, data+2, 4);
|
||||
sniffUIDType = SNF_UID_10;
|
||||
sniffState = SNF_SAK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_SAK:{
|
||||
// SAK from card?
|
||||
if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) {
|
||||
sniffSAK = data[0];
|
||||
// CL2 UID part to be expected
|
||||
if (( sniffSAK == 0x04) && (sniffUIDType == SNF_UID_4)) {
|
||||
sniffState = SNF_UID;
|
||||
// CL3 UID part to be expected
|
||||
} else if ((sniffSAK == 0x04) && (sniffUIDType == SNF_UID_7)) {
|
||||
sniffState = SNF_UID;
|
||||
} else {
|
||||
// select completed
|
||||
sniffState = SNF_CARD_IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNF_CARD_IDLE:{ // trace the card select sequence
|
||||
sniffBuf[0] = 0xFF;
|
||||
sniffBuf[1] = 0xFF;
|
||||
memcpy(sniffBuf + 2, sniffUID, sizeof(sniffUID));
|
||||
memcpy(sniffBuf + 12, sniffATQA, sizeof(sniffATQA));
|
||||
sniffBuf[14] = sniffSAK;
|
||||
sniffBuf[15] = 0xFF;
|
||||
sniffBuf[16] = 0xFF;
|
||||
LogTrace(sniffBuf, sizeof(sniffBuf), 0, 0, NULL, true);
|
||||
sniffState = SNF_CARD_CMD;
|
||||
} // intentionally no break;
|
||||
case SNF_CARD_CMD:{
|
||||
LogTrace(data, len, 0, 0, NULL, reader);
|
||||
timerData = GetTickCount();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sniffState = SNF_INIT;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
void RAMFUNC MfSniffSend() {
|
||||
uint16_t tracelen = BigBuf_get_traceLen();
|
||||
uint16_t chunksize = 0;
|
||||
int packlen = tracelen; // total number of bytes to send
|
||||
uint8_t *data = BigBuf_get_addr();
|
||||
uint16_t tracelen = BigBuf_get_traceLen();
|
||||
uint16_t chunksize = 0;
|
||||
int packlen = tracelen; // total number of bytes to send
|
||||
uint8_t *data = BigBuf_get_addr();
|
||||
|
||||
while (packlen > 0) {
|
||||
LED_B_ON();
|
||||
chunksize = MIN(USB_CMD_DATA_SIZE, packlen); // chunk size 512
|
||||
cmd_send(CMD_ACK, 1, tracelen, chunksize, data + tracelen - packlen, chunksize);
|
||||
packlen -= chunksize;
|
||||
LED_B_OFF();
|
||||
}
|
||||
while (packlen > 0) {
|
||||
LED_B_ON();
|
||||
chunksize = MIN(USB_CMD_DATA_SIZE, packlen); // chunk size 512
|
||||
cmd_send(CMD_ACK, 1, tracelen, chunksize, data + tracelen - packlen, chunksize);
|
||||
packlen -= chunksize;
|
||||
LED_B_OFF();
|
||||
}
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK, 2, 0, 0, 0, 0); // 2 == data transfer finished.
|
||||
LED_B_OFF();
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK, 2, 0, 0, 0, 0); // 2 == data transfer finished.
|
||||
LED_B_OFF();
|
||||
}
|
|
@ -21,18 +21,18 @@
|
|||
#include "mifareutil.h"
|
||||
#include "common.h"
|
||||
|
||||
#define SNF_INIT 0
|
||||
#define SNF_NO_FIELD 1
|
||||
#define SNF_ATQA 2
|
||||
#define SNF_UID 3
|
||||
#define SNF_SAK 4
|
||||
#define SNF_CARD_IDLE 5
|
||||
#define SNF_CARD_CMD 6
|
||||
#define SNF_MAGIC_WUPC2 7
|
||||
#define SNF_INIT 0
|
||||
#define SNF_NO_FIELD 1
|
||||
#define SNF_ATQA 2
|
||||
#define SNF_UID 3
|
||||
#define SNF_SAK 4
|
||||
#define SNF_CARD_IDLE 5
|
||||
#define SNF_CARD_CMD 6
|
||||
#define SNF_MAGIC_WUPC2 7
|
||||
|
||||
#define SNF_UID_4 0
|
||||
#define SNF_UID_7 0
|
||||
#define SNF_UID_10 0
|
||||
#define SNF_UID_4 0
|
||||
#define SNF_UID_7 0
|
||||
#define SNF_UID_10 0
|
||||
|
||||
void MfSniffInit(void);
|
||||
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -21,7 +21,7 @@
|
|||
#include "iso14443a.h"
|
||||
#include "crapto1/crapto1.h"
|
||||
#include "des.h"
|
||||
#include "random.h" // fast_prand, prand
|
||||
#include "random.h" // fast_prand, prand
|
||||
|
||||
// mifare authentication
|
||||
#define CRYPT_NONE 0
|
||||
|
@ -30,8 +30,8 @@
|
|||
#define AUTH_FIRST 0
|
||||
#define AUTH_NESTED 2
|
||||
|
||||
#define AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
|
||||
#define PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication
|
||||
#define AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
|
||||
#define PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication
|
||||
|
||||
// mifare 4bit card answers
|
||||
#define CARD_ACK 0x0A // 1010 - ACK
|
||||
|
@ -48,7 +48,7 @@
|
|||
#define MFEMUL_SELECT3 4
|
||||
#define MFEMUL_AUTH1 5
|
||||
#define MFEMUL_AUTH2 6
|
||||
#define MFEMUL_WORK 7
|
||||
#define MFEMUL_WORK 7
|
||||
#define MFEMUL_WRITEBL2 8
|
||||
#define MFEMUL_INTREG_INC 9
|
||||
#define MFEMUL_INTREG_DEC 10
|
||||
|
|
|
@ -41,8 +41,8 @@
|
|||
This file contains an optimized version of the MAC-calculation algorithm. Some measurements on
|
||||
a std laptop showed it runs in about 1/3 of the time:
|
||||
|
||||
Std: 0.428962
|
||||
Opt: 0.151609
|
||||
Std: 0.428962
|
||||
Opt: 0.151609
|
||||
|
||||
Additionally, it is self-reliant, not requiring e.g. bitstreams from the cipherutils, thus can
|
||||
be easily dropped into a code base.
|
||||
|
@ -67,162 +67,162 @@
|
|||
#define opt_B(s) (((s->b >> 6) ^ (s->b >> 5) ^ (s->b >> 4) ^ (s->b)) & 0x1)
|
||||
|
||||
#define opt__select(x,y,r) (4 & (((r & (r << 2)) >> 5) ^ ((r & ~(r << 2)) >> 4) ^ ( (r | r << 2) >> 3)))\
|
||||
|(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\
|
||||
|(1 & (((r & ~(r << 2)) >> 4) ^ ((r & (r << 2)) >> 3) ^ r ^ x))
|
||||
|(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\
|
||||
|(1 & (((r & ~(r << 2)) >> 4) ^ ((r & (r << 2)) >> 3) ^ r ^ x))
|
||||
|
||||
/*
|
||||
* Some background on the expression above can be found here...
|
||||
uint8_t xopt__select(bool x, bool y, uint8_t r)
|
||||
{
|
||||
uint8_t r_ls2 = r << 2;
|
||||
uint8_t r_and_ls2 = r & r_ls2;
|
||||
uint8_t r_or_ls2 = r | r_ls2;
|
||||
uint8_t r_ls2 = r << 2;
|
||||
uint8_t r_and_ls2 = r & r_ls2;
|
||||
uint8_t r_or_ls2 = r | r_ls2;
|
||||
|
||||
//r: r0 r1 r2 r3 r4 r5 r6 r7
|
||||
//r_ls2: r2 r3 r4 r5 r6 r7 0 0
|
||||
// z0
|
||||
// z1
|
||||
//r: r0 r1 r2 r3 r4 r5 r6 r7
|
||||
//r_ls2: r2 r3 r4 r5 r6 r7 0 0
|
||||
// z0
|
||||
// z1
|
||||
|
||||
// uint8_t z0 = (r0 & r2) ^ (r1 & ~r3) ^ (r2 | r4); // <-- original
|
||||
uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3);
|
||||
// uint8_t z0 = (r0 & r2) ^ (r1 & ~r3) ^ (r2 | r4); // <-- original
|
||||
uint8_t z0 = (r_and_ls2 >> 5) ^ ((r & ~r_ls2) >> 4) ^ ( r_or_ls2 >> 3);
|
||||
|
||||
// uint8_t z1 = (r0 | r2) ^ ( r5 | r7) ^ r1 ^ r6 ^ x ^ y; // <-- original
|
||||
uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1);
|
||||
// uint8_t z1 = (r0 | r2) ^ ( r5 | r7) ^ r1 ^ r6 ^ x ^ y; // <-- original
|
||||
uint8_t z1 = (r_or_ls2 >> 6) ^ ( r_or_ls2 >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1);
|
||||
|
||||
// uint8_t z2 = (r3 & ~r5) ^ (r4 & r6 ) ^ r7 ^ x; // <-- original
|
||||
uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r ^ x;
|
||||
// uint8_t z2 = (r3 & ~r5) ^ (r4 & r6 ) ^ r7 ^ x; // <-- original
|
||||
uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r ^ x;
|
||||
|
||||
return (z0 & 4) | (z1 & 2) | (z2 & 1);
|
||||
return (z0 & 4) | (z1 & 2) | (z2 & 1);
|
||||
}
|
||||
*/
|
||||
|
||||
void opt_successor(const uint8_t* k, State *s, bool y, State* successor) {
|
||||
uint8_t Tt = 1 & opt_T(s);
|
||||
uint8_t Tt = 1 & opt_T(s);
|
||||
|
||||
successor->t = (s->t >> 1);
|
||||
successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15;
|
||||
successor->t = (s->t >> 1);
|
||||
successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15;
|
||||
|
||||
successor->b = s->b >> 1;
|
||||
successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7;
|
||||
successor->b = s->b >> 1;
|
||||
successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7;
|
||||
|
||||
successor->r = (k[opt__select(Tt,y,s->r)] ^ successor->b) + s->l ;
|
||||
successor->l = successor->r+s->r;
|
||||
successor->r = (k[opt__select(Tt,y,s->r)] ^ successor->b) + s->l ;
|
||||
successor->l = successor->r+s->r;
|
||||
}
|
||||
|
||||
void opt_suc(const uint8_t* k,State* s, uint8_t *in, uint8_t length, bool add32Zeroes) {
|
||||
State x2;
|
||||
int i;
|
||||
uint8_t head = 0;
|
||||
for (i = 0; i < length; i++) {
|
||||
head = 1 & (in[i] >> 7);
|
||||
opt_successor(k, s, head, &x2);
|
||||
State x2;
|
||||
int i;
|
||||
uint8_t head = 0;
|
||||
for (i = 0; i < length; i++) {
|
||||
head = 1 & (in[i] >> 7);
|
||||
opt_successor(k, s, head, &x2);
|
||||
|
||||
head = 1 & (in[i] >> 6);
|
||||
opt_successor(k, &x2, head, s);
|
||||
head = 1 & (in[i] >> 6);
|
||||
opt_successor(k, &x2, head, s);
|
||||
|
||||
head = 1 & (in[i] >> 5);
|
||||
opt_successor(k, s, head, &x2);
|
||||
head = 1 & (in[i] >> 5);
|
||||
opt_successor(k, s, head, &x2);
|
||||
|
||||
head = 1 & (in[i] >> 4);
|
||||
opt_successor(k, &x2, head, s);
|
||||
head = 1 & (in[i] >> 4);
|
||||
opt_successor(k, &x2, head, s);
|
||||
|
||||
head = 1 & (in[i] >> 3);
|
||||
opt_successor(k, s, head, &x2);
|
||||
head = 1 & (in[i] >> 3);
|
||||
opt_successor(k, s, head, &x2);
|
||||
|
||||
head = 1 & (in[i] >> 2);
|
||||
opt_successor(k, &x2, head, s);
|
||||
head = 1 & (in[i] >> 2);
|
||||
opt_successor(k, &x2, head, s);
|
||||
|
||||
head = 1 & (in[i] >> 1);
|
||||
opt_successor(k, s, head, &x2);
|
||||
head = 1 & (in[i] >> 1);
|
||||
opt_successor(k, s, head, &x2);
|
||||
|
||||
head = 1 & in[i];
|
||||
opt_successor(k, &x2, head, s);
|
||||
}
|
||||
head = 1 & in[i];
|
||||
opt_successor(k, &x2, head, s);
|
||||
}
|
||||
|
||||
//For tag MAC, an additional 32 zeroes
|
||||
if (add32Zeroes) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
opt_successor(k, s, 0, &x2);
|
||||
opt_successor(k, &x2, 0, s);
|
||||
}
|
||||
}
|
||||
//For tag MAC, an additional 32 zeroes
|
||||
if (add32Zeroes) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
opt_successor(k, s, 0, &x2);
|
||||
opt_successor(k, &x2, 0, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void opt_output(const uint8_t* k,State* s, uint8_t *buffer) {
|
||||
uint8_t times = 0;
|
||||
uint8_t bout = 0;
|
||||
State temp = {0,0,0,0};
|
||||
for ( ; times < 4; times++) {
|
||||
bout =0;
|
||||
bout |= (s->r & 0x4) << 5;
|
||||
opt_successor(k, s, 0, &temp);
|
||||
bout |= (temp.r & 0x4) << 4;
|
||||
opt_successor(k, &temp, 0, s);
|
||||
bout |= (s->r & 0x4) << 3;
|
||||
opt_successor(k, s, 0, &temp);
|
||||
bout |= (temp.r & 0x4) << 2;
|
||||
opt_successor(k, &temp, 0, s);
|
||||
bout |= (s->r & 0x4) << 1;
|
||||
opt_successor(k, s, 0, &temp);
|
||||
bout |= (temp.r & 0x4) ;
|
||||
opt_successor(k, &temp, 0, s);
|
||||
bout |= (s->r & 0x4) >> 1;
|
||||
opt_successor(k, s, 0, &temp);
|
||||
bout |= (temp.r & 0x4) >> 2;
|
||||
opt_successor(k, &temp, 0, s);
|
||||
buffer[times] = bout;
|
||||
}
|
||||
uint8_t times = 0;
|
||||
uint8_t bout = 0;
|
||||
State temp = {0,0,0,0};
|
||||
for ( ; times < 4; times++) {
|
||||
bout =0;
|
||||
bout |= (s->r & 0x4) << 5;
|
||||
opt_successor(k, s, 0, &temp);
|
||||
bout |= (temp.r & 0x4) << 4;
|
||||
opt_successor(k, &temp, 0, s);
|
||||
bout |= (s->r & 0x4) << 3;
|
||||
opt_successor(k, s, 0, &temp);
|
||||
bout |= (temp.r & 0x4) << 2;
|
||||
opt_successor(k, &temp, 0, s);
|
||||
bout |= (s->r & 0x4) << 1;
|
||||
opt_successor(k, s, 0, &temp);
|
||||
bout |= (temp.r & 0x4) ;
|
||||
opt_successor(k, &temp, 0, s);
|
||||
bout |= (s->r & 0x4) >> 1;
|
||||
opt_successor(k, s, 0, &temp);
|
||||
bout |= (temp.r & 0x4) >> 2;
|
||||
opt_successor(k, &temp, 0, s);
|
||||
buffer[times] = bout;
|
||||
}
|
||||
}
|
||||
|
||||
void opt_MAC(uint8_t* k, uint8_t* input, uint8_t* out) {
|
||||
State _init = {
|
||||
((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||
((k[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||
0x4c, // b
|
||||
0xE012 // t
|
||||
};
|
||||
State _init = {
|
||||
((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||
((k[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||
0x4c, // b
|
||||
0xE012 // t
|
||||
};
|
||||
|
||||
opt_suc(k,&_init,input,12, false);
|
||||
opt_output(k,&_init, out);
|
||||
opt_suc(k,&_init,input,12, false);
|
||||
opt_output(k,&_init, out);
|
||||
}
|
||||
|
||||
uint8_t rev_byte(uint8_t b) {
|
||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||
return b;
|
||||
}
|
||||
|
||||
void opt_reverse_arraybytecpy(uint8_t* dest, uint8_t *src, size_t len) {
|
||||
uint8_t i;
|
||||
for ( i =0; i< len ; i++)
|
||||
dest[i] = rev_byte(src[i]);
|
||||
uint8_t i;
|
||||
for ( i =0; i< len ; i++)
|
||||
dest[i] = rev_byte(src[i]);
|
||||
}
|
||||
|
||||
void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) {
|
||||
static uint8_t cc_nr[12];
|
||||
opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12);
|
||||
uint8_t dest [] = {0,0,0,0,0,0,0,0};
|
||||
opt_MAC(div_key_p, cc_nr, dest);
|
||||
//The output MAC must also be reversed
|
||||
opt_reverse_arraybytecpy(mac, dest, 4);
|
||||
return;
|
||||
static uint8_t cc_nr[12];
|
||||
opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12);
|
||||
uint8_t dest [] = {0,0,0,0,0,0,0,0};
|
||||
opt_MAC(div_key_p, cc_nr, dest);
|
||||
//The output MAC must also be reversed
|
||||
opt_reverse_arraybytecpy(mac, dest, 4);
|
||||
return;
|
||||
}
|
||||
void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) {
|
||||
static uint8_t cc_nr[8+4+4];
|
||||
opt_reverse_arraybytecpy(cc_nr, cc_p, 12);
|
||||
State _init = {
|
||||
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||
0x4c, // b
|
||||
0xE012 // t
|
||||
};
|
||||
opt_suc(div_key_p, &_init, cc_nr, 12, true);
|
||||
uint8_t dest [] = {0,0,0,0};
|
||||
opt_output(div_key_p, &_init, dest);
|
||||
//The output MAC must also be reversed
|
||||
opt_reverse_arraybytecpy(mac, dest,4);
|
||||
return;
|
||||
static uint8_t cc_nr[8+4+4];
|
||||
opt_reverse_arraybytecpy(cc_nr, cc_p, 12);
|
||||
State _init = {
|
||||
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||
0x4c, // b
|
||||
0xE012 // t
|
||||
};
|
||||
opt_suc(div_key_p, &_init, cc_nr, 12, true);
|
||||
uint8_t dest [] = {0,0,0,0};
|
||||
opt_output(div_key_p, &_init, dest);
|
||||
//The output MAC must also be reversed
|
||||
opt_reverse_arraybytecpy(mac, dest,4);
|
||||
return;
|
||||
|
||||
}
|
||||
/**
|
||||
|
@ -234,16 +234,16 @@ void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) {
|
|||
* @return the cipher state
|
||||
*/
|
||||
State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
|
||||
static uint8_t cc_nr[8];
|
||||
opt_reverse_arraybytecpy(cc_nr, cc_p, 8);
|
||||
State _init = {
|
||||
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||
0x4c, // b
|
||||
0xE012 // t
|
||||
};
|
||||
opt_suc(div_key_p, &_init, cc_nr, 8, false);
|
||||
return _init;
|
||||
static uint8_t cc_nr[8];
|
||||
opt_reverse_arraybytecpy(cc_nr, cc_p, 8);
|
||||
State _init = {
|
||||
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||
0x4c, // b
|
||||
0xE012 // t
|
||||
};
|
||||
opt_suc(div_key_p, &_init, cc_nr, 8, false);
|
||||
return _init;
|
||||
}
|
||||
/**
|
||||
* The second part of the tag MAC calculation, since the CC is already calculated into the state,
|
||||
|
@ -255,13 +255,13 @@ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
|
|||
* @param div_key_p - the key to use
|
||||
*/
|
||||
void opt_doTagMAC_2(State _init, uint8_t* nr, uint8_t mac[4], const uint8_t* div_key_p) {
|
||||
static uint8_t _nr[4];
|
||||
opt_reverse_arraybytecpy(_nr, nr, 4);
|
||||
opt_suc(div_key_p, &_init,_nr, 4, true);
|
||||
static uint8_t _nr[4];
|
||||
opt_reverse_arraybytecpy(_nr, nr, 4);
|
||||
opt_suc(div_key_p, &_init,_nr, 4, true);
|
||||
|
||||
uint8_t dest [] = {0,0,0,0};
|
||||
opt_output(div_key_p, &_init, dest);
|
||||
//The output MAC must also be reversed
|
||||
opt_reverse_arraybytecpy(mac, dest,4);
|
||||
return;
|
||||
uint8_t dest [] = {0,0,0,0};
|
||||
opt_output(div_key_p, &_init, dest);
|
||||
//The output MAC must also be reversed
|
||||
opt_reverse_arraybytecpy(mac, dest,4);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,16 +8,16 @@
|
|||
/**
|
||||
* Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2
|
||||
* consisting of the following four components:
|
||||
* 1. the left register l = (l 0 . . . l 7 ) ∈ F 8/2 ;
|
||||
* 2. the right register r = (r 0 . . . r 7 ) ∈ F 8/2 ;
|
||||
* 3. the top register t = (t 0 . . . t 15 ) ∈ F 16/2 .
|
||||
* 4. the bottom register b = (b 0 . . . b 7 ) ∈ F 8/2 .
|
||||
* 1. the left register l = (l 0 . . . l 7 ) ∈ F 8/2 ;
|
||||
* 2. the right register r = (r 0 . . . r 7 ) ∈ F 8/2 ;
|
||||
* 3. the top register t = (t 0 . . . t 15 ) ∈ F 16/2 .
|
||||
* 4. the bottom register b = (b 0 . . . b 7 ) ∈ F 8/2 .
|
||||
**/
|
||||
typedef struct {
|
||||
uint8_t l;
|
||||
uint8_t r;
|
||||
uint8_t b;
|
||||
uint16_t t;
|
||||
uint8_t l;
|
||||
uint8_t r;
|
||||
uint8_t b;
|
||||
uint16_t t;
|
||||
} State;
|
||||
|
||||
/** The reader MAC is MAC(key, CC * NR )
|
||||
|
|
788
armsrc/pcf7931.c
788
armsrc/pcf7931.c
|
@ -5,384 +5,384 @@
|
|||
|
||||
size_t DemodPCF7931(uint8_t **outBlocks) {
|
||||
uint8_t bits[256] = {0x00};
|
||||
uint8_t blocks[8][16];
|
||||
uint8_t blocks[8][16];
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
int GraphTraceLen = BigBuf_max_traceLen();
|
||||
if ( GraphTraceLen > 18000 )
|
||||
GraphTraceLen = 18000;
|
||||
int GraphTraceLen = BigBuf_max_traceLen();
|
||||
if ( GraphTraceLen > 18000 )
|
||||
GraphTraceLen = 18000;
|
||||
|
||||
int i, j, lastval, bitidx, half_switch;
|
||||
int clock = 64;
|
||||
int tolerance = clock / 8;
|
||||
int pmc, block_done;
|
||||
int lc, warnings = 0;
|
||||
size_t num_blocks = 0;
|
||||
int lmin=128, lmax=128;
|
||||
uint8_t dir;
|
||||
//clear read buffer
|
||||
BigBuf_Clear_keep_EM();
|
||||
int i, j, lastval, bitidx, half_switch;
|
||||
int clock = 64;
|
||||
int tolerance = clock / 8;
|
||||
int pmc, block_done;
|
||||
int lc, warnings = 0;
|
||||
size_t num_blocks = 0;
|
||||
int lmin=128, lmax=128;
|
||||
uint8_t dir;
|
||||
//clear read buffer
|
||||
BigBuf_Clear_keep_EM();
|
||||
|
||||
LFSetupFPGAForADC(95, true);
|
||||
DoAcquisition_default(0, true);
|
||||
LFSetupFPGAForADC(95, true);
|
||||
DoAcquisition_default(0, true);
|
||||
|
||||
lmin = 64;
|
||||
lmax = 192;
|
||||
lmin = 64;
|
||||
lmax = 192;
|
||||
|
||||
i = 2;
|
||||
i = 2;
|
||||
|
||||
/* Find first local max/min */
|
||||
/* Find first local max/min */
|
||||
if(dest[1] > dest[0]) {
|
||||
while(i < GraphTraceLen) {
|
||||
while(i < GraphTraceLen) {
|
||||
if( !(dest[i] > dest[i-1]) && dest[i] > lmax)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
dir = 0;
|
||||
} else {
|
||||
while(i < GraphTraceLen) {
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
dir = 0;
|
||||
} else {
|
||||
while(i < GraphTraceLen) {
|
||||
if( !(dest[i] < dest[i-1]) && dest[i] < lmin)
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
dir = 1;
|
||||
}
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
dir = 1;
|
||||
}
|
||||
|
||||
lastval = i++;
|
||||
half_switch = 0;
|
||||
pmc = 0;
|
||||
block_done = 0;
|
||||
lastval = i++;
|
||||
half_switch = 0;
|
||||
pmc = 0;
|
||||
block_done = 0;
|
||||
|
||||
for (bitidx = 0; i < GraphTraceLen; i++) {
|
||||
if ((dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin)) {
|
||||
lc = i - lastval;
|
||||
lastval = i;
|
||||
for (bitidx = 0; i < GraphTraceLen; i++) {
|
||||
if ((dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin)) {
|
||||
lc = i - lastval;
|
||||
lastval = i;
|
||||
|
||||
// Switch depending on lc length:
|
||||
// Tolerance is 1/8 of clock rate (arbitrary)
|
||||
if (ABS(lc-clock/4) < tolerance) {
|
||||
// 16T0
|
||||
if((i - pmc) == lc) { /* 16T0 was previous one */
|
||||
/* It's a PMC ! */
|
||||
i += (128+127+16+32+33+16)-1;
|
||||
lastval = i;
|
||||
pmc = 0;
|
||||
block_done = 1;
|
||||
} else {
|
||||
pmc = i;
|
||||
}
|
||||
} else if (ABS(lc-clock/2) < tolerance) {
|
||||
// 32TO
|
||||
if((i - pmc) == lc) { /* 16T0 was previous one */
|
||||
/* It's a PMC ! */
|
||||
i += (128+127+16+32+33)-1;
|
||||
lastval = i;
|
||||
pmc = 0;
|
||||
block_done = 1;
|
||||
} else if(half_switch == 1) {
|
||||
// Switch depending on lc length:
|
||||
// Tolerance is 1/8 of clock rate (arbitrary)
|
||||
if (ABS(lc-clock/4) < tolerance) {
|
||||
// 16T0
|
||||
if((i - pmc) == lc) { /* 16T0 was previous one */
|
||||
/* It's a PMC ! */
|
||||
i += (128+127+16+32+33+16)-1;
|
||||
lastval = i;
|
||||
pmc = 0;
|
||||
block_done = 1;
|
||||
} else {
|
||||
pmc = i;
|
||||
}
|
||||
} else if (ABS(lc-clock/2) < tolerance) {
|
||||
// 32TO
|
||||
if((i - pmc) == lc) { /* 16T0 was previous one */
|
||||
/* It's a PMC ! */
|
||||
i += (128+127+16+32+33)-1;
|
||||
lastval = i;
|
||||
pmc = 0;
|
||||
block_done = 1;
|
||||
} else if(half_switch == 1) {
|
||||
bits[bitidx++] = 0;
|
||||
half_switch = 0;
|
||||
}
|
||||
else
|
||||
half_switch++;
|
||||
} else if (ABS(lc-clock) < tolerance) {
|
||||
// 64TO
|
||||
half_switch = 0;
|
||||
}
|
||||
else
|
||||
half_switch++;
|
||||
} else if (ABS(lc-clock) < tolerance) {
|
||||
// 64TO
|
||||
bits[bitidx++] = 1;
|
||||
} else {
|
||||
// Error
|
||||
if (++warnings > 10) {
|
||||
Dbprintf("Error: too many detection errors, aborting.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Error
|
||||
if (++warnings > 10) {
|
||||
Dbprintf("Error: too many detection errors, aborting.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(block_done == 1) {
|
||||
if(bitidx == 128) {
|
||||
for(j = 0; j < 16; ++j) {
|
||||
blocks[num_blocks][j] =
|
||||
128 * bits[j*8 + 7]+
|
||||
if(block_done == 1) {
|
||||
if(bitidx == 128) {
|
||||
for(j = 0; j < 16; ++j) {
|
||||
blocks[num_blocks][j] =
|
||||
128 * bits[j*8 + 7]+
|
||||
64*bits[j*8+6]+
|
||||
32*bits[j*8+5]+
|
||||
16*bits[j*8+4]+
|
||||
8*bits[j*8+3]+
|
||||
4*bits[j*8+2]+
|
||||
2*bits[j*8+1]+
|
||||
bits[j*8]
|
||||
;
|
||||
}
|
||||
num_blocks++;
|
||||
}
|
||||
bitidx = 0;
|
||||
block_done = 0;
|
||||
half_switch = 0;
|
||||
}
|
||||
if(i < GraphTraceLen)
|
||||
bits[j*8]
|
||||
;
|
||||
}
|
||||
num_blocks++;
|
||||
}
|
||||
bitidx = 0;
|
||||
block_done = 0;
|
||||
half_switch = 0;
|
||||
}
|
||||
if(i < GraphTraceLen)
|
||||
dir =(dest[i-1] > dest[i]) ? 0 : 1;
|
||||
}
|
||||
if(bitidx==255)
|
||||
bitidx=0;
|
||||
warnings = 0;
|
||||
if(num_blocks == 4) break;
|
||||
}
|
||||
}
|
||||
if(bitidx==255)
|
||||
bitidx=0;
|
||||
warnings = 0;
|
||||
if(num_blocks == 4) break;
|
||||
}
|
||||
memcpy(outBlocks, blocks, 16*num_blocks);
|
||||
return num_blocks;
|
||||
return num_blocks;
|
||||
}
|
||||
|
||||
bool IsBlock0PCF7931(uint8_t *block) {
|
||||
// assuming all RFU bits are set to 0
|
||||
// if PAC is enabled password is set to 0
|
||||
if (block[7] == 0x01)
|
||||
{
|
||||
if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7))
|
||||
return true;
|
||||
}
|
||||
else if (block[7] == 0x00)
|
||||
{
|
||||
if (!memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// assuming all RFU bits are set to 0
|
||||
// if PAC is enabled password is set to 0
|
||||
if (block[7] == 0x01)
|
||||
{
|
||||
if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7))
|
||||
return true;
|
||||
}
|
||||
else if (block[7] == 0x00)
|
||||
{
|
||||
if (!memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsBlock1PCF7931(uint8_t *block) {
|
||||
// assuming all RFU bits are set to 0
|
||||
if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0)
|
||||
if((block[14] & 0x7f) <= 9 && block[15] <= 9)
|
||||
return true;
|
||||
// assuming all RFU bits are set to 0
|
||||
if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0)
|
||||
if((block[14] & 0x7f) <= 9 && block[15] <= 9)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void ReadPCF7931() {
|
||||
int found_blocks = 0; // successfully read blocks
|
||||
int max_blocks = 8; // readable blocks
|
||||
uint8_t memory_blocks[8][17]; // PCF content
|
||||
int found_blocks = 0; // successfully read blocks
|
||||
int max_blocks = 8; // readable blocks
|
||||
uint8_t memory_blocks[8][17]; // PCF content
|
||||
|
||||
uint8_t single_blocks[8][17]; // PFC blocks with unknown position
|
||||
int single_blocks_cnt = 0;
|
||||
uint8_t single_blocks[8][17]; // PFC blocks with unknown position
|
||||
int single_blocks_cnt = 0;
|
||||
|
||||
size_t n = 0; // transmitted blocks
|
||||
uint8_t tmp_blocks[4][16]; // temporary read buffer
|
||||
size_t n = 0; // transmitted blocks
|
||||
uint8_t tmp_blocks[4][16]; // temporary read buffer
|
||||
|
||||
uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found
|
||||
int errors = 0; // error counter
|
||||
int tries = 0; // tries counter
|
||||
uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found
|
||||
int errors = 0; // error counter
|
||||
int tries = 0; // tries counter
|
||||
|
||||
memset(memory_blocks, 0, 8*17*sizeof(uint8_t));
|
||||
memset(single_blocks, 0, 8*17*sizeof(uint8_t));
|
||||
memset(memory_blocks, 0, 8*17*sizeof(uint8_t));
|
||||
memset(single_blocks, 0, 8*17*sizeof(uint8_t));
|
||||
|
||||
int i = 0, j = 0;
|
||||
int i = 0, j = 0;
|
||||
|
||||
do {
|
||||
i = 0;
|
||||
do {
|
||||
i = 0;
|
||||
|
||||
memset(tmp_blocks, 0, 4*16*sizeof(uint8_t));
|
||||
n = DemodPCF7931((uint8_t**)tmp_blocks);
|
||||
if(!n)
|
||||
++errors;
|
||||
memset(tmp_blocks, 0, 4*16*sizeof(uint8_t));
|
||||
n = DemodPCF7931((uint8_t**)tmp_blocks);
|
||||
if(!n)
|
||||
++errors;
|
||||
|
||||
// exit if no block is received
|
||||
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
|
||||
Dbprintf("Error, no tag or bad tag");
|
||||
return;
|
||||
}
|
||||
// exit if too many errors during reading
|
||||
if (tries > 50 && (2*errors > tries)) {
|
||||
Dbprintf("Error reading the tag");
|
||||
Dbprintf("Here is the partial content");
|
||||
goto end;
|
||||
}
|
||||
// exit if no block is received
|
||||
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
|
||||
Dbprintf("Error, no tag or bad tag");
|
||||
return;
|
||||
}
|
||||
// exit if too many errors during reading
|
||||
if (tries > 50 && (2*errors > tries)) {
|
||||
Dbprintf("Error reading the tag");
|
||||
Dbprintf("Here is the partial content");
|
||||
goto end;
|
||||
}
|
||||
|
||||
// our logic breaks if we don't get at least two blocks
|
||||
if (n < 2) {
|
||||
if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))
|
||||
continue;
|
||||
// our logic breaks if we don't get at least two blocks
|
||||
if (n < 2) {
|
||||
if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))
|
||||
continue;
|
||||
|
||||
if (single_blocks_cnt < max_blocks) {
|
||||
for (i = 0; i < single_blocks_cnt; ++i) {
|
||||
if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) {
|
||||
j = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j != 1) {
|
||||
memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16);
|
||||
single_blocks_cnt++;
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
++tries;
|
||||
continue;
|
||||
}
|
||||
if (single_blocks_cnt < max_blocks) {
|
||||
for (i = 0; i < single_blocks_cnt; ++i) {
|
||||
if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) {
|
||||
j = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j != 1) {
|
||||
memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16);
|
||||
single_blocks_cnt++;
|
||||
}
|
||||
j = 0;
|
||||
}
|
||||
++tries;
|
||||
continue;
|
||||
}
|
||||
|
||||
Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors);
|
||||
Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors);
|
||||
|
||||
i = 0;
|
||||
if(!found_0_1) {
|
||||
while (i < n - 1) {
|
||||
if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i+1])) {
|
||||
found_0_1 = 1;
|
||||
memcpy(memory_blocks[0], tmp_blocks[i], 16);
|
||||
memcpy(memory_blocks[1], tmp_blocks[i+1], 16);
|
||||
memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1;
|
||||
// block 1 tells how many blocks are going to be sent
|
||||
max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1;
|
||||
found_blocks = 2;
|
||||
i = 0;
|
||||
if(!found_0_1) {
|
||||
while (i < n - 1) {
|
||||
if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i+1])) {
|
||||
found_0_1 = 1;
|
||||
memcpy(memory_blocks[0], tmp_blocks[i], 16);
|
||||
memcpy(memory_blocks[1], tmp_blocks[i+1], 16);
|
||||
memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1;
|
||||
// block 1 tells how many blocks are going to be sent
|
||||
max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1;
|
||||
found_blocks = 2;
|
||||
|
||||
Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", max_blocks);
|
||||
Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", max_blocks);
|
||||
|
||||
// handle the following blocks
|
||||
for (j = i + 2; j < n; ++j) {
|
||||
memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16);
|
||||
memory_blocks[found_blocks][ALLOC] = 1;
|
||||
++found_blocks;
|
||||
}
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
// Trying to re-order blocks
|
||||
// Look for identical block in memory blocks
|
||||
while (i < n-1) {
|
||||
// skip all zeroes blocks
|
||||
if (memcmp(tmp_blocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) {
|
||||
for (j = 1; j < max_blocks - 1; ++j) {
|
||||
if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j+1][ALLOC]) {
|
||||
memcpy(memory_blocks[j+1], tmp_blocks[i+1], 16);
|
||||
memory_blocks[j+1][ALLOC] = 1;
|
||||
if (++found_blocks >= max_blocks) goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (memcmp(tmp_blocks[i+1], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) {
|
||||
for (j = 0; j < max_blocks; ++j) {
|
||||
if (!memcmp(tmp_blocks[i+1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? max_blocks : j) -1][ALLOC]) {
|
||||
if (j == 0) {
|
||||
memcpy(memory_blocks[max_blocks - 1], tmp_blocks[i], 16);
|
||||
memory_blocks[max_blocks - 1][ALLOC] = 1;
|
||||
} else {
|
||||
memcpy(memory_blocks[j-1], tmp_blocks[i], 16);
|
||||
memory_blocks[j-1][ALLOC] = 1;
|
||||
}
|
||||
if (++found_blocks >= max_blocks) goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
++tries;
|
||||
if (BUTTON_PRESS()) {
|
||||
Dbprintf("Button pressed, stopping.");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
while (found_blocks != max_blocks);
|
||||
// handle the following blocks
|
||||
for (j = i + 2; j < n; ++j) {
|
||||
memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16);
|
||||
memory_blocks[found_blocks][ALLOC] = 1;
|
||||
++found_blocks;
|
||||
}
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
} else {
|
||||
// Trying to re-order blocks
|
||||
// Look for identical block in memory blocks
|
||||
while (i < n-1) {
|
||||
// skip all zeroes blocks
|
||||
if (memcmp(tmp_blocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) {
|
||||
for (j = 1; j < max_blocks - 1; ++j) {
|
||||
if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j+1][ALLOC]) {
|
||||
memcpy(memory_blocks[j+1], tmp_blocks[i+1], 16);
|
||||
memory_blocks[j+1][ALLOC] = 1;
|
||||
if (++found_blocks >= max_blocks) goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (memcmp(tmp_blocks[i+1], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) {
|
||||
for (j = 0; j < max_blocks; ++j) {
|
||||
if (!memcmp(tmp_blocks[i+1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? max_blocks : j) -1][ALLOC]) {
|
||||
if (j == 0) {
|
||||
memcpy(memory_blocks[max_blocks - 1], tmp_blocks[i], 16);
|
||||
memory_blocks[max_blocks - 1][ALLOC] = 1;
|
||||
} else {
|
||||
memcpy(memory_blocks[j-1], tmp_blocks[i], 16);
|
||||
memory_blocks[j-1][ALLOC] = 1;
|
||||
}
|
||||
if (++found_blocks >= max_blocks) goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
++tries;
|
||||
if (BUTTON_PRESS()) {
|
||||
Dbprintf("Button pressed, stopping.");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
while (found_blocks != max_blocks);
|
||||
|
||||
end:
|
||||
Dbprintf("-----------------------------------------");
|
||||
Dbprintf("Memory content:");
|
||||
Dbprintf("-----------------------------------------");
|
||||
for (i = 0; i < max_blocks; ++i) {
|
||||
if (memory_blocks[i][ALLOC])
|
||||
print_result("Block", memory_blocks[i], 16);
|
||||
else
|
||||
Dbprintf("<missing block %d>", i);
|
||||
}
|
||||
Dbprintf("-----------------------------------------");
|
||||
Dbprintf("-----------------------------------------");
|
||||
Dbprintf("Memory content:");
|
||||
Dbprintf("-----------------------------------------");
|
||||
for (i = 0; i < max_blocks; ++i) {
|
||||
if (memory_blocks[i][ALLOC])
|
||||
print_result("Block", memory_blocks[i], 16);
|
||||
else
|
||||
Dbprintf("<missing block %d>", i);
|
||||
}
|
||||
Dbprintf("-----------------------------------------");
|
||||
|
||||
if (found_blocks < max_blocks) {
|
||||
Dbprintf("-----------------------------------------");
|
||||
Dbprintf("Blocks with unknown position:");
|
||||
Dbprintf("-----------------------------------------");
|
||||
for (i = 0; i < single_blocks_cnt; ++i)
|
||||
print_result("Block", single_blocks[i], 16);
|
||||
if (found_blocks < max_blocks) {
|
||||
Dbprintf("-----------------------------------------");
|
||||
Dbprintf("Blocks with unknown position:");
|
||||
Dbprintf("-----------------------------------------");
|
||||
for (i = 0; i < single_blocks_cnt; ++i)
|
||||
print_result("Block", single_blocks[i], 16);
|
||||
|
||||
Dbprintf("-----------------------------------------");
|
||||
}
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
Dbprintf("-----------------------------------------");
|
||||
}
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
}
|
||||
|
||||
static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
|
||||
uint32_t tab[1024] = {0}; // data times frame
|
||||
uint32_t u = 0;
|
||||
uint8_t parity = 0;
|
||||
bool comp = 0;
|
||||
uint32_t tab[1024] = {0}; // data times frame
|
||||
uint32_t u = 0;
|
||||
uint8_t parity = 0;
|
||||
bool comp = 0;
|
||||
|
||||
//BUILD OF THE DATA FRAME
|
||||
//alimentation of the tag (time for initializing)
|
||||
AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab);
|
||||
AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab);
|
||||
//password indication bit
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
//password (on 56 bits)
|
||||
AddBytePCF7931(pass[0], tab, l, p);
|
||||
AddBytePCF7931(pass[1], tab, l, p);
|
||||
AddBytePCF7931(pass[2], tab, l, p);
|
||||
AddBytePCF7931(pass[3], tab, l, p);
|
||||
AddBytePCF7931(pass[4], tab, l, p);
|
||||
AddBytePCF7931(pass[5], tab, l, p);
|
||||
AddBytePCF7931(pass[6], tab, l, p);
|
||||
//programming mode (0 or 1)
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
//BUILD OF THE DATA FRAME
|
||||
//alimentation of the tag (time for initializing)
|
||||
AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab);
|
||||
AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab);
|
||||
//password indication bit
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
//password (on 56 bits)
|
||||
AddBytePCF7931(pass[0], tab, l, p);
|
||||
AddBytePCF7931(pass[1], tab, l, p);
|
||||
AddBytePCF7931(pass[2], tab, l, p);
|
||||
AddBytePCF7931(pass[3], tab, l, p);
|
||||
AddBytePCF7931(pass[4], tab, l, p);
|
||||
AddBytePCF7931(pass[5], tab, l, p);
|
||||
AddBytePCF7931(pass[6], tab, l, p);
|
||||
//programming mode (0 or 1)
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
|
||||
//block adress on 6 bits
|
||||
for (u = 0; u < 6; ++u) {
|
||||
if (address&(1<<u)) { // bit 1
|
||||
++parity;
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
} else{ // bit 0
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
}
|
||||
}
|
||||
//block adress on 6 bits
|
||||
for (u = 0; u < 6; ++u) {
|
||||
if (address&(1<<u)) { // bit 1
|
||||
++parity;
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
} else{ // bit 0
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
}
|
||||
}
|
||||
|
||||
//byte address on 4 bits
|
||||
for (u = 0; u < 4; ++u)
|
||||
{
|
||||
if (byte&(1<<u)) { // bit 1
|
||||
parity++;
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
}
|
||||
else // bit 0
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
}
|
||||
//byte address on 4 bits
|
||||
for (u = 0; u < 4; ++u)
|
||||
{
|
||||
if (byte&(1<<u)) { // bit 1
|
||||
parity++;
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
}
|
||||
else // bit 0
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
}
|
||||
|
||||
//data on 8 bits
|
||||
for (u=0; u<8; u++)
|
||||
{
|
||||
if (data&(1<<u)) { // bit 1
|
||||
parity++;
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
}
|
||||
else //bit 0
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
}
|
||||
//data on 8 bits
|
||||
for (u=0; u<8; u++)
|
||||
{
|
||||
if (data&(1<<u)) { // bit 1
|
||||
parity++;
|
||||
AddBitPCF7931(1, tab, l, p);
|
||||
}
|
||||
else //bit 0
|
||||
AddBitPCF7931(0, tab, l, p);
|
||||
}
|
||||
|
||||
//parity bit
|
||||
if ((parity % 2) == 0)
|
||||
AddBitPCF7931(0, tab, l, p); //even parity
|
||||
else
|
||||
AddBitPCF7931(1, tab, l, p);//odd parity
|
||||
//parity bit
|
||||
if ((parity % 2) == 0)
|
||||
AddBitPCF7931(0, tab, l, p); //even parity
|
||||
else
|
||||
AddBitPCF7931(1, tab, l, p);//odd parity
|
||||
|
||||
//time access memory
|
||||
AddPatternPCF7931(5120+2680, 0, 0, tab);
|
||||
//time access memory
|
||||
AddPatternPCF7931(5120+2680, 0, 0, tab);
|
||||
|
||||
//conversion of the scale time
|
||||
for (u = 0; u < 500; ++u)
|
||||
tab[u]=(tab[u] * 3)/2;
|
||||
//conversion of the scale time
|
||||
for (u = 0; u < 500; ++u)
|
||||
tab[u]=(tab[u] * 3)/2;
|
||||
|
||||
//compensation of the counter reload
|
||||
while (!comp){
|
||||
comp = 1;
|
||||
for (u = 0; tab[u] != 0; ++u)
|
||||
if(tab[u] > 0xFFFF){
|
||||
tab[u] -= 0xFFFF;
|
||||
comp = 0;
|
||||
}
|
||||
}
|
||||
//compensation of the counter reload
|
||||
while (!comp){
|
||||
comp = 1;
|
||||
for (u = 0; tab[u] != 0; ++u)
|
||||
if(tab[u] > 0xFFFF){
|
||||
tab[u] -= 0xFFFF;
|
||||
comp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SendCmdPCF7931(tab);
|
||||
SendCmdPCF7931(tab);
|
||||
}
|
||||
|
||||
/* Write on a byte of a PCF7931 tag
|
||||
|
@ -391,16 +391,16 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3
|
|||
@param data : data to write
|
||||
*/
|
||||
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
|
||||
Dbprintf("Initialization delay : %d us", init_delay);
|
||||
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
|
||||
Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7);
|
||||
Dbprintf("Block address : %02x", address);
|
||||
Dbprintf("Byte address : %02x", byte);
|
||||
Dbprintf("Data : %02x", data);
|
||||
Dbprintf("Initialization delay : %d us", init_delay);
|
||||
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
|
||||
Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7);
|
||||
Dbprintf("Block address : %02x", address);
|
||||
Dbprintf("Byte address : %02x", byte);
|
||||
Dbprintf("Data : %02x", data);
|
||||
|
||||
uint8_t password[7] = {pass1, pass2, pass3, pass4, pass5, pass6, pass7};
|
||||
uint8_t password[7] = {pass1, pass2, pass3, pass4, pass5, pass6, pass7};
|
||||
|
||||
RealWritePCF7931 (password, init_delay, l, p, address, byte, data);
|
||||
RealWritePCF7931 (password, init_delay, l, p, address, byte, data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -409,52 +409,52 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui
|
|||
*/
|
||||
|
||||
void SendCmdPCF7931(uint32_t * tab){
|
||||
uint16_t u=0, tempo=0;
|
||||
uint16_t u=0, tempo=0;
|
||||
|
||||
Dbprintf("Sending data frame...");
|
||||
Dbprintf("Sending data frame...");
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU );
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU );
|
||||
|
||||
LED_A_ON();
|
||||
LED_A_ON();
|
||||
|
||||
// steal this pin from the SSP and use it to control the modulation
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
// steal this pin from the SSP and use it to control the modulation
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
|
||||
//initialization of the timer
|
||||
AT91C_BASE_PMC->PMC_PCER |= (0x1 << AT91C_ID_TC0);
|
||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
|
||||
AT91C_BASE_TCB->TCB_BCR = 1;
|
||||
//initialization of the timer
|
||||
AT91C_BASE_PMC->PMC_PCER |= (0x1 << AT91C_ID_TC0);
|
||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
|
||||
AT91C_BASE_TCB->TCB_BCR = 1;
|
||||
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
for( u = 0; tab[u] != 0; u += 3){
|
||||
// modulate antenna
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
while (tempo != tab[u])
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
for( u = 0; tab[u] != 0; u += 3){
|
||||
// modulate antenna
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
while (tempo != tab[u])
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
|
||||
// stop modulating antenna
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
while (tempo != tab[u+1])
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
// stop modulating antenna
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
while (tempo != tab[u+1])
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
|
||||
// modulate antenna
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
while (tempo != tab[u+2])
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
}
|
||||
// modulate antenna
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
while (tempo != tab[u+2])
|
||||
tempo = AT91C_BASE_TC0->TC_CV;
|
||||
}
|
||||
|
||||
LED_A_OFF();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
LED_A_OFF();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
LED(0xFFFF, 1000);
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
LED(0xFFFF, 1000);
|
||||
}
|
||||
|
||||
|
||||
|
@ -465,16 +465,16 @@ void SendCmdPCF7931(uint32_t * tab){
|
|||
* @param p : offset on low pulse positioning
|
||||
*/
|
||||
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){
|
||||
uint32_t u;
|
||||
for (u = 0; u < 8; ++u) {
|
||||
if (byte & (1 << u)) { //bit is 1
|
||||
if( AddBitPCF7931(1, tab, l, p)==1) return 1;
|
||||
} else { //bit is 0
|
||||
if (AddBitPCF7931(0, tab, l, p)==1) return 1;
|
||||
}
|
||||
}
|
||||
uint32_t u;
|
||||
for (u = 0; u < 8; ++u) {
|
||||
if (byte & (1 << u)) { //bit is 1
|
||||
if( AddBitPCF7931(1, tab, l, p)==1) return 1;
|
||||
} else { //bit is 0
|
||||
if (AddBitPCF7931(0, tab, l, p)==1) return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Add a bits for building the data frame of PCF7931 tags
|
||||
|
@ -484,32 +484,32 @@ bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){
|
|||
* @param p : offset on low pulse positioning
|
||||
*/
|
||||
bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){
|
||||
uint8_t u = 0;
|
||||
uint8_t u = 0;
|
||||
|
||||
//we put the cursor at the last value of the array
|
||||
for ( u = 0; tab[u] != 0; u += 3 ) { }
|
||||
//we put the cursor at the last value of the array
|
||||
for ( u = 0; tab[u] != 0; u += 3 ) { }
|
||||
|
||||
if ( b == 1 ) { //add a bit 1
|
||||
if ( u == 0 )
|
||||
tab[u] = 34 * T0_PCF + p;
|
||||
else
|
||||
tab[u] = 34 * T0_PCF + tab[u-1] + p;
|
||||
if ( b == 1 ) { //add a bit 1
|
||||
if ( u == 0 )
|
||||
tab[u] = 34 * T0_PCF + p;
|
||||
else
|
||||
tab[u] = 34 * T0_PCF + tab[u-1] + p;
|
||||
|
||||
tab[u+1] = 6 * T0_PCF + tab[u] + l;
|
||||
tab[u+2] = 88 * T0_PCF + tab[u+1] - l - p;
|
||||
return 0;
|
||||
} else { //add a bit 0
|
||||
tab[u+1] = 6 * T0_PCF + tab[u] + l;
|
||||
tab[u+2] = 88 * T0_PCF + tab[u+1] - l - p;
|
||||
return 0;
|
||||
} else { //add a bit 0
|
||||
|
||||
if ( u == 0 )
|
||||
tab[u] = 98 * T0_PCF + p;
|
||||
else
|
||||
tab[u] = 98 * T0_PCF + tab[u-1] + p;
|
||||
if ( u == 0 )
|
||||
tab[u] = 98 * T0_PCF + p;
|
||||
else
|
||||
tab[u] = 98 * T0_PCF + tab[u-1] + p;
|
||||
|
||||
tab[u+1] = 6 * T0_PCF + tab[u] + l;
|
||||
tab[u+2] = 24 * T0_PCF + tab[u+1] - l - p;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
tab[u+1] = 6 * T0_PCF + tab[u] + l;
|
||||
tab[u+2] = 24 * T0_PCF + tab[u+1] - l - p;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add a custom pattern in the data frame
|
||||
|
@ -519,12 +519,12 @@ bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){
|
|||
* @param tab : array of the data frame
|
||||
*/
|
||||
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab){
|
||||
uint32_t u = 0;
|
||||
for(u = 0; tab[u] != 0; u += 3){} //we put the cursor at the last value of the array
|
||||
uint32_t u = 0;
|
||||
for(u = 0; tab[u] != 0; u += 3){} //we put the cursor at the last value of the array
|
||||
|
||||
tab[u] = (u == 0) ? a : a + tab[u-1];
|
||||
tab[u+1] = b + tab[u];
|
||||
tab[u+2] = c + tab[u+1];
|
||||
tab[u] = (u == 0) ? a : a + tab[u-1];
|
||||
tab[u+1] = b + tab[u];
|
||||
tab[u+2] = c + tab[u+1];
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
630
armsrc/printf.c
630
armsrc/printf.c
|
@ -1,6 +1,6 @@
|
|||
/*-
|
||||
* Copyright (c) 1986, 1988, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
|
@ -31,7 +31,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
|
||||
* @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
|
||||
*/
|
||||
#include "printf.h"
|
||||
|
||||
|
@ -50,7 +50,7 @@ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|||
#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))
|
||||
|
||||
/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
|
||||
#define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
|
||||
#define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
|
||||
|
||||
/*
|
||||
* Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
|
||||
|
@ -61,17 +61,17 @@ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|||
static char *
|
||||
ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
|
||||
{
|
||||
char *p, c;
|
||||
char *p, c;
|
||||
|
||||
p = nbuf;
|
||||
*p = '\0';
|
||||
do {
|
||||
c = hex2ascii(num % base);
|
||||
*++p = upper ? toupper(c) : c;
|
||||
} while (num /= base);
|
||||
if (lenp)
|
||||
*lenp = p - nbuf;
|
||||
return (p);
|
||||
p = nbuf;
|
||||
*p = '\0';
|
||||
do {
|
||||
c = hex2ascii(num % base);
|
||||
*++p = upper ? toupper(c) : c;
|
||||
} while (num /= base);
|
||||
if (lenp)
|
||||
*lenp = p - nbuf;
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -82,7 +82,7 @@ ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
|
|||
* The format %b is supported to decode error registers.
|
||||
* Its usage is:
|
||||
*
|
||||
* printf("reg=%b\n", regval, "*");
|
||||
* printf("reg=%b\n", regval, "*");
|
||||
*
|
||||
* where is the output base expressed as a control character, e.g.
|
||||
* \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
|
||||
|
@ -90,340 +90,340 @@ ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
|
|||
* the next characters (up to a control character, i.e. a character <= 32),
|
||||
* give the name of the register. Thus:
|
||||
*
|
||||
* kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
|
||||
* kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
|
||||
*
|
||||
* would produce output:
|
||||
*
|
||||
* reg=3
|
||||
* reg=3
|
||||
*
|
||||
* XXX: %D -- Hexdump, takes pointer and separator string:
|
||||
* ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
|
||||
* ("%*D", len, ptr, " " -> XX XX XX XX ...
|
||||
* ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
|
||||
* ("%*D", len, ptr, " " -> XX XX XX XX ...
|
||||
*/
|
||||
int
|
||||
kvsprintf(char const *fmt, void *arg, int radix, va_list ap)
|
||||
{
|
||||
#define PCHAR(c) {int cc=(c); *d++ = cc; retval++; }
|
||||
char nbuf[MAXNBUF];
|
||||
char *d;
|
||||
const char *p, *percent, *q;
|
||||
u_char *up;
|
||||
int ch, n;
|
||||
uintmax_t num;
|
||||
int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
|
||||
int cflag, hflag, jflag, tflag, zflag;
|
||||
int dwidth, upper;
|
||||
char padc;
|
||||
int stop = 0, retval = 0;
|
||||
char nbuf[MAXNBUF];
|
||||
char *d;
|
||||
const char *p, *percent, *q;
|
||||
u_char *up;
|
||||
int ch, n;
|
||||
uintmax_t num;
|
||||
int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
|
||||
int cflag, hflag, jflag, tflag, zflag;
|
||||
int dwidth, upper;
|
||||
char padc;
|
||||
int stop = 0, retval = 0;
|
||||
|
||||
num = 0;
|
||||
d = (char *) arg;
|
||||
num = 0;
|
||||
d = (char *) arg;
|
||||
|
||||
if (fmt == NULL)
|
||||
fmt = "(fmt null)\n";
|
||||
if (fmt == NULL)
|
||||
fmt = "(fmt null)\n";
|
||||
|
||||
if (radix < 2 || radix > 36)
|
||||
radix = 10;
|
||||
if (radix < 2 || radix > 36)
|
||||
radix = 10;
|
||||
|
||||
for (;;) {
|
||||
padc = ' ';
|
||||
width = 0;
|
||||
while ((ch = (u_char)*fmt++) != '%' || stop) {
|
||||
PCHAR(ch);
|
||||
if (ch == '\0')
|
||||
return (retval);
|
||||
}
|
||||
percent = fmt - 1;
|
||||
qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
|
||||
sign = 0; dot = 0; dwidth = 0; upper = 0;
|
||||
cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
|
||||
reswitch: switch (ch = (u_char)*fmt++) {
|
||||
case '.':
|
||||
dot = 1;
|
||||
goto reswitch;
|
||||
case '#':
|
||||
sharpflag = 1;
|
||||
goto reswitch;
|
||||
case '+':
|
||||
sign = 1;
|
||||
goto reswitch;
|
||||
case '-':
|
||||
ladjust = 1;
|
||||
goto reswitch;
|
||||
case '%':
|
||||
PCHAR(ch);
|
||||
break;
|
||||
case '*':
|
||||
if (!dot) {
|
||||
width = va_arg(ap, int);
|
||||
if (width < 0) {
|
||||
ladjust = !ladjust;
|
||||
width = -width;
|
||||
}
|
||||
} else {
|
||||
dwidth = va_arg(ap, int);
|
||||
}
|
||||
goto reswitch;
|
||||
case '0':
|
||||
if (!dot) {
|
||||
padc = '0';
|
||||
goto reswitch;
|
||||
}
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
for (n = 0;; ++fmt) {
|
||||
n = n * 10 + ch - '0';
|
||||
ch = *fmt;
|
||||
if (ch < '0' || ch > '9')
|
||||
break;
|
||||
}
|
||||
if (dot)
|
||||
dwidth = n;
|
||||
else
|
||||
width = n;
|
||||
goto reswitch;
|
||||
case 'b':
|
||||
num = (u_int)va_arg(ap, int);
|
||||
p = va_arg(ap, char *);
|
||||
for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
|
||||
PCHAR(*q--);
|
||||
for (;;) {
|
||||
padc = ' ';
|
||||
width = 0;
|
||||
while ((ch = (u_char)*fmt++) != '%' || stop) {
|
||||
PCHAR(ch);
|
||||
if (ch == '\0')
|
||||
return (retval);
|
||||
}
|
||||
percent = fmt - 1;
|
||||
qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
|
||||
sign = 0; dot = 0; dwidth = 0; upper = 0;
|
||||
cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
|
||||
reswitch: switch (ch = (u_char)*fmt++) {
|
||||
case '.':
|
||||
dot = 1;
|
||||
goto reswitch;
|
||||
case '#':
|
||||
sharpflag = 1;
|
||||
goto reswitch;
|
||||
case '+':
|
||||
sign = 1;
|
||||
goto reswitch;
|
||||
case '-':
|
||||
ladjust = 1;
|
||||
goto reswitch;
|
||||
case '%':
|
||||
PCHAR(ch);
|
||||
break;
|
||||
case '*':
|
||||
if (!dot) {
|
||||
width = va_arg(ap, int);
|
||||
if (width < 0) {
|
||||
ladjust = !ladjust;
|
||||
width = -width;
|
||||
}
|
||||
} else {
|
||||
dwidth = va_arg(ap, int);
|
||||
}
|
||||
goto reswitch;
|
||||
case '0':
|
||||
if (!dot) {
|
||||
padc = '0';
|
||||
goto reswitch;
|
||||
}
|
||||
case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
for (n = 0;; ++fmt) {
|
||||
n = n * 10 + ch - '0';
|
||||
ch = *fmt;
|
||||
if (ch < '0' || ch > '9')
|
||||
break;
|
||||
}
|
||||
if (dot)
|
||||
dwidth = n;
|
||||
else
|
||||
width = n;
|
||||
goto reswitch;
|
||||
case 'b':
|
||||
num = (u_int)va_arg(ap, int);
|
||||
p = va_arg(ap, char *);
|
||||
for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
|
||||
PCHAR(*q--);
|
||||
|
||||
if (num == 0)
|
||||
break;
|
||||
if (num == 0)
|
||||
break;
|
||||
|
||||
for (tmp = 0; *p;) {
|
||||
n = *p++;
|
||||
if (num & (1 << (n - 1))) {
|
||||
PCHAR(tmp ? ',' : '<');
|
||||
for (; (n = *p) > ' '; ++p)
|
||||
PCHAR(n);
|
||||
tmp = 1;
|
||||
} else
|
||||
for (; *p > ' '; ++p)
|
||||
continue;
|
||||
}
|
||||
if (tmp)
|
||||
PCHAR('>');
|
||||
break;
|
||||
case 'c':
|
||||
PCHAR(va_arg(ap, int));
|
||||
break;
|
||||
case 'D':
|
||||
up = va_arg(ap, u_char *);
|
||||
p = va_arg(ap, char *);
|
||||
if (!width)
|
||||
width = 16;
|
||||
while(width--) {
|
||||
PCHAR(hex2ascii(*up >> 4));
|
||||
PCHAR(hex2ascii(*up & 0x0f));
|
||||
up++;
|
||||
if (width)
|
||||
for (q=p;*q;q++)
|
||||
PCHAR(*q);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
base = 10;
|
||||
sign = 1;
|
||||
goto handle_sign;
|
||||
case 'h':
|
||||
if (hflag) {
|
||||
hflag = 0;
|
||||
cflag = 1;
|
||||
} else
|
||||
hflag = 1;
|
||||
goto reswitch;
|
||||
case 'j':
|
||||
jflag = 1;
|
||||
goto reswitch;
|
||||
case 'l':
|
||||
if (lflag) {
|
||||
lflag = 0;
|
||||
qflag = 1;
|
||||
} else
|
||||
lflag = 1;
|
||||
goto reswitch;
|
||||
case 'n':
|
||||
if (jflag)
|
||||
*(va_arg(ap, intmax_t *)) = retval;
|
||||
else if (qflag)
|
||||
*(va_arg(ap, quad_t *)) = retval;
|
||||
else if (lflag)
|
||||
*(va_arg(ap, long *)) = retval;
|
||||
else if (zflag)
|
||||
*(va_arg(ap, size_t *)) = retval;
|
||||
else if (hflag)
|
||||
*(va_arg(ap, short *)) = retval;
|
||||
else if (cflag)
|
||||
*(va_arg(ap, char *)) = retval;
|
||||
else
|
||||
*(va_arg(ap, int *)) = retval;
|
||||
break;
|
||||
case 'o':
|
||||
base = 8;
|
||||
goto handle_nosign;
|
||||
case 'p':
|
||||
base = 16;
|
||||
sharpflag = (width == 0);
|
||||
sign = 0;
|
||||
num = (uintptr_t)va_arg(ap, void *);
|
||||
goto number;
|
||||
case 'q':
|
||||
qflag = 1;
|
||||
goto reswitch;
|
||||
case 'r':
|
||||
base = radix;
|
||||
if (sign)
|
||||
goto handle_sign;
|
||||
goto handle_nosign;
|
||||
case 's':
|
||||
p = va_arg(ap, char *);
|
||||
if (p == NULL)
|
||||
p = "(null)";
|
||||
if (!dot)
|
||||
n = strlen (p);
|
||||
else
|
||||
for (n = 0; n < dwidth && p[n]; n++)
|
||||
continue;
|
||||
for (tmp = 0; *p;) {
|
||||
n = *p++;
|
||||
if (num & (1 << (n - 1))) {
|
||||
PCHAR(tmp ? ',' : '<');
|
||||
for (; (n = *p) > ' '; ++p)
|
||||
PCHAR(n);
|
||||
tmp = 1;
|
||||
} else
|
||||
for (; *p > ' '; ++p)
|
||||
continue;
|
||||
}
|
||||
if (tmp)
|
||||
PCHAR('>');
|
||||
break;
|
||||
case 'c':
|
||||
PCHAR(va_arg(ap, int));
|
||||
break;
|
||||
case 'D':
|
||||
up = va_arg(ap, u_char *);
|
||||
p = va_arg(ap, char *);
|
||||
if (!width)
|
||||
width = 16;
|
||||
while(width--) {
|
||||
PCHAR(hex2ascii(*up >> 4));
|
||||
PCHAR(hex2ascii(*up & 0x0f));
|
||||
up++;
|
||||
if (width)
|
||||
for (q=p;*q;q++)
|
||||
PCHAR(*q);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
base = 10;
|
||||
sign = 1;
|
||||
goto handle_sign;
|
||||
case 'h':
|
||||
if (hflag) {
|
||||
hflag = 0;
|
||||
cflag = 1;
|
||||
} else
|
||||
hflag = 1;
|
||||
goto reswitch;
|
||||
case 'j':
|
||||
jflag = 1;
|
||||
goto reswitch;
|
||||
case 'l':
|
||||
if (lflag) {
|
||||
lflag = 0;
|
||||
qflag = 1;
|
||||
} else
|
||||
lflag = 1;
|
||||
goto reswitch;
|
||||
case 'n':
|
||||
if (jflag)
|
||||
*(va_arg(ap, intmax_t *)) = retval;
|
||||
else if (qflag)
|
||||
*(va_arg(ap, quad_t *)) = retval;
|
||||
else if (lflag)
|
||||
*(va_arg(ap, long *)) = retval;
|
||||
else if (zflag)
|
||||
*(va_arg(ap, size_t *)) = retval;
|
||||
else if (hflag)
|
||||
*(va_arg(ap, short *)) = retval;
|
||||
else if (cflag)
|
||||
*(va_arg(ap, char *)) = retval;
|
||||
else
|
||||
*(va_arg(ap, int *)) = retval;
|
||||
break;
|
||||
case 'o':
|
||||
base = 8;
|
||||
goto handle_nosign;
|
||||
case 'p':
|
||||
base = 16;
|
||||
sharpflag = (width == 0);
|
||||
sign = 0;
|
||||
num = (uintptr_t)va_arg(ap, void *);
|
||||
goto number;
|
||||
case 'q':
|
||||
qflag = 1;
|
||||
goto reswitch;
|
||||
case 'r':
|
||||
base = radix;
|
||||
if (sign)
|
||||
goto handle_sign;
|
||||
goto handle_nosign;
|
||||
case 's':
|
||||
p = va_arg(ap, char *);
|
||||
if (p == NULL)
|
||||
p = "(null)";
|
||||
if (!dot)
|
||||
n = strlen (p);
|
||||
else
|
||||
for (n = 0; n < dwidth && p[n]; n++)
|
||||
continue;
|
||||
|
||||
width -= n;
|
||||
width -= n;
|
||||
|
||||
if (!ladjust && width > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
while (n--)
|
||||
PCHAR(*p++);
|
||||
if (ladjust && width > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
break;
|
||||
case 't':
|
||||
tflag = 1;
|
||||
goto reswitch;
|
||||
case 'u':
|
||||
base = 10;
|
||||
goto handle_nosign;
|
||||
case 'X':
|
||||
upper = 1;
|
||||
case 'x':
|
||||
base = 16;
|
||||
goto handle_nosign;
|
||||
case 'y':
|
||||
base = 16;
|
||||
sign = 1;
|
||||
goto handle_sign;
|
||||
case 'z':
|
||||
zflag = 1;
|
||||
goto reswitch;
|
||||
if (!ladjust && width > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
while (n--)
|
||||
PCHAR(*p++);
|
||||
if (ladjust && width > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
break;
|
||||
case 't':
|
||||
tflag = 1;
|
||||
goto reswitch;
|
||||
case 'u':
|
||||
base = 10;
|
||||
goto handle_nosign;
|
||||
case 'X':
|
||||
upper = 1;
|
||||
case 'x':
|
||||
base = 16;
|
||||
goto handle_nosign;
|
||||
case 'y':
|
||||
base = 16;
|
||||
sign = 1;
|
||||
goto handle_sign;
|
||||
case 'z':
|
||||
zflag = 1;
|
||||
goto reswitch;
|
||||
handle_nosign:
|
||||
sign = 0;
|
||||
if (jflag)
|
||||
num = va_arg(ap, uintmax_t);
|
||||
else if (qflag)
|
||||
num = va_arg(ap, u_quad_t);
|
||||
else if (tflag)
|
||||
num = va_arg(ap, ptrdiff_t);
|
||||
else if (lflag)
|
||||
num = va_arg(ap, u_long);
|
||||
else if (zflag)
|
||||
num = va_arg(ap, size_t);
|
||||
else if (hflag)
|
||||
num = (u_short)va_arg(ap, int);
|
||||
else if (cflag)
|
||||
num = (u_char)va_arg(ap, int);
|
||||
else
|
||||
num = va_arg(ap, u_int);
|
||||
goto number;
|
||||
sign = 0;
|
||||
if (jflag)
|
||||
num = va_arg(ap, uintmax_t);
|
||||
else if (qflag)
|
||||
num = va_arg(ap, u_quad_t);
|
||||
else if (tflag)
|
||||
num = va_arg(ap, ptrdiff_t);
|
||||
else if (lflag)
|
||||
num = va_arg(ap, u_long);
|
||||
else if (zflag)
|
||||
num = va_arg(ap, size_t);
|
||||
else if (hflag)
|
||||
num = (u_short)va_arg(ap, int);
|
||||
else if (cflag)
|
||||
num = (u_char)va_arg(ap, int);
|
||||
else
|
||||
num = va_arg(ap, u_int);
|
||||
goto number;
|
||||
handle_sign:
|
||||
if (jflag)
|
||||
num = va_arg(ap, intmax_t);
|
||||
else if (qflag)
|
||||
num = va_arg(ap, quad_t);
|
||||
else if (tflag)
|
||||
num = va_arg(ap, ptrdiff_t);
|
||||
else if (lflag)
|
||||
num = va_arg(ap, long);
|
||||
else if (zflag)
|
||||
num = va_arg(ap, ssize_t);
|
||||
else if (hflag)
|
||||
num = (short)va_arg(ap, int);
|
||||
else if (cflag)
|
||||
num = (char)va_arg(ap, int);
|
||||
else
|
||||
num = va_arg(ap, int);
|
||||
if (jflag)
|
||||
num = va_arg(ap, intmax_t);
|
||||
else if (qflag)
|
||||
num = va_arg(ap, quad_t);
|
||||
else if (tflag)
|
||||
num = va_arg(ap, ptrdiff_t);
|
||||
else if (lflag)
|
||||
num = va_arg(ap, long);
|
||||
else if (zflag)
|
||||
num = va_arg(ap, ssize_t);
|
||||
else if (hflag)
|
||||
num = (short)va_arg(ap, int);
|
||||
else if (cflag)
|
||||
num = (char)va_arg(ap, int);
|
||||
else
|
||||
num = va_arg(ap, int);
|
||||
number:
|
||||
if (sign && (intmax_t)num < 0) {
|
||||
neg = 1;
|
||||
num = -(intmax_t)num;
|
||||
}
|
||||
p = ksprintn(nbuf, num, base, &tmp, upper);
|
||||
if (sharpflag && num != 0) {
|
||||
if (base == 8)
|
||||
tmp++;
|
||||
else if (base == 16)
|
||||
tmp += 2;
|
||||
}
|
||||
if (neg)
|
||||
tmp++;
|
||||
if (sign && (intmax_t)num < 0) {
|
||||
neg = 1;
|
||||
num = -(intmax_t)num;
|
||||
}
|
||||
p = ksprintn(nbuf, num, base, &tmp, upper);
|
||||
if (sharpflag && num != 0) {
|
||||
if (base == 8)
|
||||
tmp++;
|
||||
else if (base == 16)
|
||||
tmp += 2;
|
||||
}
|
||||
if (neg)
|
||||
tmp++;
|
||||
|
||||
if (!ladjust && padc != '0' && width
|
||||
&& (width -= tmp) > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
if (neg)
|
||||
PCHAR('-');
|
||||
if (sharpflag && num != 0) {
|
||||
if (base == 8) {
|
||||
PCHAR('0');
|
||||
} else if (base == 16) {
|
||||
PCHAR('0');
|
||||
PCHAR('x');
|
||||
}
|
||||
}
|
||||
if (!ladjust && width && (width -= tmp) > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
if (!ladjust && padc != '0' && width
|
||||
&& (width -= tmp) > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
if (neg)
|
||||
PCHAR('-');
|
||||
if (sharpflag && num != 0) {
|
||||
if (base == 8) {
|
||||
PCHAR('0');
|
||||
} else if (base == 16) {
|
||||
PCHAR('0');
|
||||
PCHAR('x');
|
||||
}
|
||||
}
|
||||
if (!ladjust && width && (width -= tmp) > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
|
||||
while (*p)
|
||||
PCHAR(*p--);
|
||||
while (*p)
|
||||
PCHAR(*p--);
|
||||
|
||||
if (ladjust && width && (width -= tmp) > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
if (ladjust && width && (width -= tmp) > 0)
|
||||
while (width--)
|
||||
PCHAR(padc);
|
||||
|
||||
break;
|
||||
default:
|
||||
while (percent < fmt)
|
||||
PCHAR(*percent++);
|
||||
/*
|
||||
* Since we ignore an formatting argument it is no
|
||||
* longer safe to obey the remaining formatting
|
||||
* arguments as the arguments will no longer match
|
||||
* the format specs.
|
||||
*/
|
||||
stop = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PCHAR(0);
|
||||
return retval;
|
||||
break;
|
||||
default:
|
||||
while (percent < fmt)
|
||||
PCHAR(*percent++);
|
||||
/*
|
||||
* Since we ignore an formatting argument it is no
|
||||
* longer safe to obey the remaining formatting
|
||||
* arguments as the arguments will no longer match
|
||||
* the format specs.
|
||||
*/
|
||||
stop = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PCHAR(0);
|
||||
return retval;
|
||||
#undef PCHAR
|
||||
}
|
||||
|
||||
int vsprintf(char *dest, const char *fmt, va_list ap)
|
||||
{
|
||||
return kvsprintf(fmt, dest, 10, ap);
|
||||
return kvsprintf(fmt, dest, 10, ap);
|
||||
}
|
||||
|
||||
int
|
||||
sprintf(char *dest, const char *fmt, ...)
|
||||
{
|
||||
/* http://www.pagetable.com/?p=298 */
|
||||
int retval;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
retval = kvsprintf(fmt, dest, 10, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
/* http://www.pagetable.com/?p=298 */
|
||||
int retval;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
retval = kvsprintf(fmt, dest, 10, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -23,62 +23,62 @@ extern char __data_src_start__, __data_start__, __data_end__, __bss_start__, __b
|
|||
|
||||
static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
uint8_t *allocated_memory;
|
||||
uint8_t *allocated_memory;
|
||||
|
||||
allocated_memory = next_free_memory;
|
||||
next_free_memory += items*size;
|
||||
return allocated_memory;
|
||||
allocated_memory = next_free_memory;
|
||||
next_free_memory += items*size;
|
||||
return allocated_memory;
|
||||
}
|
||||
|
||||
static void inflate_free(voidpf opaque, voidpf address)
|
||||
{
|
||||
// nothing to do
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
static void uncompress_data_section(void)
|
||||
{
|
||||
z_stream data_section;
|
||||
z_stream data_section;
|
||||
|
||||
next_free_memory = BigBuf_get_addr();
|
||||
next_free_memory = BigBuf_get_addr();
|
||||
|
||||
// initialize zstream structure
|
||||
data_section.next_in = (uint8_t *) &__data_src_start__;
|
||||
data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter.
|
||||
data_section.next_out = (uint8_t *) &__data_start__;
|
||||
data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
|
||||
data_section.zalloc = &inflate_malloc;
|
||||
data_section.zfree = &inflate_free;
|
||||
data_section.opaque = NULL;
|
||||
// initialize zstream structure
|
||||
data_section.next_in = (uint8_t *) &__data_src_start__;
|
||||
data_section.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter.
|
||||
data_section.next_out = (uint8_t *) &__data_start__;
|
||||
data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
|
||||
data_section.zalloc = &inflate_malloc;
|
||||
data_section.zfree = &inflate_free;
|
||||
data_section.opaque = NULL;
|
||||
|
||||
// initialize zlib for inflate
|
||||
inflateInit2(&data_section, 15);
|
||||
// initialize zlib for inflate
|
||||
inflateInit2(&data_section, 15);
|
||||
|
||||
// uncompress data segment to RAM
|
||||
inflate(&data_section, Z_FINISH);
|
||||
// uncompress data segment to RAM
|
||||
inflate(&data_section, Z_FINISH);
|
||||
|
||||
// save the size of the compressed data section
|
||||
common_area.arg1 = data_section.total_in;
|
||||
// save the size of the compressed data section
|
||||
common_area.arg1 = data_section.total_in;
|
||||
}
|
||||
|
||||
void __attribute__((section(".startos"))) Vector(void)
|
||||
{
|
||||
/* Stack should have been set up by the bootloader */
|
||||
// char *src;
|
||||
char *dst, *end;
|
||||
/* Stack should have been set up by the bootloader */
|
||||
// char *src;
|
||||
char *dst, *end;
|
||||
|
||||
uncompress_data_section();
|
||||
uncompress_data_section();
|
||||
|
||||
/* Set up (that is: clear) BSS. */
|
||||
dst = &__bss_start__;
|
||||
end = &__bss_end__;
|
||||
while(dst < end) *dst++ = 0;
|
||||
/* Set up (that is: clear) BSS. */
|
||||
dst = &__bss_start__;
|
||||
end = &__bss_end__;
|
||||
while(dst < end) *dst++ = 0;
|
||||
|
||||
// Set up data segment: Copy from flash to ram
|
||||
// src = &__data_src_start__;
|
||||
// dst = &__data_start__;
|
||||
// end = &__data_end__;
|
||||
// while(dst < end) *dst++ = *src++;
|
||||
// Set up data segment: Copy from flash to ram
|
||||
// src = &__data_src_start__;
|
||||
// dst = &__data_start__;
|
||||
// end = &__data_end__;
|
||||
// while(dst < end) *dst++ = *src++;
|
||||
|
||||
AppMain();
|
||||
AppMain();
|
||||
}
|
||||
#endif
|
|
@ -11,39 +11,39 @@
|
|||
|
||||
void *memcpy(void *dest, const void *src, int len)
|
||||
{
|
||||
uint8_t *d = dest;
|
||||
const uint8_t *s = src;
|
||||
while((len--) > 0) {
|
||||
*d = *s;
|
||||
d++;
|
||||
s++;
|
||||
}
|
||||
return dest;
|
||||
uint8_t *d = dest;
|
||||
const uint8_t *s = src;
|
||||
while((len--) > 0) {
|
||||
*d = *s;
|
||||
d++;
|
||||
s++;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memset(void *dest, int c, int len)
|
||||
{
|
||||
uint8_t *d = dest;
|
||||
while((len--) > 0) {
|
||||
*d = c;
|
||||
d++;
|
||||
}
|
||||
return dest;
|
||||
uint8_t *d = dest;
|
||||
while((len--) > 0) {
|
||||
*d = c;
|
||||
d++;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memcmp(const void *av, const void *bv, int len)
|
||||
{
|
||||
const uint8_t *a = av;
|
||||
const uint8_t *b = bv;
|
||||
const uint8_t *a = av;
|
||||
const uint8_t *b = bv;
|
||||
|
||||
while((len--) > 0) {
|
||||
if(*a != *b) {
|
||||
return *a - *b;
|
||||
}
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
return 0;
|
||||
while((len--) > 0) {
|
||||
if(*a != *b) {
|
||||
return *a - *b;
|
||||
}
|
||||
a++;
|
||||
b++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void memxor(uint8_t * dest, uint8_t * src, size_t len) {
|
||||
|
@ -53,36 +53,36 @@ void memxor(uint8_t * dest, uint8_t * src, size_t len) {
|
|||
|
||||
int strlen(const char *str)
|
||||
{
|
||||
int l = 0;
|
||||
while(*str) {
|
||||
l++;
|
||||
str++;
|
||||
}
|
||||
return l;
|
||||
int l = 0;
|
||||
while(*str) {
|
||||
l++;
|
||||
str++;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
char* strncat(char *dest, const char *src, unsigned int n)
|
||||
{
|
||||
unsigned int dest_len = strlen(dest);
|
||||
unsigned int i;
|
||||
unsigned int dest_len = strlen(dest);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0 ; i < n && src[i] != '\0' ; i++)
|
||||
dest[dest_len + i] = src[i];
|
||||
dest[dest_len + i] = '\0';
|
||||
for (i = 0 ; i < n && src[i] != '\0' ; i++)
|
||||
dest[dest_len + i] = src[i];
|
||||
dest[dest_len + i] = '\0';
|
||||
|
||||
return dest;
|
||||
return dest;
|
||||
}
|
||||
|
||||
char* strcat(char *dest, const char *src)
|
||||
{
|
||||
unsigned int dest_len = strlen(dest);
|
||||
unsigned int i;
|
||||
unsigned int dest_len = strlen(dest);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0 ; src[i] != '\0' ; i++)
|
||||
dest[dest_len + i] = src[i];
|
||||
dest[dest_len + i] = '\0';
|
||||
for (i = 0 ; src[i] != '\0' ; i++)
|
||||
dest[dest_len + i] = src[i];
|
||||
dest[dest_len + i] = '\0';
|
||||
|
||||
return dest;
|
||||
return dest;
|
||||
}
|
||||
////////////////////////////////////////// code to do 'itoa'
|
||||
|
||||
|
|
280
armsrc/ticks.c
280
armsrc/ticks.c
|
@ -12,160 +12,160 @@
|
|||
// attempt at high resolution microsecond timer
|
||||
// beware: timer counts in 21.3uS increments (1024/48Mhz)
|
||||
void SpinDelayUs(int us) {
|
||||
int ticks = (48 * us) >> 10;
|
||||
int ticks = (48 * us) >> 10;
|
||||
|
||||
// Borrow a PWM unit for my real-time clock
|
||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||
// Borrow a PWM unit for my real-time clock
|
||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||
|
||||
// 48 MHz / 1024 gives 46.875 kHz
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); // Channel Mode Register
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period Register
|
||||
// 48 MHz / 1024 gives 46.875 kHz
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); // Channel Mode Register
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period Register
|
||||
|
||||
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
|
||||
for(;;) {
|
||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
if (now == (uint16_t)(start + ticks))
|
||||
return;
|
||||
for(;;) {
|
||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
if (now == (uint16_t)(start + ticks))
|
||||
return;
|
||||
|
||||
WDT_HIT();
|
||||
}
|
||||
WDT_HIT();
|
||||
}
|
||||
}
|
||||
|
||||
void SpinDelay(int ms) {
|
||||
// convert to uS and call microsecond delay function
|
||||
SpinDelayUs(ms*1000);
|
||||
SpinDelayUs(ms*1000);
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// timer lib
|
||||
// -------------------------------------------------------------------------
|
||||
// test procedure:
|
||||
//
|
||||
// ti = GetTickCount();
|
||||
// SpinDelay(1000);
|
||||
// ti = GetTickCount() - ti;
|
||||
// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
|
||||
// ti = GetTickCount();
|
||||
// SpinDelay(1000);
|
||||
// ti = GetTickCount() - ti;
|
||||
// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
|
||||
void StartTickCount(void) {
|
||||
// This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
|
||||
// We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register.
|
||||
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency
|
||||
// set RealTimeCounter divider to count at 1kHz:
|
||||
AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((256000 + (mainf/2)) / mainf);
|
||||
// note: worst case precision is approx 2.5%
|
||||
// This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
|
||||
// We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register.
|
||||
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency
|
||||
// set RealTimeCounter divider to count at 1kHz:
|
||||
AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((256000 + (mainf/2)) / mainf);
|
||||
// note: worst case precision is approx 2.5%
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current count.
|
||||
*/
|
||||
uint32_t RAMFUNC GetTickCount(void){
|
||||
return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2;
|
||||
return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// microseconds timer
|
||||
// -------------------------------------------------------------------------
|
||||
void StartCountUS(void) {
|
||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||
|
||||
// fast clock
|
||||
// tick=1.5mks
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR |
|
||||
AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET;
|
||||
AT91C_BASE_TC0->TC_RA = 1;
|
||||
AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000
|
||||
// fast clock
|
||||
// tick=1.5mks
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR |
|
||||
AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET;
|
||||
AT91C_BASE_TC0->TC_RA = 1;
|
||||
AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000
|
||||
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from timer 0
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // from timer 0
|
||||
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TCB->TCB_BCR = 1;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TCB->TCB_BCR = 1;
|
||||
|
||||
while (AT91C_BASE_TC1->TC_CV > 0);
|
||||
while (AT91C_BASE_TC1->TC_CV > 0);
|
||||
}
|
||||
|
||||
uint32_t RAMFUNC GetCountUS(void){
|
||||
//return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10);
|
||||
// By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548
|
||||
return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3;
|
||||
//return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10);
|
||||
// By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548
|
||||
return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Timer for iso14443 commands. Uses ssp_clk from FPGA
|
||||
// -------------------------------------------------------------------------
|
||||
void StartCountSspClk(void) {
|
||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); // Enable Clock to all timers
|
||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1
|
||||
| AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none
|
||||
| AT91C_TCB_TC2XC2S_TIOA0; // XC2 Clock = TIOA0
|
||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); // Enable Clock to all timers
|
||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1
|
||||
| AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none
|
||||
| AT91C_TCB_TC2XC2S_TIOA0; // XC2 Clock = TIOA0
|
||||
|
||||
// configure TC1 to create a short pulse on TIOA1 when a rising edge on TIOB1 (= ssp_clk from FPGA) occurs:
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // disable TC1
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK // TC1 Clock = MCK(48MHz)/2 = 24MHz
|
||||
| AT91C_TC_CPCSTOP // Stop clock on RC compare
|
||||
| AT91C_TC_EEVTEDG_RISING // Trigger on rising edge of Event
|
||||
| AT91C_TC_EEVT_TIOB // Event-Source: TIOB1 (= ssp_clk from FPGA = 13,56MHz/16)
|
||||
| AT91C_TC_ENETRG // Enable external trigger event
|
||||
| AT91C_TC_WAVESEL_UP // Upmode without automatic trigger on RC compare
|
||||
| AT91C_TC_WAVE // Waveform Mode
|
||||
| AT91C_TC_AEEVT_SET // Set TIOA1 on external event
|
||||
| AT91C_TC_ACPC_CLEAR; // Clear TIOA1 on RC Compare
|
||||
AT91C_BASE_TC1->TC_RC = 0x04; // RC Compare value = 0x04
|
||||
// configure TC1 to create a short pulse on TIOA1 when a rising edge on TIOB1 (= ssp_clk from FPGA) occurs:
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // disable TC1
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK // TC1 Clock = MCK(48MHz)/2 = 24MHz
|
||||
| AT91C_TC_CPCSTOP // Stop clock on RC compare
|
||||
| AT91C_TC_EEVTEDG_RISING // Trigger on rising edge of Event
|
||||
| AT91C_TC_EEVT_TIOB // Event-Source: TIOB1 (= ssp_clk from FPGA = 13,56MHz/16)
|
||||
| AT91C_TC_ENETRG // Enable external trigger event
|
||||
| AT91C_TC_WAVESEL_UP // Upmode without automatic trigger on RC compare
|
||||
| AT91C_TC_WAVE // Waveform Mode
|
||||
| AT91C_TC_AEEVT_SET // Set TIOA1 on external event
|
||||
| AT91C_TC_ACPC_CLEAR; // Clear TIOA1 on RC Compare
|
||||
AT91C_BASE_TC1->TC_RC = 0x04; // RC Compare value = 0x04
|
||||
|
||||
// use TC0 to count TIOA1 pulses
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // disable TC0
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_XC0 // TC0 clock = XC0 clock = TIOA1
|
||||
| AT91C_TC_WAVE // Waveform Mode
|
||||
| AT91C_TC_WAVESEL_UP // just count
|
||||
| AT91C_TC_ACPA_CLEAR // Clear TIOA0 on RA Compare
|
||||
| AT91C_TC_ACPC_SET; // Set TIOA0 on RC Compare
|
||||
AT91C_BASE_TC0->TC_RA = 1; // RA Compare value = 1; pulse width to TC2
|
||||
AT91C_BASE_TC0->TC_RC = 0; // RC Compare value = 0; increment TC2 on overflow
|
||||
// use TC0 to count TIOA1 pulses
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // disable TC0
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_XC0 // TC0 clock = XC0 clock = TIOA1
|
||||
| AT91C_TC_WAVE // Waveform Mode
|
||||
| AT91C_TC_WAVESEL_UP // just count
|
||||
| AT91C_TC_ACPA_CLEAR // Clear TIOA0 on RA Compare
|
||||
| AT91C_TC_ACPC_SET; // Set TIOA0 on RC Compare
|
||||
AT91C_BASE_TC0->TC_RA = 1; // RA Compare value = 1; pulse width to TC2
|
||||
AT91C_BASE_TC0->TC_RC = 0; // RC Compare value = 0; increment TC2 on overflow
|
||||
|
||||
// use TC2 to count TIOA0 pulses (giving us a 32bit counter (TC0/TC2) clocked by ssp_clk)
|
||||
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS; // disable TC2
|
||||
AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_XC2 // TC2 clock = XC2 clock = TIOA0
|
||||
| AT91C_TC_WAVE // Waveform Mode
|
||||
| AT91C_TC_WAVESEL_UP; // just count
|
||||
// use TC2 to count TIOA0 pulses (giving us a 32bit counter (TC0/TC2) clocked by ssp_clk)
|
||||
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS; // disable TC2
|
||||
AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_XC2 // TC2 clock = XC2 clock = TIOA0
|
||||
| AT91C_TC_WAVE // Waveform Mode
|
||||
| AT91C_TC_WAVESEL_UP; // just count
|
||||
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC0
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC1
|
||||
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC2
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC0
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC1
|
||||
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC2
|
||||
|
||||
// synchronize the counter with the ssp_frame signal.
|
||||
// Note: FPGA must be in any iso14443 mode, otherwise the frame signal would not be present
|
||||
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME)); // wait for ssp_frame to go high (start of frame)
|
||||
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME); // wait for ssp_frame to be low
|
||||
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high
|
||||
// synchronize the counter with the ssp_frame signal.
|
||||
// Note: FPGA must be in any iso14443 mode, otherwise the frame signal would not be present
|
||||
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME)); // wait for ssp_frame to go high (start of frame)
|
||||
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME); // wait for ssp_frame to be low
|
||||
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high
|
||||
|
||||
// note: up to now two ssp_clk rising edges have passed since the rising edge of ssp_frame
|
||||
// it is now safe to assert a sync signal. This sets all timers to 0 on next active clock edge
|
||||
AT91C_BASE_TCB->TCB_BCR = 1; // assert Sync (set all timers to 0 on next active clock edge)
|
||||
// at the next (3rd) ssp_clk rising edge, TC1 will be reset (and not generate a clock signal to TC0)
|
||||
// at the next (4th) ssp_clk rising edge, TC0 (the low word of our counter) will be reset. From now on,
|
||||
// whenever the last three bits of our counter go 0, we can be sure to be in the middle of a frame transfer.
|
||||
// (just started with the transfer of the 4th Bit).
|
||||
// note: up to now two ssp_clk rising edges have passed since the rising edge of ssp_frame
|
||||
// it is now safe to assert a sync signal. This sets all timers to 0 on next active clock edge
|
||||
AT91C_BASE_TCB->TCB_BCR = 1; // assert Sync (set all timers to 0 on next active clock edge)
|
||||
// at the next (3rd) ssp_clk rising edge, TC1 will be reset (and not generate a clock signal to TC0)
|
||||
// at the next (4th) ssp_clk rising edge, TC0 (the low word of our counter) will be reset. From now on,
|
||||
// whenever the last three bits of our counter go 0, we can be sure to be in the middle of a frame transfer.
|
||||
// (just started with the transfer of the 4th Bit).
|
||||
|
||||
// The high word of the counter (TC2) will not reset until the low word (TC0) overflows.
|
||||
// Therefore need to wait quite some time before we can use the counter.
|
||||
while (AT91C_BASE_TC2->TC_CV > 0);
|
||||
// The high word of the counter (TC2) will not reset until the low word (TC0) overflows.
|
||||
// Therefore need to wait quite some time before we can use the counter.
|
||||
while (AT91C_BASE_TC2->TC_CV > 0);
|
||||
}
|
||||
void ResetSspClk(void) {
|
||||
//enable clock of timer and software trigger
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
while (AT91C_BASE_TC2->TC_CV > 0);
|
||||
//enable clock of timer and software trigger
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
while (AT91C_BASE_TC2->TC_CV > 0);
|
||||
}
|
||||
uint32_t RAMFUNC GetCountSspClk(void) {
|
||||
uint32_t tmp_count = (AT91C_BASE_TC2->TC_CV << 16) | AT91C_BASE_TC0->TC_CV;
|
||||
if ((tmp_count & 0x0000ffff) == 0) //small chance that we may have missed an increment in TC2
|
||||
return (AT91C_BASE_TC2->TC_CV << 16);
|
||||
return tmp_count;
|
||||
uint32_t tmp_count = (AT91C_BASE_TC2->TC_CV << 16) | AT91C_BASE_TC0->TC_CV;
|
||||
if ((tmp_count & 0x0000ffff) == 0) //small chance that we may have missed an increment in TC2
|
||||
return (AT91C_BASE_TC2->TC_CV << 16);
|
||||
return tmp_count;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
@ -173,68 +173,68 @@ uint32_t RAMFUNC GetCountSspClk(void) {
|
|||
// 1us = 1.5ticks
|
||||
// -------------------------------------------------------------------------
|
||||
void StartTicks(void){
|
||||
// initialization of the timer
|
||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||
// initialization of the timer
|
||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||
|
||||
// disable TC0 and TC1 for re-configuration
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
// disable TC0 and TC1 for re-configuration
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// first configure TC1 (higher, 0xFFFF0000) 16 bit counter
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // just connect to TIOA0 from TC0
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // re-enable timer and wait for TC0
|
||||
// first configure TC1 (higher, 0xFFFF0000) 16 bit counter
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_XC1; // just connect to TIOA0 from TC0
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // re-enable timer and wait for TC0
|
||||
|
||||
// second configure TC0 (lower, 0x0000FFFF) 16 bit counter
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO |
|
||||
AT91C_TC_ACPA_CLEAR | // RA comperator clears TIOA (carry bit)
|
||||
AT91C_TC_ACPC_SET | // RC comperator sets TIOA (carry bit)
|
||||
AT91C_TC_ASWTRG_SET; // SWTriger sets TIOA (carry bit)
|
||||
AT91C_BASE_TC0->TC_RC = 0; // set TIOA (carry bit) on overflow, return to zero
|
||||
AT91C_BASE_TC0->TC_RA = 1; // clear carry bit on next clock cycle
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // reset and re-enable timer
|
||||
// second configure TC0 (lower, 0x0000FFFF) 16 bit counter
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO |
|
||||
AT91C_TC_ACPA_CLEAR | // RA comperator clears TIOA (carry bit)
|
||||
AT91C_TC_ACPC_SET | // RC comperator sets TIOA (carry bit)
|
||||
AT91C_TC_ASWTRG_SET; // SWTriger sets TIOA (carry bit)
|
||||
AT91C_BASE_TC0->TC_RC = 0; // set TIOA (carry bit) on overflow, return to zero
|
||||
AT91C_BASE_TC0->TC_RA = 1; // clear carry bit on next clock cycle
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // reset and re-enable timer
|
||||
|
||||
// synchronized startup procedure
|
||||
while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero
|
||||
while (AT91C_BASE_TC0->TC_CV < 2); // and has started (TC_CV > TC_RA, now TC1 is cleared)
|
||||
// synchronized startup procedure
|
||||
while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero
|
||||
while (AT91C_BASE_TC0->TC_CV < 2); // and has started (TC_CV > TC_RA, now TC1 is cleared)
|
||||
|
||||
// return to zero
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||
while (AT91C_BASE_TC0->TC_CV > 0);
|
||||
// return to zero
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||
while (AT91C_BASE_TC0->TC_CV > 0);
|
||||
}
|
||||
|
||||
uint32_t GetTicks(void) {
|
||||
uint32_t hi, lo;
|
||||
uint32_t hi, lo;
|
||||
|
||||
do {
|
||||
hi = AT91C_BASE_TC1->TC_CV;
|
||||
lo = AT91C_BASE_TC0->TC_CV;
|
||||
} while(hi != AT91C_BASE_TC1->TC_CV);
|
||||
do {
|
||||
hi = AT91C_BASE_TC1->TC_CV;
|
||||
lo = AT91C_BASE_TC0->TC_CV;
|
||||
} while(hi != AT91C_BASE_TC1->TC_CV);
|
||||
|
||||
return (hi << 16) | lo;
|
||||
return (hi << 16) | lo;
|
||||
}
|
||||
|
||||
// Wait - Spindelay in ticks.
|
||||
// if called with a high number, this will trigger the WDT...
|
||||
void WaitTicks(uint32_t ticks){
|
||||
if ( ticks == 0 ) return;
|
||||
ticks += GetTicks();
|
||||
while (GetTicks() < ticks);
|
||||
if ( ticks == 0 ) return;
|
||||
ticks += GetTicks();
|
||||
while (GetTicks() < ticks);
|
||||
}
|
||||
|
||||
// Wait / Spindelay in us (microseconds)
|
||||
// 1us = 1.5ticks.
|
||||
void WaitUS(uint16_t us){
|
||||
WaitTicks( (uint32_t)us * 3/2 );
|
||||
WaitTicks( (uint32_t)us * 3/2 );
|
||||
}
|
||||
void WaitMS(uint16_t ms){
|
||||
WaitTicks( (uint32_t)ms * 1500 );
|
||||
WaitTicks( (uint32_t)ms * 1500 );
|
||||
}
|
||||
|
||||
// stop clock
|
||||
void StopTicks(void){
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
}
|
||||
|
|
288
armsrc/util.c
288
armsrc/util.c
|
@ -10,7 +10,7 @@
|
|||
#include "util.h"
|
||||
|
||||
size_t nbytes(size_t nbits) {
|
||||
return (nbits >> 3)+((nbits % 8) > 0);
|
||||
return (nbits >> 3)+((nbits % 8) > 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -19,19 +19,19 @@ size_t nbytes(size_t nbits) {
|
|||
Example: reflect(0x3e23L,3) == 0x3e26
|
||||
*/
|
||||
uint32_t reflect(uint32_t v, int b) {
|
||||
uint32_t t = v;
|
||||
for ( int i = 0; i < b; ++i) {
|
||||
if (t & 1)
|
||||
v |= BITMASK((b-1)-i);
|
||||
else
|
||||
v &= ~BITMASK((b-1)-i);
|
||||
t>>=1;
|
||||
}
|
||||
return v;
|
||||
uint32_t t = v;
|
||||
for ( int i = 0; i < b; ++i) {
|
||||
if (t & 1)
|
||||
v |= BITMASK((b-1)-i);
|
||||
else
|
||||
v &= ~BITMASK((b-1)-i);
|
||||
t>>=1;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
uint8_t reflect8(uint8_t b) {
|
||||
return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
|
||||
return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
|
||||
}
|
||||
uint16_t reflect16(uint16_t b) {
|
||||
uint16_t v = 0;
|
||||
|
@ -56,19 +56,19 @@ uint16_t reflect16(uint16_t b) {
|
|||
}
|
||||
|
||||
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest) {
|
||||
while (len--) {
|
||||
dest[len] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
while (len--) {
|
||||
dest[len] = (uint8_t) n;
|
||||
n >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t bytes_to_num(uint8_t* src, size_t len) {
|
||||
uint64_t num = 0;
|
||||
while (len--) {
|
||||
num = (num << 8) | (*src);
|
||||
src++;
|
||||
}
|
||||
return num;
|
||||
uint64_t num = 0;
|
||||
while (len--) {
|
||||
num = (num << 8) | (*src);
|
||||
src++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
// RotateLeft - Ultralight, Desfire
|
||||
|
@ -107,11 +107,11 @@ uint8_t hex2int(char hexchar){
|
|||
case 'a':
|
||||
case 'A': return 10; break;
|
||||
case 'b':
|
||||
case 'B': return 11; break;
|
||||
case 'B': return 11; break;
|
||||
case 'c':
|
||||
case 'C': return 12; break;
|
||||
case 'd':
|
||||
case 'D': return 13; break;
|
||||
case 'D': return 13; break;
|
||||
case 'e':
|
||||
case 'E': return 14; break;
|
||||
case 'f':
|
||||
|
@ -122,36 +122,36 @@ uint8_t hex2int(char hexchar){
|
|||
}
|
||||
|
||||
void LEDsoff() {
|
||||
LED_A_OFF();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
LED_D_OFF();
|
||||
LED_A_OFF();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
// LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]
|
||||
void LED(int led, int ms) {
|
||||
if (led & LED_RED)
|
||||
LED_C_ON();
|
||||
if (led & LED_ORANGE)
|
||||
LED_A_ON();
|
||||
if (led & LED_GREEN)
|
||||
LED_B_ON();
|
||||
if (led & LED_RED2)
|
||||
LED_D_ON();
|
||||
if (led & LED_RED)
|
||||
LED_C_ON();
|
||||
if (led & LED_ORANGE)
|
||||
LED_A_ON();
|
||||
if (led & LED_GREEN)
|
||||
LED_B_ON();
|
||||
if (led & LED_RED2)
|
||||
LED_D_ON();
|
||||
|
||||
if (!ms)
|
||||
return;
|
||||
if (!ms)
|
||||
return;
|
||||
|
||||
SpinDelay(ms);
|
||||
SpinDelay(ms);
|
||||
|
||||
if (led & LED_RED)
|
||||
LED_C_OFF();
|
||||
if (led & LED_ORANGE)
|
||||
LED_A_OFF();
|
||||
if (led & LED_GREEN)
|
||||
LED_B_OFF();
|
||||
if (led & LED_RED2)
|
||||
LED_D_OFF();
|
||||
if (led & LED_RED)
|
||||
LED_C_OFF();
|
||||
if (led & LED_ORANGE)
|
||||
LED_A_OFF();
|
||||
if (led & LED_GREEN)
|
||||
LED_B_OFF();
|
||||
if (led & LED_RED2)
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
void SpinOff(uint32_t pause) {
|
||||
|
@ -166,7 +166,7 @@ void SpinOff(uint32_t pause) {
|
|||
void SpinErr(uint8_t led, uint32_t speed, uint8_t times) {
|
||||
SpinOff(speed);
|
||||
NTIME(times)
|
||||
{
|
||||
{
|
||||
switch (led) {
|
||||
case 0:
|
||||
LED_A_INV();
|
||||
|
@ -223,102 +223,102 @@ void SpinUp(uint32_t speed) {
|
|||
// In general, don't use this function unless you expect a
|
||||
// double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
|
||||
int BUTTON_CLICKED(int ms) {
|
||||
// Up to 500ms in between clicks to mean a double click
|
||||
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
|
||||
// Up to 500ms in between clicks to mean a double click
|
||||
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
|
||||
|
||||
// If we're not even pressed, forget about it!
|
||||
if (!BUTTON_PRESS())
|
||||
return BUTTON_NO_CLICK;
|
||||
// If we're not even pressed, forget about it!
|
||||
if (!BUTTON_PRESS())
|
||||
return BUTTON_NO_CLICK;
|
||||
|
||||
// Borrow a PWM unit for my real-time clock
|
||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||
// 48 MHz / 1024 gives 46.875 kHz
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
|
||||
// Borrow a PWM unit for my real-time clock
|
||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||
// 48 MHz / 1024 gives 46.875 kHz
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
|
||||
|
||||
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
|
||||
int letoff = 0;
|
||||
for(;;)
|
||||
{
|
||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
int letoff = 0;
|
||||
for(;;)
|
||||
{
|
||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
|
||||
// We haven't let off the button yet
|
||||
if (!letoff)
|
||||
{
|
||||
// We just let it off!
|
||||
if (!BUTTON_PRESS())
|
||||
{
|
||||
letoff = 1;
|
||||
// We haven't let off the button yet
|
||||
if (!letoff)
|
||||
{
|
||||
// We just let it off!
|
||||
if (!BUTTON_PRESS())
|
||||
{
|
||||
letoff = 1;
|
||||
|
||||
// reset our timer for 500ms
|
||||
start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
ticks = (48000 * (500)) >> 10;
|
||||
}
|
||||
// reset our timer for 500ms
|
||||
start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
ticks = (48000 * (500)) >> 10;
|
||||
}
|
||||
|
||||
// Still haven't let it off
|
||||
else
|
||||
// Have we held down a full second?
|
||||
if (now == (uint16_t)(start + ticks))
|
||||
return BUTTON_HOLD;
|
||||
}
|
||||
// Still haven't let it off
|
||||
else
|
||||
// Have we held down a full second?
|
||||
if (now == (uint16_t)(start + ticks))
|
||||
return BUTTON_HOLD;
|
||||
}
|
||||
|
||||
// We already let off, did we click again?
|
||||
else
|
||||
// Sweet, double click!
|
||||
if (BUTTON_PRESS())
|
||||
return BUTTON_DOUBLE_CLICK;
|
||||
// We already let off, did we click again?
|
||||
else
|
||||
// Sweet, double click!
|
||||
if (BUTTON_PRESS())
|
||||
return BUTTON_DOUBLE_CLICK;
|
||||
|
||||
// Have we ran out of time to double click?
|
||||
else
|
||||
if (now == (uint16_t)(start + ticks))
|
||||
// At least we did a single click
|
||||
return BUTTON_SINGLE_CLICK;
|
||||
// Have we ran out of time to double click?
|
||||
else
|
||||
if (now == (uint16_t)(start + ticks))
|
||||
// At least we did a single click
|
||||
return BUTTON_SINGLE_CLICK;
|
||||
|
||||
WDT_HIT();
|
||||
}
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
// We should never get here
|
||||
return BUTTON_ERROR;
|
||||
// We should never get here
|
||||
return BUTTON_ERROR;
|
||||
}
|
||||
|
||||
// Determine if a button is held down
|
||||
int BUTTON_HELD(int ms) {
|
||||
// If button is held for one second
|
||||
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
|
||||
// If button is held for one second
|
||||
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
|
||||
|
||||
// If we're not even pressed, forget about it!
|
||||
if (!BUTTON_PRESS())
|
||||
return BUTTON_NO_CLICK;
|
||||
// If we're not even pressed, forget about it!
|
||||
if (!BUTTON_PRESS())
|
||||
return BUTTON_NO_CLICK;
|
||||
|
||||
// Borrow a PWM unit for my real-time clock
|
||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||
// 48 MHz / 1024 gives 46.875 kHz
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
|
||||
// Borrow a PWM unit for my real-time clock
|
||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||
// 48 MHz / 1024 gives 46.875 kHz
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
|
||||
|
||||
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
for(;;)
|
||||
{
|
||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||
|
||||
// As soon as our button let go, we didn't hold long enough
|
||||
if (!BUTTON_PRESS())
|
||||
return BUTTON_SINGLE_CLICK;
|
||||
// As soon as our button let go, we didn't hold long enough
|
||||
if (!BUTTON_PRESS())
|
||||
return BUTTON_SINGLE_CLICK;
|
||||
|
||||
// Have we waited the full second?
|
||||
else
|
||||
if (now == (uint16_t)(start + ticks))
|
||||
return BUTTON_HOLD;
|
||||
// Have we waited the full second?
|
||||
else
|
||||
if (now == (uint16_t)(start + ticks))
|
||||
return BUTTON_HOLD;
|
||||
|
||||
WDT_HIT();
|
||||
}
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
// We should never get here
|
||||
return BUTTON_ERROR;
|
||||
// We should never get here
|
||||
return BUTTON_ERROR;
|
||||
}
|
||||
|
||||
/* Similar to FpgaGatherVersion this formats stored version information
|
||||
|
@ -327,30 +327,30 @@ int BUTTON_HELD(int ms) {
|
|||
* prefix in dst.
|
||||
*/
|
||||
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information) {
|
||||
struct version_information *v = (struct version_information*)version_information;
|
||||
dst[0] = 0;
|
||||
strncat(dst, prefix, len-1);
|
||||
if (v->magic != VERSION_INFORMATION_MAGIC) {
|
||||
strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1);
|
||||
return;
|
||||
}
|
||||
if (v->versionversion != 1) {
|
||||
strncat(dst, "Version information not understood\n", len - strlen(dst) - 1);
|
||||
return;
|
||||
}
|
||||
if (!v->present) {
|
||||
strncat(dst, "Version information not available\n", len - strlen(dst) - 1);
|
||||
return;
|
||||
}
|
||||
struct version_information *v = (struct version_information*)version_information;
|
||||
dst[0] = 0;
|
||||
strncat(dst, prefix, len-1);
|
||||
if (v->magic != VERSION_INFORMATION_MAGIC) {
|
||||
strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1);
|
||||
return;
|
||||
}
|
||||
if (v->versionversion != 1) {
|
||||
strncat(dst, "Version information not understood\n", len - strlen(dst) - 1);
|
||||
return;
|
||||
}
|
||||
if (!v->present) {
|
||||
strncat(dst, "Version information not available\n", len - strlen(dst) - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
strncat(dst, v->gitversion, len - strlen(dst) - 1);
|
||||
if (v->clean == 0) {
|
||||
strncat(dst, "-unclean", len - strlen(dst) - 1);
|
||||
} else if (v->clean == 2) {
|
||||
strncat(dst, "-suspect", len - strlen(dst) - 1);
|
||||
}
|
||||
strncat(dst, v->gitversion, len - strlen(dst) - 1);
|
||||
if (v->clean == 0) {
|
||||
strncat(dst, "-unclean", len - strlen(dst) - 1);
|
||||
} else if (v->clean == 2) {
|
||||
strncat(dst, "-suspect", len - strlen(dst) - 1);
|
||||
}
|
||||
|
||||
strncat(dst, " ", len - strlen(dst) - 1);
|
||||
strncat(dst, v->buildtime, len - strlen(dst) - 1);
|
||||
strncat(dst, "\n", len - strlen(dst) - 1);
|
||||
strncat(dst, " ", len - strlen(dst) - 1);
|
||||
strncat(dst, v->buildtime, len - strlen(dst) - 1);
|
||||
strncat(dst, "\n", len - strlen(dst) - 1);
|
||||
}
|
||||
|
|
|
@ -46,8 +46,8 @@
|
|||
size_t nbytes(size_t nbits);
|
||||
|
||||
extern uint32_t reflect(uint32_t v, int b); // used in crc.c ...
|
||||
extern uint8_t reflect8(uint8_t b); // dedicated 8bit reversal
|
||||
extern uint16_t reflect16(uint16_t b); // dedicated 16bit reversal
|
||||
extern uint8_t reflect8(uint8_t b); // dedicated 8bit reversal
|
||||
extern uint16_t reflect16(uint16_t b); // dedicated 16bit reversal
|
||||
|
||||
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
|
||||
uint64_t bytes_to_num(uint8_t* src, size_t len);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue