mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03: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
|
high BIGBUF_SIZE
|
||||||
reserved = BigBuf_malloc() subtracts amount from BigBuf_hi,
|
reserved = BigBuf_malloc() subtracts amount from BigBuf_hi,
|
||||||
low 0x00
|
low 0x00
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// High memory mark
|
// High memory mark
|
||||||
|
@ -35,92 +35,92 @@ static bool tracing = true; //todo static?
|
||||||
|
|
||||||
// get the address of BigBuf
|
// get the address of BigBuf
|
||||||
uint8_t *BigBuf_get_addr(void) {
|
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
|
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
||||||
uint8_t *BigBuf_get_EM_addr(void) {
|
uint8_t *BigBuf_get_EM_addr(void) {
|
||||||
// not yet allocated
|
// not yet allocated
|
||||||
if (emulator_memory == NULL)
|
if (emulator_memory == NULL)
|
||||||
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
|
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
|
||||||
|
|
||||||
return emulator_memory;
|
return emulator_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear ALL of BigBuf
|
// clear ALL of BigBuf
|
||||||
void BigBuf_Clear(void) {
|
void BigBuf_Clear(void) {
|
||||||
BigBuf_Clear_ext(true);
|
BigBuf_Clear_ext(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear ALL of BigBuf
|
// clear ALL of BigBuf
|
||||||
void BigBuf_Clear_ext(bool verbose) {
|
void BigBuf_Clear_ext(bool verbose) {
|
||||||
memset(BigBuf, 0, BIGBUF_SIZE);
|
memset(BigBuf, 0, BIGBUF_SIZE);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE);
|
Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigBuf_Clear_EM(void) {
|
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) {
|
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
|
// 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
|
// at the beginning of BigBuf is always for traces/samples
|
||||||
uint8_t *BigBuf_malloc(uint16_t chunksize) {
|
uint8_t *BigBuf_malloc(uint16_t chunksize) {
|
||||||
if (BigBuf_hi - chunksize < 0)
|
if (BigBuf_hi - chunksize < 0)
|
||||||
return NULL; // no memory left
|
return NULL; // no memory left
|
||||||
|
|
||||||
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
||||||
BigBuf_hi -= chunksize; // aligned to 4 Byte boundary
|
BigBuf_hi -= chunksize; // aligned to 4 Byte boundary
|
||||||
return (uint8_t *)BigBuf + BigBuf_hi;
|
return (uint8_t *)BigBuf + BigBuf_hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
|
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
|
||||||
void BigBuf_free(void){
|
void BigBuf_free(void){
|
||||||
BigBuf_hi = BIGBUF_SIZE;
|
BigBuf_hi = BIGBUF_SIZE;
|
||||||
emulator_memory = NULL;
|
emulator_memory = NULL;
|
||||||
// shouldn't this empty BigBuf also?
|
// shouldn't this empty BigBuf also?
|
||||||
}
|
}
|
||||||
|
|
||||||
// free allocated chunks EXCEPT the emulator memory
|
// free allocated chunks EXCEPT the emulator memory
|
||||||
void BigBuf_free_keep_EM(void) {
|
void BigBuf_free_keep_EM(void) {
|
||||||
if (emulator_memory != NULL)
|
if (emulator_memory != NULL)
|
||||||
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
||||||
else
|
else
|
||||||
BigBuf_hi = BIGBUF_SIZE;
|
BigBuf_hi = BIGBUF_SIZE;
|
||||||
|
|
||||||
// shouldn't this empty BigBuf also?
|
// shouldn't this empty BigBuf also?
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigBuf_print_status(void) {
|
void BigBuf_print_status(void) {
|
||||||
Dbprintf("Memory");
|
Dbprintf("Memory");
|
||||||
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
|
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
|
||||||
Dbprintf(" Available memory........%d", BigBuf_hi);
|
Dbprintf(" Available memory........%d", BigBuf_hi);
|
||||||
Dbprintf("Tracing");
|
Dbprintf("Tracing");
|
||||||
Dbprintf(" tracing ................%d", tracing);
|
Dbprintf(" tracing ................%d", tracing);
|
||||||
Dbprintf(" traceLen ...............%d", traceLen);
|
Dbprintf(" traceLen ...............%d", traceLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the maximum trace length (i.e. the unallocated size of BigBuf)
|
// return the maximum trace length (i.e. the unallocated size of BigBuf)
|
||||||
uint16_t BigBuf_max_traceLen(void) {
|
uint16_t BigBuf_max_traceLen(void) {
|
||||||
return BigBuf_hi;
|
return BigBuf_hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_trace(void) {
|
void clear_trace(void) {
|
||||||
traceLen = 0;
|
traceLen = 0;
|
||||||
}
|
}
|
||||||
void set_tracelen(uint32_t value) {
|
void set_tracelen(uint32_t value) {
|
||||||
traceLen = value;
|
traceLen = value;
|
||||||
}
|
}
|
||||||
void set_tracing(bool enable) {
|
void set_tracing(bool enable) {
|
||||||
tracing = enable;
|
tracing = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_tracing(void) {
|
bool get_tracing(void) {
|
||||||
return tracing;
|
return tracing;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,7 +128,7 @@ bool get_tracing(void) {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
uint32_t BigBuf_get_traceLen(void) {
|
uint32_t BigBuf_get_traceLen(void) {
|
||||||
return traceLen;
|
return traceLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -138,111 +138,111 @@ uint32_t BigBuf_get_traceLen(void) {
|
||||||
annotation of commands/responses.
|
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) {
|
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 num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
||||||
uint32_t duration = timestamp_end - timestamp_start;
|
uint32_t duration = timestamp_end - timestamp_start;
|
||||||
|
|
||||||
// Return when trace is full
|
// Return when trace is full
|
||||||
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) {
|
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= BigBuf_max_traceLen()) {
|
||||||
tracing = false; // don't trace any more
|
tracing = false; // don't trace any more
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Traceformat:
|
// Traceformat:
|
||||||
// 32 bits timestamp (little endian)
|
// 32 bits timestamp (little endian)
|
||||||
// 16 bits duration (little endian)
|
// 16 bits duration (little endian)
|
||||||
// 16 bits data length (little endian, Highest Bit used as readerToTag flag)
|
// 16 bits data length (little endian, Highest Bit used as readerToTag flag)
|
||||||
// y Bytes data
|
// y Bytes data
|
||||||
// x Bytes parity (one byte per 8 bytes data)
|
// x Bytes parity (one byte per 8 bytes data)
|
||||||
|
|
||||||
// timestamp (start)
|
// timestamp (start)
|
||||||
trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
|
trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
|
||||||
trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
|
trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
|
||||||
trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
|
trace[traceLen++] = ((timestamp_start >> 16) & 0xff);
|
||||||
trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
|
trace[traceLen++] = ((timestamp_start >> 24) & 0xff);
|
||||||
|
|
||||||
// duration
|
// duration
|
||||||
trace[traceLen++] = ((duration >> 0) & 0xff);
|
trace[traceLen++] = ((duration >> 0) & 0xff);
|
||||||
trace[traceLen++] = ((duration >> 8) & 0xff);
|
trace[traceLen++] = ((duration >> 8) & 0xff);
|
||||||
|
|
||||||
// data length
|
// data length
|
||||||
trace[traceLen++] = ((iLen >> 0) & 0xff);
|
trace[traceLen++] = ((iLen >> 0) & 0xff);
|
||||||
trace[traceLen++] = ((iLen >> 8) & 0xff);
|
trace[traceLen++] = ((iLen >> 8) & 0xff);
|
||||||
|
|
||||||
// readerToTag flag
|
// readerToTag flag
|
||||||
if (!readerToTag) {
|
if (!readerToTag) {
|
||||||
trace[traceLen - 1] |= 0x80;
|
trace[traceLen - 1] |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
// data bytes
|
// data bytes
|
||||||
if (btBytes != NULL && iLen != 0) {
|
if (btBytes != NULL && iLen != 0) {
|
||||||
memcpy(trace + traceLen, btBytes, iLen);
|
memcpy(trace + traceLen, btBytes, iLen);
|
||||||
}
|
}
|
||||||
traceLen += iLen;
|
traceLen += iLen;
|
||||||
|
|
||||||
// parity bytes
|
// parity bytes
|
||||||
if (num_paritybytes != 0) {
|
if (num_paritybytes != 0) {
|
||||||
if (parity != NULL) {
|
if (parity != NULL) {
|
||||||
memcpy(trace + traceLen, parity, num_paritybytes);
|
memcpy(trace + traceLen, parity, num_paritybytes);
|
||||||
} else {
|
} else {
|
||||||
memset(trace + traceLen, 0x00, num_paritybytes);
|
memset(trace + traceLen, 0x00, num_paritybytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
traceLen += num_paritybytes;
|
traceLen += num_paritybytes;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag) {
|
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,
|
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.
|
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();
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
uint32_t iLen = nbytes(iBits);
|
uint32_t iLen = nbytes(iBits);
|
||||||
// Return when trace is full
|
// Return when trace is full
|
||||||
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return false;
|
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return false;
|
||||||
|
|
||||||
//Hitag traces appear to use this traceformat:
|
//Hitag traces appear to use this traceformat:
|
||||||
// 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
|
// 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
|
||||||
// 32 bits parity
|
// 32 bits parity
|
||||||
// 8 bits size (number of bits in the trace entry, not number of bytes)
|
// 8 bits size (number of bits in the trace entry, not number of bytes)
|
||||||
// y Bytes data
|
// y Bytes data
|
||||||
|
|
||||||
rsamples += iSamples;
|
rsamples += iSamples;
|
||||||
trace[traceLen++] = ((rsamples >> 0) & 0xff);
|
trace[traceLen++] = ((rsamples >> 0) & 0xff);
|
||||||
trace[traceLen++] = ((rsamples >> 8) & 0xff);
|
trace[traceLen++] = ((rsamples >> 8) & 0xff);
|
||||||
trace[traceLen++] = ((rsamples >> 16) & 0xff);
|
trace[traceLen++] = ((rsamples >> 16) & 0xff);
|
||||||
trace[traceLen++] = ((rsamples >> 24) & 0xff);
|
trace[traceLen++] = ((rsamples >> 24) & 0xff);
|
||||||
|
|
||||||
if (!readerToTag) {
|
if (!readerToTag) {
|
||||||
trace[traceLen - 1] |= 0x80;
|
trace[traceLen - 1] |= 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
trace[traceLen++] = ((dwParity >> 0) & 0xff);
|
trace[traceLen++] = ((dwParity >> 0) & 0xff);
|
||||||
trace[traceLen++] = ((dwParity >> 8) & 0xff);
|
trace[traceLen++] = ((dwParity >> 8) & 0xff);
|
||||||
trace[traceLen++] = ((dwParity >> 16) & 0xff);
|
trace[traceLen++] = ((dwParity >> 16) & 0xff);
|
||||||
trace[traceLen++] = ((dwParity >> 24) & 0xff);
|
trace[traceLen++] = ((dwParity >> 24) & 0xff);
|
||||||
trace[traceLen++] = iBits;
|
trace[traceLen++] = iBits;
|
||||||
|
|
||||||
memcpy(trace + traceLen, btBytes, iLen);
|
memcpy(trace + traceLen, btBytes, iLen);
|
||||||
traceLen += iLen;
|
traceLen += iLen;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emulator memory
|
// Emulator memory
|
||||||
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
|
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){
|
||||||
uint8_t* mem = BigBuf_get_EM_addr();
|
uint8_t* mem = BigBuf_get_EM_addr();
|
||||||
if (offset + length < CARD_MEMORY_SIZE) {
|
if (offset + length < CARD_MEMORY_SIZE) {
|
||||||
memcpy(mem+offset, data, length);
|
memcpy(mem+offset, data, length);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset + length), CARD_MEMORY_SIZE);
|
Dbprintf("Error, trying to set memory outside of bounds! %d > %d", (offset + length), CARD_MEMORY_SIZE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "ticks.h"
|
#include "ticks.h"
|
||||||
|
|
||||||
#define BIGBUF_SIZE 40000
|
#define BIGBUF_SIZE 40000
|
||||||
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
||||||
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
|
#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_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 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 CARD_MEMORY_SIZE 4096
|
||||||
#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!?
|
#define DMA_BUFFER_SIZE 256 //128 (how big is the dma?!?
|
||||||
|
|
||||||
extern uint8_t *BigBuf_get_addr(void);
|
extern uint8_t *BigBuf_get_addr(void);
|
||||||
extern uint8_t *BigBuf_get_EM_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)
|
void LCDSend(unsigned int data)
|
||||||
{
|
{
|
||||||
// 9th bit set for data, clear for 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
|
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
|
// 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
|
// 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
|
AT91C_BASE_SPI->SPI_TDR = data^0x100; // Send the data/command
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCDSetXY(unsigned char x, unsigned char y)
|
void LCDSetXY(unsigned char x, unsigned char y)
|
||||||
{
|
{
|
||||||
LCDSend(PPASET); // page start/end ram
|
LCDSend(PPASET); // page start/end ram
|
||||||
LCDSend(y); // Start Page to display to
|
LCDSend(y); // Start Page to display to
|
||||||
LCDSend(131); // End Page to display to
|
LCDSend(131); // End Page to display to
|
||||||
|
|
||||||
LCDSend(PCASET); // column start/end ram
|
LCDSend(PCASET); // column start/end ram
|
||||||
LCDSend(x); // Start Column to display to
|
LCDSend(x); // Start Column to display to
|
||||||
LCDSend(131); // End Column to display to
|
LCDSend(131); // End Column to display to
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCDSetPixel(unsigned char x, unsigned char y, unsigned char color)
|
void LCDSetPixel(unsigned char x, unsigned char y, unsigned char color)
|
||||||
{
|
{
|
||||||
LCDSetXY(x,y); // Set position
|
LCDSetXY(x,y); // Set position
|
||||||
LCDSend(PRAMWR); // Now write the pixel to the display
|
LCDSend(PRAMWR); // Now write the pixel to the display
|
||||||
LCDSend(color); // Write the data in the specified Color
|
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)
|
void LCDFill (unsigned char xs,unsigned char ys,unsigned char width,unsigned char height, unsigned char color)
|
||||||
{
|
{
|
||||||
unsigned char i,j;
|
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)
|
LCDSetXY(xs,ys+i); // Goto start of fill area (Top Left)
|
||||||
LCDSend(PRAMWR); // Write to display
|
LCDSend(PRAMWR); // Write to display
|
||||||
|
|
||||||
for (j=0;j < width;j++) // pixels per line
|
for (j=0;j < width;j++) // pixels per line
|
||||||
LCDSend(color);
|
LCDSend(color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCDString (char *lcd_string, const char *font_style,unsigned char x, unsigned char y, unsigned char fcolor, unsigned char bcolor)
|
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 int i;
|
||||||
unsigned char mask=0, px, py, xme, yme, offset;
|
unsigned char mask=0, px, py, xme, yme, offset;
|
||||||
const char *data;
|
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
|
xme = *data; // get font x width
|
||||||
data++;
|
data++;
|
||||||
yme = *data; // get font y length
|
yme = *data; // get font y length
|
||||||
data++;
|
data++;
|
||||||
offset = *data; // get data bytes per font
|
offset = *data; // get data bytes per font
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// point to data in table to be loaded
|
// point to data in table to be loaded
|
||||||
data = (font_style + offset) + (offset * (int)(*lcd_string - 32));
|
data = (font_style + offset) + (offset * (int)(*lcd_string - 32));
|
||||||
|
|
||||||
for (i=0;i < yme;i++) {
|
for (i=0;i < yme;i++) {
|
||||||
mask |=0x80;
|
mask |=0x80;
|
||||||
|
|
||||||
for (px=x; px < (x + xme); px++) {
|
for (px=x; px < (x + xme); px++) {
|
||||||
py= y + i;
|
py= y + i;
|
||||||
|
|
||||||
if (*data & mask) LCDSetPixel (px,py,fcolor);
|
if (*data & mask) LCDSetPixel (px,py,fcolor);
|
||||||
else LCDSetPixel (px,py,bcolor);
|
else LCDSetPixel (px,py,bcolor);
|
||||||
|
|
||||||
mask>>=1;
|
mask>>=1;
|
||||||
}
|
}
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
x+=xme;
|
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)
|
void LCDReset(void)
|
||||||
{
|
{
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
SetupSpi(SPI_LCD_MODE);
|
SetupSpi(SPI_LCD_MODE);
|
||||||
LOW(GPIO_LRST);
|
LOW(GPIO_LRST);
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
|
|
||||||
HIGH(GPIO_LRST);
|
HIGH(GPIO_LRST);
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCDInit(void)
|
void LCDInit(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
LCDReset();
|
LCDReset();
|
||||||
|
|
||||||
LCDSend(PSWRESET); // software reset
|
LCDSend(PSWRESET); // software reset
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
LCDSend(PSLEEPOUT); // exit sleep mode
|
LCDSend(PSLEEPOUT); // exit sleep mode
|
||||||
LCDSend(PBSTRON); // booster on
|
LCDSend(PBSTRON); // booster on
|
||||||
LCDSend(PDISPON); // display on
|
LCDSend(PDISPON); // display on
|
||||||
LCDSend(PNORON); // normal on
|
LCDSend(PNORON); // normal on
|
||||||
LCDSend(PMADCTL); // rotate display 180 deg
|
LCDSend(PMADCTL); // rotate display 180 deg
|
||||||
LCDSend(0xC0);
|
LCDSend(0xC0);
|
||||||
|
|
||||||
LCDSend(PCOLMOD); // color mode
|
LCDSend(PCOLMOD); // color mode
|
||||||
LCDSend(0x02); // 8bpp color mode
|
LCDSend(0x02); // 8bpp color mode
|
||||||
|
|
||||||
LCDSend(PSETCON); // set contrast
|
LCDSend(PSETCON); // set contrast
|
||||||
LCDSend(0xDC);
|
LCDSend(0xDC);
|
||||||
|
|
||||||
// clear display
|
// clear display
|
||||||
LCDSetXY(0,0);
|
LCDSetXY(0,0);
|
||||||
LCDSend(PRAMWR); // Write to display
|
LCDSend(PRAMWR); // Write to display
|
||||||
i=LCD_XRES*LCD_YRES;
|
i=LCD_XRES*LCD_YRES;
|
||||||
while(i--) LCDSend(WHITE);
|
while(i--) LCDSend(WHITE);
|
||||||
|
|
||||||
// test text on different colored backgrounds
|
// test text on different colored backgrounds
|
||||||
LCDString(" The quick brown fox ", (char *)&FONT6x8,1,1+8*0,WHITE ,BLACK );
|
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(" jumped over the ", (char *)&FONT6x8,1,1+8*1,BLACK ,WHITE );
|
||||||
LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED );
|
LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED );
|
||||||
LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN );
|
LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN );
|
||||||
LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE );
|
LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE );
|
||||||
LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8,1,1+8*5,BLUE ,YELLOW);
|
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*6,BLACK ,CYAN );
|
||||||
LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
|
LCDString(" _+{}|:\\\"<>? ", (char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
|
||||||
|
|
||||||
// color bands
|
// color bands
|
||||||
LCDFill(0, 1+8* 8, 132, 8, BLACK);
|
LCDFill(0, 1+8* 8, 132, 8, BLACK);
|
||||||
LCDFill(0, 1+8* 9, 132, 8, WHITE);
|
LCDFill(0, 1+8* 9, 132, 8, WHITE);
|
||||||
LCDFill(0, 1+8*10, 132, 8, RED);
|
LCDFill(0, 1+8*10, 132, 8, RED);
|
||||||
LCDFill(0, 1+8*11, 132, 8, GREEN);
|
LCDFill(0, 1+8*11, 132, 8, GREEN);
|
||||||
LCDFill(0, 1+8*12, 132, 8, BLUE);
|
LCDFill(0, 1+8*12, 132, 8, BLUE);
|
||||||
LCDFill(0, 1+8*13, 132, 8, YELLOW);
|
LCDFill(0, 1+8*13, 132, 8, YELLOW);
|
||||||
LCDFill(0, 1+8*14, 132, 8, CYAN);
|
LCDFill(0, 1+8*14, 132, 8, CYAN);
|
||||||
LCDFill(0, 1+8*15, 132, 8, MAGENTA);
|
LCDFill(0, 1+8*15, 132, 8, MAGENTA);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
190
armsrc/LCD.h
190
armsrc/LCD.h
|
@ -14,110 +14,110 @@
|
||||||
#include "fonts.h"
|
#include "fonts.h"
|
||||||
|
|
||||||
// The resolution of the LCD
|
// The resolution of the LCD
|
||||||
#define LCD_XRES 132
|
#define LCD_XRES 132
|
||||||
#define LCD_YRES 132
|
#define LCD_YRES 132
|
||||||
|
|
||||||
// 8bpp Color Mode - Some basic colors defined for ease of use
|
// 8bpp Color Mode - Some basic colors defined for ease of use
|
||||||
// remember 8bpp color = 3xRed, 3xGreen & 2xBlue bits
|
// remember 8bpp color = 3xRed, 3xGreen & 2xBlue bits
|
||||||
// organised as RRRGGGBB
|
// organised as RRRGGGBB
|
||||||
|
|
||||||
#define BLACK 0x00
|
#define BLACK 0x00
|
||||||
#define BLUE 0x03
|
#define BLUE 0x03
|
||||||
#define GREEN 0x1C
|
#define GREEN 0x1C
|
||||||
#define CYAN 0x1F
|
#define CYAN 0x1F
|
||||||
#define RED 0xE0
|
#define RED 0xE0
|
||||||
#define MAGENTA 0xE3
|
#define MAGENTA 0xE3
|
||||||
#define YELLOW 0xFC
|
#define YELLOW 0xFC
|
||||||
#define WHITE 0xFF
|
#define WHITE 0xFF
|
||||||
|
|
||||||
// EPSON LCD command set
|
// EPSON LCD command set
|
||||||
#define ECASET 0x115
|
#define ECASET 0x115
|
||||||
#define EPWRCTR 0x120
|
#define EPWRCTR 0x120
|
||||||
#define ENOP 0x125
|
#define ENOP 0x125
|
||||||
#define ERAMWR 0x15C
|
#define ERAMWR 0x15C
|
||||||
#define ERAMRD 0x15D
|
#define ERAMRD 0x15D
|
||||||
#define EPASET 0x175
|
#define EPASET 0x175
|
||||||
#define EEPSRRD1 0x17C
|
#define EEPSRRD1 0x17C
|
||||||
#define EEPSRRD2 0x17D
|
#define EEPSRRD2 0x17D
|
||||||
#define EVOLCTR 0x181
|
#define EVOLCTR 0x181
|
||||||
#define ETMPGRD 0x182
|
#define ETMPGRD 0x182
|
||||||
#define ESLPOUT 0x194
|
#define ESLPOUT 0x194
|
||||||
#define ESLPIN 0x195
|
#define ESLPIN 0x195
|
||||||
#define EDISNOR 0x1A6
|
#define EDISNOR 0x1A6
|
||||||
#define EDISINV 0x1A7
|
#define EDISINV 0x1A7
|
||||||
#define EPTLIN 0x1A8
|
#define EPTLIN 0x1A8
|
||||||
#define EPTLOUT 0x1A9
|
#define EPTLOUT 0x1A9
|
||||||
#define EASCSET 0x1AA
|
#define EASCSET 0x1AA
|
||||||
#define ESCSTART 0x1AB
|
#define ESCSTART 0x1AB
|
||||||
#define EDISOFF 0x1AE
|
#define EDISOFF 0x1AE
|
||||||
#define EDISON 0x1AF
|
#define EDISON 0x1AF
|
||||||
#define ECOMSCN 0x1BB
|
#define ECOMSCN 0x1BB
|
||||||
#define EDATCTL 0x1BC
|
#define EDATCTL 0x1BC
|
||||||
#define EDISCTL 0x1CA
|
#define EDISCTL 0x1CA
|
||||||
#define EEPCOUT 0x1CC
|
#define EEPCOUT 0x1CC
|
||||||
#define EEPCTIN 0x1CD
|
#define EEPCTIN 0x1CD
|
||||||
#define ERGBSET8 0x1CE
|
#define ERGBSET8 0x1CE
|
||||||
#define EOSCON 0x1D1
|
#define EOSCON 0x1D1
|
||||||
#define EOSCOFF 0x1D2
|
#define EOSCOFF 0x1D2
|
||||||
#define EVOLUP 0x1D6
|
#define EVOLUP 0x1D6
|
||||||
#define EVOLDOWN 0x1D7
|
#define EVOLDOWN 0x1D7
|
||||||
#define ERMWIN 0x1E0
|
#define ERMWIN 0x1E0
|
||||||
#define ERMWOUT 0x1EE
|
#define ERMWOUT 0x1EE
|
||||||
#define EEPMWR 0x1FC
|
#define EEPMWR 0x1FC
|
||||||
#define EEPMRD 0x1FD
|
#define EEPMRD 0x1FD
|
||||||
|
|
||||||
// PHILIPS LCD command set
|
// PHILIPS LCD command set
|
||||||
#define PNOP 0x100
|
#define PNOP 0x100
|
||||||
#define PSWRESET 0x101
|
#define PSWRESET 0x101
|
||||||
#define PBSTROFF 0x102
|
#define PBSTROFF 0x102
|
||||||
#define PBSTRON 0x103
|
#define PBSTRON 0x103
|
||||||
#define PRDDIDIF 0x104
|
#define PRDDIDIF 0x104
|
||||||
#define PRDDST 0x109
|
#define PRDDST 0x109
|
||||||
#define PSLEEPIN 0x110
|
#define PSLEEPIN 0x110
|
||||||
#define PSLEEPOUT 0x111
|
#define PSLEEPOUT 0x111
|
||||||
#define PPTLON 0x112
|
#define PPTLON 0x112
|
||||||
#define PNORON 0x113
|
#define PNORON 0x113
|
||||||
#define PINVOFF 0x120
|
#define PINVOFF 0x120
|
||||||
#define PINVON 0x121
|
#define PINVON 0x121
|
||||||
#define PDALO 0x122
|
#define PDALO 0x122
|
||||||
#define PDAL 0x123
|
#define PDAL 0x123
|
||||||
#define PSETCON 0x125
|
#define PSETCON 0x125
|
||||||
#define PDISPOFF 0x128
|
#define PDISPOFF 0x128
|
||||||
#define PDISPON 0x129
|
#define PDISPON 0x129
|
||||||
#define PCASET 0x12A
|
#define PCASET 0x12A
|
||||||
#define PPASET 0x12B
|
#define PPASET 0x12B
|
||||||
#define PRAMWR 0x12C
|
#define PRAMWR 0x12C
|
||||||
#define PRGBSET 0x12D
|
#define PRGBSET 0x12D
|
||||||
#define PPTLAR 0x130
|
#define PPTLAR 0x130
|
||||||
#define PVSCRDEF 0x133
|
#define PVSCRDEF 0x133
|
||||||
#define PTEOFF 0x134
|
#define PTEOFF 0x134
|
||||||
#define PTEON 0x135
|
#define PTEON 0x135
|
||||||
#define PMADCTL 0x136
|
#define PMADCTL 0x136
|
||||||
#define PSEP 0x137
|
#define PSEP 0x137
|
||||||
#define PIDMOFF 0x138
|
#define PIDMOFF 0x138
|
||||||
#define PIDMON 0x139
|
#define PIDMON 0x139
|
||||||
#define PCOLMOD 0x13A
|
#define PCOLMOD 0x13A
|
||||||
#define PSETVOP 0x1B0
|
#define PSETVOP 0x1B0
|
||||||
#define PBRS 0x1B4
|
#define PBRS 0x1B4
|
||||||
#define PTRS 0x1B6
|
#define PTRS 0x1B6
|
||||||
#define PFINV 0x1B9
|
#define PFINV 0x1B9
|
||||||
#define PDOR 0x1BA
|
#define PDOR 0x1BA
|
||||||
#define PTCDFE 0x1BD
|
#define PTCDFE 0x1BD
|
||||||
#define PTCVOPE 0x1BF
|
#define PTCVOPE 0x1BF
|
||||||
#define PEC 0x1C0
|
#define PEC 0x1C0
|
||||||
#define PSETMUL 0x1C2
|
#define PSETMUL 0x1C2
|
||||||
#define PTCVOPAB 0x1C3
|
#define PTCVOPAB 0x1C3
|
||||||
#define PTCVOPCD 0x1C4
|
#define PTCVOPCD 0x1C4
|
||||||
#define PTCDF 0x1C5
|
#define PTCDF 0x1C5
|
||||||
#define PDF8C 0x1C6
|
#define PDF8C 0x1C6
|
||||||
#define PSETBS 0x1C7
|
#define PSETBS 0x1C7
|
||||||
#define PRDTEMP 0x1C8
|
#define PRDTEMP 0x1C8
|
||||||
#define PNLI 0x1C9
|
#define PNLI 0x1C9
|
||||||
#define PRDID1 0x1DA
|
#define PRDID1 0x1DA
|
||||||
#define PRDID2 0x1DB
|
#define PRDID2 0x1DB
|
||||||
#define PRDID3 0x1DC
|
#define PRDID3 0x1DC
|
||||||
#define PSFD 0x1EF
|
#define PSFD 0x1EF
|
||||||
#define PECM 0x1F0
|
#define PECM 0x1F0
|
||||||
|
|
||||||
void LCDSend(unsigned int data);
|
void LCDSend(unsigned int data);
|
||||||
void LCDInit(void);
|
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
|
// iso15693.h
|
||||||
void RecordRawAdcSamplesIso15693(void);
|
void RecordRawAdcSamplesIso15693(void);
|
||||||
void AcquireRawAdcSamplesIso15693(void);
|
void AcquireRawAdcSamplesIso15693(void);
|
||||||
void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - 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 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 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 DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI - atrox
|
||||||
void Iso15693InitReader(void);
|
void Iso15693InitReader(void);
|
||||||
|
|
112
armsrc/buzzer.c
112
armsrc/buzzer.c
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
void Ring_BEE_ONCE(uint16_t music_note) {
|
void Ring_BEE_ONCE(uint16_t music_note) {
|
||||||
BEE_ON();
|
BEE_ON();
|
||||||
SpinDelayUs(music_note);
|
SpinDelayUs(music_note);
|
||||||
BEE_OFF();
|
BEE_OFF();
|
||||||
SpinDelayUs(music_note);
|
SpinDelayUs(music_note);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ring_2_7khz(uint16_t count) {
|
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) {
|
void Ring_BEE_TIME(uint16_t music_note,uint16_t count) {
|
||||||
for(uint16_t i=0 ; i < count; i++)
|
for(uint16_t i=0 ; i < count; i++)
|
||||||
Ring_BEE_ONCE(music_note);
|
Ring_BEE_ONCE(music_note);
|
||||||
SpinDelay(9);
|
SpinDelay(9);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ring_ALL(uint16_t count) {
|
void Ring_ALL(uint16_t count) {
|
||||||
|
@ -29,58 +29,58 @@ void Ring_ALL(uint16_t count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ring_Little_Star(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_1,count);
|
Ring_BEE_TIME(note_1,count);
|
||||||
Ring_BEE_TIME(note_5,count);
|
Ring_BEE_TIME(note_5,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_6,count);
|
Ring_BEE_TIME(note_6,count);
|
||||||
Ring_BEE_TIME(note_5,2*count);
|
Ring_BEE_TIME(note_5,2*count);
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
/*
|
/*
|
||||||
Ring_BEE_TIME(note_4,count);
|
Ring_BEE_TIME(note_4,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_3,count);
|
Ring_BEE_TIME(note_3,count);
|
||||||
Ring_BEE_TIME(note_2,count);
|
Ring_BEE_TIME(note_2,count);
|
||||||
Ring_BEE_TIME(note_2,count);
|
Ring_BEE_TIME(note_2,count);
|
||||||
Ring_BEE_TIME(note_1,2*count);
|
Ring_BEE_TIME(note_1,2*count);
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
|
|
||||||
Ring_BEE_TIME(note_5,count);
|
Ring_BEE_TIME(note_5,count);
|
||||||
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_4,count);
|
Ring_BEE_TIME(note_4,count);
|
||||||
Ring_BEE_TIME(note_3,count);
|
Ring_BEE_TIME(note_3,count);
|
||||||
Ring_BEE_TIME(note_3,count);
|
Ring_BEE_TIME(note_3,count);
|
||||||
Ring_BEE_TIME(note_2,2*count);
|
Ring_BEE_TIME(note_2,2*count);
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
Ring_BEE_TIME(note_5,count);
|
Ring_BEE_TIME(note_5,count);
|
||||||
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_4,count);
|
Ring_BEE_TIME(note_4,count);
|
||||||
Ring_BEE_TIME(note_3,count);
|
Ring_BEE_TIME(note_3,count);
|
||||||
Ring_BEE_TIME(note_3,count);
|
Ring_BEE_TIME(note_3,count);
|
||||||
Ring_BEE_TIME(note_2,2*count);
|
Ring_BEE_TIME(note_2,2*count);
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
|
|
||||||
Ring_BEE_TIME(note_1,count);
|
Ring_BEE_TIME(note_1,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_5,count);
|
Ring_BEE_TIME(note_5,count);
|
||||||
Ring_BEE_TIME(note_6,count);
|
Ring_BEE_TIME(note_6,count);
|
||||||
Ring_BEE_TIME(note_6,count);
|
Ring_BEE_TIME(note_6,count);
|
||||||
Ring_BEE_TIME(note_5,2*count);
|
Ring_BEE_TIME(note_5,2*count);
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
Ring_BEE_TIME(note_4,count);
|
Ring_BEE_TIME(note_4,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_3,count);
|
Ring_BEE_TIME(note_3,count);
|
||||||
Ring_BEE_TIME(note_2,count);
|
Ring_BEE_TIME(note_2,count);
|
||||||
Ring_BEE_TIME(note_2,count);
|
Ring_BEE_TIME(note_2,count);
|
||||||
Ring_BEE_TIME(note_1,2*count);
|
Ring_BEE_TIME(note_1,2*count);
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
*/
|
*/
|
||||||
}
|
}
|
450
armsrc/des.c
450
armsrc/des.c
|
@ -22,7 +22,7 @@
|
||||||
* \email daniel.otte@rub.de
|
* \email daniel.otte@rub.de
|
||||||
* \date 2007-06-16
|
* \date 2007-06-16
|
||||||
* \brief DES and EDE-DES implementation
|
* \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[] ={
|
const uint8_t e_permtab[] ={
|
||||||
4, 6, /* 4 bytes in 6 bytes out*/
|
4, 6, /* 4 bytes in 6 bytes out*/
|
||||||
32, 1, 2, 3, 4, 5,
|
32, 1, 2, 3, 4, 5,
|
||||||
4, 5, 6, 7, 8, 9,
|
4, 5, 6, 7, 8, 9,
|
||||||
8, 9, 10, 11, 12, 13,
|
8, 9, 10, 11, 12, 13,
|
||||||
12, 13, 14, 15, 16, 17,
|
12, 13, 14, 15, 16, 17,
|
||||||
16, 17, 18, 19, 20, 21,
|
16, 17, 18, 19, 20, 21,
|
||||||
20, 21, 22, 23, 24, 25,
|
20, 21, 22, 23, 24, 25,
|
||||||
24, 25, 26, 27, 28, 29,
|
24, 25, 26, 27, 28, 29,
|
||||||
28, 29, 30, 31, 32, 1
|
28, 29, 30, 31, 32, 1
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t p_permtab[] ={
|
const uint8_t p_permtab[] ={
|
||||||
4, 4, /* 32 bit -> 32 bit */
|
4, 4, /* 32 bit -> 32 bit */
|
||||||
16, 7, 20, 21,
|
16, 7, 20, 21,
|
||||||
29, 12, 28, 17,
|
29, 12, 28, 17,
|
||||||
1, 15, 23, 26,
|
1, 15, 23, 26,
|
||||||
5, 18, 31, 10,
|
5, 18, 31, 10,
|
||||||
2, 8, 24, 14,
|
2, 8, 24, 14,
|
||||||
32, 27, 3, 9,
|
32, 27, 3, 9,
|
||||||
19, 13, 30, 6,
|
19, 13, 30, 6,
|
||||||
22, 11, 4, 25
|
22, 11, 4, 25
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t ip_permtab[] ={
|
const uint8_t ip_permtab[] ={
|
||||||
8, 8, /* 64 bit -> 64 bit */
|
8, 8, /* 64 bit -> 64 bit */
|
||||||
58, 50, 42, 34, 26, 18, 10, 2,
|
58, 50, 42, 34, 26, 18, 10, 2,
|
||||||
60, 52, 44, 36, 28, 20, 12, 4,
|
60, 52, 44, 36, 28, 20, 12, 4,
|
||||||
62, 54, 46, 38, 30, 22, 14, 6,
|
62, 54, 46, 38, 30, 22, 14, 6,
|
||||||
64, 56, 48, 40, 32, 24, 16, 8,
|
64, 56, 48, 40, 32, 24, 16, 8,
|
||||||
57, 49, 41, 33, 25, 17, 9, 1,
|
57, 49, 41, 33, 25, 17, 9, 1,
|
||||||
59, 51, 43, 35, 27, 19, 11, 3,
|
59, 51, 43, 35, 27, 19, 11, 3,
|
||||||
61, 53, 45, 37, 29, 21, 13, 5,
|
61, 53, 45, 37, 29, 21, 13, 5,
|
||||||
63, 55, 47, 39, 31, 23, 15, 7
|
63, 55, 47, 39, 31, 23, 15, 7
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t inv_ip_permtab[] ={
|
const uint8_t inv_ip_permtab[] ={
|
||||||
8, 8, /* 64 bit -> 64 bit */
|
8, 8, /* 64 bit -> 64 bit */
|
||||||
40, 8, 48, 16, 56, 24, 64, 32,
|
40, 8, 48, 16, 56, 24, 64, 32,
|
||||||
39, 7, 47, 15, 55, 23, 63, 31,
|
39, 7, 47, 15, 55, 23, 63, 31,
|
||||||
38, 6, 46, 14, 54, 22, 62, 30,
|
38, 6, 46, 14, 54, 22, 62, 30,
|
||||||
37, 5, 45, 13, 53, 21, 61, 29,
|
37, 5, 45, 13, 53, 21, 61, 29,
|
||||||
36, 4, 44, 12, 52, 20, 60, 28,
|
36, 4, 44, 12, 52, 20, 60, 28,
|
||||||
35, 3, 43, 11, 51, 19, 59, 27,
|
35, 3, 43, 11, 51, 19, 59, 27,
|
||||||
34, 2, 42, 10, 50, 18, 58, 26,
|
34, 2, 42, 10, 50, 18, 58, 26,
|
||||||
33, 1, 41, 9, 49, 17, 57, 25
|
33, 1, 41, 9, 49, 17, 57, 25
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t pc1_permtab[] ={
|
const uint8_t pc1_permtab[] ={
|
||||||
8, 7, /* 64 bit -> 56 bit*/
|
8, 7, /* 64 bit -> 56 bit*/
|
||||||
57, 49, 41, 33, 25, 17, 9,
|
57, 49, 41, 33, 25, 17, 9,
|
||||||
1, 58, 50, 42, 34, 26, 18,
|
1, 58, 50, 42, 34, 26, 18,
|
||||||
10, 2, 59, 51, 43, 35, 27,
|
10, 2, 59, 51, 43, 35, 27,
|
||||||
19, 11, 3, 60, 52, 44, 36,
|
19, 11, 3, 60, 52, 44, 36,
|
||||||
63, 55, 47, 39, 31, 23, 15,
|
63, 55, 47, 39, 31, 23, 15,
|
||||||
7, 62, 54, 46, 38, 30, 22,
|
7, 62, 54, 46, 38, 30, 22,
|
||||||
14, 6, 61, 53, 45, 37, 29,
|
14, 6, 61, 53, 45, 37, 29,
|
||||||
21, 13, 5, 28, 20, 12, 4
|
21, 13, 5, 28, 20, 12, 4
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t pc2_permtab[] ={
|
const uint8_t pc2_permtab[] ={
|
||||||
7, 6, /* 56 bit -> 48 bit */
|
7, 6, /* 56 bit -> 48 bit */
|
||||||
14, 17, 11, 24, 1, 5,
|
14, 17, 11, 24, 1, 5,
|
||||||
3, 28, 15, 6, 21, 10,
|
3, 28, 15, 6, 21, 10,
|
||||||
23, 19, 12, 4, 26, 8,
|
23, 19, 12, 4, 26, 8,
|
||||||
16, 7, 27, 20, 13, 2,
|
16, 7, 27, 20, 13, 2,
|
||||||
41, 52, 31, 37, 47, 55,
|
41, 52, 31, 37, 47, 55,
|
||||||
30, 40, 51, 45, 33, 48,
|
30, 40, 51, 45, 33, 48,
|
||||||
44, 49, 39, 56, 34, 53,
|
44, 49, 39, 56, 34, 53,
|
||||||
46, 42, 50, 36, 29, 32
|
46, 42, 50, 36, 29, 32
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t splitin6bitword_permtab[] = {
|
const uint8_t splitin6bitword_permtab[] = {
|
||||||
8, 8, /* 64 bit -> 64 bit */
|
8, 8, /* 64 bit -> 64 bit */
|
||||||
64, 64, 1, 6, 2, 3, 4, 5,
|
64, 64, 1, 6, 2, 3, 4, 5,
|
||||||
64, 64, 7, 12, 8, 9, 10, 11,
|
64, 64, 7, 12, 8, 9, 10, 11,
|
||||||
64, 64, 13, 18, 14, 15, 16, 17,
|
64, 64, 13, 18, 14, 15, 16, 17,
|
||||||
64, 64, 19, 24, 20, 21, 22, 23,
|
64, 64, 19, 24, 20, 21, 22, 23,
|
||||||
64, 64, 25, 30, 26, 27, 28, 29,
|
64, 64, 25, 30, 26, 27, 28, 29,
|
||||||
64, 64, 31, 36, 32, 33, 34, 35,
|
64, 64, 31, 36, 32, 33, 34, 35,
|
||||||
64, 64, 37, 42, 38, 39, 40, 41,
|
64, 64, 37, 42, 38, 39, 40, 41,
|
||||||
64, 64, 43, 48, 44, 45, 46, 47
|
64, 64, 43, 48, 44, 45, 46, 47
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t shiftkey_permtab[] = {
|
const uint8_t shiftkey_permtab[] = {
|
||||||
7, 7, /* 56 bit -> 56 bit */
|
7, 7, /* 56 bit -> 56 bit */
|
||||||
2, 3, 4, 5, 6, 7, 8, 9,
|
2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
10, 11, 12, 13, 14, 15, 16, 17,
|
10, 11, 12, 13, 14, 15, 16, 17,
|
||||||
18, 19, 20, 21, 22, 23, 24, 25,
|
18, 19, 20, 21, 22, 23, 24, 25,
|
||||||
26, 27, 28, 1,
|
26, 27, 28, 1,
|
||||||
30, 31, 32, 33, 34, 35, 36, 37,
|
30, 31, 32, 33, 34, 35, 36, 37,
|
||||||
38, 39, 40, 41, 42, 43, 44, 45,
|
38, 39, 40, 41, 42, 43, 44, 45,
|
||||||
46, 47, 48, 49, 50, 51, 52, 53,
|
46, 47, 48, 49, 50, 51, 52, 53,
|
||||||
54, 55, 56, 29
|
54, 55, 56, 29
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t shiftkeyinv_permtab[] = {
|
const uint8_t shiftkeyinv_permtab[] = {
|
||||||
7, 7,
|
7, 7,
|
||||||
28, 1, 2, 3, 4, 5, 6, 7,
|
28, 1, 2, 3, 4, 5, 6, 7,
|
||||||
8, 9, 10, 11, 12, 13, 14, 15,
|
8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
16, 17, 18, 19, 20, 21, 22, 23,
|
16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
24, 25, 26, 27,
|
24, 25, 26, 27,
|
||||||
56, 29, 30, 31, 32, 33, 34, 35,
|
56, 29, 30, 31, 32, 33, 34, 35,
|
||||||
36, 37, 38, 39, 40, 41, 42, 43,
|
36, 37, 38, 39, 40, 41, 42, 43,
|
||||||
44, 45, 46, 47, 48, 49, 50, 51,
|
44, 45, 46, 47, 48, 49, 50, 51,
|
||||||
52, 53, 54, 55
|
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){
|
void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out){
|
||||||
uint8_t ob; /* in-bytes and out-bytes */
|
uint8_t ob; /* in-bytes and out-bytes */
|
||||||
uint8_t byte, bit; /* counter for bit and byte */
|
uint8_t byte, bit; /* counter for bit and byte */
|
||||||
ob = ptable[1];
|
ob = ptable[1];
|
||||||
ptable = &(ptable[2]);
|
ptable = &(ptable[2]);
|
||||||
for(byte=0; byte<ob; ++byte){
|
for(byte=0; byte<ob; ++byte){
|
||||||
uint8_t x,t=0;
|
uint8_t x,t=0;
|
||||||
for(bit=0; bit<8; ++bit){
|
for(bit=0; bit<8; ++bit){
|
||||||
x = *ptable++ - 1;
|
x = *ptable++ - 1;
|
||||||
t<<=1;
|
t<<=1;
|
||||||
if((in[x/8]) & (0x80>>(x%8)) ){
|
if((in[x/8]) & (0x80>>(x%8)) ){
|
||||||
t|=0x01;
|
t|=0x01;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out[byte]=t;
|
out[byte]=t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void changeendian32(uint32_t * a){
|
void changeendian32(uint32_t * a){
|
||||||
*a = (*a & 0x000000FF) << 24 |
|
*a = (*a & 0x000000FF) << 24 |
|
||||||
(*a & 0x0000FF00) << 8 |
|
(*a & 0x0000FF00) << 8 |
|
||||||
(*a & 0x00FF0000) >> 8 |
|
(*a & 0x00FF0000) >> 8 |
|
||||||
(*a & 0xFF000000) >> 24;
|
(*a & 0xFF000000) >> 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
static inline
|
static inline
|
||||||
void shiftkey(uint8_t *key){
|
void shiftkey(uint8_t *key){
|
||||||
uint8_t k[7];
|
uint8_t k[7];
|
||||||
memcpy(k, key, 7);
|
memcpy(k, key, 7);
|
||||||
permute((uint8_t*)shiftkey_permtab, k, key);
|
permute((uint8_t*)shiftkey_permtab, k, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
static inline
|
static inline
|
||||||
void shiftkey_inv(uint8_t *key){
|
void shiftkey_inv(uint8_t *key){
|
||||||
uint8_t k[7];
|
uint8_t k[7];
|
||||||
memcpy(k, key, 7);
|
memcpy(k, key, 7);
|
||||||
permute((uint8_t*)shiftkeyinv_permtab, k, key);
|
permute((uint8_t*)shiftkeyinv_permtab, k, key);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
static inline
|
static inline
|
||||||
uint64_t splitin6bitwords(uint64_t a){
|
uint64_t splitin6bitwords(uint64_t a){
|
||||||
uint64_t ret=0;
|
uint64_t ret=0;
|
||||||
a &= 0x0000ffffffffffffLL;
|
a &= 0x0000ffffffffffffLL;
|
||||||
permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);
|
permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
uint8_t substitute(uint8_t a, uint8_t * sbp){
|
uint8_t substitute(uint8_t a, uint8_t * sbp){
|
||||||
uint8_t x;
|
uint8_t x;
|
||||||
x = sbp[a>>1];
|
x = sbp[a>>1];
|
||||||
x = (a&1)?x&0x0F:x>>4;
|
x = (a&1)?x&0x0F:x>>4;
|
||||||
return x;
|
return x;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
uint32_t des_f(uint32_t r, uint8_t* kr){
|
uint32_t des_f(uint32_t r, uint8_t* kr){
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
uint32_t t=0,ret;
|
uint32_t t=0,ret;
|
||||||
uint64_t data;
|
uint64_t data;
|
||||||
uint8_t *sbp; /* sboxpointer */
|
uint8_t *sbp; /* sboxpointer */
|
||||||
permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
|
permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
|
||||||
for(i=0; i<6; ++i)
|
for(i=0; i<6; ++i)
|
||||||
((uint8_t*)&data)[i] ^= kr[i];
|
((uint8_t*)&data)[i] ^= kr[i];
|
||||||
|
|
||||||
/* Sbox substitution */
|
/* Sbox substitution */
|
||||||
data = splitin6bitwords(data);
|
data = splitin6bitwords(data);
|
||||||
sbp=(uint8_t*)sbox;
|
sbp=(uint8_t*)sbox;
|
||||||
for(i=0; i<8; ++i){
|
for(i=0; i<8; ++i){
|
||||||
uint8_t x;
|
uint8_t x;
|
||||||
x = substitute(((uint8_t*)&data)[i], sbp);
|
x = substitute(((uint8_t*)&data)[i], sbp);
|
||||||
t<<=4;
|
t<<=4;
|
||||||
t |= x;
|
t |= x;
|
||||||
sbp += 32;
|
sbp += 32;
|
||||||
}
|
}
|
||||||
changeendian32(&t);
|
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 {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
uint8_t v8[8];
|
uint8_t v8[8];
|
||||||
uint32_t v32[2];
|
uint32_t v32[2];
|
||||||
} d;
|
} d;
|
||||||
} data_t;
|
} data_t;
|
||||||
#define R (data.d.v32[1])
|
#define R (data.d.v32[1])
|
||||||
#define L (data.d.v32[0])
|
#define L (data.d.v32[0])
|
||||||
|
|
||||||
void des_enc(void* out, const void* in, const void* key){
|
void des_enc(void* out, const void* in, const void* key){
|
||||||
|
|
||||||
uint8_t kr[6], k[7];
|
uint8_t kr[6], k[7];
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
data_t data;
|
data_t data;
|
||||||
|
|
||||||
permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8);
|
permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8);
|
||||||
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||||
|
|
||||||
for(i=0; i<8; ++i){
|
for(i=0; i<8; ++i){
|
||||||
shiftkey(k);
|
shiftkey(k);
|
||||||
if(ROTTABLE&((1<<((i<<1)+0))) )
|
if(ROTTABLE&((1<<((i<<1)+0))) )
|
||||||
shiftkey(k);
|
shiftkey(k);
|
||||||
permute((uint8_t*)pc2_permtab, k, kr);
|
permute((uint8_t*)pc2_permtab, k, kr);
|
||||||
L ^= des_f(R, kr);
|
L ^= des_f(R, kr);
|
||||||
|
|
||||||
shiftkey(k);
|
shiftkey(k);
|
||||||
if(ROTTABLE&((1<<((i<<1)+1))) )
|
if(ROTTABLE&((1<<((i<<1)+1))) )
|
||||||
shiftkey(k);
|
shiftkey(k);
|
||||||
permute((uint8_t*)pc2_permtab, k, kr);
|
permute((uint8_t*)pc2_permtab, k, kr);
|
||||||
R ^= des_f(L, kr);
|
R ^= des_f(L, kr);
|
||||||
|
|
||||||
}
|
}
|
||||||
/* L <-> R*/
|
/* L <-> R*/
|
||||||
R ^= L;
|
R ^= L;
|
||||||
L ^= R;
|
L ^= R;
|
||||||
R ^= L;
|
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){
|
void des_dec(void* out, const void* in, const uint8_t* key){
|
||||||
|
|
||||||
uint8_t kr[6],k[7];
|
uint8_t kr[6],k[7];
|
||||||
int8_t i;
|
int8_t i;
|
||||||
data_t data;
|
data_t data;
|
||||||
|
|
||||||
permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8);
|
permute((uint8_t*)ip_permtab, (uint8_t*)in, data.d.v8);
|
||||||
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||||
for(i=7; i>=0; --i){
|
for(i=7; i>=0; --i){
|
||||||
|
|
||||||
permute((uint8_t*)pc2_permtab, k, kr);
|
permute((uint8_t*)pc2_permtab, k, kr);
|
||||||
L ^= des_f(R, kr);
|
L ^= des_f(R, kr);
|
||||||
shiftkey_inv(k);
|
shiftkey_inv(k);
|
||||||
if(ROTTABLE&((1<<((i<<1)+1))) ){
|
if(ROTTABLE&((1<<((i<<1)+1))) ){
|
||||||
shiftkey_inv(k);
|
shiftkey_inv(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
permute((uint8_t*)pc2_permtab, k, kr);
|
permute((uint8_t*)pc2_permtab, k, kr);
|
||||||
R ^= des_f(L, kr);
|
R ^= des_f(L, kr);
|
||||||
shiftkey_inv(k);
|
shiftkey_inv(k);
|
||||||
if(ROTTABLE&((1<<((i<<1)+0))) ){
|
if(ROTTABLE&((1<<((i<<1)+0))) ){
|
||||||
shiftkey_inv(k);
|
shiftkey_inv(k);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
/* L <-> R*/
|
/* L <-> R*/
|
||||||
R ^= L;
|
R ^= L;
|
||||||
L ^= R;
|
L ^= R;
|
||||||
R ^= L;
|
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){
|
void tdes_enc(void* out, void* in, const void* key){
|
||||||
des_enc(out, in, (uint8_t*)key + 0);
|
des_enc(out, in, (uint8_t*)key + 0);
|
||||||
des_dec(out, out, (uint8_t*)key + 8);
|
des_dec(out, out, (uint8_t*)key + 8);
|
||||||
des_enc(out, out, (uint8_t*)key +16);
|
des_enc(out, out, (uint8_t*)key +16);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
void tdes_dec(void* out, void* in, const uint8_t* key){
|
void tdes_dec(void* out, void* in, const uint8_t* key){
|
||||||
des_dec(out, in, (uint8_t*)key +16);
|
des_dec(out, in, (uint8_t*)key +16);
|
||||||
des_enc(out, out, (uint8_t*)key + 8);
|
des_enc(out, out, (uint8_t*)key + 8);
|
||||||
des_dec(out, out, (uint8_t*)key + 0);
|
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]){
|
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 i;
|
||||||
uint8_t* tin = (uint8_t*) in;
|
uint8_t* tin = (uint8_t*) in;
|
||||||
uint8_t* tout = (uint8_t*) out;
|
uint8_t* tout = (uint8_t*) out;
|
||||||
|
|
||||||
while( length > 0 )
|
while( length > 0 )
|
||||||
{
|
{
|
||||||
for( i = 0; i < 8; i++ )
|
for( i = 0; i < 8; i++ )
|
||||||
tout[i] = (unsigned char)( tin[i] ^ iv[i] );
|
tout[i] = (unsigned char)( tin[i] ^ iv[i] );
|
||||||
|
|
||||||
des_enc(tout, tin, (uint8_t*)key + 0);
|
des_enc(tout, tin, (uint8_t*)key + 0);
|
||||||
des_dec(tout, tout, (uint8_t*)key + 8);
|
des_dec(tout, tout, (uint8_t*)key + 8);
|
||||||
des_enc(tout, tout, (uint8_t*)key + 0);
|
des_enc(tout, tout, (uint8_t*)key + 0);
|
||||||
|
|
||||||
memcpy( iv, tout, 8 );
|
memcpy( iv, tout, 8 );
|
||||||
|
|
||||||
tin += 8;
|
tin += 8;
|
||||||
tout += 8;
|
tout += 8;
|
||||||
length -= 8;
|
length -= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tdes_2key_dec(void* out, const void* in, size_t length, const void* key, unsigned char iv[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;
|
uint8_t i;
|
||||||
unsigned char temp[8];
|
unsigned char temp[8];
|
||||||
uint8_t* tin = (uint8_t*) in;
|
uint8_t* tin = (uint8_t*) in;
|
||||||
uint8_t* tout = (uint8_t*) out;
|
uint8_t* tout = (uint8_t*) out;
|
||||||
|
|
||||||
while( length > 0 )
|
while( length > 0 )
|
||||||
{
|
{
|
||||||
memcpy( temp, tin, 8 );
|
memcpy( temp, tin, 8 );
|
||||||
|
|
||||||
des_dec(tout, tin, (uint8_t*)key + 0);
|
des_dec(tout, tin, (uint8_t*)key + 0);
|
||||||
des_enc(tout, tout, (uint8_t*)key + 8);
|
des_enc(tout, tout, (uint8_t*)key + 8);
|
||||||
des_dec(tout, tout, (uint8_t*)key + 0);
|
des_dec(tout, tout, (uint8_t*)key + 0);
|
||||||
|
|
||||||
for( i = 0; i < 8; i++ )
|
for( i = 0; i < 8; i++ )
|
||||||
tout[i] = (unsigned char)( tout[i] ^ iv[i] );
|
tout[i] = (unsigned char)( tout[i] ^ iv[i] );
|
||||||
|
|
||||||
memcpy( iv, temp, 8 );
|
memcpy( iv, temp, 8 );
|
||||||
|
|
||||||
tin += 8;
|
tin += 8;
|
||||||
tout += 8;
|
tout += 8;
|
||||||
length -= 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/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* \file des.h
|
* \file des.h
|
||||||
* \author Daniel Otte
|
* \author Daniel Otte
|
||||||
* \date 2007-06-16
|
* \date 2007-06-16
|
||||||
* \brief des and tdes declarations
|
* \brief des and tdes declarations
|
||||||
* \license GPLv3 or later
|
* \license GPLv3 or later
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifndef __DES_H_
|
#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);
|
mifare_cypher_blocks_chained (NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER);
|
||||||
|
|
||||||
memcpy (cmac, ivect, kbs);
|
memcpy (cmac, ivect, kbs);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t key_block_size (const desfirekey_t key) {
|
size_t key_block_size (const desfirekey_t key) {
|
||||||
size_t block_size = 8;
|
size_t block_size = 8;
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
case T_DES:
|
case T_DES:
|
||||||
case T_3DES:
|
case T_3DES:
|
||||||
case T_3K3DES:
|
case T_3K3DES:
|
||||||
block_size = 8;
|
block_size = 8;
|
||||||
break;
|
break;
|
||||||
case T_AES:
|
case T_AES:
|
||||||
block_size = 16;
|
block_size = 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return block_size;
|
return block_size;
|
||||||
}
|
}
|
||||||
|
@ -211,7 +211,7 @@ void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes
|
||||||
break;
|
break;
|
||||||
// Append MAC
|
// Append MAC
|
||||||
size_t bla = maced_data_length (DESFIRE(tag)->session_key, *nbytes - offset) + offset;
|
size_t bla = maced_data_length (DESFIRE(tag)->session_key, *nbytes - offset) + offset;
|
||||||
bla++;
|
bla++;
|
||||||
|
|
||||||
memcpy (res + *nbytes, mac, 4);
|
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) {
|
if (append_mac) {
|
||||||
size_t len = maced_data_length (key, *nbytes);
|
size_t len = maced_data_length (key, *nbytes);
|
||||||
++len;
|
++len;
|
||||||
memcpy (res, data, *nbytes);
|
memcpy (res, data, *nbytes);
|
||||||
memcpy (res + *nbytes, DESFIRE (tag)->cmac, CMAC_LENGTH);
|
memcpy (res + *nbytes, DESFIRE (tag)->cmac, CMAC_LENGTH);
|
||||||
*nbytes += 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:
|
case AS_LEGACY:
|
||||||
AddCrc14A( (uint8_t*)res, end_crc_pos);
|
AddCrc14A( (uint8_t*)res, end_crc_pos);
|
||||||
end_crc_pos = crc_pos + 2;
|
end_crc_pos = crc_pos + 2;
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
crc = crc16;
|
crc = crc16;
|
||||||
|
@ -529,11 +529,11 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case MCO_ENCYPHER:
|
case MCO_ENCYPHER:
|
||||||
//DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
|
//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;
|
break;
|
||||||
case MCO_DECYPHER:
|
case MCO_DECYPHER:
|
||||||
//DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
|
//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;
|
||||||
}
|
}
|
||||||
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 *) 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 *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
|
||||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
|
// 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;
|
break;
|
||||||
case MCO_DECYPHER:
|
case MCO_DECYPHER:
|
||||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
|
// 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 *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
|
||||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
|
// 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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_3K3DES:
|
case T_3K3DES:
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case MCO_ENCYPHER:
|
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 *) 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 *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
|
||||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
|
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
|
||||||
break;
|
break;
|
||||||
case MCO_DECYPHER:
|
case MCO_DECYPHER:
|
||||||
tdes_dec(data, edata, key->data);
|
tdes_dec(data, edata, key->data);
|
||||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT);
|
// 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 *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
|
||||||
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
|
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
|
||||||
break;
|
break;
|
||||||
|
@ -571,21 +571,21 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect
|
||||||
break;
|
break;
|
||||||
case T_AES:
|
case T_AES:
|
||||||
switch (operation)
|
switch (operation)
|
||||||
{
|
{
|
||||||
case MCO_ENCYPHER:
|
case MCO_ENCYPHER:
|
||||||
{
|
{
|
||||||
AesCtx ctx;
|
AesCtx ctx;
|
||||||
AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
|
AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
|
||||||
AesEncrypt(&ctx, data, edata, sizeof(edata) );
|
AesEncrypt(&ctx, data, edata, sizeof(edata) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MCO_DECYPHER:
|
case MCO_DECYPHER:
|
||||||
{
|
{
|
||||||
AesCtx ctx;
|
AesCtx ctx;
|
||||||
AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
|
AesCtxIni(&ctx, ivect, key->data, KEY128,CBC);
|
||||||
AesDecrypt(&ctx, edata, data, sizeof(edata));
|
AesDecrypt(&ctx, edata, data, sizeof(edata));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -620,11 +620,11 @@ void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *
|
||||||
ivect = DESFIRE (tag)->ivect;
|
ivect = DESFIRE (tag)->ivect;
|
||||||
|
|
||||||
switch (DESFIRE (tag)->authentication_scheme) {
|
switch (DESFIRE (tag)->authentication_scheme) {
|
||||||
case AS_LEGACY:
|
case AS_LEGACY:
|
||||||
memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
|
memset (ivect, 0, MAX_CRYPTO_BLOCK_SIZE);
|
||||||
break;
|
break;
|
||||||
case AS_NEW:
|
case AS_NEW:
|
||||||
break;
|
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) {
|
void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key) {
|
||||||
if ( key != NULL) {
|
if ( key != NULL) {
|
||||||
key->type = T_DES;
|
key->type = T_DES;
|
||||||
memcpy (key->data, value, 8);
|
memcpy (key->data, value, 8);
|
||||||
memcpy (key->data+8, value, 8);
|
memcpy (key->data+8, value, 8);
|
||||||
update_key_schedules (key);
|
update_key_schedules (key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t 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) {
|
void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key) {
|
||||||
if ( key != NULL ){
|
if ( key != NULL ){
|
||||||
key->type = T_3DES;
|
key->type = T_3DES;
|
||||||
memcpy (key->data, value, 16);
|
memcpy (key->data, value, 16);
|
||||||
memcpy (key->data + 16, value, 8);
|
memcpy (key->data + 16, value, 8);
|
||||||
update_key_schedules (key);
|
update_key_schedules (key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t 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) {
|
void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key) {
|
||||||
if ( key != NULL){
|
if ( key != NULL){
|
||||||
key->type = T_3K3DES;
|
key->type = T_3K3DES;
|
||||||
memcpy (key->data, value, 24);
|
memcpy (key->data, value, 24);
|
||||||
update_key_schedules (key);
|
update_key_schedules (key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t 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) {
|
void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version, desfirekey_t key) {
|
||||||
|
|
||||||
if (key != NULL) {
|
if (key != NULL) {
|
||||||
memcpy (key->data, value, 16);
|
memcpy (key->data, value, 16);
|
||||||
key->type = T_AES;
|
key->type = T_AES;
|
||||||
key->aes_version = version;
|
key->aes_version = version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t Desfire_key_get_version (desfirekey_t key) {
|
uint8_t Desfire_key_get_version (desfirekey_t key) {
|
||||||
|
|
|
@ -6,15 +6,15 @@
|
||||||
#include "iso14443a.h"
|
#include "iso14443a.h"
|
||||||
#include "desfire.h"
|
#include "desfire.h"
|
||||||
//#include "mifare.h" // iso14a_card_select_t struct
|
//#include "mifare.h" // iso14a_card_select_t struct
|
||||||
void Desfire_des_key_new (const uint8_t value[8], 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_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_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_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 (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_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 (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);
|
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);
|
uint8_t Desfire_key_get_version (desfirekey_t key);
|
||||||
void Desfire_key_set_version (desfirekey_t key, uint8_t version);
|
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_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key);
|
||||||
#endif
|
#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
|
// General Authenticate (request encrypted nonce) WITHOUT the Le at the end
|
||||||
static const uint8_t apdu_general_authenticate_pace_get_nonce[] = {
|
static const uint8_t apdu_general_authenticate_pace_get_nonce[] = {
|
||||||
0x10, // CLA
|
0x10, // CLA
|
||||||
0x86, // INS
|
0x86, // INS
|
||||||
0x00, // P1
|
0x00, // P1
|
||||||
0x00, // P2
|
0x00, // P2
|
||||||
0x02, // Lc
|
0x02, // Lc
|
||||||
0x7C, // Type: Dynamic Authentication Data
|
0x7C, // Type: Dynamic Authentication Data
|
||||||
0x00, // Length: 0 bytes
|
0x00, // Length: 0 bytes
|
||||||
};
|
};
|
||||||
|
|
||||||
// MSE: Set AT (only CLA, INS, P1 and P2)
|
// MSE: Set AT (only CLA, INS, P1 and P2)
|
||||||
static const uint8_t apdu_mse_set_at_start[] = {
|
static const uint8_t apdu_mse_set_at_start[] = {
|
||||||
0x00, // CLA
|
0x00, // CLA
|
||||||
0x22, // INS
|
0x22, // INS
|
||||||
0xC1, // P1
|
0xC1, // P1
|
||||||
0xA4, // P2
|
0xA4, // P2
|
||||||
};
|
};
|
||||||
|
|
||||||
// SELECT BINARY with the ID for EF.CardAccess
|
// SELECT BINARY with the ID for EF.CardAccess
|
||||||
static const uint8_t apdu_select_binary_cardaccess[] = {
|
static const uint8_t apdu_select_binary_cardaccess[] = {
|
||||||
0x00, // CLA
|
0x00, // CLA
|
||||||
0xA4, // INS
|
0xA4, // INS
|
||||||
0x02, // P1
|
0x02, // P1
|
||||||
0x0C, // P2
|
0x0C, // P2
|
||||||
0x02, // Lc
|
0x02, // Lc
|
||||||
0x01, // ID
|
0x01, // ID
|
||||||
0x1C // ID
|
0x1C // ID
|
||||||
};
|
};
|
||||||
|
|
||||||
// READ BINARY
|
// READ BINARY
|
||||||
static const uint8_t apdu_read_binary[] = {
|
static const uint8_t apdu_read_binary[] = {
|
||||||
0x00, // CLA
|
0x00, // CLA
|
||||||
0xB0, // INS
|
0xB0, // INS
|
||||||
0x00, // P1
|
0x00, // P1
|
||||||
0x00, // P2
|
0x00, // P2
|
||||||
0x38 // Le
|
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];
|
static uint8_t apdu_replay_general_authenticate_pace_perform_key_agreement[18];
|
||||||
// pointers to the APDUs (for iterations)
|
// pointers to the APDUs (for iterations)
|
||||||
static struct {
|
static struct {
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
} const apdus_replay[] = {
|
} const apdus_replay[] = {
|
||||||
{sizeof(apdu_replay_mse_set_at_pace), apdu_replay_mse_set_at_pace},
|
{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_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_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_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_general_authenticate_pace_perform_key_agreement), apdu_replay_general_authenticate_pace_perform_key_agreement}
|
||||||
};
|
};
|
||||||
|
|
||||||
// lengths of the replay APDUs
|
// 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)
|
int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response)
|
||||||
{
|
{
|
||||||
switch(iso_type)
|
switch(iso_type)
|
||||||
{
|
{
|
||||||
case 'a':
|
case 'a':
|
||||||
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
|
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
return iso14443b_apdu(apdu, length, response);
|
return iso14443b_apdu(apdu, length, response);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -124,9 +124,9 @@ int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void EPA_Finish()
|
void EPA_Finish()
|
||||||
{
|
{
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
iso_type = 0;
|
iso_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -146,68 +146,68 @@ size_t EPA_Parse_CardAccess(uint8_t *data,
|
||||||
size_t length,
|
size_t length,
|
||||||
pace_version_info_t *pace_info)
|
pace_version_info_t *pace_info)
|
||||||
{
|
{
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
|
|
||||||
while (index <= length - 2) {
|
while (index <= length - 2) {
|
||||||
// determine type of element
|
// determine type of element
|
||||||
// SET or SEQUENCE
|
// SET or SEQUENCE
|
||||||
if (data[index] == 0x31 || data[index] == 0x30) {
|
if (data[index] == 0x31 || data[index] == 0x30) {
|
||||||
// enter the set (skip tag + length)
|
// enter the set (skip tag + length)
|
||||||
index += 2;
|
index += 2;
|
||||||
// check for extended length
|
// check for extended length
|
||||||
if ((data[index - 1] & 0x80) != 0) {
|
if ((data[index - 1] & 0x80) != 0) {
|
||||||
index += (data[index-1] & 0x7F);
|
index += (data[index-1] & 0x7F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// OID
|
// OID
|
||||||
else if (data[index] == 0x06) {
|
else if (data[index] == 0x06) {
|
||||||
// is this a PACE OID?
|
// is this a PACE OID?
|
||||||
if (data[index + 1] == 0x0A // length matches
|
if (data[index + 1] == 0x0A // length matches
|
||||||
&& memcmp(data + index + 2,
|
&& memcmp(data + index + 2,
|
||||||
oid_pace_start,
|
oid_pace_start,
|
||||||
sizeof(oid_pace_start)) == 0 // content matches
|
sizeof(oid_pace_start)) == 0 // content matches
|
||||||
&& pace_info != NULL)
|
&& pace_info != NULL)
|
||||||
{
|
{
|
||||||
// first, clear the pace_info struct
|
// first, clear the pace_info struct
|
||||||
memset(pace_info, 0, sizeof(pace_version_info_t));
|
memset(pace_info, 0, sizeof(pace_version_info_t));
|
||||||
memcpy(pace_info->oid, data + index + 2, sizeof(pace_info->oid));
|
memcpy(pace_info->oid, data + index + 2, sizeof(pace_info->oid));
|
||||||
// a PACE OID is followed by the version
|
// a PACE OID is followed by the version
|
||||||
index += data[index + 1] + 2;
|
index += data[index + 1] + 2;
|
||||||
if (data[index] == 02 && data[index + 1] == 01) {
|
if (data[index] == 02 && data[index + 1] == 01) {
|
||||||
pace_info->version = data[index + 2];
|
pace_info->version = data[index + 2];
|
||||||
index += 3;
|
index += 3;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
// after that there might(!) be the parameter ID
|
// after that there might(!) be the parameter ID
|
||||||
if (data[index] == 02 && data[index + 1] == 01) {
|
if (data[index] == 02 && data[index + 1] == 01) {
|
||||||
pace_info->parameter_id = data[index + 2];
|
pace_info->parameter_id = data[index + 2];
|
||||||
index += 3;
|
index += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// skip this OID
|
// skip this OID
|
||||||
index += 2 + data[index + 1];
|
index += 2 + data[index + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if the length is 0, something is wrong
|
// if the length is 0, something is wrong
|
||||||
// TODO: This needs to be extended to support long tags
|
// TODO: This needs to be extended to support long tags
|
||||||
else if (data[index + 1] == 0) {
|
else if (data[index + 1] == 0) {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// skip this part
|
// skip this part
|
||||||
// TODO: This needs to be extended to support long tags
|
// TODO: This needs to be extended to support long tags
|
||||||
// TODO: This needs to be extended to support unknown elements with
|
// TODO: This needs to be extended to support unknown elements with
|
||||||
// a size > 0x7F
|
// a size > 0x7F
|
||||||
index += 2 + data[index + 1];
|
index += 2 + data[index + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: We should check whether we reached the end in error, but for that
|
// 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)
|
// we need a better parser (e.g. with states like IN_SET or IN_PACE_INFO)
|
||||||
return 0;
|
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)
|
int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
|
||||||
{
|
{
|
||||||
// the response APDU of the card
|
// the response APDU of the card
|
||||||
// since the card doesn't always care for the expected length we send it,
|
// 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)
|
// we reserve 262 bytes here just to be safe (256-byte APDU + SW + ISO frame)
|
||||||
uint8_t response_apdu[262];
|
uint8_t response_apdu[262];
|
||||||
int rapdu_length = 0;
|
int rapdu_length = 0;
|
||||||
|
|
||||||
// select the file EF.CardAccess
|
// select the file EF.CardAccess
|
||||||
rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess,
|
rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess,
|
||||||
sizeof(apdu_select_binary_cardaccess),
|
sizeof(apdu_select_binary_cardaccess),
|
||||||
response_apdu);
|
response_apdu);
|
||||||
if (rapdu_length < 6
|
if (rapdu_length < 6
|
||||||
|| response_apdu[rapdu_length - 4] != 0x90
|
|| response_apdu[rapdu_length - 4] != 0x90
|
||||||
|| response_apdu[rapdu_length - 3] != 0x00)
|
|| response_apdu[rapdu_length - 3] != 0x00)
|
||||||
{
|
{
|
||||||
DbpString("Failed to select EF.CardAccess!");
|
DbpString("Failed to select EF.CardAccess!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the file
|
// read the file
|
||||||
rapdu_length = EPA_APDU((uint8_t *)apdu_read_binary,
|
rapdu_length = EPA_APDU((uint8_t *)apdu_read_binary,
|
||||||
sizeof(apdu_read_binary),
|
sizeof(apdu_read_binary),
|
||||||
response_apdu);
|
response_apdu);
|
||||||
if (rapdu_length <= 6
|
if (rapdu_length <= 6
|
||||||
|| response_apdu[rapdu_length - 4] != 0x90
|
|| response_apdu[rapdu_length - 4] != 0x90
|
||||||
|| response_apdu[rapdu_length - 3] != 0x00)
|
|| response_apdu[rapdu_length - 3] != 0x00)
|
||||||
{
|
{
|
||||||
Dbprintf("Failed to read EF.CardAccess!");
|
Dbprintf("Failed to read EF.CardAccess!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the content into the buffer
|
// copy the content into the buffer
|
||||||
// length of data available: apdu_length - 4 (ISO frame) - 2 (SW)
|
// length of data available: apdu_length - 4 (ISO frame) - 2 (SW)
|
||||||
size_t to_copy = rapdu_length - 6;
|
size_t to_copy = rapdu_length - 6;
|
||||||
to_copy = to_copy < max_length ? to_copy : max_length;
|
to_copy = to_copy < max_length ? to_copy : max_length;
|
||||||
memcpy(buffer, response_apdu+2, to_copy);
|
memcpy(buffer, response_apdu+2, to_copy);
|
||||||
return 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)
|
static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
|
||||||
{
|
{
|
||||||
// power down the field
|
// power down the field
|
||||||
EPA_Finish();
|
EPA_Finish();
|
||||||
|
|
||||||
// send the USB packet
|
// send the USB packet
|
||||||
cmd_send(CMD_ACK,step,func_return,0,0,0);
|
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)
|
void EPA_PACE_Collect_Nonce(UsbCommand *c)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* ack layout:
|
* ack layout:
|
||||||
* arg:
|
* arg:
|
||||||
* 1. element
|
* 1. element
|
||||||
* step where the error occured or 0 if no error occured
|
* step where the error occured or 0 if no error occured
|
||||||
* 2. element
|
* 2. element
|
||||||
* return code of the last executed function
|
* return code of the last executed function
|
||||||
* d:
|
* d:
|
||||||
* Encrypted nonce
|
* Encrypted nonce
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// return value of a function
|
// return value of a function
|
||||||
int func_return = 0;
|
int func_return = 0;
|
||||||
|
|
||||||
// set up communication
|
// set up communication
|
||||||
func_return = EPA_Setup();
|
func_return = EPA_Setup();
|
||||||
if (func_return != 0) {
|
if (func_return != 0) {
|
||||||
EPA_PACE_Collect_Nonce_Abort(1, func_return);
|
EPA_PACE_Collect_Nonce_Abort(1, func_return);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the CardAccess file
|
// read the CardAccess file
|
||||||
// this array will hold the CardAccess file
|
// this array will hold the CardAccess file
|
||||||
uint8_t card_access[256] = {0};
|
uint8_t card_access[256] = {0};
|
||||||
int card_access_length = EPA_Read_CardAccess(card_access, 256);
|
int card_access_length = EPA_Read_CardAccess(card_access, 256);
|
||||||
// the response has to be at least this big to hold the OID
|
// the response has to be at least this big to hold the OID
|
||||||
if (card_access_length < 18) {
|
if (card_access_length < 18) {
|
||||||
EPA_PACE_Collect_Nonce_Abort(2, card_access_length);
|
EPA_PACE_Collect_Nonce_Abort(2, card_access_length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this will hold the PACE info of the card
|
// this will hold the PACE info of the card
|
||||||
pace_version_info_t pace_version_info;
|
pace_version_info_t pace_version_info;
|
||||||
// search for the PACE OID
|
// search for the PACE OID
|
||||||
func_return = EPA_Parse_CardAccess(card_access,
|
func_return = EPA_Parse_CardAccess(card_access,
|
||||||
card_access_length,
|
card_access_length,
|
||||||
&pace_version_info);
|
&pace_version_info);
|
||||||
if (func_return != 0 || pace_version_info.version == 0) {
|
if (func_return != 0 || pace_version_info.version == 0) {
|
||||||
EPA_PACE_Collect_Nonce_Abort(3, func_return);
|
EPA_PACE_Collect_Nonce_Abort(3, func_return);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// initiate the PACE protocol
|
// initiate the PACE protocol
|
||||||
// use the CAN for the password since that doesn't change
|
// use the CAN for the password since that doesn't change
|
||||||
func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2);
|
func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2);
|
||||||
|
|
||||||
// now get the nonce
|
// now get the nonce
|
||||||
uint8_t nonce[256] = {0};
|
uint8_t nonce[256] = {0};
|
||||||
uint8_t requested_size = (uint8_t)c->arg[0];
|
uint8_t requested_size = (uint8_t)c->arg[0];
|
||||||
func_return = EPA_PACE_Get_Nonce(requested_size, nonce);
|
func_return = EPA_PACE_Get_Nonce(requested_size, nonce);
|
||||||
// check if the command succeeded
|
// check if the command succeeded
|
||||||
if (func_return < 0)
|
if (func_return < 0)
|
||||||
{
|
{
|
||||||
EPA_PACE_Collect_Nonce_Abort(4, func_return);
|
EPA_PACE_Collect_Nonce_Abort(4, func_return);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// all done, return
|
// all done, return
|
||||||
EPA_Finish();
|
EPA_Finish();
|
||||||
|
|
||||||
// save received information
|
// save received information
|
||||||
cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
|
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)
|
int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce)
|
||||||
{
|
{
|
||||||
// build the APDU
|
// build the APDU
|
||||||
uint8_t apdu[sizeof(apdu_general_authenticate_pace_get_nonce) + 1];
|
uint8_t apdu[sizeof(apdu_general_authenticate_pace_get_nonce) + 1];
|
||||||
// copy the constant part
|
// copy the constant part
|
||||||
memcpy(apdu,
|
memcpy(apdu,
|
||||||
apdu_general_authenticate_pace_get_nonce,
|
apdu_general_authenticate_pace_get_nonce,
|
||||||
sizeof(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
|
// 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;
|
apdu[sizeof(apdu_general_authenticate_pace_get_nonce)] = requested_length + 4;
|
||||||
|
|
||||||
// send it
|
// send it
|
||||||
uint8_t response_apdu[262];
|
uint8_t response_apdu[262];
|
||||||
int send_return = EPA_APDU(apdu,
|
int send_return = EPA_APDU(apdu,
|
||||||
sizeof(apdu),
|
sizeof(apdu),
|
||||||
response_apdu);
|
response_apdu);
|
||||||
// check if the command succeeded
|
// check if the command succeeded
|
||||||
if (send_return < 6
|
if (send_return < 6
|
||||||
|| response_apdu[send_return - 4] != 0x90
|
|| response_apdu[send_return - 4] != 0x90
|
||||||
|| response_apdu[send_return - 3] != 0x00)
|
|| response_apdu[send_return - 3] != 0x00)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there is no nonce in the RAPDU, return here
|
// if there is no nonce in the RAPDU, return here
|
||||||
if (send_return < 10)
|
if (send_return < 10)
|
||||||
{
|
{
|
||||||
// no error
|
// no error
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// get the actual length of the nonce
|
// get the actual length of the nonce
|
||||||
uint8_t nonce_length = response_apdu[5];
|
uint8_t nonce_length = response_apdu[5];
|
||||||
if (nonce_length > send_return - 10)
|
if (nonce_length > send_return - 10)
|
||||||
{
|
{
|
||||||
nonce_length = send_return - 10;
|
nonce_length = send_return - 10;
|
||||||
}
|
}
|
||||||
// copy the nonce
|
// copy the nonce
|
||||||
memcpy(nonce, response_apdu + 6, nonce_length);
|
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)
|
int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
|
||||||
{
|
{
|
||||||
// create the MSE: Set AT APDU
|
// create the MSE: Set AT APDU
|
||||||
uint8_t apdu[23];
|
uint8_t apdu[23];
|
||||||
// the minimum length (will be increased as more data is added)
|
// the minimum length (will be increased as more data is added)
|
||||||
size_t apdu_length = 20;
|
size_t apdu_length = 20;
|
||||||
// copy the constant part
|
// copy the constant part
|
||||||
memcpy(apdu,
|
memcpy(apdu,
|
||||||
apdu_mse_set_at_start,
|
apdu_mse_set_at_start,
|
||||||
sizeof(apdu_mse_set_at_start));
|
sizeof(apdu_mse_set_at_start));
|
||||||
// type: OID
|
// type: OID
|
||||||
apdu[5] = 0x80;
|
apdu[5] = 0x80;
|
||||||
// length of the OID
|
// length of the OID
|
||||||
apdu[6] = sizeof(pace_version_info.oid);
|
apdu[6] = sizeof(pace_version_info.oid);
|
||||||
// copy the OID
|
// copy the OID
|
||||||
memcpy(apdu + 7,
|
memcpy(apdu + 7,
|
||||||
pace_version_info.oid,
|
pace_version_info.oid,
|
||||||
sizeof(pace_version_info.oid));
|
sizeof(pace_version_info.oid));
|
||||||
// type: password
|
// type: password
|
||||||
apdu[17] = 0x83;
|
apdu[17] = 0x83;
|
||||||
// length: 1
|
// length: 1
|
||||||
apdu[18] = 1;
|
apdu[18] = 1;
|
||||||
// password
|
// password
|
||||||
apdu[19] = password;
|
apdu[19] = password;
|
||||||
// if standardized domain parameters are used, copy the ID
|
// if standardized domain parameters are used, copy the ID
|
||||||
if (pace_version_info.parameter_id != 0) {
|
if (pace_version_info.parameter_id != 0) {
|
||||||
apdu_length += 3;
|
apdu_length += 3;
|
||||||
// type: domain parameter
|
// type: domain parameter
|
||||||
apdu[20] = 0x84;
|
apdu[20] = 0x84;
|
||||||
// length: 1
|
// length: 1
|
||||||
apdu[21] = 1;
|
apdu[21] = 1;
|
||||||
// copy the parameter ID
|
// copy the parameter ID
|
||||||
apdu[22] = pace_version_info.parameter_id;
|
apdu[22] = pace_version_info.parameter_id;
|
||||||
}
|
}
|
||||||
// now set Lc to the actual length
|
// now set Lc to the actual length
|
||||||
apdu[4] = apdu_length - 5;
|
apdu[4] = apdu_length - 5;
|
||||||
// send it
|
// send it
|
||||||
uint8_t response_apdu[6];
|
uint8_t response_apdu[6];
|
||||||
int send_return = EPA_APDU(apdu,
|
int send_return = EPA_APDU(apdu,
|
||||||
apdu_length,
|
apdu_length,
|
||||||
response_apdu);
|
response_apdu);
|
||||||
// check if the command succeeded
|
// check if the command succeeded
|
||||||
if (send_return != 6
|
if (send_return != 6
|
||||||
|| response_apdu[send_return - 4] != 0x90
|
|| response_apdu[send_return - 4] != 0x90
|
||||||
|| response_apdu[send_return - 3] != 0x00)
|
|| response_apdu[send_return - 3] != 0x00)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
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)
|
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 an APDU has been passed, save it
|
||||||
if (c->arg[0] != 0) {
|
if (c->arg[0] != 0) {
|
||||||
// make sure it's not too big
|
// make sure it's not too big
|
||||||
if(c->arg[2] > apdus_replay[c->arg[0] - 1].len)
|
if(c->arg[2] > apdus_replay[c->arg[0] - 1].len)
|
||||||
{
|
{
|
||||||
cmd_send(CMD_ACK, 1, 0, 0, NULL, 0);
|
cmd_send(CMD_ACK, 1, 0, 0, NULL, 0);
|
||||||
}
|
}
|
||||||
memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1],
|
memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1],
|
||||||
c->d.asBytes,
|
c->d.asBytes,
|
||||||
c->arg[2]);
|
c->arg[2]);
|
||||||
// save/update APDU length
|
// save/update APDU length
|
||||||
if (c->arg[1] == 0) {
|
if (c->arg[1] == 0) {
|
||||||
apdu_lengths_replay[c->arg[0] - 1] = c->arg[2];
|
apdu_lengths_replay[c->arg[0] - 1] = c->arg[2];
|
||||||
} else {
|
} else {
|
||||||
apdu_lengths_replay[c->arg[0] - 1] += c->arg[2];
|
apdu_lengths_replay[c->arg[0] - 1] += c->arg[2];
|
||||||
}
|
}
|
||||||
cmd_send(CMD_ACK, 0, 0, 0, NULL, 0);
|
cmd_send(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return value of a function
|
// return value of a function
|
||||||
int func_return;
|
int func_return;
|
||||||
|
|
||||||
// set up communication
|
// set up communication
|
||||||
func_return = EPA_Setup();
|
func_return = EPA_Setup();
|
||||||
if (func_return != 0) {
|
if (func_return != 0) {
|
||||||
EPA_Finish();
|
EPA_Finish();
|
||||||
cmd_send(CMD_ACK, 2, func_return, 0, NULL, 0);
|
cmd_send(CMD_ACK, 2, func_return, 0, NULL, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// increase the timeout (at least some cards really do need this!)/////////////
|
// increase the timeout (at least some cards really do need this!)/////////////
|
||||||
// iso14a_set_timeout(0x0003FFFF);
|
// iso14a_set_timeout(0x0003FFFF);
|
||||||
|
|
||||||
// response APDU
|
// response APDU
|
||||||
uint8_t response_apdu[300] = {0};
|
uint8_t response_apdu[300] = {0};
|
||||||
|
|
||||||
// now replay the data and measure the timings
|
// now replay the data and measure the timings
|
||||||
for (int i = 0; i < sizeof(apdu_lengths_replay); i++) {
|
for (int i = 0; i < sizeof(apdu_lengths_replay); i++) {
|
||||||
StartCountUS();
|
StartCountUS();
|
||||||
func_return = EPA_APDU(apdus_replay[i].data,
|
func_return = EPA_APDU(apdus_replay[i].data,
|
||||||
apdu_lengths_replay[i],
|
apdu_lengths_replay[i],
|
||||||
response_apdu);
|
response_apdu);
|
||||||
timings[i] = GetCountUS();
|
timings[i] = GetCountUS();
|
||||||
// every step but the last one should succeed
|
// every step but the last one should succeed
|
||||||
if (i < sizeof(apdu_lengths_replay) - 1
|
if (i < sizeof(apdu_lengths_replay) - 1
|
||||||
&& (func_return < 6
|
&& (func_return < 6
|
||||||
|| response_apdu[func_return - 4] != 0x90
|
|| response_apdu[func_return - 4] != 0x90
|
||||||
|| response_apdu[func_return - 3] != 0x00))
|
|| response_apdu[func_return - 3] != 0x00))
|
||||||
{
|
{
|
||||||
EPA_Finish();
|
EPA_Finish();
|
||||||
cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20);
|
cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EPA_Finish();
|
EPA_Finish();
|
||||||
cmd_send(CMD_ACK,0,0,0,timings,20);
|
cmd_send(CMD_ACK,0,0,0,timings,20);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -515,40 +515,40 @@ void EPA_PACE_Replay(UsbCommand *c)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
int EPA_Setup()
|
int EPA_Setup()
|
||||||
{
|
{
|
||||||
int return_code = 0;
|
int return_code = 0;
|
||||||
uint8_t uid[10];
|
uint8_t uid[10];
|
||||||
uint8_t pps_response[3];
|
uint8_t pps_response[3];
|
||||||
uint8_t pps_response_par[1];
|
uint8_t pps_response_par[1];
|
||||||
iso14a_card_select_t card_a_info;
|
iso14a_card_select_t card_a_info;
|
||||||
iso14b_card_select_t card_b_info;
|
iso14b_card_select_t card_b_info;
|
||||||
|
|
||||||
// first, look for type A cards
|
// first, look for type A cards
|
||||||
// power up the field
|
// power up the field
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||||
// select the card
|
// select the card
|
||||||
return_code = iso14443a_select_card(uid, &card_a_info, NULL, true, 0, false);
|
return_code = iso14443a_select_card(uid, &card_a_info, NULL, true, 0, false);
|
||||||
if (return_code == 1) {
|
if (return_code == 1) {
|
||||||
// send the PPS request
|
// send the PPS request
|
||||||
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
|
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
|
||||||
return_code = ReaderReceive(pps_response, pps_response_par);
|
return_code = ReaderReceive(pps_response, pps_response_par);
|
||||||
if (return_code != 3 || pps_response[0] != 0xD0) {
|
if (return_code != 3 || pps_response[0] != 0xD0) {
|
||||||
return return_code == 0 ? 2 : return_code;
|
return return_code == 0 ? 2 : return_code;
|
||||||
}
|
}
|
||||||
Dbprintf("ISO 14443 Type A");
|
Dbprintf("ISO 14443 Type A");
|
||||||
iso_type = 'a';
|
iso_type = 'a';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're here, there is no type A card, so we look for type B
|
// if we're here, there is no type A card, so we look for type B
|
||||||
// power up the field
|
// power up the field
|
||||||
iso14443b_setup();
|
iso14443b_setup();
|
||||||
// select the card
|
// select the card
|
||||||
return_code = iso14443b_select_card( &card_b_info );
|
return_code = iso14443b_select_card( &card_b_info );
|
||||||
if (return_code == 0) {
|
if (return_code == 0) {
|
||||||
Dbprintf("ISO 14443 Type B");
|
Dbprintf("ISO 14443 Type B");
|
||||||
iso_type = 'b';
|
iso_type = 'b';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Dbprintf("No card found.");
|
Dbprintf("No card found.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
// this struct is used by EPA_Parse_CardAccess and contains info about the
|
// this struct is used by EPA_Parse_CardAccess and contains info about the
|
||||||
// PACE protocol supported by the chip
|
// PACE protocol supported by the chip
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t oid[10];
|
uint8_t oid[10];
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
uint8_t parameter_id;
|
uint8_t parameter_id;
|
||||||
} pace_version_info_t;
|
} pace_version_info_t;
|
||||||
|
|
||||||
// note: EPA_PACE_Collect_Nonce and EPA_PACE_Replay are declared in apps.h
|
// 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);
|
Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE/1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize
|
// initialize
|
||||||
bool FlashInit() {
|
bool FlashInit() {
|
||||||
FlashSetup(FLASHMEM_SPIBAUDRATE);
|
FlashSetup(FLASHMEM_SPIBAUDRATE);
|
||||||
|
|
||||||
StartTicks();
|
StartTicks();
|
||||||
|
|
||||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) {
|
if (Flash_CheckBusy(BUSY_TIMEOUT)) {
|
||||||
StopTicks();
|
StopTicks();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlashSetup(uint32_t baudrate){
|
void FlashSetup(uint32_t baudrate){
|
||||||
//WDT_DISABLE
|
//WDT_DISABLE
|
||||||
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
|
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
|
||||||
|
|
||||||
// PA10 -> SPI_NCS2 chip select (FLASHMEM)
|
// PA10 -> SPI_NCS2 chip select (FLASHMEM)
|
||||||
// PA11 -> SPI_NCS0 chip select (FPGA)
|
// PA11 -> SPI_NCS0 chip select (FPGA)
|
||||||
// PA12 -> SPI_MISO Master-In Slave-Out
|
// PA12 -> SPI_MISO Master-In Slave-Out
|
||||||
// PA13 -> SPI_MOSI Master-Out Slave-In
|
// PA13 -> SPI_MOSI Master-Out Slave-In
|
||||||
// PA14 -> SPI_SPCK Serial Clock
|
// PA14 -> SPI_SPCK Serial Clock
|
||||||
|
|
||||||
// Disable PIO control of the following pins, allows use by the SPI peripheral
|
// 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);
|
AT91C_BASE_PIOA->PIO_PDR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
|
||||||
|
|
||||||
// Pull-up Enable
|
// Pull-up Enable
|
||||||
AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
|
AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK | GPIO_NCS2);
|
||||||
|
|
||||||
// Peripheral A
|
// Peripheral A
|
||||||
AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK);
|
AT91C_BASE_PIOA->PIO_ASR |= (GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK);
|
||||||
|
|
||||||
// Peripheral B
|
// Peripheral B
|
||||||
AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
|
AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
|
||||||
|
|
||||||
//enable the SPI Peripheral clock
|
//enable the SPI Peripheral clock
|
||||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
||||||
|
|
||||||
|
|
||||||
//reset spi needs double SWRST, see atmel's errata on this case
|
//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;
|
||||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
|
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
|
||||||
|
|
||||||
// Enable SPI
|
// Enable SPI
|
||||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
||||||
|
|
||||||
// NPCS2 Mode 0
|
// NPCS2 Mode 0
|
||||||
AT91C_BASE_SPI->SPI_MR =
|
AT91C_BASE_SPI->SPI_MR =
|
||||||
(0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT:
|
(0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT:
|
||||||
// If DLYBCS is less than or equal to six, six MCK periods
|
// If DLYBCS is less than or equal to six, six MCK periods
|
||||||
// will be inserted by default.
|
// will be inserted by default.
|
||||||
SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10)
|
SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10)
|
||||||
( 0 << 7) | // Disable LLB (1=MOSI2MISO test mode)
|
( 0 << 7) | // Disable LLB (1=MOSI2MISO test mode)
|
||||||
( 1 << 4) | // Disable ModeFault Protection
|
( 1 << 4) | // Disable ModeFault Protection
|
||||||
( 0 << 3) | // makes spi operate at MCK (1 is MCK/2)
|
( 0 << 3) | // makes spi operate at MCK (1 is MCK/2)
|
||||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||||
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
||||||
AT91C_SPI_MSTR; // Master Mode
|
AT91C_SPI_MSTR; // Master Mode
|
||||||
|
|
||||||
uint8_t csaat = 1;
|
uint8_t csaat = 1;
|
||||||
uint32_t dlybct = 0;
|
uint32_t dlybct = 0;
|
||||||
if (baudrate > FLASH_MINFAST) {
|
if (baudrate > FLASH_MINFAST) {
|
||||||
baudrate = FLASH_FASTBAUD;
|
baudrate = FLASH_FASTBAUD;
|
||||||
//csaat = 0;
|
//csaat = 0;
|
||||||
dlybct = 1500;
|
dlybct = 1500;
|
||||||
}
|
}
|
||||||
|
|
||||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||||
SPI_DLYBCT(dlybct,MCK) | // Delay between Consecutive Transfers (32 MCK periods)
|
SPI_DLYBCT(dlybct,MCK)| // Delay between Consecutive Transfers (32 MCK periods)
|
||||||
SPI_DLYBS(0,MCK) | // Delay Beforce SPCK CLock
|
SPI_DLYBS(0,MCK) | // Delay Beforce SPCK CLock
|
||||||
SPI_SCBR(baudrate,MCK) | // SPI Baudrate Selection
|
SPI_SCBR(baudrate,MCK)| // SPI Baudrate Selection
|
||||||
AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits)
|
AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits)
|
||||||
//AT91C_SPI_CSAAT | // Chip Select inactive after transfer
|
//AT91C_SPI_CSAAT | // Chip Select inactive after transfer
|
||||||
// 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1
|
// 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
|
// 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
|
// 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.
|
// 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
|
// 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) |
|
( csaat << 3) |
|
||||||
/* Spi modes:
|
/* Spi modes:
|
||||||
Mode CPOL CPHA NCPHA
|
Mode CPOL CPHA NCPHA
|
||||||
0 0 0 1 clock normally low read on rising edge
|
0 0 0 1 clock normally low read on rising edge
|
||||||
1 0 1 0 clock normally low read on falling edge
|
1 0 1 0 clock normally low read on falling edge
|
||||||
2 1 0 1 clock normally high 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
|
3 1 1 0 clock normally high read on rising edge
|
||||||
However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI
|
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
|
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
|
(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
|
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
|
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
|
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
|
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
|
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
|
rising edge. Therefore, it appears that NCPHA should be treated the
|
||||||
same as CPHA. Thus:
|
same as CPHA. Thus:
|
||||||
Mode CPOL CPHA NCPHA
|
Mode CPOL CPHA NCPHA
|
||||||
0 0 0 0 clock normally low read on rising edge
|
0 0 0 0 clock normally low read on rising edge
|
||||||
1 0 1 1 clock normally low read on falling edge
|
1 0 1 1 clock normally low read on falling edge
|
||||||
2 1 0 0 clock normally high 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
|
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 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||||
|
|
||||||
// read first, empty buffer
|
// read first, empty buffer
|
||||||
if (AT91C_BASE_SPI->SPI_RDR == 0) {};
|
if (AT91C_BASE_SPI->SPI_RDR == 0) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlashStop(void) {
|
void FlashStop(void) {
|
||||||
//Bof
|
//Bof
|
||||||
//* Reset all the Chip Select register
|
//* Reset all the Chip Select register
|
||||||
AT91C_BASE_SPI->SPI_CSR[0] = 0;
|
AT91C_BASE_SPI->SPI_CSR[0] = 0;
|
||||||
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
||||||
AT91C_BASE_SPI->SPI_CSR[2] = 0;
|
AT91C_BASE_SPI->SPI_CSR[2] = 0;
|
||||||
|
@ -141,164 +141,164 @@ void FlashStop(void) {
|
||||||
// Disable all interrupts
|
// Disable all interrupts
|
||||||
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
|
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
|
||||||
|
|
||||||
// SPI disable
|
// SPI disable
|
||||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
|
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) {
|
uint16_t FlashSendByte(uint32_t data) {
|
||||||
|
|
||||||
// wait until SPI is ready for transfer
|
// wait until SPI is ready for transfer
|
||||||
//if you are checking for incoming data returned then the TXEMPTY flag is redundant
|
//if you are checking for incoming data returned then the TXEMPTY flag is redundant
|
||||||
//while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {};
|
//while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {};
|
||||||
|
|
||||||
// send the data
|
// send the data
|
||||||
AT91C_BASE_SPI->SPI_TDR = data;
|
AT91C_BASE_SPI->SPI_TDR = data;
|
||||||
|
|
||||||
//while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){};
|
//while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){};
|
||||||
|
|
||||||
// wait recive transfer is complete
|
// wait recive transfer is complete
|
||||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0){};
|
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0){};
|
||||||
|
|
||||||
// reading incoming data
|
// reading incoming data
|
||||||
return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF);
|
return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// send last byte over SPI
|
// send last byte over SPI
|
||||||
uint16_t FlashSendLastByte(uint32_t data) {
|
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) {
|
uint8_t Flash_ReadStat1(void) {
|
||||||
FlashSendByte(READSTAT1);
|
FlashSendByte(READSTAT1);
|
||||||
return FlashSendLastByte(0xFF);
|
return FlashSendLastByte(0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Flash_CheckBusy(uint32_t timeout)
|
bool Flash_CheckBusy(uint32_t timeout)
|
||||||
{
|
{
|
||||||
WaitUS(WINBOND_WRITE_DELAY);
|
WaitUS(WINBOND_WRITE_DELAY);
|
||||||
StartCountUS();
|
StartCountUS();
|
||||||
uint32_t _time = GetCountUS();
|
uint32_t _time = GetCountUS();
|
||||||
|
|
||||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Checkbusy in...");
|
if ( MF_DBGLEVEL > 3 ) Dbprintf("Checkbusy in...");
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (!(Flash_ReadStat1() & BUSY))
|
if (!(Flash_ReadStat1() & BUSY))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} while ((GetCountUS() - _time) < timeout);
|
} while ((GetCountUS() - _time) < timeout);
|
||||||
|
|
||||||
if (timeout <= (GetCountUS() - _time))
|
if (timeout <= (GetCountUS() - _time))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read ID out
|
// read ID out
|
||||||
uint8_t Flash_ReadID(void) {
|
uint8_t Flash_ReadID(void) {
|
||||||
|
|
||||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||||
|
|
||||||
// Manufacture ID / device ID
|
// Manufacture ID / device ID
|
||||||
FlashSendByte(ID);
|
FlashSendByte(ID);
|
||||||
FlashSendByte(0x00);
|
FlashSendByte(0x00);
|
||||||
FlashSendByte(0x00);
|
FlashSendByte(0x00);
|
||||||
FlashSendByte(0x00);
|
FlashSendByte(0x00);
|
||||||
|
|
||||||
uint8_t man_id = FlashSendByte(0xFF);
|
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) )
|
if ( (man_id == WINBOND_MANID ) && (dev_id == WINBOND_DEVID) )
|
||||||
return dev_id;
|
return dev_id;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read unique id for chip.
|
// read unique id for chip.
|
||||||
void Flash_UniqueID(uint8_t *uid) {
|
void Flash_UniqueID(uint8_t *uid) {
|
||||||
|
|
||||||
if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
|
if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
|
||||||
|
|
||||||
// reading unique serial number
|
// reading unique serial number
|
||||||
FlashSendByte(UNIQUE_ID);
|
FlashSendByte(UNIQUE_ID);
|
||||||
FlashSendByte(0xFF);
|
FlashSendByte(0xFF);
|
||||||
FlashSendByte(0xFF);
|
FlashSendByte(0xFF);
|
||||||
FlashSendByte(0xFF);
|
FlashSendByte(0xFF);
|
||||||
FlashSendByte(0xFF);
|
FlashSendByte(0xFF);
|
||||||
|
|
||||||
uid[7] = FlashSendByte(0xFF);
|
uid[7] = FlashSendByte(0xFF);
|
||||||
uid[6] = FlashSendByte(0xFF);
|
uid[6] = FlashSendByte(0xFF);
|
||||||
uid[5] = FlashSendByte(0xFF);
|
uid[5] = FlashSendByte(0xFF);
|
||||||
uid[4] = FlashSendByte(0xFF);
|
uid[4] = FlashSendByte(0xFF);
|
||||||
uid[3] = FlashSendByte(0xFF);
|
uid[3] = FlashSendByte(0xFF);
|
||||||
uid[2] = FlashSendByte(0xFF);
|
uid[2] = FlashSendByte(0xFF);
|
||||||
uid[1] = FlashSendByte(0xFF);
|
uid[1] = FlashSendByte(0xFF);
|
||||||
uid[0] = FlashSendLastByte(0xFF);
|
uid[0] = FlashSendLastByte(0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
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
|
// length should never be zero
|
||||||
if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||||
|
|
||||||
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
||||||
|
|
||||||
FlashSendByte(cmd);
|
FlashSendByte(cmd);
|
||||||
Flash_TransferAdresse(address);
|
Flash_TransferAdresse(address);
|
||||||
|
|
||||||
if (FASTFLASH){
|
if (FASTFLASH){
|
||||||
FlashSendByte(DUMMYBYTE);
|
FlashSendByte(DUMMYBYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
for (; i < (len - 1); i++)
|
for (; i < (len - 1); i++)
|
||||||
out[i] = FlashSendByte(0xFF);
|
out[i] = FlashSendByte(0xFF);
|
||||||
|
|
||||||
out[i] = FlashSendLastByte(0xFF);
|
out[i] = FlashSendLastByte(0xFF);
|
||||||
FlashStop();
|
FlashStop();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Flash_TransferAdresse(uint32_t address){
|
void Flash_TransferAdresse(uint32_t address){
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
FlashSendByte((address >> 0) & 0xFF);
|
FlashSendByte((address >> 0) & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This ensure we can ReadData without having to cycle through initialization everytime */
|
/* 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) {
|
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
|
|
||||||
// length should never be zero
|
// length should never be zero
|
||||||
if (!len) return 0;
|
if (!len) return 0;
|
||||||
|
|
||||||
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
uint8_t cmd = (FASTFLASH) ? FASTREAD : READDATA;
|
||||||
|
|
||||||
FlashSendByte(cmd);
|
FlashSendByte(cmd);
|
||||||
Flash_TransferAdresse(address);
|
Flash_TransferAdresse(address);
|
||||||
|
|
||||||
if (FASTFLASH){
|
if (FASTFLASH){
|
||||||
FlashSendByte(DUMMYBYTE);
|
FlashSendByte(DUMMYBYTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
for (; i < (len - 1); i++)
|
for (; i < (len - 1); i++)
|
||||||
out[i] = FlashSendByte(0xFF);
|
out[i] = FlashSendByte(0xFF);
|
||||||
|
|
||||||
out[i] = FlashSendLastByte(0xFF);
|
out[i] = FlashSendLastByte(0xFF);
|
||||||
return len;
|
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.
|
// if len > 256, it might wrap around and overwrite pos 0.
|
||||||
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
// length should never be zero
|
// length should never be zero
|
||||||
if (!len)
|
if (!len)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Max 256 bytes write
|
// Max 256 bytes write
|
||||||
if (((address & 0xFF) + len) > 256) {
|
if (((address & 0xFF) + len) > 256) {
|
||||||
Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// out-of-range
|
// out-of-range
|
||||||
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
||||||
Dbprintf("Flash_WriteData, block out-of-range");
|
Dbprintf("Flash_WriteData, block out-of-range");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FlashInit()) {
|
if (!FlashInit()) {
|
||||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
|
|
||||||
FlashSendByte(PAGEPROG);
|
FlashSendByte(PAGEPROG);
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
FlashSendByte((address >> 0) & 0xFF);
|
FlashSendByte((address >> 0) & 0xFF);
|
||||||
|
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
for (; i < (len - 1); i++)
|
for (; i < (len - 1); i++)
|
||||||
FlashSendByte(in[i]);
|
FlashSendByte(in[i]);
|
||||||
|
|
||||||
FlashSendLastByte(in[i]);
|
FlashSendLastByte(in[i]);
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// length should never be zero
|
// length should never be zero
|
||||||
// Max 256 bytes write
|
// Max 256 bytes write
|
||||||
// out-of-range
|
// out-of-range
|
||||||
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
if (!len)
|
if (!len)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (((address & 0xFF) + len) > 256) {
|
if (((address & 0xFF) + len) > 256) {
|
||||||
Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
||||||
Dbprintf("Flash_WriteDataCont, block out-of-range");
|
Dbprintf("Flash_WriteDataCont, block out-of-range");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashSendByte(PAGEPROG);
|
FlashSendByte(PAGEPROG);
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
FlashSendByte((address >> 0) & 0xFF);
|
FlashSendByte((address >> 0) & 0xFF);
|
||||||
|
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
for (; i < (len - 1); i++)
|
for (; i < (len - 1); i++)
|
||||||
FlashSendByte(in[i]);
|
FlashSendByte(in[i]);
|
||||||
|
|
||||||
FlashSendLastByte(in[i]);
|
FlashSendLastByte(in[i]);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assumes valid start 256 based 00 address
|
// assumes valid start 256 based 00 address
|
||||||
//
|
//
|
||||||
uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) {
|
uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
bool isok;
|
bool isok;
|
||||||
uint16_t res, bytes_sent = 0, bytes_remaining = len;
|
uint16_t res, bytes_sent = 0, bytes_remaining = len;
|
||||||
uint8_t buf[FLASH_MEM_BLOCK_SIZE];
|
uint8_t buf[FLASH_MEM_BLOCK_SIZE];
|
||||||
while (bytes_remaining > 0) {
|
while (bytes_remaining > 0) {
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
|
|
||||||
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
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);
|
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;
|
bytes_sent += bytes_in_packet;
|
||||||
|
|
||||||
isok = (res == bytes_in_packet);
|
isok = (res == bytes_in_packet);
|
||||||
|
|
||||||
if (!isok)
|
if (!isok)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
FlashStop();
|
FlashStop();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Flash_WipeMemoryPage(uint8_t page) {
|
bool Flash_WipeMemoryPage(uint8_t page) {
|
||||||
if (!FlashInit()) {
|
if (!FlashInit()) {
|
||||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Flash_ReadStat1();
|
Flash_ReadStat1();
|
||||||
|
|
||||||
// Each block is 64Kb. One block erase takes 1s ( 1000ms )
|
// Each block is 64Kb. One block erase takes 1s ( 1000ms )
|
||||||
Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Wipes flash memory completely, fills with 0xFF
|
// Wipes flash memory completely, fills with 0xFF
|
||||||
bool Flash_WipeMemory() {
|
bool Flash_WipeMemory() {
|
||||||
if (!FlashInit()) {
|
if (!FlashInit()) {
|
||||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Flash_ReadStat1();
|
Flash_ReadStat1();
|
||||||
|
|
||||||
// Each block is 64Kb. Four blocks
|
// Each block is 64Kb. Four blocks
|
||||||
// one block erase takes 1s ( 1000ms )
|
// one block erase takes 1s ( 1000ms )
|
||||||
Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable(); Flash_Erase64k(1); 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(2); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable the flash write
|
// enable the flash write
|
||||||
void Flash_WriteEnable() {
|
void Flash_WriteEnable() {
|
||||||
FlashSendLastByte(WRITEENABLE);
|
FlashSendLastByte(WRITEENABLE);
|
||||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash Write enabled");
|
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash Write enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
// erase 4K at one time
|
// erase 4K at one time
|
||||||
// execution time: 0.8ms / 800us
|
// execution time: 0.8ms / 800us
|
||||||
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
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(SECTORERASE);
|
||||||
FlashSendByte(block);
|
FlashSendByte(block);
|
||||||
FlashSendByte(sector << 4);
|
FlashSendByte(sector << 4);
|
||||||
FlashSendLastByte(00);
|
FlashSendLastByte(00);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// erase 32K at one time
|
// erase 32K at one time
|
||||||
// execution time: 0,3s / 300ms
|
// execution time: 0,3s / 300ms
|
||||||
bool Flash_Erase32k(uint32_t address) {
|
bool Flash_Erase32k(uint32_t address) {
|
||||||
if (address & (32*1024 - 1)) {
|
if (address & (32*1024 - 1)) {
|
||||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
|
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
FlashSendByte(BLOCK32ERASE);
|
FlashSendByte(BLOCK32ERASE);
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
FlashSendLastByte((address >> 0) & 0xFF);
|
FlashSendLastByte((address >> 0) & 0xFF);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -489,52 +489,52 @@ bool Flash_Erase32k(uint32_t address) {
|
||||||
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
||||||
bool Flash_Erase64k(uint8_t block) {
|
bool Flash_Erase64k(uint8_t block) {
|
||||||
|
|
||||||
if (block > MAX_BLOCKS) return false;
|
if (block > MAX_BLOCKS) return false;
|
||||||
|
|
||||||
FlashSendByte(BLOCK64ERASE);
|
FlashSendByte(BLOCK64ERASE);
|
||||||
FlashSendByte(block);
|
FlashSendByte(block);
|
||||||
FlashSendByte(0x00);
|
FlashSendByte(0x00);
|
||||||
FlashSendLastByte(0x00);
|
FlashSendLastByte(0x00);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase chip
|
// Erase chip
|
||||||
void Flash_EraseChip(void) {
|
void Flash_EraseChip(void) {
|
||||||
FlashSendLastByte(CHIPERASE);
|
FlashSendLastByte(CHIPERASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Flashmem_print_status(void) {
|
void Flashmem_print_status(void) {
|
||||||
DbpString("Flash memory");
|
DbpString("Flash memory");
|
||||||
Dbprintf(" Baudrate................%dMHz",FLASHMEM_SPIBAUDRATE/1000000);
|
Dbprintf(" Baudrate................%dMHz",FLASHMEM_SPIBAUDRATE/1000000);
|
||||||
|
|
||||||
if (!FlashInit()) {
|
if (!FlashInit()) {
|
||||||
DbpString(" Init....................FAIL");
|
DbpString(" Init....................FAIL");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DbpString(" Init....................OK");
|
DbpString(" Init....................OK");
|
||||||
|
|
||||||
uint8_t dev_id = Flash_ReadID();
|
uint8_t dev_id = Flash_ReadID();
|
||||||
switch (dev_id) {
|
switch (dev_id) {
|
||||||
case 0x11 :
|
case 0x11 :
|
||||||
DbpString(" Memory size.............2 mbits / 256kb");
|
DbpString(" Memory size.............2 mbits / 256kb");
|
||||||
break;
|
break;
|
||||||
case 0x10 :
|
case 0x10 :
|
||||||
DbpString(" Memory size..... .......1 mbits / 128kb");
|
DbpString(" Memory size..... .......1 mbits / 128kb");
|
||||||
break;
|
break;
|
||||||
case 0x05 :
|
case 0x05 :
|
||||||
DbpString(" Memory size.............512 kbits / 64kb");
|
DbpString(" Memory size.............512 kbits / 64kb");
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
DbpString(" Device ID............... --> Unknown <--");
|
DbpString(" Device ID............... --> Unknown <--");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
uint8_t uid[8] = {0,0,0,0,0,0,0,0};
|
||||||
Flash_UniqueID(uid);
|
Flash_UniqueID(uid);
|
||||||
Dbprintf(" Unique ID...............0x%02x%02x%02x%02x%02x%02x%02x%02x",
|
Dbprintf(" Unique ID...............0x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
uid[7], uid[6], uid[5], uid[4],
|
uid[7], uid[6], uid[5], uid[4],
|
||||||
uid[3], uid[2], uid[1], uid[0]
|
uid[3], uid[2], uid[1], uid[0]
|
||||||
);
|
);
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
* <http://www.gnu.org/licenses/>.
|
* <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
// Common Instructions //
|
// Common Instructions //
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#ifndef __FLASHMEM_H
|
#ifndef __FLASHMEM_H
|
||||||
#define __FLASHMEM_H
|
#define __FLASHMEM_H
|
||||||
|
@ -32,74 +32,74 @@
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "ticks.h"
|
#include "ticks.h"
|
||||||
|
|
||||||
// Used Command
|
// Used Command
|
||||||
#define ID 0x90
|
#define ID 0x90
|
||||||
#define MANID 0x90
|
#define MANID 0x90
|
||||||
#define JEDECID 0x9F
|
#define JEDECID 0x9F
|
||||||
|
|
||||||
#define READSTAT1 0x05
|
#define READSTAT1 0x05
|
||||||
#define READSTAT2 0x35
|
#define READSTAT2 0x35
|
||||||
#define WRITESTAT 0x01
|
#define WRITESTAT 0x01
|
||||||
|
|
||||||
#define WRITEDISABLE 0x04
|
#define WRITEDISABLE 0x04
|
||||||
#define WRITEENABLE 0x06
|
#define WRITEENABLE 0x06
|
||||||
|
|
||||||
#define READDATA 0x03
|
#define READDATA 0x03
|
||||||
#define FASTREAD 0x0B
|
#define FASTREAD 0x0B
|
||||||
#define PAGEPROG 0x02
|
#define PAGEPROG 0x02
|
||||||
|
|
||||||
#define SECTORERASE 0x20
|
#define SECTORERASE 0x20
|
||||||
#define BLOCK32ERASE 0x52
|
#define BLOCK32ERASE 0x52
|
||||||
#define BLOCK64ERASE 0xD8
|
#define BLOCK64ERASE 0xD8
|
||||||
#define CHIPERASE 0xC7
|
#define CHIPERASE 0xC7
|
||||||
|
|
||||||
#define UNIQUE_ID 0x4B
|
#define UNIQUE_ID 0x4B
|
||||||
|
|
||||||
// Not used or not support command
|
// Not used or not support command
|
||||||
#define RELEASE 0xAB
|
#define RELEASE 0xAB
|
||||||
#define POWERDOWN 0xB9
|
#define POWERDOWN 0xB9
|
||||||
#define SUSPEND 0x75
|
#define SUSPEND 0x75
|
||||||
#define RESUME 0x7A
|
#define RESUME 0x7A
|
||||||
|
|
||||||
#define BUSY_TIMEOUT 1000000000L
|
#define BUSY_TIMEOUT 1000000000L
|
||||||
|
|
||||||
#define WINBOND_MANID 0xEF
|
#define WINBOND_MANID 0xEF
|
||||||
#define WINBOND_DEVID 0x11
|
#define WINBOND_DEVID 0x11
|
||||||
#define PAGESIZE 0x100
|
#define PAGESIZE 0x100
|
||||||
#define WINBOND_WRITE_DELAY 0x02
|
#define WINBOND_WRITE_DELAY 0x02
|
||||||
|
|
||||||
#define SPI_CLK 48000000
|
#define SPI_CLK 48000000
|
||||||
|
|
||||||
#define BUSY 0x01
|
#define BUSY 0x01
|
||||||
#define WRTEN 0x02
|
#define WRTEN 0x02
|
||||||
#define SUS 0x40
|
#define SUS 0x40
|
||||||
|
|
||||||
#define DUMMYBYTE 0xEE
|
#define DUMMYBYTE 0xEE
|
||||||
#define NULLBYTE 0x00
|
#define NULLBYTE 0x00
|
||||||
#define NULLINT 0x0000
|
#define NULLINT 0x0000
|
||||||
#define NO_CONTINUE 0x00
|
#define NO_CONTINUE 0x00
|
||||||
#define PASS 0x01
|
#define PASS 0x01
|
||||||
#define FAIL 0x00
|
#define FAIL 0x00
|
||||||
#define maxAddress capacity
|
#define maxAddress capacity
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
// List of Error codes //
|
// List of Error codes //
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
#define SUCCESS 0x00
|
#define SUCCESS 0x00
|
||||||
#define CALLBEGIN 0x01
|
#define CALLBEGIN 0x01
|
||||||
#define UNKNOWNCHIP 0x02
|
#define UNKNOWNCHIP 0x02
|
||||||
#define UNKNOWNCAP 0x03
|
#define UNKNOWNCAP 0x03
|
||||||
#define CHIPBUSY 0x04
|
#define CHIPBUSY 0x04
|
||||||
#define OUTOFBOUNDS 0x05
|
#define OUTOFBOUNDS 0x05
|
||||||
#define CANTENWRITE 0x06
|
#define CANTENWRITE 0x06
|
||||||
#define PREVWRITTEN 0x07
|
#define PREVWRITTEN 0x07
|
||||||
#define LOWRAM 0x08
|
#define LOWRAM 0x08
|
||||||
#define NOSUSPEND 0x09
|
#define NOSUSPEND 0x09
|
||||||
#define UNKNOWNERROR 0xFF
|
#define UNKNOWNERROR 0xFF
|
||||||
|
|
||||||
// List of blocks
|
// List of blocks
|
||||||
#define MAX_BLOCKS 4
|
#define MAX_BLOCKS 4
|
||||||
#define MAX_SECTORS 16
|
#define MAX_SECTORS 16
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
582
armsrc/fonts.c
582
armsrc/fonts.c
|
@ -7,302 +7,302 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
const char FONT6x8[97][8] = {
|
const char FONT6x8[97][8] = {
|
||||||
{0x06,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
{0x06,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
||||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
||||||
{0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00}, // !
|
{0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00}, // !
|
||||||
{0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00}, // "
|
{0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00}, // "
|
||||||
{0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00}, // #
|
{0x50,0x50,0xF8,0x50,0xF8,0x50,0x50,0x00}, // #
|
||||||
{0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00}, // $
|
{0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00}, // $
|
||||||
{0xC0,0xC8,0x10,0x20,0x40,0x98,0x18,0x00}, // %
|
{0xC0,0xC8,0x10,0x20,0x40,0x98,0x18,0x00}, // %
|
||||||
{0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68,0x00}, // &
|
{0x40,0xA0,0xA0,0x40,0xA8,0x90,0x68,0x00}, // &
|
||||||
{0x30,0x30,0x20,0x40,0x00,0x00,0x00,0x00}, // '
|
{0x30,0x30,0x20,0x40,0x00,0x00,0x00,0x00}, // '
|
||||||
{0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00}, // (
|
{0x10,0x20,0x40,0x40,0x40,0x20,0x10,0x00}, // (
|
||||||
{0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00}, // )
|
{0x40,0x20,0x10,0x10,0x10,0x20,0x40,0x00}, // )
|
||||||
{0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00}, // *
|
{0x00,0x20,0xA8,0x70,0x70,0xA8,0x20,0x00}, // *
|
||||||
{0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00}, // +
|
{0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00}, // +
|
||||||
{0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40}, // ,
|
{0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40}, // ,
|
||||||
{0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00}, // -
|
{0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00}, // -
|
||||||
{0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00}, // .
|
{0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00}, // .
|
||||||
{0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00}, // /
|
{0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00}, // /
|
||||||
{0x70,0x88,0x88,0xA8,0x88,0x88,0x70,0x00}, // 0
|
{0x70,0x88,0x88,0xA8,0x88,0x88,0x70,0x00}, // 0
|
||||||
{0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00}, // 1
|
{0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00}, // 1
|
||||||
{0x70,0x88,0x08,0x70,0x80,0x80,0xF8,0x00}, // 2
|
{0x70,0x88,0x08,0x70,0x80,0x80,0xF8,0x00}, // 2
|
||||||
{0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x00}, // 3
|
{0xF8,0x08,0x10,0x30,0x08,0x88,0x70,0x00}, // 3
|
||||||
{0x10,0x30,0x50,0x90,0xF8,0x10,0x10,0x00}, // 4
|
{0x10,0x30,0x50,0x90,0xF8,0x10,0x10,0x00}, // 4
|
||||||
{0xF8,0x80,0xF0,0x08,0x08,0x88,0x70,0x00}, // 5
|
{0xF8,0x80,0xF0,0x08,0x08,0x88,0x70,0x00}, // 5
|
||||||
{0x38,0x40,0x80,0xF0,0x88,0x88,0x70,0x00}, // 6
|
{0x38,0x40,0x80,0xF0,0x88,0x88,0x70,0x00}, // 6
|
||||||
{0xF8,0x08,0x08,0x10,0x20,0x40,0x80,0x00}, // 7
|
{0xF8,0x08,0x08,0x10,0x20,0x40,0x80,0x00}, // 7
|
||||||
{0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00}, // 8
|
{0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00}, // 8
|
||||||
{0x70,0x88,0x88,0x78,0x08,0x10,0xE0,0x00}, // 9
|
{0x70,0x88,0x88,0x78,0x08,0x10,0xE0,0x00}, // 9
|
||||||
{0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x00}, // :
|
{0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x00}, // :
|
||||||
{0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x00}, // ;
|
{0x00,0x00,0x20,0x00,0x20,0x20,0x40,0x00}, // ;
|
||||||
{0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00}, // <
|
{0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00}, // <
|
||||||
{0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00}, // =
|
{0x00,0x00,0xF8,0x00,0xF8,0x00,0x00,0x00}, // =
|
||||||
{0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00}, // >
|
{0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00}, // >
|
||||||
{0x70,0x88,0x08,0x30,0x20,0x00,0x20,0x00}, // ?
|
{0x70,0x88,0x08,0x30,0x20,0x00,0x20,0x00}, // ?
|
||||||
{0x70,0x88,0xA8,0xB8,0xB0,0x80,0x78,0x00}, // @
|
{0x70,0x88,0xA8,0xB8,0xB0,0x80,0x78,0x00}, // @
|
||||||
{0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00}, // A
|
{0x20,0x50,0x88,0x88,0xF8,0x88,0x88,0x00}, // A
|
||||||
{0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00}, // B
|
{0xF0,0x88,0x88,0xF0,0x88,0x88,0xF0,0x00}, // B
|
||||||
{0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00}, // C
|
{0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00}, // C
|
||||||
{0xF0,0x88,0x88,0x88,0x88,0x88,0xF0,0x00}, // D
|
{0xF0,0x88,0x88,0x88,0x88,0x88,0xF0,0x00}, // D
|
||||||
{0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00}, // E
|
{0xF8,0x80,0x80,0xF0,0x80,0x80,0xF8,0x00}, // E
|
||||||
{0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00}, // F
|
{0xF8,0x80,0x80,0xF0,0x80,0x80,0x80,0x00}, // F
|
||||||
{0x78,0x88,0x80,0x80,0x98,0x88,0x78,0x00}, // G
|
{0x78,0x88,0x80,0x80,0x98,0x88,0x78,0x00}, // G
|
||||||
{0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00}, // H
|
{0x88,0x88,0x88,0xF8,0x88,0x88,0x88,0x00}, // H
|
||||||
{0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // I
|
{0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // I
|
||||||
{0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00}, // J
|
{0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00}, // J
|
||||||
{0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00}, // K
|
{0x88,0x90,0xA0,0xC0,0xA0,0x90,0x88,0x00}, // K
|
||||||
{0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00}, // L
|
{0x80,0x80,0x80,0x80,0x80,0x80,0xF8,0x00}, // L
|
||||||
{0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x00}, // M
|
{0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x00}, // M
|
||||||
{0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00}, // N
|
{0x88,0x88,0xC8,0xA8,0x98,0x88,0x88,0x00}, // N
|
||||||
{0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // O
|
{0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // O
|
||||||
{0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00}, // P
|
{0xF0,0x88,0x88,0xF0,0x80,0x80,0x80,0x00}, // P
|
||||||
{0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00}, // Q
|
{0x70,0x88,0x88,0x88,0xA8,0x90,0x68,0x00}, // Q
|
||||||
{0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x00}, // R
|
{0xF0,0x88,0x88,0xF0,0xA0,0x90,0x88,0x00}, // R
|
||||||
{0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00}, // S
|
{0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00}, // S
|
||||||
{0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x00}, // T
|
{0xF8,0xA8,0x20,0x20,0x20,0x20,0x20,0x00}, // T
|
||||||
{0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // U
|
{0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00}, // U
|
||||||
{0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00}, // V
|
{0x88,0x88,0x88,0x88,0x88,0x50,0x20,0x00}, // V
|
||||||
{0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00}, // W
|
{0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00}, // W
|
||||||
{0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00}, // X
|
{0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00}, // X
|
||||||
{0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00}, // Y
|
{0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00}, // Y
|
||||||
{0xF8,0x08,0x10,0x70,0x40,0x80,0xF8,0x00}, // Z
|
{0xF8,0x08,0x10,0x70,0x40,0x80,0xF8,0x00}, // Z
|
||||||
{0x78,0x40,0x40,0x40,0x40,0x40,0x78,0x00}, // [
|
{0x78,0x40,0x40,0x40,0x40,0x40,0x78,0x00}, // [
|
||||||
{0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00}, // backslash
|
{0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00}, // backslash
|
||||||
{0x78,0x08,0x08,0x08,0x08,0x08,0x78,0x00}, // ]
|
{0x78,0x08,0x08,0x08,0x08,0x08,0x78,0x00}, // ]
|
||||||
{0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00}, // ^
|
{0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00}, // ^
|
||||||
{0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00}, // _
|
{0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x00}, // _
|
||||||
{0x60,0x60,0x20,0x10,0x00,0x00,0x00,0x00}, // `
|
{0x60,0x60,0x20,0x10,0x00,0x00,0x00,0x00}, // `
|
||||||
{0x00,0x00,0x60,0x10,0x70,0x90,0x78,0x00}, // a
|
{0x00,0x00,0x60,0x10,0x70,0x90,0x78,0x00}, // a
|
||||||
{0x80,0x80,0xB0,0xC8,0x88,0xC8,0xB0,0x00}, // b
|
{0x80,0x80,0xB0,0xC8,0x88,0xC8,0xB0,0x00}, // b
|
||||||
{0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00}, // c
|
{0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00}, // c
|
||||||
{0x08,0x08,0x68,0x98,0x88,0x98,0x68,0x00}, // d
|
{0x08,0x08,0x68,0x98,0x88,0x98,0x68,0x00}, // d
|
||||||
{0x00,0x00,0x70,0x88,0xF8,0x80,0x70,0x00}, // e
|
{0x00,0x00,0x70,0x88,0xF8,0x80,0x70,0x00}, // e
|
||||||
{0x10,0x28,0x20,0x70,0x20,0x20,0x20,0x00}, // f
|
{0x10,0x28,0x20,0x70,0x20,0x20,0x20,0x00}, // f
|
||||||
{0x00,0x00,0x70,0x98,0x98,0x68,0x08,0x70}, // g
|
{0x00,0x00,0x70,0x98,0x98,0x68,0x08,0x70}, // g
|
||||||
{0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x00}, // h
|
{0x80,0x80,0xB0,0xC8,0x88,0x88,0x88,0x00}, // h
|
||||||
{0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00}, // i
|
{0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00}, // i
|
||||||
{0x10,0x00,0x10,0x10,0x10,0x90,0x60,0x00}, // j
|
{0x10,0x00,0x10,0x10,0x10,0x90,0x60,0x00}, // j
|
||||||
{0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x00}, // k
|
{0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x00}, // k
|
||||||
{0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // l
|
{0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00}, // l
|
||||||
{0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x00}, // m
|
{0x00,0x00,0xD0,0xA8,0xA8,0xA8,0xA8,0x00}, // m
|
||||||
{0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x00}, // n
|
{0x00,0x00,0xB0,0xC8,0x88,0x88,0x88,0x00}, // n
|
||||||
{0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00}, // o
|
{0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00}, // o
|
||||||
{0x00,0x00,0xB0,0xC8,0xC8,0xB0,0x80,0x80}, // p
|
{0x00,0x00,0xB0,0xC8,0xC8,0xB0,0x80,0x80}, // p
|
||||||
{0x00,0x00,0x68,0x98,0x98,0x68,0x08,0x08}, // q
|
{0x00,0x00,0x68,0x98,0x98,0x68,0x08,0x08}, // q
|
||||||
{0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x00}, // r
|
{0x00,0x00,0xB0,0xC8,0x80,0x80,0x80,0x00}, // r
|
||||||
{0x00,0x00,0x78,0x80,0x70,0x08,0xF0,0x00}, // s
|
{0x00,0x00,0x78,0x80,0x70,0x08,0xF0,0x00}, // s
|
||||||
{0x20,0x20,0xF8,0x20,0x20,0x28,0x10,0x00}, // t
|
{0x20,0x20,0xF8,0x20,0x20,0x28,0x10,0x00}, // t
|
||||||
{0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00}, // u
|
{0x00,0x00,0x88,0x88,0x88,0x98,0x68,0x00}, // u
|
||||||
{0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00}, // v
|
{0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00}, // v
|
||||||
{0x00,0x00,0x88,0x88,0xA8,0xA8,0x50,0x00}, // w
|
{0x00,0x00,0x88,0x88,0xA8,0xA8,0x50,0x00}, // w
|
||||||
{0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00}, // x
|
{0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00}, // x
|
||||||
{0x00,0x00,0x88,0x88,0x78,0x08,0x88,0x70}, // y
|
{0x00,0x00,0x88,0x88,0x78,0x08,0x88,0x70}, // y
|
||||||
{0x00,0x00,0xF8,0x10,0x20,0x40,0xF8,0x00}, // z
|
{0x00,0x00,0xF8,0x10,0x20,0x40,0xF8,0x00}, // z
|
||||||
{0x10,0x20,0x20,0x40,0x20,0x20,0x10,0x00}, // {
|
{0x10,0x20,0x20,0x40,0x20,0x20,0x10,0x00}, // {
|
||||||
{0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00}, // |
|
{0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00}, // |
|
||||||
{0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00}, // }
|
{0x40,0x20,0x20,0x10,0x20,0x20,0x40,0x00}, // }
|
||||||
{0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00}, // ~
|
{0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00}, // ~
|
||||||
{0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00} // DEL
|
{0x70,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00} // DEL
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
const char FONT8x8F[97][8] = {
|
const char FONT8x8F[97][8] = {
|
||||||
{0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
{0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00}, // columns, rows, bytes per char
|
||||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // space
|
||||||
{0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
|
{0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00}, // !
|
||||||
{0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
|
{0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00}, // "
|
||||||
{0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
|
{0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00}, // #
|
||||||
{0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
|
{0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00}, // $
|
||||||
{0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
|
{0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00}, // %
|
||||||
{0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
|
{0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00}, // &
|
||||||
{0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
|
{0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00}, // '
|
||||||
{0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
|
{0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00}, // (
|
||||||
{0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
|
{0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00}, // )
|
||||||
{0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
|
{0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00}, // *
|
||||||
{0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
|
{0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00}, // +
|
||||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
|
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30}, // ,
|
||||||
{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
|
{0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00}, // -
|
||||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
|
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00}, // .
|
||||||
{0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // /
|
{0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00}, // /
|
||||||
{0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0
|
{0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00}, // 0
|
||||||
{0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
|
{0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00}, // 1
|
||||||
{0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
|
{0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00}, // 2
|
||||||
{0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
|
{0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00}, // 3
|
||||||
{0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
|
{0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00}, // 4
|
||||||
{0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
|
{0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00}, // 5
|
||||||
{0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
|
{0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00}, // 6
|
||||||
{0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
|
{0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00}, // 7
|
||||||
{0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
|
{0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00}, // 8
|
||||||
{0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
|
{0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00}, // 9
|
||||||
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
|
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00}, // :
|
||||||
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
|
{0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30}, // ;
|
||||||
{0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
|
{0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00}, // <
|
||||||
{0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
|
{0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00}, // =
|
||||||
{0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
|
{0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00}, // >
|
||||||
{0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
|
{0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00}, // ?
|
||||||
{0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @
|
{0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00}, // @
|
||||||
{0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
|
{0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00}, // A
|
||||||
{0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
|
{0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00}, // B
|
||||||
{0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
|
{0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00}, // C
|
||||||
{0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
|
{0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00}, // D
|
||||||
{0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
|
{0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00}, // E
|
||||||
{0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
|
{0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00}, // F
|
||||||
{0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
|
{0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00}, // G
|
||||||
{0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
|
{0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00}, // H
|
||||||
{0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
|
{0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // I
|
||||||
{0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
|
{0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00}, // J
|
||||||
{0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
|
{0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00}, // K
|
||||||
{0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
|
{0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00}, // L
|
||||||
{0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
|
{0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00}, // M
|
||||||
{0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
|
{0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00}, // N
|
||||||
{0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
|
{0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00}, // O
|
||||||
{0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P
|
{0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00}, // P
|
||||||
{0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
|
{0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00}, // Q
|
||||||
{0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
|
{0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00}, // R
|
||||||
{0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
|
{0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00}, // S
|
||||||
{0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
|
{0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00}, // T
|
||||||
{0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
|
{0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00}, // U
|
||||||
{0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
|
{0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00}, // V
|
||||||
{0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
|
{0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00}, // W
|
||||||
{0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
|
{0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00}, // X
|
||||||
{0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
|
{0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00}, // Y
|
||||||
{0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
|
{0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00}, // Z
|
||||||
{0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
|
{0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00}, // [
|
||||||
{0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // backslash
|
{0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00}, // backslash
|
||||||
{0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
|
{0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00}, // ]
|
||||||
{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
|
{0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00}, // ^
|
||||||
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
|
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF}, // _
|
||||||
{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // `
|
{0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00}, // `
|
||||||
{0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
|
{0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00}, // a
|
||||||
{0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
|
{0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00}, // b
|
||||||
{0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
|
{0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00}, // c
|
||||||
{0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
|
{0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00}, // d
|
||||||
{0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
|
{0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00}, // e
|
||||||
{0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
|
{0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00}, // f
|
||||||
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
|
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C}, // g
|
||||||
{0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
|
{0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00}, // h
|
||||||
{0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
|
{0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00}, // i
|
||||||
{0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
|
{0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C}, // j
|
||||||
{0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
|
{0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00}, // k
|
||||||
{0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
|
{0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00}, // l
|
||||||
{0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
|
{0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00}, // m
|
||||||
{0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
|
{0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00}, // n
|
||||||
{0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
|
{0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00}, // o
|
||||||
{0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
|
{0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78}, // p
|
||||||
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
|
{0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F}, // q
|
||||||
{0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
|
{0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00}, // r
|
||||||
{0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
|
{0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00}, // s
|
||||||
{0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
|
{0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00}, // t
|
||||||
{0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
|
{0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00}, // u
|
||||||
{0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
|
{0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00}, // v
|
||||||
{0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
|
{0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00}, // w
|
||||||
{0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
|
{0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00}, // x
|
||||||
{0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
|
{0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C}, // y
|
||||||
{0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
|
{0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00}, // z
|
||||||
{0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
|
{0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00}, // {
|
||||||
{0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
|
{0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00}, // |
|
||||||
{0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
|
{0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00}, // }
|
||||||
{0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
|
{0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00}, // ~
|
||||||
{0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00} // DEL
|
{0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00} // DEL
|
||||||
};
|
};
|
||||||
|
|
||||||
const char FONT8x16[97][16] = {
|
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
|
{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,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,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,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}, // #
|
{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}, // $
|
{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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,0x00,0x00,0x00,0x00}, // :
|
||||||
{0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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}, // ]
|
{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}, // ^
|
{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}, // _
|
{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}, // `
|
{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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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
|
{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 uint8_t *fpga_image_ptr = NULL;
|
||||||
static uint32_t uncompressed_bytes_cnt;
|
static uint32_t uncompressed_bytes_cnt;
|
||||||
|
|
||||||
#define OUTPUT_BUFFER_LEN 80
|
#define OUTPUT_BUFFER_LEN 80
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Set up the Serial Peripheral Interface as master
|
// 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
|
// May also be used to write to other SPI attached devices like an LCD
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static void DisableSpi(void) {
|
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[0] = 0;
|
||||||
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
||||||
AT91C_BASE_SPI->SPI_CSR[2] = 0;
|
AT91C_BASE_SPI->SPI_CSR[2] = 0;
|
||||||
|
@ -41,77 +41,77 @@ static void DisableSpi(void) {
|
||||||
// Disable all interrupts
|
// Disable all interrupts
|
||||||
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
|
AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
|
||||||
|
|
||||||
// SPI disable
|
// SPI disable
|
||||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
|
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupSpi(int mode) {
|
void SetupSpi(int mode) {
|
||||||
// PA1 -> SPI_NCS3 chip select (MEM)
|
// PA1 -> SPI_NCS3 chip select (MEM)
|
||||||
// PA10 -> SPI_NCS2 chip select (LCD)
|
// PA10 -> SPI_NCS2 chip select (LCD)
|
||||||
// PA11 -> SPI_NCS0 chip select (FPGA)
|
// PA11 -> SPI_NCS0 chip select (FPGA)
|
||||||
// PA12 -> SPI_MISO Master-In Slave-Out
|
// PA12 -> SPI_MISO Master-In Slave-Out
|
||||||
// PA13 -> SPI_MOSI Master-Out Slave-In
|
// PA13 -> SPI_MOSI Master-Out Slave-In
|
||||||
// PA14 -> SPI_SPCK Serial Clock
|
// PA14 -> SPI_SPCK Serial Clock
|
||||||
|
|
||||||
// Disable PIO control of the following pins, allows use by the SPI peripheral
|
// 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;
|
AT91C_BASE_PIOA->PIO_PDR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK;
|
||||||
|
|
||||||
// Peripheral A
|
// Peripheral A
|
||||||
AT91C_BASE_PIOA->PIO_ASR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK;
|
AT91C_BASE_PIOA->PIO_ASR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK;
|
||||||
|
|
||||||
// Peripheral B
|
// Peripheral B
|
||||||
//AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
|
//AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
|
||||||
|
|
||||||
//enable the SPI Peripheral clock
|
//enable the SPI Peripheral clock
|
||||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
||||||
// Enable SPI
|
// Enable SPI
|
||||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case SPI_FPGA_MODE:
|
case SPI_FPGA_MODE:
|
||||||
AT91C_BASE_SPI->SPI_MR =
|
AT91C_BASE_SPI->SPI_MR =
|
||||||
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
||||||
(0xE << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
|
(0xE << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
|
||||||
( 0 << 7) | // Local Loopback Disabled
|
( 0 << 7) | // Local Loopback Disabled
|
||||||
AT91C_SPI_MODFDIS | // Mode Fault Detection disabled
|
AT91C_SPI_MODFDIS | // Mode Fault Detection disabled
|
||||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||||
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
||||||
AT91C_SPI_MSTR; // Master Mode
|
AT91C_SPI_MSTR; // Master Mode
|
||||||
|
|
||||||
AT91C_BASE_SPI->SPI_CSR[0] =
|
AT91C_BASE_SPI->SPI_CSR[0] =
|
||||||
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||||
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
||||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
||||||
AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits)
|
AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits)
|
||||||
( 0 << 3) | // Chip Select inactive after transfer
|
( 0 << 3) | // Chip Select inactive after transfer
|
||||||
AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge
|
AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge
|
||||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||||
break;
|
break;
|
||||||
/*
|
/*
|
||||||
case SPI_LCD_MODE:
|
case SPI_LCD_MODE:
|
||||||
AT91C_BASE_SPI->SPI_MR =
|
AT91C_BASE_SPI->SPI_MR =
|
||||||
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
||||||
(0xB << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
|
(0xB << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
|
||||||
( 0 << 7) | // Local Loopback Disabled
|
( 0 << 7) | // Local Loopback Disabled
|
||||||
( 1 << 4) | // Mode Fault Detection disabled
|
( 1 << 4) | // Mode Fault Detection disabled
|
||||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||||
( 0 << 1) | // Fixed Peripheral Select
|
( 0 << 1) | // Fixed Peripheral Select
|
||||||
( 1 << 0); // Master Mode
|
( 1 << 0); // Master Mode
|
||||||
|
|
||||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||||
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||||
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
( 1 << 16) | // Delay Before SPCK (1 MCK period)
|
||||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
||||||
AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits)
|
AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits)
|
||||||
( 0 << 3) | // Chip Select inactive after transfer
|
( 0 << 3) | // Chip Select inactive after transfer
|
||||||
( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
default:
|
default:
|
||||||
DisableSpi();
|
DisableSpi();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -119,35 +119,35 @@ void SetupSpi(int mode) {
|
||||||
// always use when we are talking to the FPGA. Both RX and TX are enabled.
|
// always use when we are talking to the FPGA. Both RX and TX are enabled.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void FpgaSetupSsc(void) {
|
void FpgaSetupSsc(void) {
|
||||||
// First configure the GPIOs, and get ourselves a clock.
|
// First configure the GPIOs, and get ourselves a clock.
|
||||||
AT91C_BASE_PIOA->PIO_ASR =
|
AT91C_BASE_PIOA->PIO_ASR =
|
||||||
GPIO_SSC_FRAME |
|
GPIO_SSC_FRAME |
|
||||||
GPIO_SSC_DIN |
|
GPIO_SSC_DIN |
|
||||||
GPIO_SSC_DOUT |
|
GPIO_SSC_DOUT |
|
||||||
GPIO_SSC_CLK;
|
GPIO_SSC_CLK;
|
||||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
|
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.
|
// Now set up the SSC proper, starting from a known state.
|
||||||
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
|
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
|
||||||
|
|
||||||
// RX clock comes from TX clock, RX starts when TX starts, data changes
|
// RX clock comes from TX clock, RX starts when TX starts, data changes
|
||||||
// on RX clock rising edge, sampled on falling edge
|
// on RX clock rising edge, sampled on falling edge
|
||||||
AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1);
|
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
|
// 8 bits per transfer, no loopback, MSB first, 1 transfer per sync
|
||||||
// pulse, no output 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);
|
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
|
// 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
|
// 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);
|
AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5);
|
||||||
|
|
||||||
// tx framing is the same as the rx framing
|
// tx framing is the same as the rx framing
|
||||||
AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR;
|
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.
|
// is in apps.h, because it should be inlined, for speed.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
bool FpgaSetupSscDma(uint8_t *buf, int len) {
|
bool FpgaSetupSscDma(uint8_t *buf, int len) {
|
||||||
if (buf == NULL) return false;
|
if (buf == NULL) return false;
|
||||||
|
|
||||||
FpgaDisableSscDma();
|
FpgaDisableSscDma();
|
||||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address
|
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_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_RNPR = (uint32_t) buf; // next transfer to same memory address
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNCR = len; // ... with same number of bytes
|
AT91C_BASE_PDC_SSC->PDC_RNCR = len; // ... with same number of bytes
|
||||||
FpgaEnableSscDma();
|
FpgaEnableSscDma();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -173,20 +173,20 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) {
|
||||||
// each call.
|
// each call.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) {
|
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
|
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
|
||||||
compressed_fpga_stream->next_out = output_buffer;
|
compressed_fpga_stream->next_out = output_buffer;
|
||||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
||||||
fpga_image_ptr = output_buffer;
|
fpga_image_ptr = output_buffer;
|
||||||
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
|
int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
|
||||||
|
|
||||||
if (res != Z_OK)
|
if (res != Z_OK)
|
||||||
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
|
Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
uncompressed_bytes_cnt++;
|
uncompressed_bytes_cnt++;
|
||||||
return *fpga_image_ptr++;
|
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.
|
// 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) {
|
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)) {
|
while((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) {
|
||||||
// skip undesired data belonging to other bitstream_versions
|
// skip undesired data belonging to other bitstream_versions
|
||||||
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
|
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) {
|
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
|
// free eventually allocated BigBuf memory
|
||||||
static void fpga_inflate_free(voidpf opaque, voidpf address) {
|
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
|
// 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) {
|
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:
|
// initialize z_stream structure for inflate:
|
||||||
compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start;
|
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->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->next_out = output_buffer;
|
||||||
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
|
||||||
compressed_fpga_stream->zalloc = &fpga_inflate_malloc;
|
compressed_fpga_stream->zalloc = &fpga_inflate_malloc;
|
||||||
compressed_fpga_stream->zfree = &fpga_inflate_free;
|
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++)
|
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);
|
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||||
|
|
||||||
// Check for a valid .bit file (starts with bitparse_fixed_header)
|
// Check for a valid .bit file (starts with bitparse_fixed_header)
|
||||||
if (memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0)
|
if (memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DownloadFPGA_byte( uint8_t w) {
|
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); }
|
#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(7);
|
||||||
SEND_BIT(6);
|
SEND_BIT(6);
|
||||||
SEND_BIT(5);
|
SEND_BIT(5);
|
||||||
SEND_BIT(4);
|
SEND_BIT(4);
|
||||||
SEND_BIT(3);
|
SEND_BIT(3);
|
||||||
SEND_BIT(2);
|
SEND_BIT(2);
|
||||||
SEND_BIT(1);
|
SEND_BIT(1);
|
||||||
SEND_BIT(0);
|
SEND_BIT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download the fpga image starting at current stream position with length FpgaImageLen bytes
|
// 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) {
|
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_OER = GPIO_FPGA_ON;
|
||||||
AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON;
|
AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON;
|
||||||
HIGH(GPIO_FPGA_ON); // ensure everything is powered 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 =
|
AT91C_BASE_PIOA->PIO_ODR =
|
||||||
GPIO_FPGA_NINIT |
|
GPIO_FPGA_NINIT |
|
||||||
GPIO_FPGA_DONE;
|
GPIO_FPGA_DONE;
|
||||||
// PIO controls the following pins
|
// PIO controls the following pins
|
||||||
AT91C_BASE_PIOA->PIO_PER =
|
AT91C_BASE_PIOA->PIO_PER =
|
||||||
GPIO_FPGA_NINIT |
|
GPIO_FPGA_NINIT |
|
||||||
GPIO_FPGA_DONE;
|
GPIO_FPGA_DONE;
|
||||||
// Enable pull-ups
|
// Enable pull-ups
|
||||||
AT91C_BASE_PIOA->PIO_PPUER =
|
AT91C_BASE_PIOA->PIO_PPUER =
|
||||||
GPIO_FPGA_NINIT |
|
GPIO_FPGA_NINIT |
|
||||||
GPIO_FPGA_DONE;
|
GPIO_FPGA_DONE;
|
||||||
|
|
||||||
// setup initial logic state
|
// setup initial logic state
|
||||||
HIGH(GPIO_FPGA_NPROGRAM);
|
HIGH(GPIO_FPGA_NPROGRAM);
|
||||||
LOW(GPIO_FPGA_CCLK);
|
LOW(GPIO_FPGA_CCLK);
|
||||||
LOW(GPIO_FPGA_DIN);
|
LOW(GPIO_FPGA_DIN);
|
||||||
// These pins are outputs
|
// These pins are outputs
|
||||||
AT91C_BASE_PIOA->PIO_OER =
|
AT91C_BASE_PIOA->PIO_OER =
|
||||||
GPIO_FPGA_NPROGRAM |
|
GPIO_FPGA_NPROGRAM |
|
||||||
GPIO_FPGA_CCLK |
|
GPIO_FPGA_CCLK |
|
||||||
GPIO_FPGA_DIN;
|
GPIO_FPGA_DIN;
|
||||||
|
|
||||||
// enter FPGA configuration mode
|
// enter FPGA configuration mode
|
||||||
LOW(GPIO_FPGA_NPROGRAM);
|
LOW(GPIO_FPGA_NPROGRAM);
|
||||||
SpinDelay(50);
|
SpinDelay(50);
|
||||||
HIGH(GPIO_FPGA_NPROGRAM);
|
HIGH(GPIO_FPGA_NPROGRAM);
|
||||||
|
|
||||||
i = 100000;
|
i = 100000;
|
||||||
// wait for FPGA ready to accept data signal
|
// wait for FPGA ready to accept data signal
|
||||||
while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) {
|
while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) {
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// crude error indicator, leave both red LEDs on and return
|
// crude error indicator, leave both red LEDs on and return
|
||||||
if (i==0){
|
if (i==0){
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < FpgaImageLen; i++) {
|
for (i = 0; i < FpgaImageLen; i++) {
|
||||||
int b = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
int b = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||||
if (b < 0) {
|
if (b < 0) {
|
||||||
Dbprintf("Error %d during FpgaDownload", b);
|
Dbprintf("Error %d during FpgaDownload", b);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DownloadFPGA_byte(b);
|
DownloadFPGA_byte(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// continue to clock FPGA until ready signal goes high
|
// continue to clock FPGA until ready signal goes high
|
||||||
i = 100000;
|
i = 100000;
|
||||||
while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) {
|
while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) {
|
||||||
HIGH(GPIO_FPGA_CCLK);
|
HIGH(GPIO_FPGA_CCLK);
|
||||||
LOW(GPIO_FPGA_CCLK);
|
LOW(GPIO_FPGA_CCLK);
|
||||||
}
|
}
|
||||||
// crude error indicator, leave both red LEDs on and return
|
// crude error indicator, leave both red LEDs on and return
|
||||||
if (i==0){
|
if (i==0){
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence
|
/* 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.
|
* 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) {
|
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;
|
int result = 0;
|
||||||
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
|
||||||
uint16_t numbytes = 0;
|
uint16_t numbytes = 0;
|
||||||
while(numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) {
|
while(numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) {
|
||||||
char current_name = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
char current_name = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||||
numbytes++;
|
numbytes++;
|
||||||
uint32_t current_length = 0;
|
uint32_t current_length = 0;
|
||||||
if (current_name < 'a' || current_name > 'e') {
|
if (current_name < 'a' || current_name > 'e') {
|
||||||
/* Strange section name, abort */
|
/* Strange section name, abort */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
current_length = 0;
|
current_length = 0;
|
||||||
switch (current_name) {
|
switch (current_name) {
|
||||||
case 'e':
|
case 'e':
|
||||||
/* Four byte length field */
|
/* 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) << 24;
|
||||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 16;
|
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 16;
|
||||||
numbytes += 2;
|
numbytes += 2;
|
||||||
default: /* Fall through, two byte length field */
|
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) << 8;
|
||||||
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0;
|
current_length += get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer) << 0;
|
||||||
numbytes += 2;
|
numbytes += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_name != 'e' && current_length > 255) {
|
if (current_name != 'e' && current_length > 255) {
|
||||||
/* Maybe a parse error */
|
/* Maybe a parse error */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_name == section_name) {
|
if (current_name == section_name) {
|
||||||
/* Found it */
|
/* Found it */
|
||||||
*section_length = current_length;
|
*section_length = current_length;
|
||||||
result = 1;
|
result = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint16_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) {
|
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);
|
get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
|
||||||
numbytes++;
|
numbytes++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
@ -388,34 +388,34 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void FpgaDownloadAndGo(int bitstream_version) {
|
void FpgaDownloadAndGo(int bitstream_version) {
|
||||||
|
|
||||||
// check whether or not the bitstream is already loaded
|
// check whether or not the bitstream is already loaded
|
||||||
if (downloaded_bitstream == bitstream_version)
|
if (downloaded_bitstream == bitstream_version)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
z_stream compressed_fpga_stream;
|
z_stream compressed_fpga_stream;
|
||||||
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
|
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
|
// make sure that we have enough memory to decompress
|
||||||
BigBuf_free(); BigBuf_Clear_ext(verbose);
|
BigBuf_free(); BigBuf_Clear_ext(verbose);
|
||||||
|
|
||||||
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
|
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint32_t bitstream_length;
|
uint32_t bitstream_length;
|
||||||
if (bitparse_find_section(bitstream_version, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {
|
if (bitparse_find_section(bitstream_version, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {
|
||||||
DownloadFPGA(bitstream_version, bitstream_length, &compressed_fpga_stream, output_buffer);
|
DownloadFPGA(bitstream_version, bitstream_length, &compressed_fpga_stream, output_buffer);
|
||||||
downloaded_bitstream = bitstream_version;
|
downloaded_bitstream = bitstream_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
inflateEnd(&compressed_fpga_stream);
|
inflateEnd(&compressed_fpga_stream);
|
||||||
|
|
||||||
// turn off antenna
|
// turn off antenna
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
|
||||||
// free eventually allocated BigBuf memory
|
// free eventually allocated BigBuf memory
|
||||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
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
|
// where C is the 4 bit command and D is the 12 bit data
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void FpgaSendCommand(uint16_t cmd, uint16_t v) {
|
void FpgaSendCommand(uint16_t cmd, uint16_t v) {
|
||||||
SetupSpi(SPI_FPGA_MODE);
|
SetupSpi(SPI_FPGA_MODE);
|
||||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
|
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
|
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
|
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
|
// 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.
|
// avoid changing this function's occurence everywhere in the source code.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void FpgaWriteConfWord(uint8_t v) {
|
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.
|
// the samples from the ADC always flow through the FPGA.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SetAdcMuxFor(uint32_t whichGpio) {
|
void SetAdcMuxFor(uint32_t whichGpio) {
|
||||||
AT91C_BASE_PIOA->PIO_OER =
|
AT91C_BASE_PIOA->PIO_OER =
|
||||||
GPIO_MUXSEL_HIPKD |
|
GPIO_MUXSEL_HIPKD |
|
||||||
GPIO_MUXSEL_LOPKD |
|
GPIO_MUXSEL_LOPKD |
|
||||||
GPIO_MUXSEL_LORAW |
|
GPIO_MUXSEL_LORAW |
|
||||||
GPIO_MUXSEL_HIRAW;
|
GPIO_MUXSEL_HIRAW;
|
||||||
|
|
||||||
AT91C_BASE_PIOA->PIO_PER =
|
AT91C_BASE_PIOA->PIO_PER =
|
||||||
GPIO_MUXSEL_HIPKD |
|
GPIO_MUXSEL_HIPKD |
|
||||||
GPIO_MUXSEL_LOPKD |
|
GPIO_MUXSEL_LOPKD |
|
||||||
GPIO_MUXSEL_LORAW |
|
GPIO_MUXSEL_LORAW |
|
||||||
GPIO_MUXSEL_HIRAW;
|
GPIO_MUXSEL_HIRAW;
|
||||||
|
|
||||||
LOW(GPIO_MUXSEL_HIPKD);
|
LOW(GPIO_MUXSEL_HIPKD);
|
||||||
LOW(GPIO_MUXSEL_LOPKD);
|
LOW(GPIO_MUXSEL_LOPKD);
|
||||||
#ifndef WITH_FPC
|
#ifndef WITH_FPC
|
||||||
LOW(GPIO_MUXSEL_HIRAW);
|
LOW(GPIO_MUXSEL_HIRAW);
|
||||||
LOW(GPIO_MUXSEL_LORAW);
|
LOW(GPIO_MUXSEL_LORAW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HIGH(whichGpio);
|
HIGH(whichGpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fpga_print_status(void) {
|
void Fpga_print_status(void) {
|
||||||
Dbprintf("Currently loaded FPGA image");
|
Dbprintf("Currently loaded FPGA image");
|
||||||
Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream-1]);
|
Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int FpgaGetCurrent(void) {
|
int FpgaGetCurrent(void) {
|
||||||
return downloaded_bitstream;
|
return downloaded_bitstream;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turns off the antenna,
|
// Turns off the antenna,
|
||||||
|
@ -480,10 +480,10 @@ int FpgaGetCurrent(void) {
|
||||||
// if HF, Disable SSC DMA
|
// if HF, Disable SSC DMA
|
||||||
// turn off trace and leds off.
|
// turn off trace and leds off.
|
||||||
void switch_off(void) {
|
void switch_off(void) {
|
||||||
if (MF_DBGLEVEL > 3) Dbprintf("switch_off");
|
if (MF_DBGLEVEL > 3) Dbprintf("switch_off");
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
if (downloaded_bitstream == FPGA_BITSTREAM_HF )
|
if (downloaded_bitstream == FPGA_BITSTREAM_HF )
|
||||||
FpgaDisableSscDma();
|
FpgaDisableSscDma();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "fpga.h"
|
#include "fpga.h"
|
||||||
#include "common.h" // standard definitions
|
#include "common.h" // standard definitions
|
||||||
#include "proxmark3.h" // common area
|
#include "proxmark3.h" // common area
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "BigBuf.h" // bigbuf mem
|
#include "BigBuf.h" // bigbuf mem
|
||||||
#include "zlib.h" // uncompress
|
#include "zlib.h" // uncompress
|
||||||
|
|
||||||
|
|
||||||
void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
||||||
|
@ -32,7 +32,7 @@ void SetupSpi(int mode);
|
||||||
bool FpgaSetupSscDma(uint8_t *buf, int len);
|
bool FpgaSetupSscDma(uint8_t *buf, int len);
|
||||||
void Fpga_print_status(void);
|
void Fpga_print_status(void);
|
||||||
int FpgaGetCurrent(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;
|
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||||
void SetAdcMuxFor(uint32_t whichGpio);
|
void SetAdcMuxFor(uint32_t whichGpio);
|
||||||
|
|
||||||
|
@ -45,56 +45,56 @@ extern void switch_off(void);
|
||||||
//#define FPGA_BITSTREAM_FELICA 3
|
//#define FPGA_BITSTREAM_FELICA 3
|
||||||
|
|
||||||
// Definitions for the FPGA commands.
|
// Definitions for the FPGA commands.
|
||||||
#define FPGA_CMD_SET_CONFREG (1<<12)
|
#define FPGA_CMD_SET_CONFREG (1<<12)
|
||||||
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
||||||
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
|
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
|
||||||
// Definitions for the FPGA configuration word.
|
// Definitions for the FPGA configuration word.
|
||||||
// LF
|
// LF
|
||||||
#define FPGA_MAJOR_MODE_LF_ADC (0<<5)
|
#define FPGA_MAJOR_MODE_LF_ADC (0<<5)
|
||||||
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
|
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
|
||||||
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5)
|
#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5)
|
||||||
// HF
|
// HF
|
||||||
#define FPGA_MAJOR_MODE_HF_READER_TX (0<<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_READER_RX_XCORR (1<<5)
|
||||||
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
|
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
|
||||||
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
|
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
|
||||||
#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5)
|
#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5)
|
||||||
#define FPGA_MAJOR_MODE_HF_FELICA (5<<5)
|
#define FPGA_MAJOR_MODE_HF_FELICA (5<<5)
|
||||||
// BOTH
|
// BOTH
|
||||||
#define FPGA_MAJOR_MODE_OFF_LF (6<<5)
|
#define FPGA_MAJOR_MODE_OFF_LF (6<<5)
|
||||||
#define FPGA_MAJOR_MODE_OFF (7<<5)
|
#define FPGA_MAJOR_MODE_OFF (7<<5)
|
||||||
|
|
||||||
// Options for LF_ADC
|
// 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
|
// Options for LF_EDGE_DETECT
|
||||||
#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1
|
#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_READER_FIELD (1<<0)
|
||||||
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
|
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
|
||||||
// Options for the HF reader, tx to tag
|
// 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
|
// 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_848_KHZ (1<<0)
|
||||||
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
||||||
#define FPGA_HF_READER_RX_XCORR_QUARTER (1<<2)
|
#define FPGA_HF_READER_RX_XCORR_QUARTER (1<<2)
|
||||||
// Options for the HF simulated tag, how to modulate
|
// Options for the HF simulated tag, how to modulate
|
||||||
#define FPGA_HF_SIMULATOR_NO_MODULATION 0x0 // 0000
|
#define FPGA_HF_SIMULATOR_NO_MODULATION 0x0 // 0000
|
||||||
#define FPGA_HF_SIMULATOR_MODULATE_BPSK 0x1 // 0001
|
#define FPGA_HF_SIMULATOR_MODULATE_BPSK 0x1 // 0001
|
||||||
#define FPGA_HF_SIMULATOR_MODULATE_212K 0x2 // 0010
|
#define FPGA_HF_SIMULATOR_MODULATE_212K 0x2 // 0010
|
||||||
#define FPGA_HF_SIMULATOR_MODULATE_424K 0x4 // 0100
|
#define FPGA_HF_SIMULATOR_MODULATE_424K 0x4 // 0100
|
||||||
#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5 // 0101
|
#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5 // 0101
|
||||||
// no 848K
|
// no 848K
|
||||||
|
|
||||||
// Options for ISO14443A
|
// Options for ISO14443A
|
||||||
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
|
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
|
||||||
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
|
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
|
||||||
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
|
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
|
||||||
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
|
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
|
||||||
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
||||||
|
|
||||||
//options for Felica.
|
//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_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_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 "apps.h"
|
||||||
#include "BigBuf.h"
|
#include "BigBuf.h"
|
||||||
#include "util.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);
|
||||||
|
|
||||||
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;
|
uint16_t *destend = dest + n-1;
|
||||||
|
|
||||||
// Reading data loop
|
// Reading data loop
|
||||||
while(dest <= destend) {
|
while(dest <= destend) {
|
||||||
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
*dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
*dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
||||||
dest++;
|
dest++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//setting tracelen - important! it was set by buffer overflow before
|
//setting tracelen - important! it was set by buffer overflow before
|
||||||
set_tracelen( BigBuf_max_traceLen());
|
set_tracelen( BigBuf_max_traceLen());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HfSnoop(int samplesToSkip, int triggersToSkip)
|
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);
|
Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
|
||||||
int trigger_cnt = 0;
|
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
|
// Set up the synchronous serial port
|
||||||
FpgaSetupSsc();
|
FpgaSetupSsc();
|
||||||
|
|
||||||
// Setting Frame Mode For better performance on high speed data transfer.
|
// Setting Frame Mode For better performance on high speed data transfer.
|
||||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16);
|
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);
|
SpinDelay(100);
|
||||||
|
|
||||||
uint16_t r = 0;
|
uint16_t r = 0;
|
||||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
r = (uint16_t)AT91C_BASE_SSC->SSC_RHR;
|
r = (uint16_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
r = MAX(r & 0xff, r >> 8);
|
r = MAX(r & 0xff, r >> 8);
|
||||||
if (r >= 180) { // 0xB4 ??
|
if (r >= 180) { // 0xB4 ??
|
||||||
if (++trigger_cnt > triggersToSkip)
|
if (++trigger_cnt > triggersToSkip)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BUTTON_PRESS()) {
|
if (!BUTTON_PRESS()) {
|
||||||
int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0
|
int waitcount = samplesToSkip; // lets wait 40000 ticks of pck0
|
||||||
while(waitcount != 0) {
|
while(waitcount != 0) {
|
||||||
|
|
||||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY))
|
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY))
|
||||||
waitcount--;
|
waitcount--;
|
||||||
}
|
}
|
||||||
optimizedSnoop();
|
optimizedSnoop();
|
||||||
Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r);
|
Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Resetting Frame mode (First set in fpgaloader.c)
|
//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);
|
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");
|
DbpString("HF Snoop end");
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LED_D_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
|
#include "mifare.h" // structs
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
enum {
|
enum {
|
||||||
DEMOD_UNSYNCD,
|
DEMOD_UNSYNCD,
|
||||||
// DEMOD_HALF_SYNCD,
|
// DEMOD_HALF_SYNCD,
|
||||||
// DEMOD_MOD_FIRST_HALF,
|
// DEMOD_MOD_FIRST_HALF,
|
||||||
// DEMOD_NOMOD_FIRST_HALF,
|
// DEMOD_NOMOD_FIRST_HALF,
|
||||||
DEMOD_MANCHESTER_DATA
|
DEMOD_MANCHESTER_DATA
|
||||||
} state;
|
} state;
|
||||||
uint16_t twoBits;
|
uint16_t twoBits;
|
||||||
uint16_t highCnt;
|
uint16_t highCnt;
|
||||||
uint16_t bitCount;
|
uint16_t bitCount;
|
||||||
uint16_t collisionPos;
|
uint16_t collisionPos;
|
||||||
uint16_t syncBit;
|
uint16_t syncBit;
|
||||||
uint8_t parityBits;
|
uint8_t parityBits;
|
||||||
uint8_t parityLen;
|
uint8_t parityLen;
|
||||||
uint16_t shiftReg;
|
uint16_t shiftReg;
|
||||||
uint16_t samples;
|
uint16_t samples;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint32_t startTime, endTime;
|
uint32_t startTime, endTime;
|
||||||
uint8_t *output;
|
uint8_t *output;
|
||||||
uint8_t *parity;
|
uint8_t *parity;
|
||||||
} tDemod;
|
} tDemod;
|
||||||
/*
|
/*
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MOD_NOMOD = 0,
|
MOD_NOMOD = 0,
|
||||||
MOD_SECOND_HALF,
|
MOD_SECOND_HALF,
|
||||||
MOD_FIRST_HALF,
|
MOD_FIRST_HALF,
|
||||||
MOD_BOTH_HALVES
|
MOD_BOTH_HALVES
|
||||||
} Modulation_t;
|
} Modulation_t;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
enum {
|
enum {
|
||||||
STATE_UNSYNCD,
|
STATE_UNSYNCD,
|
||||||
STATE_START_OF_COMMUNICATION,
|
STATE_START_OF_COMMUNICATION,
|
||||||
STATE_MILLER_X,
|
STATE_MILLER_X,
|
||||||
STATE_MILLER_Y,
|
STATE_MILLER_Y,
|
||||||
STATE_MILLER_Z,
|
STATE_MILLER_Z,
|
||||||
// DROP_NONE,
|
// DROP_NONE,
|
||||||
// DROP_FIRST_HALF,
|
// DROP_FIRST_HALF,
|
||||||
} state;
|
} state;
|
||||||
uint16_t shiftReg;
|
uint16_t shiftReg;
|
||||||
int16_t bitCount;
|
int16_t bitCount;
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
//uint16_t byteCntMax;
|
//uint16_t byteCntMax;
|
||||||
uint16_t posCnt;
|
uint16_t posCnt;
|
||||||
uint16_t syncBit;
|
uint16_t syncBit;
|
||||||
uint8_t parityBits;
|
uint8_t parityBits;
|
||||||
uint8_t parityLen;
|
uint8_t parityLen;
|
||||||
uint32_t fourBits;
|
uint32_t fourBits;
|
||||||
uint32_t startTime, endTime;
|
uint32_t startTime, endTime;
|
||||||
uint8_t *output;
|
uint8_t *output;
|
||||||
uint8_t *parity;
|
uint8_t *parity;
|
||||||
} tUart;
|
} tUart;
|
||||||
|
|
||||||
#ifndef AddCrc14A
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef AddCrc14B
|
#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
|
#endif
|
||||||
|
|
||||||
extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
|
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);
|
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,
|
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);
|
//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
|
#endif
|
||||||
|
|
||||||
#include "proxmark3.h"
|
#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 "apps.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
@ -27,11 +27,11 @@ extern "C" {
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
|
|
||||||
#ifndef AddCrc14A
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef AddCrc14B
|
#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
|
#endif
|
||||||
|
|
||||||
extern void SendRawCommand14443B_Ex(UsbCommand *c);
|
extern void SendRawCommand14443B_Ex(UsbCommand *c);
|
||||||
|
@ -45,13 +45,13 @@ extern void WaitForFpgaDelayQueueIsEmpty( uint16_t delay );
|
||||||
extern void ClearFpgaShiftingRegisters(void);
|
extern void ClearFpgaShiftingRegisters(void);
|
||||||
|
|
||||||
// States for 14B SIM command
|
// States for 14B SIM command
|
||||||
#define SIM_NOFIELD 0
|
#define SIM_NOFIELD 0
|
||||||
#define SIM_IDLE 1
|
#define SIM_IDLE 1
|
||||||
#define SIM_HALTED 2
|
#define SIM_HALTED 2
|
||||||
#define SIM_SELECTING 3
|
#define SIM_SELECTING 3
|
||||||
#define SIM_HALTING 4
|
#define SIM_HALTING 4
|
||||||
#define SIM_ACKNOWLEDGE 5
|
#define SIM_ACKNOWLEDGE 5
|
||||||
#define SIM_WORK 6
|
#define SIM_WORK 6
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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:
|
Default LF config is set to:
|
||||||
decimation = 1 (we keep 1 out of 1 samples)
|
decimation = 1 (we keep 1 out of 1 samples)
|
||||||
bits_per_sample = 8
|
bits_per_sample = 8
|
||||||
averaging = YES
|
averaging = YES
|
||||||
divisor = 95 (125khz)
|
divisor = 95 (125khz)
|
||||||
trigger_threshold = 0
|
trigger_threshold = 0
|
||||||
*/
|
*/
|
||||||
sample_config config = { 1, 8, 1, 95, 0 } ;
|
sample_config config = { 1, 8, 1, 95, 0 } ;
|
||||||
|
|
||||||
void printConfig() {
|
void printConfig() {
|
||||||
Dbprintf("LF Sampling config");
|
Dbprintf("LF Sampling config");
|
||||||
Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor+1));
|
Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor+1));
|
||||||
Dbprintf(" [b] bps.................%d", config.bits_per_sample);
|
Dbprintf(" [b] bps.................%d", config.bits_per_sample);
|
||||||
Dbprintf(" [d] decimation..........%d", config.decimation);
|
Dbprintf(" [d] decimation..........%d", config.decimation);
|
||||||
Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No");
|
Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No");
|
||||||
Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold);
|
Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,25 +39,25 @@ void printConfig() {
|
||||||
* @param sc
|
* @param sc
|
||||||
*/
|
*/
|
||||||
void setSamplingConfig(sample_config *sc) {
|
void setSamplingConfig(sample_config *sc) {
|
||||||
if(sc->divisor != 0) config.divisor = sc->divisor;
|
if(sc->divisor != 0) config.divisor = sc->divisor;
|
||||||
if(sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample;
|
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->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold;
|
||||||
|
|
||||||
config.decimation = (sc->decimation != 0) ? sc->decimation : 1;
|
config.decimation = (sc->decimation != 0) ? sc->decimation : 1;
|
||||||
config.averaging = sc->averaging;
|
config.averaging = sc->averaging;
|
||||||
if(config.bits_per_sample > 8) config.bits_per_sample = 8;
|
if(config.bits_per_sample > 8) config.bits_per_sample = 8;
|
||||||
|
|
||||||
printConfig();
|
printConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
sample_config* getSamplingConfig() {
|
sample_config* getSamplingConfig() {
|
||||||
return &config;
|
return &config;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BitstreamOut {
|
struct BitstreamOut {
|
||||||
uint8_t * buffer;
|
uint8_t * buffer;
|
||||||
uint32_t numbits;
|
uint32_t numbits;
|
||||||
uint32_t position;
|
uint32_t position;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,39 +66,39 @@ struct BitstreamOut {
|
||||||
* @param bit
|
* @param bit
|
||||||
*/
|
*/
|
||||||
void pushBit( BitstreamOut* stream, uint8_t bit) {
|
void pushBit( BitstreamOut* stream, uint8_t bit) {
|
||||||
int bytepos = stream->position >> 3; // divide by 8
|
int bytepos = stream->position >> 3; // divide by 8
|
||||||
int bitpos = stream->position & 7;
|
int bitpos = stream->position & 7;
|
||||||
*(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos);
|
*(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos);
|
||||||
stream->position++;
|
stream->position++;
|
||||||
stream->numbits++;
|
stream->numbits++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
|
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
|
||||||
* if not already loaded, sets divisor and starts up the antenna.
|
* if not already loaded, sets divisor and starts up the antenna.
|
||||||
* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz
|
* @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) {
|
void LFSetupFPGAForADC(int divisor, bool lf_field) {
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
|
if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||||
else if (divisor == 0)
|
else if (divisor == 0)
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||||
else
|
else
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
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.
|
// Connect the A/D to the peak-detected low-frequency path.
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
// 50ms for the resonant antenna to settle.
|
// 50ms for the resonant antenna to settle.
|
||||||
SpinDelay(50);
|
SpinDelay(50);
|
||||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||||
FpgaSetupSsc();
|
FpgaSetupSsc();
|
||||||
// start a 1.5ticks is 1us
|
// start a 1.5ticks is 1us
|
||||||
StartTicks();
|
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) {
|
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();
|
bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen();
|
||||||
|
|
||||||
if (bits_per_sample < 1) bits_per_sample = 1;
|
if (bits_per_sample < 1) bits_per_sample = 1;
|
||||||
if (bits_per_sample > 8) bits_per_sample = 8;
|
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
|
// use a bit stream to handle the output
|
||||||
BitstreamOut data = { dest , 0, 0};
|
BitstreamOut data = { dest , 0, 0};
|
||||||
int sample_counter = 0;
|
int sample_counter = 0;
|
||||||
uint8_t sample = 0;
|
uint8_t sample = 0;
|
||||||
|
|
||||||
// if we want to do averaging
|
// if we want to do averaging
|
||||||
uint32_t sample_sum =0 ;
|
uint32_t sample_sum =0 ;
|
||||||
uint32_t sample_total_numbers = 0;
|
uint32_t sample_total_numbers = 0;
|
||||||
uint32_t sample_total_saved = 0;
|
uint32_t sample_total_saved = 0;
|
||||||
uint32_t cancel_counter = 0;
|
uint32_t cancel_counter = 0;
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
while (!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
// Testpoint 8 (TP8) can be used to trigger oscilliscope
|
// Testpoint 8 (TP8) can be used to trigger oscilliscope
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
// threshold either high or low values 128 = center 0. if trigger = 178
|
// 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 ((trigger_threshold > 0) && (sample < (trigger_threshold + 128)) && (sample > (128 - trigger_threshold))) {
|
||||||
if (cancel_after > 0) {
|
if (cancel_after > 0) {
|
||||||
cancel_counter++;
|
cancel_counter++;
|
||||||
if (cancel_after == cancel_counter)
|
if (cancel_after == cancel_counter)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
trigger_threshold = 0;
|
trigger_threshold = 0;
|
||||||
sample_total_numbers++;
|
sample_total_numbers++;
|
||||||
|
|
||||||
if (averaging)
|
if (averaging)
|
||||||
sample_sum += sample;
|
sample_sum += sample;
|
||||||
|
|
||||||
// check decimation
|
// check decimation
|
||||||
if (decimation > 1) {
|
if (decimation > 1) {
|
||||||
sample_counter++;
|
sample_counter++;
|
||||||
if (sample_counter < decimation) continue;
|
if (sample_counter < decimation) continue;
|
||||||
sample_counter = 0;
|
sample_counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// averaging
|
// averaging
|
||||||
if (averaging && decimation > 1) {
|
if (averaging && decimation > 1) {
|
||||||
sample = sample_sum / decimation;
|
sample = sample_sum / decimation;
|
||||||
sample_sum =0;
|
sample_sum =0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the sample
|
// store the sample
|
||||||
sample_total_saved ++;
|
sample_total_saved ++;
|
||||||
if (bits_per_sample == 8) {
|
if (bits_per_sample == 8) {
|
||||||
dest[sample_total_saved-1] = sample;
|
dest[sample_total_saved-1] = sample;
|
||||||
|
|
||||||
// Get the return value correct
|
// Get the return value correct
|
||||||
data.numbits = sample_total_saved << 3;
|
data.numbits = sample_total_saved << 3;
|
||||||
if (sample_total_saved >= bufsize) break;
|
if (sample_total_saved >= bufsize) break;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
pushBit(&data, sample & 0x80);
|
pushBit(&data, sample & 0x80);
|
||||||
if (bits_per_sample > 1) pushBit(&data, sample & 0x40);
|
if (bits_per_sample > 1) pushBit(&data, sample & 0x40);
|
||||||
if (bits_per_sample > 2) pushBit(&data, sample & 0x20);
|
if (bits_per_sample > 2) pushBit(&data, sample & 0x20);
|
||||||
if (bits_per_sample > 3) pushBit(&data, sample & 0x10);
|
if (bits_per_sample > 3) pushBit(&data, sample & 0x10);
|
||||||
if (bits_per_sample > 4) pushBit(&data, sample & 0x08);
|
if (bits_per_sample > 4) pushBit(&data, sample & 0x08);
|
||||||
if (bits_per_sample > 5) pushBit(&data, sample & 0x04);
|
if (bits_per_sample > 5) pushBit(&data, sample & 0x04);
|
||||||
if (bits_per_sample > 6) pushBit(&data, sample & 0x02);
|
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) {
|
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("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 ...",
|
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]);
|
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
|
// Ensure that DC offset removal and noise check is performed for any device-side processing
|
||||||
removeSignalOffset(dest, bufsize);
|
removeSignalOffset(dest, bufsize);
|
||||||
computeSignalProperties(dest, bufsize);
|
computeSignalProperties(dest, bufsize);
|
||||||
|
|
||||||
return data.numbits;
|
return data.numbits;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Does sample acquisition, ignoring the config values set in the sample_config.
|
* @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
|
* @return number of bits sampled
|
||||||
*/
|
*/
|
||||||
uint32_t DoAcquisition_default(int trigger_threshold, bool silent) {
|
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) {
|
uint32_t DoAcquisition_config( bool silent, int sample_size) {
|
||||||
return DoAcquisition(config.decimation
|
return DoAcquisition(config.decimation
|
||||||
,config.bits_per_sample
|
,config.bits_per_sample
|
||||||
,config.averaging
|
,config.averaging
|
||||||
,config.trigger_threshold
|
,config.trigger_threshold
|
||||||
,silent
|
,silent
|
||||||
,sample_size
|
,sample_size
|
||||||
,0);
|
,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after) {
|
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) {
|
uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
|
||||||
if (!silent)
|
if (!silent)
|
||||||
printConfig();
|
printConfig();
|
||||||
LFSetupFPGAForADC(config.divisor, activeField);
|
LFSetupFPGAForADC(config.divisor, activeField);
|
||||||
return DoAcquisition_config(silent, sample_size);
|
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
|
* @return number of bits sampled
|
||||||
**/
|
**/
|
||||||
uint32_t SampleLF(bool printCfg, int sample_size) {
|
uint32_t SampleLF(bool printCfg, int sample_size) {
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
uint32_t ret = ReadLF(true, printCfg, sample_size);
|
uint32_t ret = ReadLF(true, printCfg, sample_size);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
|
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
|
||||||
* @return number of bits sampled
|
* @return number of bits sampled
|
||||||
**/
|
**/
|
||||||
uint32_t SnoopLF() {
|
uint32_t SnoopLF() {
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
uint32_t ret = ReadLF(false, true, 0);
|
uint32_t ret = ReadLF(false, true, 0);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -269,61 +269,61 @@ uint32_t SnoopLF() {
|
||||||
**/
|
**/
|
||||||
void doT55x7Acquisition(size_t sample_size) {
|
void doT55x7Acquisition(size_t sample_size) {
|
||||||
|
|
||||||
#define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph
|
#define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph
|
||||||
#define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph
|
#define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph
|
||||||
#define T55xx_READ_TOL 5
|
#define T55xx_READ_TOL 5
|
||||||
|
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
uint16_t bufsize = BigBuf_max_traceLen();
|
uint16_t bufsize = BigBuf_max_traceLen();
|
||||||
|
|
||||||
if ( bufsize > sample_size )
|
if ( bufsize > sample_size )
|
||||||
bufsize = sample_size;
|
bufsize = sample_size;
|
||||||
|
|
||||||
uint8_t curSample = 0, lastSample = 0;
|
uint8_t curSample = 0, lastSample = 0;
|
||||||
uint16_t i = 0, skipCnt = 0;
|
uint16_t i = 0, skipCnt = 0;
|
||||||
bool startFound = false;
|
bool startFound = false;
|
||||||
bool highFound = false;
|
bool highFound = false;
|
||||||
bool lowFound = false;
|
bool lowFound = false;
|
||||||
|
|
||||||
while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) {
|
while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
// skip until the first high sample above threshold
|
// skip until the first high sample above threshold
|
||||||
if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) {
|
if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) {
|
||||||
//if (curSample > lastSample)
|
//if (curSample > lastSample)
|
||||||
// lastSample = curSample;
|
// lastSample = curSample;
|
||||||
highFound = true;
|
highFound = true;
|
||||||
} else if (!highFound) {
|
} else if (!highFound) {
|
||||||
skipCnt++;
|
skipCnt++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// skip until the first low sample below threshold
|
// skip until the first low sample below threshold
|
||||||
if (!startFound && curSample < T55xx_READ_LOWER_THRESHOLD) {
|
if (!startFound && curSample < T55xx_READ_LOWER_THRESHOLD) {
|
||||||
//if (curSample > lastSample)
|
//if (curSample > lastSample)
|
||||||
lastSample = curSample;
|
lastSample = curSample;
|
||||||
lowFound = true;
|
lowFound = true;
|
||||||
} else if (!lowFound) {
|
} else if (!lowFound) {
|
||||||
skipCnt++;
|
skipCnt++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip until first high samples begin to change
|
// skip until first high samples begin to change
|
||||||
if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL){
|
if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL){
|
||||||
// if just found start - recover last sample
|
// if just found start - recover last sample
|
||||||
if (!startFound) {
|
if (!startFound) {
|
||||||
dest[i++] = lastSample;
|
dest[i++] = lastSample;
|
||||||
startFound = true;
|
startFound = true;
|
||||||
}
|
}
|
||||||
// collect samples
|
// collect samples
|
||||||
dest[i++] = curSample;
|
dest[i++] = curSample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* acquisition of Cotag LF signal. Similart to other LF, since the Cotag has such long datarate RF/384
|
* 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
|
#endif
|
||||||
void doCotagAcquisition(size_t sample_size) {
|
void doCotagAcquisition(size_t sample_size) {
|
||||||
|
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
uint16_t bufsize = BigBuf_max_traceLen();
|
uint16_t bufsize = BigBuf_max_traceLen();
|
||||||
|
|
||||||
if ( bufsize > sample_size )
|
if ( bufsize > sample_size )
|
||||||
bufsize = sample_size;
|
bufsize = sample_size;
|
||||||
|
|
||||||
dest[0] = 0;
|
dest[0] = 0;
|
||||||
uint8_t sample = 0, firsthigh = 0, firstlow = 0;
|
uint8_t sample = 0, firsthigh = 0, firstlow = 0;
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
uint16_t noise_counter = 0;
|
uint16_t noise_counter = 0;
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
// find first peak
|
// find first peak
|
||||||
if ( !firsthigh ) {
|
if ( !firsthigh ) {
|
||||||
if (sample < COTAG_ONE_THRESHOLD) {
|
if (sample < COTAG_ONE_THRESHOLD) {
|
||||||
noise_counter++;
|
noise_counter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
noise_counter = 0;
|
noise_counter = 0;
|
||||||
firsthigh = 1;
|
firsthigh = 1;
|
||||||
}
|
}
|
||||||
if ( !firstlow ){
|
if ( !firstlow ){
|
||||||
if (sample > COTAG_ZERO_THRESHOLD ) {
|
if (sample > COTAG_ZERO_THRESHOLD ) {
|
||||||
noise_counter++;
|
noise_counter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
noise_counter = 0;
|
noise_counter = 0;
|
||||||
firstlow = 1;
|
firstlow = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
if ( sample > COTAG_ONE_THRESHOLD)
|
if ( sample > COTAG_ONE_THRESHOLD)
|
||||||
dest[i] = 255;
|
dest[i] = 255;
|
||||||
else if ( sample < COTAG_ZERO_THRESHOLD)
|
else if ( sample < COTAG_ZERO_THRESHOLD)
|
||||||
dest[i] = 0;
|
dest[i] = 0;
|
||||||
else
|
else
|
||||||
dest[i] = dest[i-1];
|
dest[i] = dest[i-1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t doCotagAcquisitionManchester() {
|
uint32_t doCotagAcquisitionManchester() {
|
||||||
|
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
uint16_t bufsize = BigBuf_max_traceLen();
|
uint16_t bufsize = BigBuf_max_traceLen();
|
||||||
|
|
||||||
if ( bufsize > COTAG_BITS )
|
if ( bufsize > COTAG_BITS )
|
||||||
bufsize = COTAG_BITS;
|
bufsize = COTAG_BITS;
|
||||||
|
|
||||||
dest[0] = 0;
|
dest[0] = 0;
|
||||||
uint8_t sample = 0, firsthigh = 0, firstlow = 0;
|
uint8_t sample = 0, firsthigh = 0, firstlow = 0;
|
||||||
uint16_t sample_counter = 0, period = 0;
|
uint16_t sample_counter = 0, period = 0;
|
||||||
uint8_t curr = 0, prev = 0;
|
uint8_t curr = 0, prev = 0;
|
||||||
uint16_t noise_counter = 0;
|
uint16_t noise_counter = 0;
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) && (noise_counter < (COTAG_T1 << 1)) ) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
// find first peak
|
// find first peak
|
||||||
if ( !firsthigh ) {
|
if ( !firsthigh ) {
|
||||||
if (sample < COTAG_ONE_THRESHOLD) {
|
if (sample < COTAG_ONE_THRESHOLD) {
|
||||||
noise_counter++;
|
noise_counter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
noise_counter = 0;
|
noise_counter = 0;
|
||||||
firsthigh = 1;
|
firsthigh = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !firstlow ){
|
if ( !firstlow ){
|
||||||
if (sample > COTAG_ZERO_THRESHOLD ) {
|
if (sample > COTAG_ZERO_THRESHOLD ) {
|
||||||
noise_counter++;
|
noise_counter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
noise_counter = 0;
|
noise_counter = 0;
|
||||||
firstlow = 1;
|
firstlow = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set sample 255, 0, or previous
|
// set sample 255, 0, or previous
|
||||||
if ( sample > COTAG_ONE_THRESHOLD){
|
if ( sample > COTAG_ONE_THRESHOLD){
|
||||||
prev = curr;
|
prev = curr;
|
||||||
curr = 1;
|
curr = 1;
|
||||||
}
|
}
|
||||||
else if ( sample < COTAG_ZERO_THRESHOLD) {
|
else if ( sample < COTAG_ZERO_THRESHOLD) {
|
||||||
prev = curr;
|
prev = curr;
|
||||||
curr = 0;
|
curr = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
curr = prev;
|
curr = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
// full T1 periods,
|
// full T1 periods,
|
||||||
if ( period > 0 ) {
|
if ( period > 0 ) {
|
||||||
--period;
|
--period;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
dest[sample_counter] = curr;
|
dest[sample_counter] = curr;
|
||||||
++sample_counter;
|
++sample_counter;
|
||||||
period = COTAG_T1;
|
period = COTAG_T1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sample_counter;
|
return sample_counter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "usb_cdc.h" // for usb_poll_validate_length
|
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||||
#include "ticks.h" // for StartTicks
|
#include "ticks.h" // for StartTicks
|
||||||
|
|
||||||
typedef struct BitstreamOut BitstreamOut;
|
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
|
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
|
||||||
* if not already loaded, sets divisor and starts up the antenna.
|
* if not already loaded, sets divisor and starts up the antenna.
|
||||||
* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz
|
* @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);
|
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(){
|
bool InitDesfireCard(){
|
||||||
|
|
||||||
iso14a_card_select_t card;
|
iso14a_card_select_t card;
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
if (!iso14443a_select_card(NULL, &card, NULL, true, 0, false)) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ARG0 flag enums
|
// ARG0 flag enums
|
||||||
enum {
|
enum {
|
||||||
NONE = 0x00,
|
NONE = 0x00,
|
||||||
INIT = 0x01,
|
INIT = 0x01,
|
||||||
DISCONNECT = 0x02,
|
DISCONNECT = 0x02,
|
||||||
CLEARTRACE = 0x04,
|
CLEARTRACE = 0x04,
|
||||||
BAR = 0x08,
|
BAR = 0x08,
|
||||||
} CmdOptions ;
|
} CmdOptions ;
|
||||||
|
|
||||||
void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
|
void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
|
||||||
|
|
||||||
/* ARG0 contains flags.
|
/* ARG0 contains flags.
|
||||||
0x01 = init card.
|
0x01 = init card.
|
||||||
0x02 = Disconnect
|
0x02 = Disconnect
|
||||||
0x03
|
0x03
|
||||||
*/
|
*/
|
||||||
uint8_t flags = arg0;
|
uint8_t flags = arg0;
|
||||||
size_t datalen = arg1;
|
size_t datalen = arg1;
|
||||||
uint8_t resp[RECEIVE_SIZE];
|
uint8_t resp[RECEIVE_SIZE];
|
||||||
memset(resp,0,sizeof(resp));
|
memset(resp,0,sizeof(resp));
|
||||||
|
|
||||||
if (MF_DBGLEVEL >= 4) {
|
if (MF_DBGLEVEL >= 4) {
|
||||||
Dbprintf(" flags : %02X", flags);
|
Dbprintf(" flags : %02X", flags);
|
||||||
Dbprintf(" len : %02X", datalen);
|
Dbprintf(" len : %02X", datalen);
|
||||||
print_result(" RX : ", datain, datalen);
|
print_result(" RX : ", datain, datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flags & CLEARTRACE )
|
if ( flags & CLEARTRACE )
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
if ( flags & INIT ){
|
if ( flags & INIT ){
|
||||||
if ( !InitDesfireCard() )
|
if ( !InitDesfireCard() )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = DesfireAPDU(datain, datalen, resp);
|
int len = DesfireAPDU(datain, datalen, resp);
|
||||||
if (MF_DBGLEVEL >= 4)
|
if (MF_DBGLEVEL >= 4)
|
||||||
print_result("ERR <--: ", resp, len);
|
print_result("ERR <--: ", resp, len);
|
||||||
|
|
||||||
if ( !len ) {
|
if ( !len ) {
|
||||||
OnError(2);
|
OnError(2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the pcb_blocknum,
|
// reset the pcb_blocknum,
|
||||||
pcb_blocknum = 0;
|
pcb_blocknum = 0;
|
||||||
|
|
||||||
if ( flags & DISCONNECT )
|
if ( flags & DISCONNECT )
|
||||||
OnSuccess();
|
OnSuccess();
|
||||||
|
|
||||||
cmd_send(CMD_ACK,1,len,0,resp,len);
|
cmd_send(CMD_ACK,1,len,0,resp,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MifareDesfireGetInformation(){
|
void MifareDesfireGetInformation(){
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
iso14a_card_select_t card;
|
iso14a_card_select_t card;
|
||||||
uint8_t resp[USB_CMD_DATA_SIZE] = {0x00};
|
uint8_t resp[USB_CMD_DATA_SIZE] = {0x00};
|
||||||
uint8_t dataout[USB_CMD_DATA_SIZE] = {0x00};
|
uint8_t dataout[USB_CMD_DATA_SIZE] = {0x00};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1 = PCB 1
|
1 = PCB 1
|
||||||
2 = cid 2
|
2 = cid 2
|
||||||
3 = desfire command 3
|
3 = desfire command 3
|
||||||
4-5 = crc 4 key
|
4-5 = crc 4 key
|
||||||
5-6 crc
|
5-6 crc
|
||||||
PCB == 0x0A because sending CID byte.
|
PCB == 0x0A because sending CID byte.
|
||||||
CID == 0x00 first card?
|
CID == 0x00 first card?
|
||||||
*/
|
*/
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
// card select - information
|
// card select - information
|
||||||
if ( !iso14443a_select_card(NULL, &card, NULL, true, 0, false) ) {
|
if ( !iso14443a_select_card(NULL, &card, NULL, true, 0, false) ) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) DbpString("Can't select card");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( card.uidlen != 7 ) {
|
if ( card.uidlen != 7 ) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Wrong UID size. Expected 7byte got %d", card.uidlen);
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Wrong UID size. Expected 7byte got %d", card.uidlen);
|
||||||
OnError(2);
|
OnError(2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dataout, card.uid, 7);
|
memcpy(dataout, card.uid, 7);
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
uint8_t cmd[] = {GET_VERSION};
|
uint8_t cmd[] = {GET_VERSION};
|
||||||
size_t cmd_len = sizeof(cmd);
|
size_t cmd_len = sizeof(cmd);
|
||||||
|
|
||||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||||
if ( !len ) {
|
if ( !len ) {
|
||||||
print_result("ERROR <--: ", resp, len);
|
print_result("ERROR <--: ", resp, len);
|
||||||
OnError(3);
|
OnError(3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
memcpy(dataout+7,resp+3,7);
|
memcpy(dataout+7,resp+3,7);
|
||||||
|
|
||||||
// ADDITION_FRAME 1
|
// ADDITION_FRAME 1
|
||||||
cmd[0] = ADDITIONAL_FRAME;
|
cmd[0] = ADDITIONAL_FRAME;
|
||||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||||
if ( !len ) {
|
if ( !len ) {
|
||||||
print_result("ERROR <--: ", resp, len);
|
print_result("ERROR <--: ", resp, len);
|
||||||
OnError(3);
|
OnError(3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
memcpy(dataout+7+7,resp+3,7);
|
memcpy(dataout+7+7,resp+3,7);
|
||||||
|
|
||||||
// ADDITION_FRAME 2
|
// ADDITION_FRAME 2
|
||||||
len = DesfireAPDU(cmd, cmd_len, resp);
|
len = DesfireAPDU(cmd, cmd_len, resp);
|
||||||
if ( !len ) {
|
if ( !len ) {
|
||||||
print_result("ERROR <--: ", resp, len);
|
print_result("ERROR <--: ", resp, len);
|
||||||
OnError(3);
|
OnError(3);
|
||||||
return;
|
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,
|
// reset the pcb_blocknum,
|
||||||
pcb_blocknum = 0;
|
pcb_blocknum = 0;
|
||||||
OnSuccess();
|
OnSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){
|
void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
//uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
|
//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 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_data8[8] = {0x00};
|
||||||
//uint8_t null_key_data16[16] = {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_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 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 resp[256] = {0x00};
|
||||||
uint8_t IV[16] = {0x00};
|
uint8_t IV[16] = {0x00};
|
||||||
|
|
||||||
size_t datalen = datain[0];
|
size_t datalen = datain[0];
|
||||||
|
|
||||||
uint8_t cmd[40] = {0x00};
|
uint8_t cmd[40] = {0x00};
|
||||||
uint8_t encRndB[16] = {0x00};
|
uint8_t encRndB[16] = {0x00};
|
||||||
uint8_t decRndB[16] = {0x00};
|
uint8_t decRndB[16] = {0x00};
|
||||||
uint8_t nonce[16] = {0x00};
|
uint8_t nonce[16] = {0x00};
|
||||||
uint8_t both[32] = {0x00};
|
uint8_t both[32] = {0x00};
|
||||||
uint8_t encBoth[32] = {0x00};
|
uint8_t encBoth[32] = {0x00};
|
||||||
|
|
||||||
InitDesfireCard();
|
InitDesfireCard();
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
// 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
|
// 3 olika sätt att authenticera. AUTH (CRC16) , AUTH_ISO (CRC32) , AUTH_AES (CRC32)
|
||||||
// 4 olika crypto algo DES, 3DES, 3K3DES, AES
|
// 4 olika crypto algo DES, 3DES, 3K3DES, AES
|
||||||
// 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO
|
// 3 olika kommunikations sätt, PLAIN,MAC,CRYPTO
|
||||||
|
|
||||||
// des, nyckel 0,
|
// des, nyckel 0,
|
||||||
switch (mode){
|
switch (mode){
|
||||||
case 1:{
|
case 1:{
|
||||||
uint8_t keybytes[16];
|
uint8_t keybytes[16];
|
||||||
uint8_t RndA[8] = {0x00};
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
//SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
|
//SendDesfireCommand(AUTHENTICATE_ISO, &keyno, resp);
|
||||||
break;
|
break;
|
||||||
case 3:{
|
case 3:{
|
||||||
|
|
||||||
//defaultkey
|
//defaultkey
|
||||||
uint8_t keybytes[16] = {0x00};
|
uint8_t keybytes[16] = {0x00};
|
||||||
if (datain[1] == 0xff){
|
if (datain[1] == 0xff){
|
||||||
memcpy(keybytes,PICC_MASTER_KEY16,16);
|
memcpy(keybytes,PICC_MASTER_KEY16,16);
|
||||||
} else{
|
} else{
|
||||||
memcpy(keybytes, datain+1, datalen);
|
memcpy(keybytes, datain+1, datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct desfire_key defaultkey = {0x00};
|
struct desfire_key defaultkey = {0x00};
|
||||||
desfirekey_t key = &defaultkey;
|
desfirekey_t key = &defaultkey;
|
||||||
Desfire_aes_key_new( keybytes, key);
|
Desfire_aes_key_new( keybytes, key);
|
||||||
|
|
||||||
AesCtx ctx;
|
AesCtx ctx;
|
||||||
if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){
|
if ( AesCtxIni(&ctx, IV, key->data, KEY128, CBC) < 0 ){
|
||||||
if( MF_DBGLEVEL >= 4) {
|
if( MF_DBGLEVEL >= 4) {
|
||||||
DbpString("AES context failed to init");
|
DbpString("AES context failed to init");
|
||||||
}
|
}
|
||||||
OnError(7);
|
OnError(7);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd[0] = AUTHENTICATE_AES;
|
cmd[0] = AUTHENTICATE_AES;
|
||||||
cmd[1] = 0x00; //keynumber
|
cmd[1] = 0x00; //keynumber
|
||||||
len = DesfireAPDU(cmd, 2, resp);
|
len = DesfireAPDU(cmd, 2, resp);
|
||||||
if ( !len ) {
|
if ( !len ) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) {
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) {
|
||||||
DbpString("Authentication failed. Card timeout.");
|
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.");
|
|
||||||
}
|
|
||||||
OnError(3);
|
OnError(3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( resp[2] == 0x00 ){
|
memcpy( encRndB, resp+3, 16);
|
||||||
// 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;
|
// 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[0] = ADDITIONAL_FRAME;
|
||||||
cmd_send(CMD_ACK,1,len,0,resp,len);
|
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)
|
// 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
|
// dataout = pointer to response data array
|
||||||
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
|
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
|
||||||
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
size_t wrappedLen = 0;
|
size_t wrappedLen = 0;
|
||||||
uint8_t wCmd[USB_CMD_DATA_SIZE] = {0x00};
|
uint8_t wCmd[USB_CMD_DATA_SIZE] = {0x00};
|
||||||
uint8_t resp[MAX_FRAME_SIZE];
|
uint8_t resp[MAX_FRAME_SIZE];
|
||||||
uint8_t par[MAX_PARITY_SIZE];
|
uint8_t par[MAX_PARITY_SIZE];
|
||||||
|
|
||||||
wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
|
wrappedLen = CreateAPDU( cmd, cmd_len, wCmd);
|
||||||
|
|
||||||
if (MF_DBGLEVEL >= 4)
|
if (MF_DBGLEVEL >= 4)
|
||||||
print_result("WCMD <--: ", wCmd, wrappedLen);
|
print_result("WCMD <--: ", wCmd, wrappedLen);
|
||||||
|
|
||||||
ReaderTransmit( wCmd, wrappedLen, NULL);
|
ReaderTransmit( wCmd, wrappedLen, NULL);
|
||||||
|
|
||||||
len = ReaderReceive(resp, par);
|
len = ReaderReceive(resp, par);
|
||||||
if ( !len ) {
|
if ( !len ) {
|
||||||
if (MF_DBGLEVEL >= 4) Dbprintf("fukked");
|
if (MF_DBGLEVEL >= 4) Dbprintf("fukked");
|
||||||
return false; //DATA LINK ERROR
|
return false; //DATA LINK ERROR
|
||||||
}
|
}
|
||||||
// if we received an I- or R(ACK)-Block with a block number equal to the
|
// if we received an I- or R(ACK)-Block with a block number equal to the
|
||||||
// current block number, toggle the current block number
|
// current block number, toggle the current block number
|
||||||
else if (len >= 4 // PCB+CID+CRC = 4 bytes
|
else if (len >= 4 // PCB+CID+CRC = 4 bytes
|
||||||
&& ((resp[0] & 0xC0) == 0 // I-Block
|
&& ((resp[0] & 0xC0) == 0 // I-Block
|
||||||
|| (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
|
|| (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
|
||||||
&& (resp[0] & 0x01) == pcb_blocknum) // equal block numbers
|
&& (resp[0] & 0x01) == pcb_blocknum) // equal block numbers
|
||||||
{
|
{
|
||||||
pcb_blocknum ^= 1; //toggle next block
|
pcb_blocknum ^= 1; //toggle next block
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dataout, resp, len);
|
memcpy(dataout, resp, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAPDU
|
// CreateAPDU
|
||||||
size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){
|
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];
|
uint8_t cmd[cmdlen];
|
||||||
memset(cmd, 0, cmdlen);
|
memset(cmd, 0, cmdlen);
|
||||||
|
|
||||||
cmd[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar //
|
cmd[0] = 0x0A; // 0x0A = skicka cid, 0x02 = ingen cid. Särskilda bitar //
|
||||||
cmd[0] |= pcb_blocknum; // OR the block number into the PCB
|
cmd[0] |= pcb_blocknum; // OR the block number into the PCB
|
||||||
cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards
|
cmd[1] = 0x00; // CID: 0x00 //TODO: allow multiple selected cards
|
||||||
|
|
||||||
memcpy(cmd+2, datain, len);
|
memcpy(cmd+2, datain, len);
|
||||||
AddCrc14A(cmd, len+2);
|
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, 0, 1); /* CMD_WRITE */
|
||||||
// crc_update(&desfire_crc32, addr, addr_sz);
|
// crc_update(&desfire_crc32, addr, addr_sz);
|
||||||
// crc_update(&desfire_crc32, byte, 8);
|
// crc_update(&desfire_crc32, byte, 8);
|
||||||
// uint32_t crc = crc_finish(&desfire_crc32);
|
// uint32_t crc = crc_finish(&desfire_crc32);
|
||||||
|
|
||||||
void OnSuccess(){
|
void OnSuccess(){
|
||||||
pcb_blocknum = 0;
|
pcb_blocknum = 0;
|
||||||
ReaderTransmit(deselect_cmd, 3 , NULL);
|
ReaderTransmit(deselect_cmd, 3 , NULL);
|
||||||
mifare_ultra_halt();
|
mifare_ultra_halt();
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnError(uint8_t reason){
|
void OnError(uint8_t reason){
|
||||||
cmd_send(CMD_ACK,0,reason,0,0,0);
|
cmd_send(CMD_ACK,0,reason,0,0,0);
|
||||||
OnSuccess();
|
OnSuccess();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,300 +25,300 @@ static uint32_t timerData = 0;
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// "hf mf sniff"
|
// "hf mf sniff"
|
||||||
void RAMFUNC SniffMifare(uint8_t param) {
|
void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
// param:
|
// param:
|
||||||
// bit 0 - trigger from first card answer
|
// bit 0 - trigger from first card answer
|
||||||
// bit 1 - trigger from first reader 7-bit request
|
// bit 1 - trigger from first reader 7-bit request
|
||||||
|
|
||||||
// C(red) A(yellow) B(green)
|
// C(red) A(yellow) B(green)
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
|
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
|
||||||
|
|
||||||
// Allocate memory from BigBuf for some buffers
|
// Allocate memory from BigBuf for some buffers
|
||||||
// free all previous allocations first
|
// free all previous allocations first
|
||||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
// The command (reader -> tag) that we're receiving.
|
// The command (reader -> tag) that we're receiving.
|
||||||
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||||
uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
||||||
|
|
||||||
// The response (tag -> reader) that we're receiving.
|
// The response (tag -> reader) that we're receiving.
|
||||||
uint8_t receivedResp[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
uint8_t receivedResp[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||||
uint8_t receivedRespPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
uint8_t receivedRespPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
||||||
|
|
||||||
// allocate the DMA buffer, used to stream samples from the FPGA
|
// allocate the DMA buffer, used to stream samples from the FPGA
|
||||||
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
uint8_t *data = dmaBuf;
|
uint8_t *data = dmaBuf;
|
||||||
uint8_t previous_data = 0;
|
uint8_t previous_data = 0;
|
||||||
int maxDataLen = 0;
|
int maxDataLen = 0;
|
||||||
int dataLen = 0;
|
int dataLen = 0;
|
||||||
bool ReaderIsActive = false;
|
bool ReaderIsActive = false;
|
||||||
bool TagIsActive = false;
|
bool TagIsActive = false;
|
||||||
|
|
||||||
// We won't start recording the frames that we acquire until we trigger;
|
// 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
|
// a good trigger condition to get started is probably when we see a
|
||||||
// response from the tag.
|
// response from the tag.
|
||||||
// triggered == false -- to wait first for card
|
// triggered == false -- to wait first for card
|
||||||
//bool triggered = !(param & 0x03);
|
//bool triggered = !(param & 0x03);
|
||||||
|
|
||||||
|
|
||||||
// Set up the demodulator for tag -> reader responses.
|
// Set up the demodulator for tag -> reader responses.
|
||||||
DemodInit(receivedResp, receivedRespPar);
|
DemodInit(receivedResp, receivedRespPar);
|
||||||
|
|
||||||
// Set up the demodulator for the reader -> tag commands
|
// Set up the demodulator for the reader -> tag commands
|
||||||
UartInit(receivedCmd, receivedCmdPar);
|
UartInit(receivedCmd, receivedCmdPar);
|
||||||
|
|
||||||
// Setup and start DMA.
|
// Setup and start DMA.
|
||||||
// set transfer address and number of bytes. Start transfer.
|
// set transfer address and number of bytes. Start transfer.
|
||||||
if ( !FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE) ){
|
if ( !FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE) ){
|
||||||
if (MF_DBGLEVEL > 1) Dbprintf("[!] FpgaSetupSscDma failed. Exiting");
|
if (MF_DBGLEVEL > 1) Dbprintf("[!] FpgaSetupSscDma failed. Exiting");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tUart* uart = GetUart();
|
tUart* uart = GetUart();
|
||||||
tDemod* demod = GetDemod();
|
tDemod* demod = GetDemod();
|
||||||
|
|
||||||
MfSniffInit();
|
MfSniffInit();
|
||||||
|
|
||||||
uint32_t sniffCounter = 0;
|
uint32_t sniffCounter = 0;
|
||||||
// loop and listen
|
// loop and listen
|
||||||
while (!BUTTON_PRESS()) {
|
while (!BUTTON_PRESS()) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
/*
|
/*
|
||||||
if ((sniffCounter & 0x0000FFFF) == 0) { // from time to time
|
if ((sniffCounter & 0x0000FFFF) == 0) { // from time to time
|
||||||
// check if a transaction is completed (timeout after 2000ms).
|
// 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 yes, stop the DMA transfer and send what we have so far to the client
|
||||||
if (BigBuf_get_traceLen()) {
|
if (BigBuf_get_traceLen()) {
|
||||||
MfSniffSend();
|
MfSniffSend();
|
||||||
// Reset everything - we missed some sniffed data anyway while the DMA was stopped
|
// Reset everything - we missed some sniffed data anyway while the DMA was stopped
|
||||||
sniffCounter = 0;
|
sniffCounter = 0;
|
||||||
dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
data = dmaBuf;
|
data = dmaBuf;
|
||||||
maxDataLen = 0;
|
maxDataLen = 0;
|
||||||
ReaderIsActive = false;
|
ReaderIsActive = false;
|
||||||
TagIsActive = false;
|
TagIsActive = false;
|
||||||
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
|
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// number of bytes we have processed so far
|
// number of bytes we have processed so far
|
||||||
int register readBufDataP = data - dmaBuf;
|
int register readBufDataP = data - dmaBuf;
|
||||||
// number of bytes already transferred
|
// number of bytes already transferred
|
||||||
int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
|
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
|
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
|
dataLen = dmaBufDataP - readBufDataP; // number of bytes still to be processed
|
||||||
else
|
else
|
||||||
dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; // number of bytes still to be processed
|
dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP; // number of bytes still to be processed
|
||||||
|
|
||||||
// test for length of buffer
|
// test for length of buffer
|
||||||
if (dataLen > maxDataLen) { // we are more behind than ever...
|
if (dataLen > maxDataLen) { // we are more behind than ever...
|
||||||
maxDataLen = dataLen;
|
maxDataLen = dataLen;
|
||||||
if (dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
if (dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||||
Dbprintf("[!] blew circular buffer! | datalen %u", dataLen);
|
Dbprintf("[!] blew circular buffer! | datalen %u", dataLen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dataLen < 1) continue;
|
if (dataLen < 1) continue;
|
||||||
|
|
||||||
// primary buffer was stopped ( <-- we lost data!
|
// primary buffer was stopped ( <-- we lost data!
|
||||||
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
|
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
|
||||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf;
|
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
|
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
|
||||||
Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
|
Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
|
||||||
}
|
}
|
||||||
// secondary buffer sets as primary, secondary buffer was stopped
|
// secondary buffer sets as primary, secondary buffer was stopped
|
||||||
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
|
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf;
|
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
|
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
|
|
||||||
// Need two samples to feed Miller and Manchester-Decoder
|
// Need two samples to feed Miller and Manchester-Decoder
|
||||||
if (sniffCounter & 0x01) {
|
if (sniffCounter & 0x01) {
|
||||||
|
|
||||||
// no need to try decoding tag data if the reader is sending
|
// no need to try decoding tag data if the reader is sending
|
||||||
if (!TagIsActive) {
|
if (!TagIsActive) {
|
||||||
uint8_t readerbyte = (previous_data & 0xF0) | (*data >> 4);
|
uint8_t readerbyte = (previous_data & 0xF0) | (*data >> 4);
|
||||||
if (MillerDecoding(readerbyte, (sniffCounter-1)*4)) {
|
if (MillerDecoding(readerbyte, (sniffCounter-1)*4)) {
|
||||||
LogTrace(receivedCmd, uart->len, 0, 0, NULL, true);
|
LogTrace(receivedCmd, uart->len, 0, 0, NULL, true);
|
||||||
DemodReset();
|
DemodReset();
|
||||||
UartReset();
|
UartReset();
|
||||||
}
|
}
|
||||||
ReaderIsActive = (uart->state != STATE_UNSYNCD);
|
ReaderIsActive = (uart->state != STATE_UNSYNCD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need to try decoding tag data if the reader is sending
|
// no need to try decoding tag data if the reader is sending
|
||||||
if (!ReaderIsActive) {
|
if (!ReaderIsActive) {
|
||||||
uint8_t tagbyte = (previous_data << 4) | (*data & 0x0F);
|
uint8_t tagbyte = (previous_data << 4) | (*data & 0x0F);
|
||||||
if (ManchesterDecoding(tagbyte, 0, (sniffCounter-1)*4)) {
|
if (ManchesterDecoding(tagbyte, 0, (sniffCounter-1)*4)) {
|
||||||
LogTrace(receivedResp, demod->len, 0, 0, NULL, false);
|
LogTrace(receivedResp, demod->len, 0, 0, NULL, false);
|
||||||
DemodReset();
|
DemodReset();
|
||||||
UartReset();
|
UartReset();
|
||||||
}
|
}
|
||||||
TagIsActive = (demod->state != DEMOD_UNSYNCD);
|
TagIsActive = (demod->state != DEMOD_UNSYNCD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
previous_data = *data;
|
previous_data = *data;
|
||||||
sniffCounter++;
|
sniffCounter++;
|
||||||
data++;
|
data++;
|
||||||
|
|
||||||
if (data == dmaBuf + DMA_BUFFER_SIZE)
|
if (data == dmaBuf + DMA_BUFFER_SIZE)
|
||||||
data = dmaBuf;
|
data = dmaBuf;
|
||||||
|
|
||||||
} // main cycle
|
} // main cycle
|
||||||
|
|
||||||
MfSniffEnd();
|
MfSniffEnd();
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MfSniffInit(void){
|
void MfSniffInit(void){
|
||||||
memset(sniffUID, 0x00, sizeof(sniffUID));
|
memset(sniffUID, 0x00, sizeof(sniffUID));
|
||||||
memset(sniffATQA, 0x00, sizeof(sniffATQA));
|
memset(sniffATQA, 0x00, sizeof(sniffATQA));
|
||||||
memset(sniffBuf, 0x00, sizeof(sniffBuf));
|
memset(sniffBuf, 0x00, sizeof(sniffBuf));
|
||||||
sniffSAK = 0;
|
sniffSAK = 0;
|
||||||
sniffUIDType = SNF_UID_4;
|
sniffUIDType = SNF_UID_4;
|
||||||
timerData = 0;
|
timerData = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MfSniffEnd(void){
|
void MfSniffEnd(void){
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader) {
|
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
|
// reset on 7-Bit commands from reader
|
||||||
if (reader && (len == 1) && (bitCnt == 7)) {
|
if (reader && (len == 1) && (bitCnt == 7)) {
|
||||||
sniffState = SNF_INIT;
|
sniffState = SNF_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch (sniffState) {
|
switch (sniffState) {
|
||||||
case SNF_INIT:{
|
case SNF_INIT:{
|
||||||
// REQA,WUPA or MAGICWUP from reader
|
// REQA,WUPA or MAGICWUP from reader
|
||||||
if ((len == 1) && (reader) && (bitCnt == 7) ) {
|
if ((len == 1) && (reader) && (bitCnt == 7) ) {
|
||||||
MfSniffInit();
|
MfSniffInit();
|
||||||
sniffState = (data[0] == MIFARE_MAGICWUPC1) ? SNF_MAGIC_WUPC2 : SNF_ATQA;
|
sniffState = (data[0] == MIFARE_MAGICWUPC1) ? SNF_MAGIC_WUPC2 : SNF_ATQA;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SNF_MAGIC_WUPC2: {
|
case SNF_MAGIC_WUPC2: {
|
||||||
if ((len == 1) && (reader) && (data[0] == MIFARE_MAGICWUPC2) ) {
|
if ((len == 1) && (reader) && (data[0] == MIFARE_MAGICWUPC2) ) {
|
||||||
sniffState = SNF_CARD_IDLE;
|
sniffState = SNF_CARD_IDLE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SNF_ATQA:{
|
case SNF_ATQA:{
|
||||||
// ATQA from tag
|
// ATQA from tag
|
||||||
if ((!reader) && (len == 2)) {
|
if ((!reader) && (len == 2)) {
|
||||||
sniffATQA[0] = data[0];
|
sniffATQA[0] = data[0];
|
||||||
sniffATQA[1] = data[1];
|
sniffATQA[1] = data[1];
|
||||||
sniffState = SNF_UID;
|
sniffState = SNF_UID;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SNF_UID: {
|
case SNF_UID: {
|
||||||
|
|
||||||
if ( !reader ) break;
|
if ( !reader ) break;
|
||||||
if ( len != 9 ) break;
|
if ( len != 9 ) break;
|
||||||
if ( !CheckCrc14443(CRC_14443_A, data, 9)) break;
|
if ( !CheckCrc14443(CRC_14443_A, data, 9)) break;
|
||||||
if ( data[1] != 0x70 ) break;
|
if ( data[1] != 0x70 ) break;
|
||||||
|
|
||||||
Dbprintf("[!] UID | %x", data[0]);
|
Dbprintf("[!] UID | %x", data[0]);
|
||||||
|
|
||||||
if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT)) {
|
if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT)) {
|
||||||
// UID_4 - select 4 Byte UID from reader
|
// UID_4 - select 4 Byte UID from reader
|
||||||
memcpy(sniffUID, data+2, 4);
|
memcpy(sniffUID, data+2, 4);
|
||||||
sniffUIDType = SNF_UID_4;
|
sniffUIDType = SNF_UID_4;
|
||||||
sniffState = SNF_SAK;
|
sniffState = SNF_SAK;
|
||||||
} else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2)) {
|
} else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2)) {
|
||||||
// UID_7 - Select 2nd part of 7 Byte UID
|
// UID_7 - Select 2nd part of 7 Byte UID
|
||||||
|
|
||||||
// get rid of 0x88
|
// get rid of 0x88
|
||||||
sniffUID[0] = sniffUID[1];
|
sniffUID[0] = sniffUID[1];
|
||||||
sniffUID[1] = sniffUID[2];
|
sniffUID[1] = sniffUID[2];
|
||||||
sniffUID[2] = sniffUID[3];
|
sniffUID[2] = sniffUID[3];
|
||||||
//new uid bytes
|
//new uid bytes
|
||||||
memcpy(sniffUID+3, data+2, 4);
|
memcpy(sniffUID+3, data+2, 4);
|
||||||
sniffUIDType = SNF_UID_7;
|
sniffUIDType = SNF_UID_7;
|
||||||
sniffState = SNF_SAK;
|
sniffState = SNF_SAK;
|
||||||
} else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3)) {
|
} else if ((data[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_3)) {
|
||||||
// UID_10 - Select 3nd part of 10 Byte UID
|
// UID_10 - Select 3nd part of 10 Byte UID
|
||||||
// 3+3+4 = 10.
|
// 3+3+4 = 10.
|
||||||
// get ride of previous 0x88
|
// get ride of previous 0x88
|
||||||
sniffUID[3] = sniffUID[4];
|
sniffUID[3] = sniffUID[4];
|
||||||
sniffUID[4] = sniffUID[5];
|
sniffUID[4] = sniffUID[5];
|
||||||
sniffUID[5] = sniffUID[6];
|
sniffUID[5] = sniffUID[6];
|
||||||
// new uid bytes
|
// new uid bytes
|
||||||
memcpy(sniffUID+6, data+2, 4);
|
memcpy(sniffUID+6, data+2, 4);
|
||||||
sniffUIDType = SNF_UID_10;
|
sniffUIDType = SNF_UID_10;
|
||||||
sniffState = SNF_SAK;
|
sniffState = SNF_SAK;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SNF_SAK:{
|
case SNF_SAK:{
|
||||||
// SAK from card?
|
// SAK from card?
|
||||||
if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) {
|
if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) {
|
||||||
sniffSAK = data[0];
|
sniffSAK = data[0];
|
||||||
// CL2 UID part to be expected
|
// CL2 UID part to be expected
|
||||||
if (( sniffSAK == 0x04) && (sniffUIDType == SNF_UID_4)) {
|
if (( sniffSAK == 0x04) && (sniffUIDType == SNF_UID_4)) {
|
||||||
sniffState = SNF_UID;
|
sniffState = SNF_UID;
|
||||||
// CL3 UID part to be expected
|
// CL3 UID part to be expected
|
||||||
} else if ((sniffSAK == 0x04) && (sniffUIDType == SNF_UID_7)) {
|
} else if ((sniffSAK == 0x04) && (sniffUIDType == SNF_UID_7)) {
|
||||||
sniffState = SNF_UID;
|
sniffState = SNF_UID;
|
||||||
} else {
|
} else {
|
||||||
// select completed
|
// select completed
|
||||||
sniffState = SNF_CARD_IDLE;
|
sniffState = SNF_CARD_IDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SNF_CARD_IDLE:{ // trace the card select sequence
|
case SNF_CARD_IDLE:{ // trace the card select sequence
|
||||||
sniffBuf[0] = 0xFF;
|
sniffBuf[0] = 0xFF;
|
||||||
sniffBuf[1] = 0xFF;
|
sniffBuf[1] = 0xFF;
|
||||||
memcpy(sniffBuf + 2, sniffUID, sizeof(sniffUID));
|
memcpy(sniffBuf + 2, sniffUID, sizeof(sniffUID));
|
||||||
memcpy(sniffBuf + 12, sniffATQA, sizeof(sniffATQA));
|
memcpy(sniffBuf + 12, sniffATQA, sizeof(sniffATQA));
|
||||||
sniffBuf[14] = sniffSAK;
|
sniffBuf[14] = sniffSAK;
|
||||||
sniffBuf[15] = 0xFF;
|
sniffBuf[15] = 0xFF;
|
||||||
sniffBuf[16] = 0xFF;
|
sniffBuf[16] = 0xFF;
|
||||||
LogTrace(sniffBuf, sizeof(sniffBuf), 0, 0, NULL, true);
|
LogTrace(sniffBuf, sizeof(sniffBuf), 0, 0, NULL, true);
|
||||||
sniffState = SNF_CARD_CMD;
|
sniffState = SNF_CARD_CMD;
|
||||||
} // intentionally no break;
|
} // intentionally no break;
|
||||||
case SNF_CARD_CMD:{
|
case SNF_CARD_CMD:{
|
||||||
LogTrace(data, len, 0, 0, NULL, reader);
|
LogTrace(data, len, 0, 0, NULL, reader);
|
||||||
timerData = GetTickCount();
|
timerData = GetTickCount();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
sniffState = SNF_INIT;
|
sniffState = SNF_INIT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void RAMFUNC MfSniffSend() {
|
void RAMFUNC MfSniffSend() {
|
||||||
uint16_t tracelen = BigBuf_get_traceLen();
|
uint16_t tracelen = BigBuf_get_traceLen();
|
||||||
uint16_t chunksize = 0;
|
uint16_t chunksize = 0;
|
||||||
int packlen = tracelen; // total number of bytes to send
|
int packlen = tracelen; // total number of bytes to send
|
||||||
uint8_t *data = BigBuf_get_addr();
|
uint8_t *data = BigBuf_get_addr();
|
||||||
|
|
||||||
while (packlen > 0) {
|
while (packlen > 0) {
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
chunksize = MIN(USB_CMD_DATA_SIZE, packlen); // chunk size 512
|
chunksize = MIN(USB_CMD_DATA_SIZE, packlen); // chunk size 512
|
||||||
cmd_send(CMD_ACK, 1, tracelen, chunksize, data + tracelen - packlen, chunksize);
|
cmd_send(CMD_ACK, 1, tracelen, chunksize, data + tracelen - packlen, chunksize);
|
||||||
packlen -= chunksize;
|
packlen -= chunksize;
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
cmd_send(CMD_ACK, 2, 0, 0, 0, 0); // 2 == data transfer finished.
|
cmd_send(CMD_ACK, 2, 0, 0, 0, 0); // 2 == data transfer finished.
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
}
|
}
|
|
@ -21,18 +21,18 @@
|
||||||
#include "mifareutil.h"
|
#include "mifareutil.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define SNF_INIT 0
|
#define SNF_INIT 0
|
||||||
#define SNF_NO_FIELD 1
|
#define SNF_NO_FIELD 1
|
||||||
#define SNF_ATQA 2
|
#define SNF_ATQA 2
|
||||||
#define SNF_UID 3
|
#define SNF_UID 3
|
||||||
#define SNF_SAK 4
|
#define SNF_SAK 4
|
||||||
#define SNF_CARD_IDLE 5
|
#define SNF_CARD_IDLE 5
|
||||||
#define SNF_CARD_CMD 6
|
#define SNF_CARD_CMD 6
|
||||||
#define SNF_MAGIC_WUPC2 7
|
#define SNF_MAGIC_WUPC2 7
|
||||||
|
|
||||||
#define SNF_UID_4 0
|
#define SNF_UID_4 0
|
||||||
#define SNF_UID_7 0
|
#define SNF_UID_7 0
|
||||||
#define SNF_UID_10 0
|
#define SNF_UID_10 0
|
||||||
|
|
||||||
void MfSniffInit(void);
|
void MfSniffInit(void);
|
||||||
bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader);
|
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 "iso14443a.h"
|
||||||
#include "crapto1/crapto1.h"
|
#include "crapto1/crapto1.h"
|
||||||
#include "des.h"
|
#include "des.h"
|
||||||
#include "random.h" // fast_prand, prand
|
#include "random.h" // fast_prand, prand
|
||||||
|
|
||||||
// mifare authentication
|
// mifare authentication
|
||||||
#define CRYPT_NONE 0
|
#define CRYPT_NONE 0
|
||||||
|
@ -30,8 +30,8 @@
|
||||||
#define AUTH_FIRST 0
|
#define AUTH_FIRST 0
|
||||||
#define AUTH_NESTED 2
|
#define AUTH_NESTED 2
|
||||||
|
|
||||||
#define AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
|
#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 PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication
|
||||||
|
|
||||||
// mifare 4bit card answers
|
// mifare 4bit card answers
|
||||||
#define CARD_ACK 0x0A // 1010 - ACK
|
#define CARD_ACK 0x0A // 1010 - ACK
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
#define MFEMUL_SELECT3 4
|
#define MFEMUL_SELECT3 4
|
||||||
#define MFEMUL_AUTH1 5
|
#define MFEMUL_AUTH1 5
|
||||||
#define MFEMUL_AUTH2 6
|
#define MFEMUL_AUTH2 6
|
||||||
#define MFEMUL_WORK 7
|
#define MFEMUL_WORK 7
|
||||||
#define MFEMUL_WRITEBL2 8
|
#define MFEMUL_WRITEBL2 8
|
||||||
#define MFEMUL_INTREG_INC 9
|
#define MFEMUL_INTREG_INC 9
|
||||||
#define MFEMUL_INTREG_DEC 10
|
#define MFEMUL_INTREG_DEC 10
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
This file contains an optimized version of the MAC-calculation algorithm. Some measurements on
|
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:
|
a std laptop showed it runs in about 1/3 of the time:
|
||||||
|
|
||||||
Std: 0.428962
|
Std: 0.428962
|
||||||
Opt: 0.151609
|
Opt: 0.151609
|
||||||
|
|
||||||
Additionally, it is self-reliant, not requiring e.g. bitstreams from the cipherutils, thus can
|
Additionally, it is self-reliant, not requiring e.g. bitstreams from the cipherutils, thus can
|
||||||
be easily dropped into a code base.
|
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_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)))\
|
#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)))\
|
|(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))
|
|(1 & (((r & ~(r << 2)) >> 4) ^ ((r & (r << 2)) >> 3) ^ r ^ x))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some background on the expression above can be found here...
|
* Some background on the expression above can be found here...
|
||||||
uint8_t xopt__select(bool x, bool y, uint8_t r)
|
uint8_t xopt__select(bool x, bool y, uint8_t r)
|
||||||
{
|
{
|
||||||
uint8_t r_ls2 = r << 2;
|
uint8_t r_ls2 = r << 2;
|
||||||
uint8_t r_and_ls2 = r & r_ls2;
|
uint8_t r_and_ls2 = r & r_ls2;
|
||||||
uint8_t r_or_ls2 = r | r_ls2;
|
uint8_t r_or_ls2 = r | r_ls2;
|
||||||
|
|
||||||
//r: r0 r1 r2 r3 r4 r5 r6 r7
|
//r: r0 r1 r2 r3 r4 r5 r6 r7
|
||||||
//r_ls2: r2 r3 r4 r5 r6 r7 0 0
|
//r_ls2: r2 r3 r4 r5 r6 r7 0 0
|
||||||
// z0
|
// z0
|
||||||
// z1
|
// z1
|
||||||
|
|
||||||
// uint8_t z0 = (r0 & r2) ^ (r1 & ~r3) ^ (r2 | r4); // <-- original
|
// 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 = (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 = (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 = (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 = (r3 & ~r5) ^ (r4 & r6 ) ^ r7 ^ x; // <-- original
|
||||||
uint8_t z2 = ((r & ~r_ls2) >> 4) ^ (r_and_ls2 >> 3) ^ r ^ x;
|
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) {
|
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 = (s->t >> 1);
|
||||||
successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15;
|
successor->t |= (Tt ^ (s->r >> 7 & 0x1) ^ (s->r >> 3 & 0x1)) << 15;
|
||||||
|
|
||||||
successor->b = s->b >> 1;
|
successor->b = s->b >> 1;
|
||||||
successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7;
|
successor->b |= (opt_B(s) ^ (s->r & 0x1)) << 7;
|
||||||
|
|
||||||
successor->r = (k[opt__select(Tt,y,s->r)] ^ successor->b) + s->l ;
|
successor->r = (k[opt__select(Tt,y,s->r)] ^ successor->b) + s->l ;
|
||||||
successor->l = successor->r+s->r;
|
successor->l = successor->r+s->r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_suc(const uint8_t* k,State* s, uint8_t *in, uint8_t length, bool add32Zeroes) {
|
void opt_suc(const uint8_t* k,State* s, uint8_t *in, uint8_t length, bool add32Zeroes) {
|
||||||
State x2;
|
State x2;
|
||||||
int i;
|
int i;
|
||||||
uint8_t head = 0;
|
uint8_t head = 0;
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
head = 1 & (in[i] >> 7);
|
head = 1 & (in[i] >> 7);
|
||||||
opt_successor(k, s, head, &x2);
|
opt_successor(k, s, head, &x2);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 6);
|
head = 1 & (in[i] >> 6);
|
||||||
opt_successor(k, &x2, head, s);
|
opt_successor(k, &x2, head, s);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 5);
|
head = 1 & (in[i] >> 5);
|
||||||
opt_successor(k, s, head, &x2);
|
opt_successor(k, s, head, &x2);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 4);
|
head = 1 & (in[i] >> 4);
|
||||||
opt_successor(k, &x2, head, s);
|
opt_successor(k, &x2, head, s);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 3);
|
head = 1 & (in[i] >> 3);
|
||||||
opt_successor(k, s, head, &x2);
|
opt_successor(k, s, head, &x2);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 2);
|
head = 1 & (in[i] >> 2);
|
||||||
opt_successor(k, &x2, head, s);
|
opt_successor(k, &x2, head, s);
|
||||||
|
|
||||||
head = 1 & (in[i] >> 1);
|
head = 1 & (in[i] >> 1);
|
||||||
opt_successor(k, s, head, &x2);
|
opt_successor(k, s, head, &x2);
|
||||||
|
|
||||||
head = 1 & in[i];
|
head = 1 & in[i];
|
||||||
opt_successor(k, &x2, head, s);
|
opt_successor(k, &x2, head, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
//For tag MAC, an additional 32 zeroes
|
//For tag MAC, an additional 32 zeroes
|
||||||
if (add32Zeroes) {
|
if (add32Zeroes) {
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
opt_successor(k, s, 0, &x2);
|
opt_successor(k, s, 0, &x2);
|
||||||
opt_successor(k, &x2, 0, s);
|
opt_successor(k, &x2, 0, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_output(const uint8_t* k,State* s, uint8_t *buffer) {
|
void opt_output(const uint8_t* k,State* s, uint8_t *buffer) {
|
||||||
uint8_t times = 0;
|
uint8_t times = 0;
|
||||||
uint8_t bout = 0;
|
uint8_t bout = 0;
|
||||||
State temp = {0,0,0,0};
|
State temp = {0,0,0,0};
|
||||||
for ( ; times < 4; times++) {
|
for ( ; times < 4; times++) {
|
||||||
bout =0;
|
bout =0;
|
||||||
bout |= (s->r & 0x4) << 5;
|
bout |= (s->r & 0x4) << 5;
|
||||||
opt_successor(k, s, 0, &temp);
|
opt_successor(k, s, 0, &temp);
|
||||||
bout |= (temp.r & 0x4) << 4;
|
bout |= (temp.r & 0x4) << 4;
|
||||||
opt_successor(k, &temp, 0, s);
|
opt_successor(k, &temp, 0, s);
|
||||||
bout |= (s->r & 0x4) << 3;
|
bout |= (s->r & 0x4) << 3;
|
||||||
opt_successor(k, s, 0, &temp);
|
opt_successor(k, s, 0, &temp);
|
||||||
bout |= (temp.r & 0x4) << 2;
|
bout |= (temp.r & 0x4) << 2;
|
||||||
opt_successor(k, &temp, 0, s);
|
opt_successor(k, &temp, 0, s);
|
||||||
bout |= (s->r & 0x4) << 1;
|
bout |= (s->r & 0x4) << 1;
|
||||||
opt_successor(k, s, 0, &temp);
|
opt_successor(k, s, 0, &temp);
|
||||||
bout |= (temp.r & 0x4) ;
|
bout |= (temp.r & 0x4) ;
|
||||||
opt_successor(k, &temp, 0, s);
|
opt_successor(k, &temp, 0, s);
|
||||||
bout |= (s->r & 0x4) >> 1;
|
bout |= (s->r & 0x4) >> 1;
|
||||||
opt_successor(k, s, 0, &temp);
|
opt_successor(k, s, 0, &temp);
|
||||||
bout |= (temp.r & 0x4) >> 2;
|
bout |= (temp.r & 0x4) >> 2;
|
||||||
opt_successor(k, &temp, 0, s);
|
opt_successor(k, &temp, 0, s);
|
||||||
buffer[times] = bout;
|
buffer[times] = bout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_MAC(uint8_t* k, uint8_t* input, uint8_t* out) {
|
void opt_MAC(uint8_t* k, uint8_t* input, uint8_t* out) {
|
||||||
State _init = {
|
State _init = {
|
||||||
((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||||
((k[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
((k[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||||
0x4c, // b
|
0x4c, // b
|
||||||
0xE012 // t
|
0xE012 // t
|
||||||
};
|
};
|
||||||
|
|
||||||
opt_suc(k,&_init,input,12, false);
|
opt_suc(k,&_init,input,12, false);
|
||||||
opt_output(k,&_init, out);
|
opt_output(k,&_init, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t rev_byte(uint8_t b) {
|
uint8_t rev_byte(uint8_t b) {
|
||||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_reverse_arraybytecpy(uint8_t* dest, uint8_t *src, size_t len) {
|
void opt_reverse_arraybytecpy(uint8_t* dest, uint8_t *src, size_t len) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
for ( i =0; i< len ; i++)
|
for ( i =0; i< len ; i++)
|
||||||
dest[i] = rev_byte(src[i]);
|
dest[i] = rev_byte(src[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) {
|
void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) {
|
||||||
static uint8_t cc_nr[12];
|
static uint8_t cc_nr[12];
|
||||||
opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12);
|
opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12);
|
||||||
uint8_t dest [] = {0,0,0,0,0,0,0,0};
|
uint8_t dest [] = {0,0,0,0,0,0,0,0};
|
||||||
opt_MAC(div_key_p, cc_nr, dest);
|
opt_MAC(div_key_p, cc_nr, dest);
|
||||||
//The output MAC must also be reversed
|
//The output MAC must also be reversed
|
||||||
opt_reverse_arraybytecpy(mac, dest, 4);
|
opt_reverse_arraybytecpy(mac, dest, 4);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) {
|
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];
|
static uint8_t cc_nr[8+4+4];
|
||||||
opt_reverse_arraybytecpy(cc_nr, cc_p, 12);
|
opt_reverse_arraybytecpy(cc_nr, cc_p, 12);
|
||||||
State _init = {
|
State _init = {
|
||||||
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||||
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||||
0x4c, // b
|
0x4c, // b
|
||||||
0xE012 // t
|
0xE012 // t
|
||||||
};
|
};
|
||||||
opt_suc(div_key_p, &_init, cc_nr, 12, true);
|
opt_suc(div_key_p, &_init, cc_nr, 12, true);
|
||||||
uint8_t dest [] = {0,0,0,0};
|
uint8_t dest [] = {0,0,0,0};
|
||||||
opt_output(div_key_p, &_init, dest);
|
opt_output(div_key_p, &_init, dest);
|
||||||
//The output MAC must also be reversed
|
//The output MAC must also be reversed
|
||||||
opt_reverse_arraybytecpy(mac, dest,4);
|
opt_reverse_arraybytecpy(mac, dest,4);
|
||||||
return;
|
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
|
* @return the cipher state
|
||||||
*/
|
*/
|
||||||
State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
|
State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
|
||||||
static uint8_t cc_nr[8];
|
static uint8_t cc_nr[8];
|
||||||
opt_reverse_arraybytecpy(cc_nr, cc_p, 8);
|
opt_reverse_arraybytecpy(cc_nr, cc_p, 8);
|
||||||
State _init = {
|
State _init = {
|
||||||
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
((div_key_p[0] ^ 0x4c) + 0xEC) & 0xFF,// l
|
||||||
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
((div_key_p[0] ^ 0x4c) + 0x21) & 0xFF,// r
|
||||||
0x4c, // b
|
0x4c, // b
|
||||||
0xE012 // t
|
0xE012 // t
|
||||||
};
|
};
|
||||||
opt_suc(div_key_p, &_init, cc_nr, 8, false);
|
opt_suc(div_key_p, &_init, cc_nr, 8, false);
|
||||||
return _init;
|
return _init;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* The second part of the tag MAC calculation, since the CC is already calculated into the state,
|
* 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
|
* @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) {
|
void opt_doTagMAC_2(State _init, uint8_t* nr, uint8_t mac[4], const uint8_t* div_key_p) {
|
||||||
static uint8_t _nr[4];
|
static uint8_t _nr[4];
|
||||||
opt_reverse_arraybytecpy(_nr, nr, 4);
|
opt_reverse_arraybytecpy(_nr, nr, 4);
|
||||||
opt_suc(div_key_p, &_init,_nr, 4, true);
|
opt_suc(div_key_p, &_init,_nr, 4, true);
|
||||||
|
|
||||||
uint8_t dest [] = {0,0,0,0};
|
uint8_t dest [] = {0,0,0,0};
|
||||||
opt_output(div_key_p, &_init, dest);
|
opt_output(div_key_p, &_init, dest);
|
||||||
//The output MAC must also be reversed
|
//The output MAC must also be reversed
|
||||||
opt_reverse_arraybytecpy(mac, dest,4);
|
opt_reverse_arraybytecpy(mac, dest,4);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
/**
|
/**
|
||||||
* Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2
|
* Definition 1 (Cipher state). A cipher state of iClass s is an element of F 40/2
|
||||||
* consisting of the following four components:
|
* consisting of the following four components:
|
||||||
* 1. the left register l = (l 0 . . . l 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 ;
|
* 2. the right register r = (r 0 . . . r 7 ) ∈ F 8/2 ;
|
||||||
* 3. the top register t = (t 0 . . . t 15 ) ∈ F 16/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 .
|
* 4. the bottom register b = (b 0 . . . b 7 ) ∈ F 8/2 .
|
||||||
**/
|
**/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t l;
|
uint8_t l;
|
||||||
uint8_t r;
|
uint8_t r;
|
||||||
uint8_t b;
|
uint8_t b;
|
||||||
uint16_t t;
|
uint16_t t;
|
||||||
} State;
|
} State;
|
||||||
|
|
||||||
/** The reader MAC is MAC(key, CC * NR )
|
/** 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) {
|
size_t DemodPCF7931(uint8_t **outBlocks) {
|
||||||
uint8_t bits[256] = {0x00};
|
uint8_t bits[256] = {0x00};
|
||||||
uint8_t blocks[8][16];
|
uint8_t blocks[8][16];
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
|
||||||
int GraphTraceLen = BigBuf_max_traceLen();
|
int GraphTraceLen = BigBuf_max_traceLen();
|
||||||
if ( GraphTraceLen > 18000 )
|
if ( GraphTraceLen > 18000 )
|
||||||
GraphTraceLen = 18000;
|
GraphTraceLen = 18000;
|
||||||
|
|
||||||
int i, j, lastval, bitidx, half_switch;
|
int i, j, lastval, bitidx, half_switch;
|
||||||
int clock = 64;
|
int clock = 64;
|
||||||
int tolerance = clock / 8;
|
int tolerance = clock / 8;
|
||||||
int pmc, block_done;
|
int pmc, block_done;
|
||||||
int lc, warnings = 0;
|
int lc, warnings = 0;
|
||||||
size_t num_blocks = 0;
|
size_t num_blocks = 0;
|
||||||
int lmin=128, lmax=128;
|
int lmin=128, lmax=128;
|
||||||
uint8_t dir;
|
uint8_t dir;
|
||||||
//clear read buffer
|
//clear read buffer
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(95, true);
|
||||||
DoAcquisition_default(0, true);
|
DoAcquisition_default(0, true);
|
||||||
|
|
||||||
lmin = 64;
|
lmin = 64;
|
||||||
lmax = 192;
|
lmax = 192;
|
||||||
|
|
||||||
i = 2;
|
i = 2;
|
||||||
|
|
||||||
/* Find first local max/min */
|
/* Find first local max/min */
|
||||||
if(dest[1] > dest[0]) {
|
if(dest[1] > dest[0]) {
|
||||||
while(i < GraphTraceLen) {
|
while(i < GraphTraceLen) {
|
||||||
if( !(dest[i] > dest[i-1]) && dest[i] > lmax)
|
if( !(dest[i] > dest[i-1]) && dest[i] > lmax)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
dir = 0;
|
dir = 0;
|
||||||
} else {
|
} else {
|
||||||
while(i < GraphTraceLen) {
|
while(i < GraphTraceLen) {
|
||||||
if( !(dest[i] < dest[i-1]) && dest[i] < lmin)
|
if( !(dest[i] < dest[i-1]) && dest[i] < lmin)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
dir = 1;
|
dir = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastval = i++;
|
lastval = i++;
|
||||||
half_switch = 0;
|
half_switch = 0;
|
||||||
pmc = 0;
|
pmc = 0;
|
||||||
block_done = 0;
|
block_done = 0;
|
||||||
|
|
||||||
for (bitidx = 0; i < GraphTraceLen; 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)) {
|
if ((dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin)) {
|
||||||
lc = i - lastval;
|
lc = i - lastval;
|
||||||
lastval = i;
|
lastval = i;
|
||||||
|
|
||||||
// Switch depending on lc length:
|
// Switch depending on lc length:
|
||||||
// Tolerance is 1/8 of clock rate (arbitrary)
|
// Tolerance is 1/8 of clock rate (arbitrary)
|
||||||
if (ABS(lc-clock/4) < tolerance) {
|
if (ABS(lc-clock/4) < tolerance) {
|
||||||
// 16T0
|
// 16T0
|
||||||
if((i - pmc) == lc) { /* 16T0 was previous one */
|
if((i - pmc) == lc) { /* 16T0 was previous one */
|
||||||
/* It's a PMC ! */
|
/* It's a PMC ! */
|
||||||
i += (128+127+16+32+33+16)-1;
|
i += (128+127+16+32+33+16)-1;
|
||||||
lastval = i;
|
lastval = i;
|
||||||
pmc = 0;
|
pmc = 0;
|
||||||
block_done = 1;
|
block_done = 1;
|
||||||
} else {
|
} else {
|
||||||
pmc = i;
|
pmc = i;
|
||||||
}
|
}
|
||||||
} else if (ABS(lc-clock/2) < tolerance) {
|
} else if (ABS(lc-clock/2) < tolerance) {
|
||||||
// 32TO
|
// 32TO
|
||||||
if((i - pmc) == lc) { /* 16T0 was previous one */
|
if((i - pmc) == lc) { /* 16T0 was previous one */
|
||||||
/* It's a PMC ! */
|
/* It's a PMC ! */
|
||||||
i += (128+127+16+32+33)-1;
|
i += (128+127+16+32+33)-1;
|
||||||
lastval = i;
|
lastval = i;
|
||||||
pmc = 0;
|
pmc = 0;
|
||||||
block_done = 1;
|
block_done = 1;
|
||||||
} else if(half_switch == 1) {
|
} else if(half_switch == 1) {
|
||||||
bits[bitidx++] = 0;
|
bits[bitidx++] = 0;
|
||||||
half_switch = 0;
|
half_switch = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
half_switch++;
|
half_switch++;
|
||||||
} else if (ABS(lc-clock) < tolerance) {
|
} else if (ABS(lc-clock) < tolerance) {
|
||||||
// 64TO
|
// 64TO
|
||||||
bits[bitidx++] = 1;
|
bits[bitidx++] = 1;
|
||||||
} else {
|
} else {
|
||||||
// Error
|
// Error
|
||||||
if (++warnings > 10) {
|
if (++warnings > 10) {
|
||||||
Dbprintf("Error: too many detection errors, aborting.");
|
Dbprintf("Error: too many detection errors, aborting.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block_done == 1) {
|
if(block_done == 1) {
|
||||||
if(bitidx == 128) {
|
if(bitidx == 128) {
|
||||||
for(j = 0; j < 16; ++j) {
|
for(j = 0; j < 16; ++j) {
|
||||||
blocks[num_blocks][j] =
|
blocks[num_blocks][j] =
|
||||||
128 * bits[j*8 + 7]+
|
128 * bits[j*8 + 7]+
|
||||||
64*bits[j*8+6]+
|
64*bits[j*8+6]+
|
||||||
32*bits[j*8+5]+
|
32*bits[j*8+5]+
|
||||||
16*bits[j*8+4]+
|
16*bits[j*8+4]+
|
||||||
8*bits[j*8+3]+
|
8*bits[j*8+3]+
|
||||||
4*bits[j*8+2]+
|
4*bits[j*8+2]+
|
||||||
2*bits[j*8+1]+
|
2*bits[j*8+1]+
|
||||||
bits[j*8]
|
bits[j*8]
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
num_blocks++;
|
num_blocks++;
|
||||||
}
|
}
|
||||||
bitidx = 0;
|
bitidx = 0;
|
||||||
block_done = 0;
|
block_done = 0;
|
||||||
half_switch = 0;
|
half_switch = 0;
|
||||||
}
|
}
|
||||||
if(i < GraphTraceLen)
|
if(i < GraphTraceLen)
|
||||||
dir =(dest[i-1] > dest[i]) ? 0 : 1;
|
dir =(dest[i-1] > dest[i]) ? 0 : 1;
|
||||||
}
|
}
|
||||||
if(bitidx==255)
|
if(bitidx==255)
|
||||||
bitidx=0;
|
bitidx=0;
|
||||||
warnings = 0;
|
warnings = 0;
|
||||||
if(num_blocks == 4) break;
|
if(num_blocks == 4) break;
|
||||||
}
|
}
|
||||||
memcpy(outBlocks, blocks, 16*num_blocks);
|
memcpy(outBlocks, blocks, 16*num_blocks);
|
||||||
return num_blocks;
|
return num_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBlock0PCF7931(uint8_t *block) {
|
bool IsBlock0PCF7931(uint8_t *block) {
|
||||||
// assuming all RFU bits are set to 0
|
// assuming all RFU bits are set to 0
|
||||||
// if PAC is enabled password is set to 0
|
// if PAC is enabled password is set to 0
|
||||||
if (block[7] == 0x01)
|
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))
|
if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (block[7] == 0x00)
|
else if (block[7] == 0x00)
|
||||||
{
|
{
|
||||||
if (!memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7))
|
if (!memcmp(block+9, "\x00\x00\x00\x00\x00\x00\x00", 7))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsBlock1PCF7931(uint8_t *block) {
|
bool IsBlock1PCF7931(uint8_t *block) {
|
||||||
// assuming all RFU bits are set to 0
|
// assuming all RFU bits are set to 0
|
||||||
if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0)
|
if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0)
|
||||||
if((block[14] & 0x7f) <= 9 && block[15] <= 9)
|
if((block[14] & 0x7f) <= 9 && block[15] <= 9)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadPCF7931() {
|
void ReadPCF7931() {
|
||||||
int found_blocks = 0; // successfully read blocks
|
int found_blocks = 0; // successfully read blocks
|
||||||
int max_blocks = 8; // readable blocks
|
int max_blocks = 8; // readable blocks
|
||||||
uint8_t memory_blocks[8][17]; // PCF content
|
uint8_t memory_blocks[8][17]; // PCF content
|
||||||
|
|
||||||
uint8_t single_blocks[8][17]; // PFC blocks with unknown position
|
uint8_t single_blocks[8][17]; // PFC blocks with unknown position
|
||||||
int single_blocks_cnt = 0;
|
int single_blocks_cnt = 0;
|
||||||
|
|
||||||
size_t n = 0; // transmitted blocks
|
size_t n = 0; // transmitted blocks
|
||||||
uint8_t tmp_blocks[4][16]; // temporary read buffer
|
uint8_t tmp_blocks[4][16]; // temporary read buffer
|
||||||
|
|
||||||
uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found
|
uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found
|
||||||
int errors = 0; // error counter
|
int errors = 0; // error counter
|
||||||
int tries = 0; // tries counter
|
int tries = 0; // tries counter
|
||||||
|
|
||||||
memset(memory_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));
|
memset(single_blocks, 0, 8*17*sizeof(uint8_t));
|
||||||
|
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
memset(tmp_blocks, 0, 4*16*sizeof(uint8_t));
|
memset(tmp_blocks, 0, 4*16*sizeof(uint8_t));
|
||||||
n = DemodPCF7931((uint8_t**)tmp_blocks);
|
n = DemodPCF7931((uint8_t**)tmp_blocks);
|
||||||
if(!n)
|
if(!n)
|
||||||
++errors;
|
++errors;
|
||||||
|
|
||||||
// exit if no block is received
|
// exit if no block is received
|
||||||
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
|
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
|
||||||
Dbprintf("Error, no tag or bad tag");
|
Dbprintf("Error, no tag or bad tag");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// exit if too many errors during reading
|
// exit if too many errors during reading
|
||||||
if (tries > 50 && (2*errors > tries)) {
|
if (tries > 50 && (2*errors > tries)) {
|
||||||
Dbprintf("Error reading the tag");
|
Dbprintf("Error reading the tag");
|
||||||
Dbprintf("Here is the partial content");
|
Dbprintf("Here is the partial content");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// our logic breaks if we don't get at least two blocks
|
// our logic breaks if we don't get at least two blocks
|
||||||
if (n < 2) {
|
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))
|
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;
|
continue;
|
||||||
|
|
||||||
if (single_blocks_cnt < max_blocks) {
|
if (single_blocks_cnt < max_blocks) {
|
||||||
for (i = 0; i < single_blocks_cnt; ++i) {
|
for (i = 0; i < single_blocks_cnt; ++i) {
|
||||||
if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) {
|
if (!memcmp(single_blocks[i], tmp_blocks[0], 16)) {
|
||||||
j = 1;
|
j = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j != 1) {
|
if (j != 1) {
|
||||||
memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16);
|
memcpy(single_blocks[single_blocks_cnt], tmp_blocks[0], 16);
|
||||||
single_blocks_cnt++;
|
single_blocks_cnt++;
|
||||||
}
|
}
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
++tries;
|
++tries;
|
||||||
continue;
|
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;
|
i = 0;
|
||||||
if(!found_0_1) {
|
if(!found_0_1) {
|
||||||
while (i < n - 1) {
|
while (i < n - 1) {
|
||||||
if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i+1])) {
|
if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i+1])) {
|
||||||
found_0_1 = 1;
|
found_0_1 = 1;
|
||||||
memcpy(memory_blocks[0], tmp_blocks[i], 16);
|
memcpy(memory_blocks[0], tmp_blocks[i], 16);
|
||||||
memcpy(memory_blocks[1], tmp_blocks[i+1], 16);
|
memcpy(memory_blocks[1], tmp_blocks[i+1], 16);
|
||||||
memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1;
|
memory_blocks[0][ALLOC] = memory_blocks[1][ALLOC] = 1;
|
||||||
// block 1 tells how many blocks are going to be sent
|
// block 1 tells how many blocks are going to be sent
|
||||||
max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1;
|
max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1;
|
||||||
found_blocks = 2;
|
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
|
// handle the following blocks
|
||||||
for (j = i + 2; j < n; ++j) {
|
for (j = i + 2; j < n; ++j) {
|
||||||
memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16);
|
memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16);
|
||||||
memory_blocks[found_blocks][ALLOC] = 1;
|
memory_blocks[found_blocks][ALLOC] = 1;
|
||||||
++found_blocks;
|
++found_blocks;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Trying to re-order blocks
|
// Trying to re-order blocks
|
||||||
// Look for identical block in memory blocks
|
// Look for identical block in memory blocks
|
||||||
while (i < n-1) {
|
while (i < n-1) {
|
||||||
// skip all zeroes blocks
|
// 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)) {
|
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) {
|
for (j = 1; j < max_blocks - 1; ++j) {
|
||||||
if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j+1][ALLOC]) {
|
if (!memcmp(tmp_blocks[i], memory_blocks[j], 16) && !memory_blocks[j+1][ALLOC]) {
|
||||||
memcpy(memory_blocks[j+1], tmp_blocks[i+1], 16);
|
memcpy(memory_blocks[j+1], tmp_blocks[i+1], 16);
|
||||||
memory_blocks[j+1][ALLOC] = 1;
|
memory_blocks[j+1][ALLOC] = 1;
|
||||||
if (++found_blocks >= max_blocks) goto end;
|
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)) {
|
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) {
|
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 (!memcmp(tmp_blocks[i+1], memory_blocks[j], 16) && !memory_blocks[(j == 0 ? max_blocks : j) -1][ALLOC]) {
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
memcpy(memory_blocks[max_blocks - 1], tmp_blocks[i], 16);
|
memcpy(memory_blocks[max_blocks - 1], tmp_blocks[i], 16);
|
||||||
memory_blocks[max_blocks - 1][ALLOC] = 1;
|
memory_blocks[max_blocks - 1][ALLOC] = 1;
|
||||||
} else {
|
} else {
|
||||||
memcpy(memory_blocks[j-1], tmp_blocks[i], 16);
|
memcpy(memory_blocks[j-1], tmp_blocks[i], 16);
|
||||||
memory_blocks[j-1][ALLOC] = 1;
|
memory_blocks[j-1][ALLOC] = 1;
|
||||||
}
|
}
|
||||||
if (++found_blocks >= max_blocks) goto end;
|
if (++found_blocks >= max_blocks) goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++tries;
|
++tries;
|
||||||
if (BUTTON_PRESS()) {
|
if (BUTTON_PRESS()) {
|
||||||
Dbprintf("Button pressed, stopping.");
|
Dbprintf("Button pressed, stopping.");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (found_blocks != max_blocks);
|
while (found_blocks != max_blocks);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
Dbprintf("Memory content:");
|
Dbprintf("Memory content:");
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
for (i = 0; i < max_blocks; ++i) {
|
for (i = 0; i < max_blocks; ++i) {
|
||||||
if (memory_blocks[i][ALLOC])
|
if (memory_blocks[i][ALLOC])
|
||||||
print_result("Block", memory_blocks[i], 16);
|
print_result("Block", memory_blocks[i], 16);
|
||||||
else
|
else
|
||||||
Dbprintf("<missing block %d>", i);
|
Dbprintf("<missing block %d>", i);
|
||||||
}
|
}
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
|
|
||||||
if (found_blocks < max_blocks) {
|
if (found_blocks < max_blocks) {
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
Dbprintf("Blocks with unknown position:");
|
Dbprintf("Blocks with unknown position:");
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
for (i = 0; i < single_blocks_cnt; ++i)
|
for (i = 0; i < single_blocks_cnt; ++i)
|
||||||
print_result("Block", single_blocks[i], 16);
|
print_result("Block", single_blocks[i], 16);
|
||||||
|
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
}
|
}
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
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) {
|
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 tab[1024] = {0}; // data times frame
|
||||||
uint32_t u = 0;
|
uint32_t u = 0;
|
||||||
uint8_t parity = 0;
|
uint8_t parity = 0;
|
||||||
bool comp = 0;
|
bool comp = 0;
|
||||||
|
|
||||||
//BUILD OF THE DATA FRAME
|
//BUILD OF THE DATA FRAME
|
||||||
//alimentation of the tag (time for initializing)
|
//alimentation of the tag (time for initializing)
|
||||||
AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab);
|
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);
|
AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab);
|
||||||
//password indication bit
|
//password indication bit
|
||||||
AddBitPCF7931(1, tab, l, p);
|
AddBitPCF7931(1, tab, l, p);
|
||||||
//password (on 56 bits)
|
//password (on 56 bits)
|
||||||
AddBytePCF7931(pass[0], tab, l, p);
|
AddBytePCF7931(pass[0], tab, l, p);
|
||||||
AddBytePCF7931(pass[1], tab, l, p);
|
AddBytePCF7931(pass[1], tab, l, p);
|
||||||
AddBytePCF7931(pass[2], tab, l, p);
|
AddBytePCF7931(pass[2], tab, l, p);
|
||||||
AddBytePCF7931(pass[3], tab, l, p);
|
AddBytePCF7931(pass[3], tab, l, p);
|
||||||
AddBytePCF7931(pass[4], tab, l, p);
|
AddBytePCF7931(pass[4], tab, l, p);
|
||||||
AddBytePCF7931(pass[5], tab, l, p);
|
AddBytePCF7931(pass[5], tab, l, p);
|
||||||
AddBytePCF7931(pass[6], tab, l, p);
|
AddBytePCF7931(pass[6], tab, l, p);
|
||||||
//programming mode (0 or 1)
|
//programming mode (0 or 1)
|
||||||
AddBitPCF7931(0, tab, l, p);
|
AddBitPCF7931(0, tab, l, p);
|
||||||
|
|
||||||
//block adress on 6 bits
|
//block adress on 6 bits
|
||||||
for (u = 0; u < 6; ++u) {
|
for (u = 0; u < 6; ++u) {
|
||||||
if (address&(1<<u)) { // bit 1
|
if (address&(1<<u)) { // bit 1
|
||||||
++parity;
|
++parity;
|
||||||
AddBitPCF7931(1, tab, l, p);
|
AddBitPCF7931(1, tab, l, p);
|
||||||
} else{ // bit 0
|
} else{ // bit 0
|
||||||
AddBitPCF7931(0, tab, l, p);
|
AddBitPCF7931(0, tab, l, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//byte address on 4 bits
|
//byte address on 4 bits
|
||||||
for (u = 0; u < 4; ++u)
|
for (u = 0; u < 4; ++u)
|
||||||
{
|
{
|
||||||
if (byte&(1<<u)) { // bit 1
|
if (byte&(1<<u)) { // bit 1
|
||||||
parity++;
|
parity++;
|
||||||
AddBitPCF7931(1, tab, l, p);
|
AddBitPCF7931(1, tab, l, p);
|
||||||
}
|
}
|
||||||
else // bit 0
|
else // bit 0
|
||||||
AddBitPCF7931(0, tab, l, p);
|
AddBitPCF7931(0, tab, l, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
//data on 8 bits
|
//data on 8 bits
|
||||||
for (u=0; u<8; u++)
|
for (u=0; u<8; u++)
|
||||||
{
|
{
|
||||||
if (data&(1<<u)) { // bit 1
|
if (data&(1<<u)) { // bit 1
|
||||||
parity++;
|
parity++;
|
||||||
AddBitPCF7931(1, tab, l, p);
|
AddBitPCF7931(1, tab, l, p);
|
||||||
}
|
}
|
||||||
else //bit 0
|
else //bit 0
|
||||||
AddBitPCF7931(0, tab, l, p);
|
AddBitPCF7931(0, tab, l, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
//parity bit
|
//parity bit
|
||||||
if ((parity % 2) == 0)
|
if ((parity % 2) == 0)
|
||||||
AddBitPCF7931(0, tab, l, p); //even parity
|
AddBitPCF7931(0, tab, l, p); //even parity
|
||||||
else
|
else
|
||||||
AddBitPCF7931(1, tab, l, p);//odd parity
|
AddBitPCF7931(1, tab, l, p);//odd parity
|
||||||
|
|
||||||
//time access memory
|
//time access memory
|
||||||
AddPatternPCF7931(5120+2680, 0, 0, tab);
|
AddPatternPCF7931(5120+2680, 0, 0, tab);
|
||||||
|
|
||||||
//conversion of the scale time
|
//conversion of the scale time
|
||||||
for (u = 0; u < 500; ++u)
|
for (u = 0; u < 500; ++u)
|
||||||
tab[u]=(tab[u] * 3)/2;
|
tab[u]=(tab[u] * 3)/2;
|
||||||
|
|
||||||
//compensation of the counter reload
|
//compensation of the counter reload
|
||||||
while (!comp){
|
while (!comp){
|
||||||
comp = 1;
|
comp = 1;
|
||||||
for (u = 0; tab[u] != 0; ++u)
|
for (u = 0; tab[u] != 0; ++u)
|
||||||
if(tab[u] > 0xFFFF){
|
if(tab[u] > 0xFFFF){
|
||||||
tab[u] -= 0xFFFF;
|
tab[u] -= 0xFFFF;
|
||||||
comp = 0;
|
comp = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendCmdPCF7931(tab);
|
SendCmdPCF7931(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write on a byte of a PCF7931 tag
|
/* 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
|
@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) {
|
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("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("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("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("Block address : %02x", address);
|
||||||
Dbprintf("Byte address : %02x", byte);
|
Dbprintf("Byte address : %02x", byte);
|
||||||
Dbprintf("Data : %02x", data);
|
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){
|
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);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU );
|
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
|
// 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_PER = GPIO_SSC_DOUT;
|
||||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||||
|
|
||||||
//initialization of the timer
|
//initialization of the timer
|
||||||
AT91C_BASE_PMC->PMC_PCER |= (0x1 << AT91C_ID_TC0);
|
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_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_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_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
|
||||||
AT91C_BASE_TCB->TCB_BCR = 1;
|
AT91C_BASE_TCB->TCB_BCR = 1;
|
||||||
|
|
||||||
tempo = AT91C_BASE_TC0->TC_CV;
|
tempo = AT91C_BASE_TC0->TC_CV;
|
||||||
for( u = 0; tab[u] != 0; u += 3){
|
for( u = 0; tab[u] != 0; u += 3){
|
||||||
// modulate antenna
|
// modulate antenna
|
||||||
HIGH(GPIO_SSC_DOUT);
|
HIGH(GPIO_SSC_DOUT);
|
||||||
while (tempo != tab[u])
|
while (tempo != tab[u])
|
||||||
tempo = AT91C_BASE_TC0->TC_CV;
|
tempo = AT91C_BASE_TC0->TC_CV;
|
||||||
|
|
||||||
// stop modulating antenna
|
// stop modulating antenna
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
while (tempo != tab[u+1])
|
while (tempo != tab[u+1])
|
||||||
tempo = AT91C_BASE_TC0->TC_CV;
|
tempo = AT91C_BASE_TC0->TC_CV;
|
||||||
|
|
||||||
// modulate antenna
|
// modulate antenna
|
||||||
HIGH(GPIO_SSC_DOUT);
|
HIGH(GPIO_SSC_DOUT);
|
||||||
while (tempo != tab[u+2])
|
while (tempo != tab[u+2])
|
||||||
tempo = AT91C_BASE_TC0->TC_CV;
|
tempo = AT91C_BASE_TC0->TC_CV;
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelay(200);
|
SpinDelay(200);
|
||||||
|
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
||||||
LED(0xFFFF, 1000);
|
LED(0xFFFF, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -465,16 +465,16 @@ void SendCmdPCF7931(uint32_t * tab){
|
||||||
* @param p : offset on low pulse positioning
|
* @param p : offset on low pulse positioning
|
||||||
*/
|
*/
|
||||||
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){
|
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){
|
||||||
uint32_t u;
|
uint32_t u;
|
||||||
for (u = 0; u < 8; ++u) {
|
for (u = 0; u < 8; ++u) {
|
||||||
if (byte & (1 << u)) { //bit is 1
|
if (byte & (1 << u)) { //bit is 1
|
||||||
if( AddBitPCF7931(1, tab, l, p)==1) return 1;
|
if( AddBitPCF7931(1, tab, l, p)==1) return 1;
|
||||||
} else { //bit is 0
|
} else { //bit is 0
|
||||||
if (AddBitPCF7931(0, tab, l, p)==1) return 1;
|
if (AddBitPCF7931(0, tab, l, p)==1) return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a bits for building the data frame of PCF7931 tags
|
/* 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
|
* @param p : offset on low pulse positioning
|
||||||
*/
|
*/
|
||||||
bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){
|
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
|
//we put the cursor at the last value of the array
|
||||||
for ( u = 0; tab[u] != 0; u += 3 ) { }
|
for ( u = 0; tab[u] != 0; u += 3 ) { }
|
||||||
|
|
||||||
if ( b == 1 ) { //add a bit 1
|
if ( b == 1 ) { //add a bit 1
|
||||||
if ( u == 0 )
|
if ( u == 0 )
|
||||||
tab[u] = 34 * T0_PCF + p;
|
tab[u] = 34 * T0_PCF + p;
|
||||||
else
|
else
|
||||||
tab[u] = 34 * T0_PCF + tab[u-1] + p;
|
tab[u] = 34 * T0_PCF + tab[u-1] + p;
|
||||||
|
|
||||||
tab[u+1] = 6 * T0_PCF + tab[u] + l;
|
tab[u+1] = 6 * T0_PCF + tab[u] + l;
|
||||||
tab[u+2] = 88 * T0_PCF + tab[u+1] - l - p;
|
tab[u+2] = 88 * T0_PCF + tab[u+1] - l - p;
|
||||||
return 0;
|
return 0;
|
||||||
} else { //add a bit 0
|
} else { //add a bit 0
|
||||||
|
|
||||||
if ( u == 0 )
|
if ( u == 0 )
|
||||||
tab[u] = 98 * T0_PCF + p;
|
tab[u] = 98 * T0_PCF + p;
|
||||||
else
|
else
|
||||||
tab[u] = 98 * T0_PCF + tab[u-1] + p;
|
tab[u] = 98 * T0_PCF + tab[u-1] + p;
|
||||||
|
|
||||||
tab[u+1] = 6 * T0_PCF + tab[u] + l;
|
tab[u+1] = 6 * T0_PCF + tab[u] + l;
|
||||||
tab[u+2] = 24 * T0_PCF + tab[u+1] - l - p;
|
tab[u+2] = 24 * T0_PCF + tab[u+1] - l - p;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a custom pattern in the data frame
|
/* 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
|
* @param tab : array of the data frame
|
||||||
*/
|
*/
|
||||||
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab){
|
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab){
|
||||||
uint32_t u = 0;
|
uint32_t u = 0;
|
||||||
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){} //we put the cursor at the last value of the array
|
||||||
|
|
||||||
tab[u] = (u == 0) ? a : a + tab[u-1];
|
tab[u] = (u == 0) ? a : a + tab[u-1];
|
||||||
tab[u+1] = b + tab[u];
|
tab[u+1] = b + tab[u];
|
||||||
tab[u+2] = c + tab[u+1];
|
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
|
* 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.
|
* (c) UNIX System Laboratories, Inc.
|
||||||
* All or some portions of this file are derived from material licensed
|
* All or some portions of this file are derived from material licensed
|
||||||
* to the University of California by American Telephone and Telegraph
|
* 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
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
|
* @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
|
||||||
*/
|
*/
|
||||||
#include "printf.h"
|
#include "printf.h"
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))
|
#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))
|
||||||
|
|
||||||
/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
|
/* 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
|
* Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
|
||||||
|
@ -61,17 +61,17 @@ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
static char *
|
static char *
|
||||||
ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
|
ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
|
||||||
{
|
{
|
||||||
char *p, c;
|
char *p, c;
|
||||||
|
|
||||||
p = nbuf;
|
p = nbuf;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
do {
|
do {
|
||||||
c = hex2ascii(num % base);
|
c = hex2ascii(num % base);
|
||||||
*++p = upper ? toupper(c) : c;
|
*++p = upper ? toupper(c) : c;
|
||||||
} while (num /= base);
|
} while (num /= base);
|
||||||
if (lenp)
|
if (lenp)
|
||||||
*lenp = p - nbuf;
|
*lenp = p - nbuf;
|
||||||
return (p);
|
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.
|
* The format %b is supported to decode error registers.
|
||||||
* Its usage is:
|
* 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.
|
* 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,
|
* \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),
|
* the next characters (up to a control character, i.e. a character <= 32),
|
||||||
* give the name of the register. Thus:
|
* 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:
|
* would produce output:
|
||||||
*
|
*
|
||||||
* reg=3
|
* reg=3
|
||||||
*
|
*
|
||||||
* XXX: %D -- Hexdump, takes pointer and separator string:
|
* XXX: %D -- Hexdump, takes pointer and separator string:
|
||||||
* ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
|
* ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
|
||||||
* ("%*D", len, ptr, " " -> XX XX XX XX ...
|
* ("%*D", len, ptr, " " -> XX XX XX XX ...
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
kvsprintf(char const *fmt, void *arg, int radix, va_list ap)
|
kvsprintf(char const *fmt, void *arg, int radix, va_list ap)
|
||||||
{
|
{
|
||||||
#define PCHAR(c) {int cc=(c); *d++ = cc; retval++; }
|
#define PCHAR(c) {int cc=(c); *d++ = cc; retval++; }
|
||||||
char nbuf[MAXNBUF];
|
char nbuf[MAXNBUF];
|
||||||
char *d;
|
char *d;
|
||||||
const char *p, *percent, *q;
|
const char *p, *percent, *q;
|
||||||
u_char *up;
|
u_char *up;
|
||||||
int ch, n;
|
int ch, n;
|
||||||
uintmax_t num;
|
uintmax_t num;
|
||||||
int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
|
int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
|
||||||
int cflag, hflag, jflag, tflag, zflag;
|
int cflag, hflag, jflag, tflag, zflag;
|
||||||
int dwidth, upper;
|
int dwidth, upper;
|
||||||
char padc;
|
char padc;
|
||||||
int stop = 0, retval = 0;
|
int stop = 0, retval = 0;
|
||||||
|
|
||||||
num = 0;
|
num = 0;
|
||||||
d = (char *) arg;
|
d = (char *) arg;
|
||||||
|
|
||||||
if (fmt == NULL)
|
if (fmt == NULL)
|
||||||
fmt = "(fmt null)\n";
|
fmt = "(fmt null)\n";
|
||||||
|
|
||||||
if (radix < 2 || radix > 36)
|
if (radix < 2 || radix > 36)
|
||||||
radix = 10;
|
radix = 10;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
padc = ' ';
|
padc = ' ';
|
||||||
width = 0;
|
width = 0;
|
||||||
while ((ch = (u_char)*fmt++) != '%' || stop) {
|
while ((ch = (u_char)*fmt++) != '%' || stop) {
|
||||||
PCHAR(ch);
|
PCHAR(ch);
|
||||||
if (ch == '\0')
|
if (ch == '\0')
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
percent = fmt - 1;
|
percent = fmt - 1;
|
||||||
qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
|
qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
|
||||||
sign = 0; dot = 0; dwidth = 0; upper = 0;
|
sign = 0; dot = 0; dwidth = 0; upper = 0;
|
||||||
cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
|
cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
|
||||||
reswitch: switch (ch = (u_char)*fmt++) {
|
reswitch: switch (ch = (u_char)*fmt++) {
|
||||||
case '.':
|
case '.':
|
||||||
dot = 1;
|
dot = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case '#':
|
case '#':
|
||||||
sharpflag = 1;
|
sharpflag = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case '+':
|
case '+':
|
||||||
sign = 1;
|
sign = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case '-':
|
case '-':
|
||||||
ladjust = 1;
|
ladjust = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case '%':
|
case '%':
|
||||||
PCHAR(ch);
|
PCHAR(ch);
|
||||||
break;
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
if (!dot) {
|
if (!dot) {
|
||||||
width = va_arg(ap, int);
|
width = va_arg(ap, int);
|
||||||
if (width < 0) {
|
if (width < 0) {
|
||||||
ladjust = !ladjust;
|
ladjust = !ladjust;
|
||||||
width = -width;
|
width = -width;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dwidth = va_arg(ap, int);
|
dwidth = va_arg(ap, int);
|
||||||
}
|
}
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case '0':
|
case '0':
|
||||||
if (!dot) {
|
if (!dot) {
|
||||||
padc = '0';
|
padc = '0';
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
}
|
}
|
||||||
case '1': case '2': case '3': case '4':
|
case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
for (n = 0;; ++fmt) {
|
for (n = 0;; ++fmt) {
|
||||||
n = n * 10 + ch - '0';
|
n = n * 10 + ch - '0';
|
||||||
ch = *fmt;
|
ch = *fmt;
|
||||||
if (ch < '0' || ch > '9')
|
if (ch < '0' || ch > '9')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (dot)
|
if (dot)
|
||||||
dwidth = n;
|
dwidth = n;
|
||||||
else
|
else
|
||||||
width = n;
|
width = n;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case 'b':
|
case 'b':
|
||||||
num = (u_int)va_arg(ap, int);
|
num = (u_int)va_arg(ap, int);
|
||||||
p = va_arg(ap, char *);
|
p = va_arg(ap, char *);
|
||||||
for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
|
for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
|
||||||
PCHAR(*q--);
|
PCHAR(*q--);
|
||||||
|
|
||||||
if (num == 0)
|
if (num == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (tmp = 0; *p;) {
|
for (tmp = 0; *p;) {
|
||||||
n = *p++;
|
n = *p++;
|
||||||
if (num & (1 << (n - 1))) {
|
if (num & (1 << (n - 1))) {
|
||||||
PCHAR(tmp ? ',' : '<');
|
PCHAR(tmp ? ',' : '<');
|
||||||
for (; (n = *p) > ' '; ++p)
|
for (; (n = *p) > ' '; ++p)
|
||||||
PCHAR(n);
|
PCHAR(n);
|
||||||
tmp = 1;
|
tmp = 1;
|
||||||
} else
|
} else
|
||||||
for (; *p > ' '; ++p)
|
for (; *p > ' '; ++p)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (tmp)
|
if (tmp)
|
||||||
PCHAR('>');
|
PCHAR('>');
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
PCHAR(va_arg(ap, int));
|
PCHAR(va_arg(ap, int));
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
up = va_arg(ap, u_char *);
|
up = va_arg(ap, u_char *);
|
||||||
p = va_arg(ap, char *);
|
p = va_arg(ap, char *);
|
||||||
if (!width)
|
if (!width)
|
||||||
width = 16;
|
width = 16;
|
||||||
while(width--) {
|
while(width--) {
|
||||||
PCHAR(hex2ascii(*up >> 4));
|
PCHAR(hex2ascii(*up >> 4));
|
||||||
PCHAR(hex2ascii(*up & 0x0f));
|
PCHAR(hex2ascii(*up & 0x0f));
|
||||||
up++;
|
up++;
|
||||||
if (width)
|
if (width)
|
||||||
for (q=p;*q;q++)
|
for (q=p;*q;q++)
|
||||||
PCHAR(*q);
|
PCHAR(*q);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'i':
|
case 'i':
|
||||||
base = 10;
|
base = 10;
|
||||||
sign = 1;
|
sign = 1;
|
||||||
goto handle_sign;
|
goto handle_sign;
|
||||||
case 'h':
|
case 'h':
|
||||||
if (hflag) {
|
if (hflag) {
|
||||||
hflag = 0;
|
hflag = 0;
|
||||||
cflag = 1;
|
cflag = 1;
|
||||||
} else
|
} else
|
||||||
hflag = 1;
|
hflag = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case 'j':
|
case 'j':
|
||||||
jflag = 1;
|
jflag = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (lflag) {
|
if (lflag) {
|
||||||
lflag = 0;
|
lflag = 0;
|
||||||
qflag = 1;
|
qflag = 1;
|
||||||
} else
|
} else
|
||||||
lflag = 1;
|
lflag = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case 'n':
|
case 'n':
|
||||||
if (jflag)
|
if (jflag)
|
||||||
*(va_arg(ap, intmax_t *)) = retval;
|
*(va_arg(ap, intmax_t *)) = retval;
|
||||||
else if (qflag)
|
else if (qflag)
|
||||||
*(va_arg(ap, quad_t *)) = retval;
|
*(va_arg(ap, quad_t *)) = retval;
|
||||||
else if (lflag)
|
else if (lflag)
|
||||||
*(va_arg(ap, long *)) = retval;
|
*(va_arg(ap, long *)) = retval;
|
||||||
else if (zflag)
|
else if (zflag)
|
||||||
*(va_arg(ap, size_t *)) = retval;
|
*(va_arg(ap, size_t *)) = retval;
|
||||||
else if (hflag)
|
else if (hflag)
|
||||||
*(va_arg(ap, short *)) = retval;
|
*(va_arg(ap, short *)) = retval;
|
||||||
else if (cflag)
|
else if (cflag)
|
||||||
*(va_arg(ap, char *)) = retval;
|
*(va_arg(ap, char *)) = retval;
|
||||||
else
|
else
|
||||||
*(va_arg(ap, int *)) = retval;
|
*(va_arg(ap, int *)) = retval;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
base = 8;
|
base = 8;
|
||||||
goto handle_nosign;
|
goto handle_nosign;
|
||||||
case 'p':
|
case 'p':
|
||||||
base = 16;
|
base = 16;
|
||||||
sharpflag = (width == 0);
|
sharpflag = (width == 0);
|
||||||
sign = 0;
|
sign = 0;
|
||||||
num = (uintptr_t)va_arg(ap, void *);
|
num = (uintptr_t)va_arg(ap, void *);
|
||||||
goto number;
|
goto number;
|
||||||
case 'q':
|
case 'q':
|
||||||
qflag = 1;
|
qflag = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case 'r':
|
case 'r':
|
||||||
base = radix;
|
base = radix;
|
||||||
if (sign)
|
if (sign)
|
||||||
goto handle_sign;
|
goto handle_sign;
|
||||||
goto handle_nosign;
|
goto handle_nosign;
|
||||||
case 's':
|
case 's':
|
||||||
p = va_arg(ap, char *);
|
p = va_arg(ap, char *);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
p = "(null)";
|
p = "(null)";
|
||||||
if (!dot)
|
if (!dot)
|
||||||
n = strlen (p);
|
n = strlen (p);
|
||||||
else
|
else
|
||||||
for (n = 0; n < dwidth && p[n]; n++)
|
for (n = 0; n < dwidth && p[n]; n++)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
width -= n;
|
width -= n;
|
||||||
|
|
||||||
if (!ladjust && width > 0)
|
if (!ladjust && width > 0)
|
||||||
while (width--)
|
while (width--)
|
||||||
PCHAR(padc);
|
PCHAR(padc);
|
||||||
while (n--)
|
while (n--)
|
||||||
PCHAR(*p++);
|
PCHAR(*p++);
|
||||||
if (ladjust && width > 0)
|
if (ladjust && width > 0)
|
||||||
while (width--)
|
while (width--)
|
||||||
PCHAR(padc);
|
PCHAR(padc);
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
tflag = 1;
|
tflag = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
case 'u':
|
case 'u':
|
||||||
base = 10;
|
base = 10;
|
||||||
goto handle_nosign;
|
goto handle_nosign;
|
||||||
case 'X':
|
case 'X':
|
||||||
upper = 1;
|
upper = 1;
|
||||||
case 'x':
|
case 'x':
|
||||||
base = 16;
|
base = 16;
|
||||||
goto handle_nosign;
|
goto handle_nosign;
|
||||||
case 'y':
|
case 'y':
|
||||||
base = 16;
|
base = 16;
|
||||||
sign = 1;
|
sign = 1;
|
||||||
goto handle_sign;
|
goto handle_sign;
|
||||||
case 'z':
|
case 'z':
|
||||||
zflag = 1;
|
zflag = 1;
|
||||||
goto reswitch;
|
goto reswitch;
|
||||||
handle_nosign:
|
handle_nosign:
|
||||||
sign = 0;
|
sign = 0;
|
||||||
if (jflag)
|
if (jflag)
|
||||||
num = va_arg(ap, uintmax_t);
|
num = va_arg(ap, uintmax_t);
|
||||||
else if (qflag)
|
else if (qflag)
|
||||||
num = va_arg(ap, u_quad_t);
|
num = va_arg(ap, u_quad_t);
|
||||||
else if (tflag)
|
else if (tflag)
|
||||||
num = va_arg(ap, ptrdiff_t);
|
num = va_arg(ap, ptrdiff_t);
|
||||||
else if (lflag)
|
else if (lflag)
|
||||||
num = va_arg(ap, u_long);
|
num = va_arg(ap, u_long);
|
||||||
else if (zflag)
|
else if (zflag)
|
||||||
num = va_arg(ap, size_t);
|
num = va_arg(ap, size_t);
|
||||||
else if (hflag)
|
else if (hflag)
|
||||||
num = (u_short)va_arg(ap, int);
|
num = (u_short)va_arg(ap, int);
|
||||||
else if (cflag)
|
else if (cflag)
|
||||||
num = (u_char)va_arg(ap, int);
|
num = (u_char)va_arg(ap, int);
|
||||||
else
|
else
|
||||||
num = va_arg(ap, u_int);
|
num = va_arg(ap, u_int);
|
||||||
goto number;
|
goto number;
|
||||||
handle_sign:
|
handle_sign:
|
||||||
if (jflag)
|
if (jflag)
|
||||||
num = va_arg(ap, intmax_t);
|
num = va_arg(ap, intmax_t);
|
||||||
else if (qflag)
|
else if (qflag)
|
||||||
num = va_arg(ap, quad_t);
|
num = va_arg(ap, quad_t);
|
||||||
else if (tflag)
|
else if (tflag)
|
||||||
num = va_arg(ap, ptrdiff_t);
|
num = va_arg(ap, ptrdiff_t);
|
||||||
else if (lflag)
|
else if (lflag)
|
||||||
num = va_arg(ap, long);
|
num = va_arg(ap, long);
|
||||||
else if (zflag)
|
else if (zflag)
|
||||||
num = va_arg(ap, ssize_t);
|
num = va_arg(ap, ssize_t);
|
||||||
else if (hflag)
|
else if (hflag)
|
||||||
num = (short)va_arg(ap, int);
|
num = (short)va_arg(ap, int);
|
||||||
else if (cflag)
|
else if (cflag)
|
||||||
num = (char)va_arg(ap, int);
|
num = (char)va_arg(ap, int);
|
||||||
else
|
else
|
||||||
num = va_arg(ap, int);
|
num = va_arg(ap, int);
|
||||||
number:
|
number:
|
||||||
if (sign && (intmax_t)num < 0) {
|
if (sign && (intmax_t)num < 0) {
|
||||||
neg = 1;
|
neg = 1;
|
||||||
num = -(intmax_t)num;
|
num = -(intmax_t)num;
|
||||||
}
|
}
|
||||||
p = ksprintn(nbuf, num, base, &tmp, upper);
|
p = ksprintn(nbuf, num, base, &tmp, upper);
|
||||||
if (sharpflag && num != 0) {
|
if (sharpflag && num != 0) {
|
||||||
if (base == 8)
|
if (base == 8)
|
||||||
tmp++;
|
tmp++;
|
||||||
else if (base == 16)
|
else if (base == 16)
|
||||||
tmp += 2;
|
tmp += 2;
|
||||||
}
|
}
|
||||||
if (neg)
|
if (neg)
|
||||||
tmp++;
|
tmp++;
|
||||||
|
|
||||||
if (!ladjust && padc != '0' && width
|
if (!ladjust && padc != '0' && width
|
||||||
&& (width -= tmp) > 0)
|
&& (width -= tmp) > 0)
|
||||||
while (width--)
|
while (width--)
|
||||||
PCHAR(padc);
|
PCHAR(padc);
|
||||||
if (neg)
|
if (neg)
|
||||||
PCHAR('-');
|
PCHAR('-');
|
||||||
if (sharpflag && num != 0) {
|
if (sharpflag && num != 0) {
|
||||||
if (base == 8) {
|
if (base == 8) {
|
||||||
PCHAR('0');
|
PCHAR('0');
|
||||||
} else if (base == 16) {
|
} else if (base == 16) {
|
||||||
PCHAR('0');
|
PCHAR('0');
|
||||||
PCHAR('x');
|
PCHAR('x');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ladjust && width && (width -= tmp) > 0)
|
if (!ladjust && width && (width -= tmp) > 0)
|
||||||
while (width--)
|
while (width--)
|
||||||
PCHAR(padc);
|
PCHAR(padc);
|
||||||
|
|
||||||
while (*p)
|
while (*p)
|
||||||
PCHAR(*p--);
|
PCHAR(*p--);
|
||||||
|
|
||||||
if (ladjust && width && (width -= tmp) > 0)
|
if (ladjust && width && (width -= tmp) > 0)
|
||||||
while (width--)
|
while (width--)
|
||||||
PCHAR(padc);
|
PCHAR(padc);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
while (percent < fmt)
|
while (percent < fmt)
|
||||||
PCHAR(*percent++);
|
PCHAR(*percent++);
|
||||||
/*
|
/*
|
||||||
* Since we ignore an formatting argument it is no
|
* Since we ignore an formatting argument it is no
|
||||||
* longer safe to obey the remaining formatting
|
* longer safe to obey the remaining formatting
|
||||||
* arguments as the arguments will no longer match
|
* arguments as the arguments will no longer match
|
||||||
* the format specs.
|
* the format specs.
|
||||||
*/
|
*/
|
||||||
stop = 1;
|
stop = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PCHAR(0);
|
PCHAR(0);
|
||||||
return retval;
|
return retval;
|
||||||
#undef PCHAR
|
#undef PCHAR
|
||||||
}
|
}
|
||||||
|
|
||||||
int vsprintf(char *dest, const char *fmt, va_list ap)
|
int vsprintf(char *dest, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
return kvsprintf(fmt, dest, 10, ap);
|
return kvsprintf(fmt, dest, 10, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sprintf(char *dest, const char *fmt, ...)
|
sprintf(char *dest, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
/* http://www.pagetable.com/?p=298 */
|
/* http://www.pagetable.com/?p=298 */
|
||||||
int retval;
|
int retval;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
retval = kvsprintf(fmt, dest, 10, ap);
|
retval = kvsprintf(fmt, dest, 10, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
return retval;
|
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)
|
static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size)
|
||||||
{
|
{
|
||||||
uint8_t *allocated_memory;
|
uint8_t *allocated_memory;
|
||||||
|
|
||||||
allocated_memory = next_free_memory;
|
allocated_memory = next_free_memory;
|
||||||
next_free_memory += items*size;
|
next_free_memory += items*size;
|
||||||
return allocated_memory;
|
return allocated_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inflate_free(voidpf opaque, voidpf address)
|
static void inflate_free(voidpf opaque, voidpf address)
|
||||||
{
|
{
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uncompress_data_section(void)
|
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
|
// initialize zstream structure
|
||||||
data_section.next_in = (uint8_t *) &__data_src_start__;
|
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.avail_in = &__data_end__ - &__data_start__; // uncompressed size. Wrong but doesn't matter.
|
||||||
data_section.next_out = (uint8_t *) &__data_start__;
|
data_section.next_out = (uint8_t *) &__data_start__;
|
||||||
data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
|
data_section.avail_out = &__data_end__ - &__data_start__; // uncompressed size. Correct.
|
||||||
data_section.zalloc = &inflate_malloc;
|
data_section.zalloc = &inflate_malloc;
|
||||||
data_section.zfree = &inflate_free;
|
data_section.zfree = &inflate_free;
|
||||||
data_section.opaque = NULL;
|
data_section.opaque = NULL;
|
||||||
|
|
||||||
// initialize zlib for inflate
|
// initialize zlib for inflate
|
||||||
inflateInit2(&data_section, 15);
|
inflateInit2(&data_section, 15);
|
||||||
|
|
||||||
// uncompress data segment to RAM
|
// uncompress data segment to RAM
|
||||||
inflate(&data_section, Z_FINISH);
|
inflate(&data_section, Z_FINISH);
|
||||||
|
|
||||||
// save the size of the compressed data section
|
// save the size of the compressed data section
|
||||||
common_area.arg1 = data_section.total_in;
|
common_area.arg1 = data_section.total_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((section(".startos"))) Vector(void)
|
void __attribute__((section(".startos"))) Vector(void)
|
||||||
{
|
{
|
||||||
/* Stack should have been set up by the bootloader */
|
/* Stack should have been set up by the bootloader */
|
||||||
// char *src;
|
// char *src;
|
||||||
char *dst, *end;
|
char *dst, *end;
|
||||||
|
|
||||||
uncompress_data_section();
|
uncompress_data_section();
|
||||||
|
|
||||||
/* Set up (that is: clear) BSS. */
|
/* Set up (that is: clear) BSS. */
|
||||||
dst = &__bss_start__;
|
dst = &__bss_start__;
|
||||||
end = &__bss_end__;
|
end = &__bss_end__;
|
||||||
while(dst < end) *dst++ = 0;
|
while(dst < end) *dst++ = 0;
|
||||||
|
|
||||||
// Set up data segment: Copy from flash to ram
|
// Set up data segment: Copy from flash to ram
|
||||||
// src = &__data_src_start__;
|
// src = &__data_src_start__;
|
||||||
// dst = &__data_start__;
|
// dst = &__data_start__;
|
||||||
// end = &__data_end__;
|
// end = &__data_end__;
|
||||||
// while(dst < end) *dst++ = *src++;
|
// while(dst < end) *dst++ = *src++;
|
||||||
|
|
||||||
AppMain();
|
AppMain();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
|
@ -11,39 +11,39 @@
|
||||||
|
|
||||||
void *memcpy(void *dest, const void *src, int len)
|
void *memcpy(void *dest, const void *src, int len)
|
||||||
{
|
{
|
||||||
uint8_t *d = dest;
|
uint8_t *d = dest;
|
||||||
const uint8_t *s = src;
|
const uint8_t *s = src;
|
||||||
while((len--) > 0) {
|
while((len--) > 0) {
|
||||||
*d = *s;
|
*d = *s;
|
||||||
d++;
|
d++;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *memset(void *dest, int c, int len)
|
void *memset(void *dest, int c, int len)
|
||||||
{
|
{
|
||||||
uint8_t *d = dest;
|
uint8_t *d = dest;
|
||||||
while((len--) > 0) {
|
while((len--) > 0) {
|
||||||
*d = c;
|
*d = c;
|
||||||
d++;
|
d++;
|
||||||
}
|
}
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
int memcmp(const void *av, const void *bv, int len)
|
int memcmp(const void *av, const void *bv, int len)
|
||||||
{
|
{
|
||||||
const uint8_t *a = av;
|
const uint8_t *a = av;
|
||||||
const uint8_t *b = bv;
|
const uint8_t *b = bv;
|
||||||
|
|
||||||
while((len--) > 0) {
|
while((len--) > 0) {
|
||||||
if(*a != *b) {
|
if(*a != *b) {
|
||||||
return *a - *b;
|
return *a - *b;
|
||||||
}
|
}
|
||||||
a++;
|
a++;
|
||||||
b++;
|
b++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memxor(uint8_t * dest, uint8_t * src, size_t len) {
|
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 strlen(const char *str)
|
||||||
{
|
{
|
||||||
int l = 0;
|
int l = 0;
|
||||||
while(*str) {
|
while(*str) {
|
||||||
l++;
|
l++;
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* strncat(char *dest, const char *src, unsigned int n)
|
char* strncat(char *dest, const char *src, unsigned int n)
|
||||||
{
|
{
|
||||||
unsigned int dest_len = strlen(dest);
|
unsigned int dest_len = strlen(dest);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0 ; i < n && src[i] != '\0' ; i++)
|
for (i = 0 ; i < n && src[i] != '\0' ; i++)
|
||||||
dest[dest_len + i] = src[i];
|
dest[dest_len + i] = src[i];
|
||||||
dest[dest_len + i] = '\0';
|
dest[dest_len + i] = '\0';
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* strcat(char *dest, const char *src)
|
char* strcat(char *dest, const char *src)
|
||||||
{
|
{
|
||||||
unsigned int dest_len = strlen(dest);
|
unsigned int dest_len = strlen(dest);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0 ; src[i] != '\0' ; i++)
|
for (i = 0 ; src[i] != '\0' ; i++)
|
||||||
dest[dest_len + i] = src[i];
|
dest[dest_len + i] = src[i];
|
||||||
dest[dest_len + i] = '\0';
|
dest[dest_len + i] = '\0';
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
////////////////////////////////////////// code to do 'itoa'
|
////////////////////////////////////////// code to do 'itoa'
|
||||||
|
|
||||||
|
|
280
armsrc/ticks.c
280
armsrc/ticks.c
|
@ -12,160 +12,160 @@
|
||||||
// attempt at high resolution microsecond timer
|
// attempt at high resolution microsecond timer
|
||||||
// beware: timer counts in 21.3uS increments (1024/48Mhz)
|
// beware: timer counts in 21.3uS increments (1024/48Mhz)
|
||||||
void SpinDelayUs(int us) {
|
void SpinDelayUs(int us) {
|
||||||
int ticks = (48 * us) >> 10;
|
int ticks = (48 * us) >> 10;
|
||||||
|
|
||||||
// Borrow a PWM unit for my real-time clock
|
// Borrow a PWM unit for my real-time clock
|
||||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||||
|
|
||||||
// 48 MHz / 1024 gives 46.875 kHz
|
// 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_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_CDTYR = 0; // Channel Duty Cycle Register
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; // Channel Period 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(;;) {
|
for(;;) {
|
||||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||||
if (now == (uint16_t)(start + ticks))
|
if (now == (uint16_t)(start + ticks))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpinDelay(int ms) {
|
void SpinDelay(int ms) {
|
||||||
// convert to uS and call microsecond delay function
|
// convert to uS and call microsecond delay function
|
||||||
SpinDelayUs(ms*1000);
|
SpinDelayUs(ms*1000);
|
||||||
}
|
}
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// timer lib
|
// timer lib
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// test procedure:
|
// test procedure:
|
||||||
//
|
//
|
||||||
// ti = GetTickCount();
|
// ti = GetTickCount();
|
||||||
// SpinDelay(1000);
|
// SpinDelay(1000);
|
||||||
// ti = GetTickCount() - ti;
|
// ti = GetTickCount() - ti;
|
||||||
// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
|
// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
|
||||||
void StartTickCount(void) {
|
void StartTickCount(void) {
|
||||||
// This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
|
// 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.
|
// 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
|
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency
|
||||||
// set RealTimeCounter divider to count at 1kHz:
|
// set RealTimeCounter divider to count at 1kHz:
|
||||||
AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((256000 + (mainf/2)) / mainf);
|
AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((256000 + (mainf/2)) / mainf);
|
||||||
// note: worst case precision is approx 2.5%
|
// note: worst case precision is approx 2.5%
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the current count.
|
* Get the current count.
|
||||||
*/
|
*/
|
||||||
uint32_t RAMFUNC GetTickCount(void){
|
uint32_t RAMFUNC GetTickCount(void){
|
||||||
return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2;
|
return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// microseconds timer
|
// microseconds timer
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
void StartCountUS(void) {
|
void StartCountUS(void) {
|
||||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
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_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||||
|
|
||||||
// fast clock
|
// fast clock
|
||||||
// tick=1.5mks
|
// tick=1.5mks
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
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_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_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_ACPA_CLEAR |
|
||||||
AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET;
|
AT91C_TC_ACPC_SET | AT91C_TC_ASWTRG_SET;
|
||||||
AT91C_BASE_TC0->TC_RA = 1;
|
AT91C_BASE_TC0->TC_RA = 1;
|
||||||
AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000
|
AT91C_BASE_TC0->TC_RC = 0xBFFF + 1; // 0xC000
|
||||||
|
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // timer disable
|
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_CMR = AT91C_TC_CLKS_XC1; // from timer 0
|
||||||
|
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
AT91C_BASE_TC1->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_TCB->TCB_BCR = 1;
|
||||||
|
|
||||||
while (AT91C_BASE_TC1->TC_CV > 0);
|
while (AT91C_BASE_TC1->TC_CV > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t RAMFUNC GetCountUS(void){
|
uint32_t RAMFUNC GetCountUS(void){
|
||||||
//return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10);
|
//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
|
// 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 ((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
|
// Timer for iso14443 commands. Uses ssp_clk from FPGA
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
void StartCountSspClk(void) {
|
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_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_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1
|
||||||
| AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none
|
| AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none
|
||||||
| AT91C_TCB_TC2XC2S_TIOA0; // XC2 Clock = TIOA0
|
| 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:
|
// 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_CCR = AT91C_TC_CLKDIS; // disable TC1
|
||||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK // TC1 Clock = MCK(48MHz)/2 = 24MHz
|
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_CPCSTOP // Stop clock on RC compare
|
||||||
| AT91C_TC_EEVTEDG_RISING // Trigger on rising edge of Event
|
| 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_EEVT_TIOB // Event-Source: TIOB1 (= ssp_clk from FPGA = 13,56MHz/16)
|
||||||
| AT91C_TC_ENETRG // Enable external trigger event
|
| AT91C_TC_ENETRG // Enable external trigger event
|
||||||
| AT91C_TC_WAVESEL_UP // Upmode without automatic trigger on RC compare
|
| AT91C_TC_WAVESEL_UP // Upmode without automatic trigger on RC compare
|
||||||
| AT91C_TC_WAVE // Waveform Mode
|
| AT91C_TC_WAVE // Waveform Mode
|
||||||
| AT91C_TC_AEEVT_SET // Set TIOA1 on external event
|
| AT91C_TC_AEEVT_SET // Set TIOA1 on external event
|
||||||
| AT91C_TC_ACPC_CLEAR; // Clear TIOA1 on RC Compare
|
| AT91C_TC_ACPC_CLEAR; // Clear TIOA1 on RC Compare
|
||||||
AT91C_BASE_TC1->TC_RC = 0x04; // RC Compare value = 0x04
|
AT91C_BASE_TC1->TC_RC = 0x04; // RC Compare value = 0x04
|
||||||
|
|
||||||
// use TC0 to count TIOA1 pulses
|
// use TC0 to count TIOA1 pulses
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // disable TC0
|
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_BASE_TC0->TC_CMR = AT91C_TC_CLKS_XC0 // TC0 clock = XC0 clock = TIOA1
|
||||||
| AT91C_TC_WAVE // Waveform Mode
|
| AT91C_TC_WAVE // Waveform Mode
|
||||||
| AT91C_TC_WAVESEL_UP // just count
|
| AT91C_TC_WAVESEL_UP // just count
|
||||||
| AT91C_TC_ACPA_CLEAR // Clear TIOA0 on RA Compare
|
| AT91C_TC_ACPA_CLEAR // Clear TIOA0 on RA Compare
|
||||||
| AT91C_TC_ACPC_SET; // Set TIOA0 on RC 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_RA = 1; // RA Compare value = 1; pulse width to TC2
|
||||||
AT91C_BASE_TC0->TC_RC = 0; // RC Compare value = 0; increment TC2 on overflow
|
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)
|
// 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_CCR = AT91C_TC_CLKDIS; // disable TC2
|
||||||
AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_XC2 // TC2 clock = XC2 clock = TIOA0
|
AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_XC2 // TC2 clock = XC2 clock = TIOA0
|
||||||
| AT91C_TC_WAVE // Waveform Mode
|
| AT91C_TC_WAVE // Waveform Mode
|
||||||
| AT91C_TC_WAVESEL_UP; // just count
|
| AT91C_TC_WAVESEL_UP; // just count
|
||||||
|
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC0
|
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_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_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // enable and reset TC2
|
||||||
|
|
||||||
// synchronize the counter with the ssp_frame signal.
|
// synchronize the counter with the ssp_frame signal.
|
||||||
// Note: FPGA must be in any iso14443 mode, otherwise the frame signal would not be present
|
// 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 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_FRAME); // wait for ssp_frame to be low
|
||||||
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high
|
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
|
// 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
|
// 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)
|
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 (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,
|
// 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.
|
// 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).
|
// (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.
|
// 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.
|
// Therefore need to wait quite some time before we can use the counter.
|
||||||
while (AT91C_BASE_TC2->TC_CV > 0);
|
while (AT91C_BASE_TC2->TC_CV > 0);
|
||||||
}
|
}
|
||||||
void ResetSspClk(void) {
|
void ResetSspClk(void) {
|
||||||
//enable clock of timer and software trigger
|
//enable clock of timer and software trigger
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
AT91C_BASE_TC1->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;
|
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
while (AT91C_BASE_TC2->TC_CV > 0);
|
while (AT91C_BASE_TC2->TC_CV > 0);
|
||||||
}
|
}
|
||||||
uint32_t RAMFUNC GetCountSspClk(void) {
|
uint32_t RAMFUNC GetCountSspClk(void) {
|
||||||
uint32_t tmp_count = (AT91C_BASE_TC2->TC_CV << 16) | AT91C_BASE_TC0->TC_CV;
|
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
|
if ((tmp_count & 0x0000ffff) == 0) //small chance that we may have missed an increment in TC2
|
||||||
return (AT91C_BASE_TC2->TC_CV << 16);
|
return (AT91C_BASE_TC2->TC_CV << 16);
|
||||||
return tmp_count;
|
return tmp_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
@ -173,68 +173,68 @@ uint32_t RAMFUNC GetCountSspClk(void) {
|
||||||
// 1us = 1.5ticks
|
// 1us = 1.5ticks
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
void StartTicks(void){
|
void StartTicks(void){
|
||||||
// initialization of the timer
|
// initialization of the timer
|
||||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
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_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
|
||||||
|
|
||||||
// disable TC0 and TC1 for re-configuration
|
// disable TC0 and TC1 for re-configuration
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
|
|
||||||
// first configure TC1 (higher, 0xFFFF0000) 16 bit counter
|
// 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_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
|
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
|
// second configure TC0 (lower, 0x0000FFFF) 16 bit counter
|
||||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
|
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
|
||||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO |
|
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO |
|
||||||
AT91C_TC_ACPA_CLEAR | // RA comperator clears TIOA (carry bit)
|
AT91C_TC_ACPA_CLEAR | // RA comperator clears TIOA (carry bit)
|
||||||
AT91C_TC_ACPC_SET | // RC comperator sets TIOA (carry bit)
|
AT91C_TC_ACPC_SET | // RC comperator sets TIOA (carry bit)
|
||||||
AT91C_TC_ASWTRG_SET; // SWTriger 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_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_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
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // reset and re-enable timer
|
||||||
|
|
||||||
// synchronized startup procedure
|
// synchronized startup procedure
|
||||||
while (AT91C_BASE_TC0->TC_CV > 0); // wait until TC0 returned to zero
|
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)
|
while (AT91C_BASE_TC0->TC_CV < 2); // and has started (TC_CV > TC_RA, now TC1 is cleared)
|
||||||
|
|
||||||
// return to zero
|
// return to zero
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||||
while (AT91C_BASE_TC0->TC_CV > 0);
|
while (AT91C_BASE_TC0->TC_CV > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetTicks(void) {
|
uint32_t GetTicks(void) {
|
||||||
uint32_t hi, lo;
|
uint32_t hi, lo;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
hi = AT91C_BASE_TC1->TC_CV;
|
hi = AT91C_BASE_TC1->TC_CV;
|
||||||
lo = AT91C_BASE_TC0->TC_CV;
|
lo = AT91C_BASE_TC0->TC_CV;
|
||||||
} while(hi != AT91C_BASE_TC1->TC_CV);
|
} while(hi != AT91C_BASE_TC1->TC_CV);
|
||||||
|
|
||||||
return (hi << 16) | lo;
|
return (hi << 16) | lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait - Spindelay in ticks.
|
// Wait - Spindelay in ticks.
|
||||||
// if called with a high number, this will trigger the WDT...
|
// if called with a high number, this will trigger the WDT...
|
||||||
void WaitTicks(uint32_t ticks){
|
void WaitTicks(uint32_t ticks){
|
||||||
if ( ticks == 0 ) return;
|
if ( ticks == 0 ) return;
|
||||||
ticks += GetTicks();
|
ticks += GetTicks();
|
||||||
while (GetTicks() < ticks);
|
while (GetTicks() < ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait / Spindelay in us (microseconds)
|
// Wait / Spindelay in us (microseconds)
|
||||||
// 1us = 1.5ticks.
|
// 1us = 1.5ticks.
|
||||||
void WaitUS(uint16_t us){
|
void WaitUS(uint16_t us){
|
||||||
WaitTicks( (uint32_t)us * 3/2 );
|
WaitTicks( (uint32_t)us * 3/2 );
|
||||||
}
|
}
|
||||||
void WaitMS(uint16_t ms){
|
void WaitMS(uint16_t ms){
|
||||||
WaitTicks( (uint32_t)ms * 1500 );
|
WaitTicks( (uint32_t)ms * 1500 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop clock
|
// stop clock
|
||||||
void StopTicks(void){
|
void StopTicks(void){
|
||||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||||
AT91C_BASE_TC1->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"
|
#include "util.h"
|
||||||
|
|
||||||
size_t nbytes(size_t nbits) {
|
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
|
Example: reflect(0x3e23L,3) == 0x3e26
|
||||||
*/
|
*/
|
||||||
uint32_t reflect(uint32_t v, int b) {
|
uint32_t reflect(uint32_t v, int b) {
|
||||||
uint32_t t = v;
|
uint32_t t = v;
|
||||||
for ( int i = 0; i < b; ++i) {
|
for ( int i = 0; i < b; ++i) {
|
||||||
if (t & 1)
|
if (t & 1)
|
||||||
v |= BITMASK((b-1)-i);
|
v |= BITMASK((b-1)-i);
|
||||||
else
|
else
|
||||||
v &= ~BITMASK((b-1)-i);
|
v &= ~BITMASK((b-1)-i);
|
||||||
t>>=1;
|
t>>=1;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t reflect8(uint8_t b) {
|
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 reflect16(uint16_t b) {
|
||||||
uint16_t v = 0;
|
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) {
|
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest) {
|
||||||
while (len--) {
|
while (len--) {
|
||||||
dest[len] = (uint8_t) n;
|
dest[len] = (uint8_t) n;
|
||||||
n >>= 8;
|
n >>= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t bytes_to_num(uint8_t* src, size_t len) {
|
uint64_t bytes_to_num(uint8_t* src, size_t len) {
|
||||||
uint64_t num = 0;
|
uint64_t num = 0;
|
||||||
while (len--) {
|
while (len--) {
|
||||||
num = (num << 8) | (*src);
|
num = (num << 8) | (*src);
|
||||||
src++;
|
src++;
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RotateLeft - Ultralight, Desfire
|
// RotateLeft - Ultralight, Desfire
|
||||||
|
@ -107,11 +107,11 @@ uint8_t hex2int(char hexchar){
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'A': return 10; break;
|
case 'A': return 10; break;
|
||||||
case 'b':
|
case 'b':
|
||||||
case 'B': return 11; break;
|
case 'B': return 11; break;
|
||||||
case 'c':
|
case 'c':
|
||||||
case 'C': return 12; break;
|
case 'C': return 12; break;
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'D': return 13; break;
|
case 'D': return 13; break;
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'E': return 14; break;
|
case 'E': return 14; break;
|
||||||
case 'f':
|
case 'f':
|
||||||
|
@ -122,36 +122,36 @@ uint8_t hex2int(char hexchar){
|
||||||
}
|
}
|
||||||
|
|
||||||
void LEDsoff() {
|
void LEDsoff() {
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
// LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]
|
// LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]
|
||||||
void LED(int led, int ms) {
|
void LED(int led, int ms) {
|
||||||
if (led & LED_RED)
|
if (led & LED_RED)
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
if (led & LED_ORANGE)
|
if (led & LED_ORANGE)
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
if (led & LED_GREEN)
|
if (led & LED_GREEN)
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
if (led & LED_RED2)
|
if (led & LED_RED2)
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
|
||||||
if (!ms)
|
if (!ms)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SpinDelay(ms);
|
SpinDelay(ms);
|
||||||
|
|
||||||
if (led & LED_RED)
|
if (led & LED_RED)
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
if (led & LED_ORANGE)
|
if (led & LED_ORANGE)
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
if (led & LED_GREEN)
|
if (led & LED_GREEN)
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
if (led & LED_RED2)
|
if (led & LED_RED2)
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpinOff(uint32_t pause) {
|
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) {
|
void SpinErr(uint8_t led, uint32_t speed, uint8_t times) {
|
||||||
SpinOff(speed);
|
SpinOff(speed);
|
||||||
NTIME(times)
|
NTIME(times)
|
||||||
{
|
{
|
||||||
switch (led) {
|
switch (led) {
|
||||||
case 0:
|
case 0:
|
||||||
LED_A_INV();
|
LED_A_INV();
|
||||||
|
@ -223,102 +223,102 @@ void SpinUp(uint32_t speed) {
|
||||||
// In general, don't use this function unless you expect a
|
// In general, don't use this function unless you expect a
|
||||||
// double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
|
// double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
|
||||||
int BUTTON_CLICKED(int ms) {
|
int BUTTON_CLICKED(int ms) {
|
||||||
// Up to 500ms in between clicks to mean a double click
|
// Up to 500ms in between clicks to mean a double click
|
||||||
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
|
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
|
||||||
|
|
||||||
// If we're not even pressed, forget about it!
|
// If we're not even pressed, forget about it!
|
||||||
if (!BUTTON_PRESS())
|
if (!BUTTON_PRESS())
|
||||||
return BUTTON_NO_CLICK;
|
return BUTTON_NO_CLICK;
|
||||||
|
|
||||||
// Borrow a PWM unit for my real-time clock
|
// Borrow a PWM unit for my real-time clock
|
||||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||||
// 48 MHz / 1024 gives 46.875 kHz
|
// 48 MHz / 1024 gives 46.875 kHz
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
|
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;
|
int letoff = 0;
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||||
|
|
||||||
// We haven't let off the button yet
|
// We haven't let off the button yet
|
||||||
if (!letoff)
|
if (!letoff)
|
||||||
{
|
{
|
||||||
// We just let it off!
|
// We just let it off!
|
||||||
if (!BUTTON_PRESS())
|
if (!BUTTON_PRESS())
|
||||||
{
|
{
|
||||||
letoff = 1;
|
letoff = 1;
|
||||||
|
|
||||||
// reset our timer for 500ms
|
// reset our timer for 500ms
|
||||||
start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||||
ticks = (48000 * (500)) >> 10;
|
ticks = (48000 * (500)) >> 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Still haven't let it off
|
// Still haven't let it off
|
||||||
else
|
else
|
||||||
// Have we held down a full second?
|
// Have we held down a full second?
|
||||||
if (now == (uint16_t)(start + ticks))
|
if (now == (uint16_t)(start + ticks))
|
||||||
return BUTTON_HOLD;
|
return BUTTON_HOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We already let off, did we click again?
|
// We already let off, did we click again?
|
||||||
else
|
else
|
||||||
// Sweet, double click!
|
// Sweet, double click!
|
||||||
if (BUTTON_PRESS())
|
if (BUTTON_PRESS())
|
||||||
return BUTTON_DOUBLE_CLICK;
|
return BUTTON_DOUBLE_CLICK;
|
||||||
|
|
||||||
// Have we ran out of time to double click?
|
// Have we ran out of time to double click?
|
||||||
else
|
else
|
||||||
if (now == (uint16_t)(start + ticks))
|
if (now == (uint16_t)(start + ticks))
|
||||||
// At least we did a single click
|
// At least we did a single click
|
||||||
return BUTTON_SINGLE_CLICK;
|
return BUTTON_SINGLE_CLICK;
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should never get here
|
// We should never get here
|
||||||
return BUTTON_ERROR;
|
return BUTTON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if a button is held down
|
// Determine if a button is held down
|
||||||
int BUTTON_HELD(int ms) {
|
int BUTTON_HELD(int ms) {
|
||||||
// If button is held for one second
|
// If button is held for one second
|
||||||
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
|
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
|
||||||
|
|
||||||
// If we're not even pressed, forget about it!
|
// If we're not even pressed, forget about it!
|
||||||
if (!BUTTON_PRESS())
|
if (!BUTTON_PRESS())
|
||||||
return BUTTON_NO_CLICK;
|
return BUTTON_NO_CLICK;
|
||||||
|
|
||||||
// Borrow a PWM unit for my real-time clock
|
// Borrow a PWM unit for my real-time clock
|
||||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||||
// 48 MHz / 1024 gives 46.875 kHz
|
// 48 MHz / 1024 gives 46.875 kHz
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
|
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(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
|
||||||
|
|
||||||
// As soon as our button let go, we didn't hold long enough
|
// As soon as our button let go, we didn't hold long enough
|
||||||
if (!BUTTON_PRESS())
|
if (!BUTTON_PRESS())
|
||||||
return BUTTON_SINGLE_CLICK;
|
return BUTTON_SINGLE_CLICK;
|
||||||
|
|
||||||
// Have we waited the full second?
|
// Have we waited the full second?
|
||||||
else
|
else
|
||||||
if (now == (uint16_t)(start + ticks))
|
if (now == (uint16_t)(start + ticks))
|
||||||
return BUTTON_HOLD;
|
return BUTTON_HOLD;
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We should never get here
|
// We should never get here
|
||||||
return BUTTON_ERROR;
|
return BUTTON_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Similar to FpgaGatherVersion this formats stored version information
|
/* Similar to FpgaGatherVersion this formats stored version information
|
||||||
|
@ -327,30 +327,30 @@ int BUTTON_HELD(int ms) {
|
||||||
* prefix in dst.
|
* prefix in dst.
|
||||||
*/
|
*/
|
||||||
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information) {
|
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information) {
|
||||||
struct version_information *v = (struct version_information*)version_information;
|
struct version_information *v = (struct version_information*)version_information;
|
||||||
dst[0] = 0;
|
dst[0] = 0;
|
||||||
strncat(dst, prefix, len-1);
|
strncat(dst, prefix, len-1);
|
||||||
if (v->magic != VERSION_INFORMATION_MAGIC) {
|
if (v->magic != VERSION_INFORMATION_MAGIC) {
|
||||||
strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1);
|
strncat(dst, "Missing/Invalid version information\n", len - strlen(dst) - 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (v->versionversion != 1) {
|
if (v->versionversion != 1) {
|
||||||
strncat(dst, "Version information not understood\n", len - strlen(dst) - 1);
|
strncat(dst, "Version information not understood\n", len - strlen(dst) - 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!v->present) {
|
if (!v->present) {
|
||||||
strncat(dst, "Version information not available\n", len - strlen(dst) - 1);
|
strncat(dst, "Version information not available\n", len - strlen(dst) - 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncat(dst, v->gitversion, len - strlen(dst) - 1);
|
strncat(dst, v->gitversion, len - strlen(dst) - 1);
|
||||||
if (v->clean == 0) {
|
if (v->clean == 0) {
|
||||||
strncat(dst, "-unclean", len - strlen(dst) - 1);
|
strncat(dst, "-unclean", len - strlen(dst) - 1);
|
||||||
} else if (v->clean == 2) {
|
} else if (v->clean == 2) {
|
||||||
strncat(dst, "-suspect", len - strlen(dst) - 1);
|
strncat(dst, "-suspect", len - strlen(dst) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncat(dst, " ", len - strlen(dst) - 1);
|
strncat(dst, " ", len - strlen(dst) - 1);
|
||||||
strncat(dst, v->buildtime, len - strlen(dst) - 1);
|
strncat(dst, v->buildtime, len - strlen(dst) - 1);
|
||||||
strncat(dst, "\n", len - strlen(dst) - 1);
|
strncat(dst, "\n", len - strlen(dst) - 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,8 @@
|
||||||
size_t nbytes(size_t nbits);
|
size_t nbytes(size_t nbits);
|
||||||
|
|
||||||
extern uint32_t reflect(uint32_t v, int b); // used in crc.c ...
|
extern uint32_t reflect(uint32_t v, int b); // used in crc.c ...
|
||||||
extern uint8_t reflect8(uint8_t b); // dedicated 8bit reversal
|
extern uint8_t reflect8(uint8_t b); // dedicated 8bit reversal
|
||||||
extern uint16_t reflect16(uint16_t b); // dedicated 16bit reversal
|
extern uint16_t reflect16(uint16_t b); // dedicated 16bit reversal
|
||||||
|
|
||||||
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
|
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
|
||||||
uint64_t bytes_to_num(uint8_t* src, size_t len);
|
uint64_t bytes_to_num(uint8_t* src, size_t len);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue