Pushed standard AT91 defines into main code

This commit is contained in:
d18c7db 2009-09-29 12:13:41 +00:00
commit 6949aca9fa
16 changed files with 1368 additions and 1521 deletions

View file

@ -5,10 +5,10 @@
void LCDSend(unsigned int data)
{
// 9th bit set for data, clear for command
while ((SPI_STATUS & SPI_STATUS_TX_EMPTY) == 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
// bit set since they're implemented as defines, se we need to invert bit
SPI_TX_DATA = 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)
@ -86,10 +86,10 @@ void LCDReset(void)
{
LED_A_ON();
SetupSpi(SPI_LCD_MODE);
LCD_RESET_LOW();
LOW(GPIO_LRST);
SpinDelay(100);
LCD_RESET_HIGH();
HIGH(GPIO_LRST);
SpinDelay(100);
LED_A_OFF();
}

View file

@ -1,9 +1,6 @@
#ifndef __LCD
#define __LCD
#define LCD_RESET_HIGH() PIO_OUTPUT_DATA_SET |= (1<<GPIO_LRST)
#define LCD_RESET_LOW() PIO_OUTPUT_DATA_CLEAR |= (1<<GPIO_LRST)
// The resolution of the LCD
#define LCD_XRES 132
#define LCD_YRES 132

File diff suppressed because it is too large Load diff

View file

@ -34,33 +34,33 @@ void FpgaGatherVersion(char *dst, int len);
void FpgaSetupSsc(void);
void SetupSpi(int mode);
void FpgaSetupSscDma(BYTE *buf, int len);
void SetAdcMuxFor(int whichGpio);
void SetAdcMuxFor(DWORD whichGpio);
// Definitions for the FPGA commands.
#define FPGA_CMD_SET_CONFREG (1<<12)
#define FPGA_CMD_SET_DIVISOR (2<<12)
#define FPGA_CMD_SET_CONFREG (1<<12)
#define FPGA_CMD_SET_DIVISOR (2<<12)
// Definitions for the FPGA configuration word.
#define FPGA_MAJOR_MODE_LF_READER (0<<5)
#define FPGA_MAJOR_MODE_LF_READER (0<<5)
#define FPGA_MAJOR_MODE_LF_SIMULATOR (1<<5)
#define FPGA_MAJOR_MODE_HF_READER_TX (2<<5)
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (3<<5)
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (3<<5)
#define FPGA_MAJOR_MODE_HF_SIMULATOR (4<<5)
#define FPGA_MAJOR_MODE_HF_ISO14443A (5<<5)
#define FPGA_MAJOR_MODE_LF_PASSTHRU (6<<5)
#define FPGA_MAJOR_MODE_OFF (7<<5)
#define FPGA_MAJOR_MODE_OFF (7<<5)
// Options for the HF reader, tx to tag
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
// Options for the HF reader, correlating against rx from tag
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
// Options for the HF simulated tag, how to modulate
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
// Options for ISO14443A
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
#define FPGA_HF_ISO14443A_TAGSIM_MOD (2<<0)
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
/// lfops.h

View file

@ -21,27 +21,29 @@ void SetupSpi(int mode)
// PA14 -> SPI_SPCK Serial Clock
// Disable PIO control of the following pins, allows use by the SPI peripheral
PIO_DISABLE = (1 << GPIO_NCS0) |
(1 << GPIO_NCS2) |
(1 << GPIO_MISO) |
(1 << GPIO_MOSI) |
(1 << GPIO_SPCK);
AT91C_BASE_PIOA->PIO_PDR =
GPIO_NCS0 |
GPIO_NCS2 |
GPIO_MISO |
GPIO_MOSI |
GPIO_SPCK;
PIO_PERIPHERAL_A_SEL = (1 << GPIO_NCS0) |
(1 << GPIO_MISO) |
(1 << GPIO_MOSI) |
(1 << GPIO_SPCK);
AT91C_BASE_PIOA->PIO_ASR =
GPIO_NCS0 |
GPIO_MISO |
GPIO_MOSI |
GPIO_SPCK;
PIO_PERIPHERAL_B_SEL = (1 << GPIO_NCS2);
AT91C_BASE_PIOA->PIO_BSR = GPIO_NCS2;
//enable the SPI Peripheral clock
PMC_PERIPHERAL_CLK_ENABLE = (1<<PERIPH_SPI);
AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_SPI);
// Enable SPI
SPI_CONTROL = SPI_CONTROL_ENABLE;
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
switch (mode) {
case SPI_FPGA_MODE:
SPI_MODE =
AT91C_BASE_SPI->SPI_MR =
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
(14 << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
( 0 << 7) | // Local Loopback Disabled
@ -49,7 +51,7 @@ void SetupSpi(int mode)
( 0 << 2) | // Chip selects connected directly to peripheral
( 0 << 1) | // Fixed Peripheral Select
( 1 << 0); // Master Mode
SPI_FOR_CHIPSEL_0 =
AT91C_BASE_SPI->SPI_CSR[0] =
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
( 1 << 16) | // Delay Before SPCK (1 MCK period)
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
@ -59,7 +61,7 @@ void SetupSpi(int mode)
( 0 << 0); // Clock Polarity inactive state is logic 0
break;
case SPI_LCD_MODE:
SPI_MODE =
AT91C_BASE_SPI->SPI_MR =
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
(11 << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
( 0 << 7) | // Local Loopback Disabled
@ -67,7 +69,7 @@ void SetupSpi(int mode)
( 0 << 2) | // Chip selects connected directly to peripheral
( 0 << 1) | // Fixed Peripheral Select
( 1 << 0); // Master Mode
SPI_FOR_CHIPSEL_2 =
AT91C_BASE_SPI->SPI_CSR[2] =
( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
( 1 << 16) | // Delay Before SPCK (1 MCK period)
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
@ -77,7 +79,7 @@ void SetupSpi(int mode)
( 0 << 0); // Clock Polarity inactive state is logic 0
break;
default: // Disable SPI
SPI_CONTROL = SPI_CONTROL_DISABLE;
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
break;
}
}
@ -89,35 +91,36 @@ void SetupSpi(int mode)
void FpgaSetupSsc(void)
{
// First configure the GPIOs, and get ourselves a clock.
PIO_PERIPHERAL_A_SEL = (1 << GPIO_SSC_FRAME) |
(1 << GPIO_SSC_DIN) |
(1 << GPIO_SSC_DOUT) |
(1 << GPIO_SSC_CLK);
PIO_DISABLE = (1 << GPIO_SSC_DOUT);
AT91C_BASE_PIOA->PIO_ASR =
GPIO_SSC_FRAME |
GPIO_SSC_DIN |
GPIO_SSC_DOUT |
GPIO_SSC_CLK;
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
PMC_PERIPHERAL_CLK_ENABLE = (1 << PERIPH_SSC);
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SSC);
// Now set up the SSC proper, starting from a known state.
SSC_CONTROL = SSC_CONTROL_RESET;
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
// RX clock comes from TX clock, RX starts when TX starts, data changes
// on RX clock rising edge, sampled on falling edge
SSC_RECEIVE_CLOCK_MODE = 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
// pulse, no output sync, start on positive-going edge of sync
SSC_RECEIVE_FRAME_MODE = SSC_FRAME_MODE_BITS_IN_WORD(8) |
SSC_FRAME_MODE_MSB_FIRST | 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
// edge of TK, start on rising edge of TF
SSC_TRANSMIT_CLOCK_MODE = SSC_CLOCK_MODE_SELECT(2) |
AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) |
SSC_CLOCK_MODE_START(5);
// tx framing is the same as the rx framing
SSC_TRANSMIT_FRAME_MODE = SSC_RECEIVE_FRAME_MODE;
AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR;
SSC_CONTROL = SSC_CONTROL_RX_ENABLE | SSC_CONTROL_TX_ENABLE;
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
}
//-----------------------------------------------------------------------------
@ -128,11 +131,11 @@ void FpgaSetupSsc(void)
//-----------------------------------------------------------------------------
void FpgaSetupSscDma(BYTE *buf, int len)
{
PDC_RX_POINTER(SSC_BASE) = (DWORD)buf;
PDC_RX_COUNTER(SSC_BASE) = len;
PDC_RX_NEXT_POINTER(SSC_BASE) = (DWORD)buf;
PDC_RX_NEXT_COUNTER(SSC_BASE) = len;
PDC_CONTROL(SSC_BASE) = PDC_RX_ENABLE;
AT91C_BASE_PDC_SSC->PDC_RPR = (DWORD)buf;
AT91C_BASE_PDC_SSC->PDC_RCR = len;
AT91C_BASE_PDC_SSC->PDC_RNPR = (DWORD)buf;
AT91C_BASE_PDC_SSC->PDC_RNCR = len;
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
}
static void DownloadFPGA_byte(unsigned char w)
@ -154,8 +157,8 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
{
int i=0;
PIO_OUTPUT_ENABLE = (1 << GPIO_FPGA_ON);
PIO_ENABLE = (1 << GPIO_FPGA_ON);
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON;
HIGH(GPIO_FPGA_ON); // ensure everything is powered on
SpinDelay(50);
@ -163,20 +166,27 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
LED_D_ON();
// These pins are inputs
PIO_OUTPUT_DISABLE = (1 << GPIO_FPGA_NINIT) | (1 << GPIO_FPGA_DONE);
AT91C_BASE_PIOA->PIO_ODR =
GPIO_FPGA_NINIT |
GPIO_FPGA_DONE;
// PIO controls the following pins
PIO_ENABLE = (1 << GPIO_FPGA_NINIT) | (1 << GPIO_FPGA_DONE);
AT91C_BASE_PIOA->PIO_PER =
GPIO_FPGA_NINIT |
GPIO_FPGA_DONE;
// Enable pull-ups
PIO_NO_PULL_UP_DISABLE = (1 << GPIO_FPGA_NINIT) | (1 << GPIO_FPGA_DONE);
AT91C_BASE_PIOA->PIO_PPUER =
GPIO_FPGA_NINIT |
GPIO_FPGA_DONE;
// setup initial logic state
HIGH(GPIO_FPGA_NPROGRAM);
LOW(GPIO_FPGA_CCLK);
LOW(GPIO_FPGA_DIN);
// These pins are outputs
PIO_OUTPUT_ENABLE = (1 << GPIO_FPGA_NPROGRAM) |
(1 << GPIO_FPGA_CCLK) |
(1 << GPIO_FPGA_DIN);
AT91C_BASE_PIOA->PIO_OER =
GPIO_FPGA_NPROGRAM |
GPIO_FPGA_CCLK |
GPIO_FPGA_DIN;
// enter FPGA configuration mode
LOW(GPIO_FPGA_NPROGRAM);
@ -185,7 +195,7 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
i=100000;
// wait for FPGA ready to accept data signal
while ((i) && ( !(PIO_PIN_DATA_STATUS & (1<<GPIO_FPGA_NINIT) ) ) ) {
while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) {
i--;
}
@ -215,7 +225,7 @@ static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int byterevers
// continue to clock FPGA until ready signal goes high
i=100000;
while ( (i--) && ( !(PIO_PIN_DATA_STATUS & (1<<GPIO_FPGA_DONE) ) ) ) {
while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) {
HIGH(GPIO_FPGA_CCLK);
LOW(GPIO_FPGA_CCLK);
}
@ -235,7 +245,7 @@ static int bitparse_initialized;
* 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01
* After that the format is 1 byte section type (ASCII character), 2 byte length
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
* length.
* length.
*/
static const char _bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01};
static int bitparse_init(void * start_address, void *end_address)
@ -303,11 +313,11 @@ int bitparse_find_section(char section_name, char **section_start, unsigned int
extern char _binary_fpga_bit_start, _binary_fpga_bit_end;
void FpgaDownloadAndGo(void)
{
/* Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
/* Check for the new flash image format: Should have the .bit file at &_binary_fpga_bit_start
*/
if(bitparse_init(&_binary_fpga_bit_start, &_binary_fpga_bit_end)) {
/* Successfully initialized the .bit parser. Find the 'e' section and
* send its contents to the FPGA.
* send its contents to the FPGA.
*/
char *bitstream_start;
unsigned int bitstream_length;
@ -323,7 +333,7 @@ void FpgaDownloadAndGo(void)
* = 10,524 DWORDs, stored as DWORDS e.g. little-endian in memory, but each DWORD
* is still to be transmitted in MSBit first order. Set the invert flag to indicate
* that the DownloadFPGA function should invert every 4 byte sequence when doing
* the bytewise download.
* the bytewise download.
*/
if( *(DWORD*)0x102000 == 0xFFFFFFFF && *(DWORD*)0x102004 == 0xAA995566 )
DownloadFPGA((char*)0x102000, 10524*4, 1);
@ -368,8 +378,8 @@ void FpgaGatherVersion(char *dst, int len)
void FpgaSendCommand(WORD cmd, WORD v)
{
SetupSpi(SPI_FPGA_MODE);
while ((SPI_STATUS & SPI_STATUS_TX_EMPTY) == 0); // wait for the transfer to complete
SPI_TX_DATA = SPI_CONTROL_LAST_TRANSFER | cmd | v; // send the data
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
}
//-----------------------------------------------------------------------------
// Write the FPGA setup word (that determines what mode the logic is in, read
@ -386,17 +396,19 @@ void FpgaWriteConfWord(BYTE v)
// closable, but should only close one at a time. Not an FPGA thing, but
// the samples from the ADC always flow through the FPGA.
//-----------------------------------------------------------------------------
void SetAdcMuxFor(int whichGpio)
void SetAdcMuxFor(DWORD whichGpio)
{
PIO_OUTPUT_ENABLE = (1 << GPIO_MUXSEL_HIPKD) |
(1 << GPIO_MUXSEL_LOPKD) |
(1 << GPIO_MUXSEL_LORAW) |
(1 << GPIO_MUXSEL_HIRAW);
AT91C_BASE_PIOA->PIO_OER =
GPIO_MUXSEL_HIPKD |
GPIO_MUXSEL_LOPKD |
GPIO_MUXSEL_LORAW |
GPIO_MUXSEL_HIRAW;
PIO_ENABLE = (1 << GPIO_MUXSEL_HIPKD) |
(1 << GPIO_MUXSEL_LOPKD) |
(1 << GPIO_MUXSEL_LORAW) |
(1 << GPIO_MUXSEL_HIRAW);
AT91C_BASE_PIOA->PIO_PER =
GPIO_MUXSEL_HIPKD |
GPIO_MUXSEL_LOPKD |
GPIO_MUXSEL_LORAW |
GPIO_MUXSEL_HIRAW;
LOW(GPIO_MUXSEL_HIPKD);
LOW(GPIO_MUXSEL_HIRAW);

View file

@ -295,11 +295,11 @@ static BOOL GetIso14443CommandFromReader(BYTE *received, int *len, int maxLen)
if(BUTTON_PRESS()) return FALSE;
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x00;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00;
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
BYTE b = (BYTE)SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR;
mask = 0x80;
for(i = 0; i < 8; i++, mask >>= 1) {
@ -392,24 +392,24 @@ void SimulateIso14443Tag(void)
LED_D_OFF();
FpgaWriteConfWord(
FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
SSC_TRANSMIT_HOLDING = 0xff;
AT91C_BASE_SSC->SSC_THR = 0xff;
FpgaSetupSsc();
// Transmit the response.
i = 0;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
BYTE b = resp[i];
SSC_TRANSMIT_HOLDING = b;
AT91C_BASE_SSC->SSC_THR = b;
i++;
if(i > respLen) {
break;
}
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
volatile BYTE b = (BYTE)SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR;
(void)b;
}
}
@ -454,7 +454,7 @@ static struct {
*
* Returns: true if we received a EOF
* false if we are still waiting for some more
*
*
*/
static BOOL Handle14443SamplesDemod(int ci, int cq)
{
@ -612,7 +612,7 @@ static BOOL Handle14443SamplesDemod(int ci, int cq)
* Demodulate the samples we received from the tag
* weTx: set to 'TRUE' if we behave like a reader
* set to 'FALSE' if we behave like a snooper
* quiet: set to 'TRUE' to disable debug output
* quiet: set to 'TRUE' to disable debug output
*/
static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet)
{
@ -654,10 +654,10 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet)
(weTx ? 0 : FPGA_HF_READER_RX_XCORR_SNOOP));
for(;;) {
int behindBy = lastRxCounter - PDC_RX_COUNTER(SSC_BASE);
int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
if(behindBy > max) max = behindBy;
while(((lastRxCounter-PDC_RX_COUNTER(SSC_BASE)) & (DMA_BUFFER_SIZE-1))
while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1))
> 2)
{
ci = upTo[0];
@ -665,8 +665,8 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet)
upTo += 2;
if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
upTo -= DMA_BUFFER_SIZE;
PDC_RX_NEXT_POINTER(SSC_BASE) = (DWORD)upTo;
PDC_RX_NEXT_COUNTER(SSC_BASE) = DMA_BUFFER_SIZE;
AT91C_BASE_PDC_SSC->PDC_RNPR = (DWORD)upTo;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
lastRxCounter -= 2;
if(lastRxCounter <= 0) {
@ -687,7 +687,7 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet)
break;
}
}
PDC_CONTROL(SSC_BASE) = PDC_RX_DISABLE;
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
if (!quiet) DbpIntegers(max, gotFrame, Demod.len);
}
@ -707,12 +707,12 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet)
c = 0;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x43;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x43;
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
SBYTE b;
b = (SBYTE)SSC_RECEIVE_HOLDING;
b = (SBYTE)AT91C_BASE_SSC->SSC_RHR;
dest[c++] = (BYTE)b;
@ -732,8 +732,8 @@ static void TransmitFor14443(void)
FpgaSetupSsc();
while(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0xff;
while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0xff;
}
// Signal field is ON with the appropriate Red LED
@ -744,12 +744,12 @@ static void TransmitFor14443(void)
FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
for(c = 0; c < 10;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0xff;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0xff;
c++;
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
volatile DWORD r = SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
(void)r;
}
WDT_HIT();
@ -757,15 +757,15 @@ static void TransmitFor14443(void)
c = 0;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = ToSend[c];
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = ToSend[c];
c++;
if(c >= ToSendMax) {
break;
}
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
volatile DWORD r = SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
(void)r;
}
WDT_HIT();
@ -831,8 +831,8 @@ void CodeIso14443bAsReader(const BYTE *cmd, int len)
//-----------------------------------------------------------------------------
// Read an ISO 14443 tag. We send it some set of commands, and record the
// responses.
// The command name is misleading, it actually decodes the reponse in HEX
// responses.
// The command name is misleading, it actually decodes the reponse in HEX
// into the output buffer (read the result using hexsamples, not hisamples)
//-----------------------------------------------------------------------------
void AcquireRawAdcSamplesIso14443(DWORD parameter)
@ -861,19 +861,19 @@ void AcquireRawAdcSamplesIso14443(DWORD parameter)
GetSamplesFor14443Demod(TRUE, 2000, FALSE);
// LED_A_OFF();
}
//-----------------------------------------------------------------------------
// Read a SRI512 ISO 14443 tag.
//
// SRI512 tags are just simple memory tags, here we're looking at making a dump
// of the contents of the memory. No anticollision algorithm is done, we assume
// we have a single tag in the field.
//
//
// SRI512 tags are just simple memory tags, here we're looking at making a dump
// of the contents of the memory. No anticollision algorithm is done, we assume
// we have a single tag in the field.
//
// I tried to be systematic and check every answer of the tag, every CRC, etc...
//-----------------------------------------------------------------------------
void ReadSRI512Iso14443(DWORD parameter)
{
BYTE i = 0x00;
BYTE i = 0x00;
// Make sure that we start from off, since the tags are stateful;
// confusing things will happen if we don't reset them between reads.
@ -890,7 +890,7 @@ void ReadSRI512Iso14443(DWORD parameter)
FpgaWriteConfWord(
FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
SpinDelay(200);
// First command: wake up the tag using the INITIATE command
BYTE cmd1[] = { 0x06, 0x00, 0x97, 0x5b};
CodeIso14443bAsReader(cmd1, sizeof(cmd1));
@ -898,102 +898,102 @@ void ReadSRI512Iso14443(DWORD parameter)
// LED_A_ON();
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
if (Demod.len == 0) {
DbpString("No response from tag");
return;
} else {
DbpString("Randomly generated UID from tag (+ 2 byte CRC):");
DbpIntegers(Demod.output[0], Demod.output[1],Demod.output[2]);
}
// There is a response, SELECT the uid
DbpString("Now SELECT tag:");
cmd1[0] = 0x0E; // 0x0E is SELECT
cmd1[1] = Demod.output[0];
if (Demod.len == 0) {
DbpString("No response from tag");
return;
} else {
DbpString("Randomly generated UID from tag (+ 2 byte CRC):");
DbpIntegers(Demod.output[0], Demod.output[1],Demod.output[2]);
}
// There is a response, SELECT the uid
DbpString("Now SELECT tag:");
cmd1[0] = 0x0E; // 0x0E is SELECT
cmd1[1] = Demod.output[0];
ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
CodeIso14443bAsReader(cmd1, sizeof(cmd1));
TransmitFor14443();
// LED_A_ON();
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
if (Demod.len != 3) {
DbpString("Expected 3 bytes from tag, got:");
DbpIntegers(Demod.len,0x0,0x0);
return;
}
// Check the CRC of the answer:
if (Demod.len != 3) {
DbpString("Expected 3 bytes from tag, got:");
DbpIntegers(Demod.len,0x0,0x0);
return;
}
// Check the CRC of the answer:
ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]);
if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) {
DbpString("CRC Error reading select response.");
return;
}
// Check response from the tag: should be the same UID as the command we just sent:
if (cmd1[1] != Demod.output[0]) {
DbpString("Bad response to SELECT from Tag, aborting:");
DbpIntegers(cmd1[1],Demod.output[0],0x0);
return;
}
// Tag is now selected,
// First get the tag's UID:
cmd1[0] = 0x0B;
ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
DbpString("CRC Error reading select response.");
return;
}
// Check response from the tag: should be the same UID as the command we just sent:
if (cmd1[1] != Demod.output[0]) {
DbpString("Bad response to SELECT from Tag, aborting:");
DbpIntegers(cmd1[1],Demod.output[0],0x0);
return;
}
// Tag is now selected,
// First get the tag's UID:
cmd1[0] = 0x0B;
ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]);
CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one
TransmitFor14443();
// LED_A_ON();
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
if (Demod.len != 10) {
DbpString("Expected 10 bytes from tag, got:");
DbpIntegers(Demod.len,0x0,0x0);
return;
}
// The check the CRC of the answer (use cmd1 as temporary variable):
if (Demod.len != 10) {
DbpString("Expected 10 bytes from tag, got:");
DbpIntegers(Demod.len,0x0,0x0);
return;
}
// The check the CRC of the answer (use cmd1 as temporary variable):
ComputeCrc14443(CRC_14443_B, Demod.output, 8, &cmd1[2], &cmd1[3]);
if(cmd1[2] != Demod.output[8] || cmd1[3] != Demod.output[9]) {
DbpString("CRC Error reading block! - Below: expected, got");
DbpIntegers( (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9],0);
// Do not return;, let's go on... (we should retry, maybe ?)
}
DbpString("Tag UID (64 bits):");
DbpIntegers((Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4], (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], 0);
// Now loop to read all 16 blocks, address from 0 to 15
DbpString("Tag memory dump, block 0 to 15");
cmd1[0] = 0x08;
i = 0x00;
for (;;) {
if (i == 0x10) {
DbpString("System area block (0xff):");
i = 0xff;
}
cmd1[1] = i;
DbpString("CRC Error reading block! - Below: expected, got");
DbpIntegers( (cmd1[2]<<8)+cmd1[3], (Demod.output[8]<<8)+Demod.output[9],0);
// Do not return;, let's go on... (we should retry, maybe ?)
}
DbpString("Tag UID (64 bits):");
DbpIntegers((Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4], (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], 0);
// Now loop to read all 16 blocks, address from 0 to 15
DbpString("Tag memory dump, block 0 to 15");
cmd1[0] = 0x08;
i = 0x00;
for (;;) {
if (i == 0x10) {
DbpString("System area block (0xff):");
i = 0xff;
}
cmd1[1] = i;
ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]);
CodeIso14443bAsReader(cmd1, sizeof(cmd1));
TransmitFor14443();
// LED_A_ON();
GetSamplesFor14443Demod(TRUE, 2000,TRUE);
// LED_A_OFF();
if (Demod.len != 6) { // Check if we got an answer from the tag
DbpString("Expected 6 bytes from tag, got less...");
return;
}
// The check the CRC of the answer (use cmd1 as temporary variable):
// LED_A_OFF();
if (Demod.len != 6) { // Check if we got an answer from the tag
DbpString("Expected 6 bytes from tag, got less...");
return;
}
// The check the CRC of the answer (use cmd1 as temporary variable):
ComputeCrc14443(CRC_14443_B, Demod.output, 4, &cmd1[2], &cmd1[3]);
if(cmd1[2] != Demod.output[4] || cmd1[3] != Demod.output[5]) {
DbpString("CRC Error reading block! - Below: expected, got");
DbpIntegers( (cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5],0);
// Do not return;, let's go on... (we should retry, maybe ?)
}
// Now print out the memory location:
DbpString("Address , Contents, CRC");
DbpIntegers(i, (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], (Demod.output[4]<<8)+Demod.output[5]);
if (i == 0xff) {
break;
}
i++;
}
DbpString("CRC Error reading block! - Below: expected, got");
DbpIntegers( (cmd1[2]<<8)+cmd1[3], (Demod.output[4]<<8)+Demod.output[5],0);
// Do not return;, let's go on... (we should retry, maybe ?)
}
// Now print out the memory location:
DbpString("Address , Contents, CRC");
DbpIntegers(i, (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0], (Demod.output[4]<<8)+Demod.output[5]);
if (i == 0xff) {
break;
}
i++;
}
}
//=============================================================================
// Finally, the `sniffer' combines elements from both the reader and
@ -1010,7 +1010,7 @@ void ReadSRI512Iso14443(DWORD parameter)
* 0-1023 : Demodulated samples receive (1024 bytes)
* 1024-1535 : Last Received command, 512 bytes (reader->tag)
* 1536-2047 : Last Received command, 512 bytes(tag->reader)
* 2048-2304 : DMA Buffer, 256 bytes (samples)
* 2048-2304 : DMA Buffer, 256 bytes (samples)
*/
void SnoopIso14443(void)
{
@ -1069,7 +1069,7 @@ void SnoopIso14443(void)
FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE);
// And now we loop, receiving samples.
for(;;) {
int behindBy = (lastRxCounter - PDC_RX_COUNTER(SSC_BASE)) &
int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
(DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) {
maxBehindBy = behindBy;
@ -1088,8 +1088,8 @@ void SnoopIso14443(void)
if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
upTo -= DMA_BUFFER_SIZE;
lastRxCounter += DMA_BUFFER_SIZE;
PDC_RX_NEXT_POINTER(SSC_BASE) = (DWORD) upTo;
PDC_RX_NEXT_COUNTER(SSC_BASE) = DMA_BUFFER_SIZE;
AT91C_BASE_PDC_SSC->PDC_RNPR = (DWORD) upTo;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
samples += 2;
@ -1169,5 +1169,5 @@ void SnoopIso14443(void)
done:
LED_D_OFF();
PDC_CONTROL(SSC_BASE) = PDC_RX_DISABLE;
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
}

View file

@ -583,7 +583,7 @@ void SnoopIso14443a(void)
// And now we loop, receiving samples.
for(;;) {
WDT_HIT();
int behindBy = (lastRxCounter - PDC_RX_COUNTER(SSC_BASE)) &
int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
(DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) {
maxBehindBy = behindBy;
@ -600,8 +600,8 @@ void SnoopIso14443a(void)
if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
upTo -= DMA_BUFFER_SIZE;
lastRxCounter += DMA_BUFFER_SIZE;
PDC_RX_NEXT_POINTER(SSC_BASE) = (DWORD)upTo;
PDC_RX_NEXT_COUNTER(SSC_BASE) = DMA_BUFFER_SIZE;
AT91C_BASE_PDC_SSC->PDC_RNPR = (DWORD)upTo;
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
}
samples += 4;
@ -672,7 +672,7 @@ void SnoopIso14443a(void)
DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);
done:
PDC_CONTROL(SSC_BASE) = PDC_RX_DISABLE;
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
DbpIntegers(maxBehindBy, Uart.state, Uart.byteCnt);
DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);
LED_A_OFF();
@ -857,11 +857,11 @@ static BOOL GetIso14443aCommandFromReader(BYTE *received, int *len, int maxLen)
if(BUTTON_PRESS()) return FALSE;
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x00;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00;
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
BYTE b = (BYTE)SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR;
if(MillerDecoding((b & 0xf0) >> 4)) {
*len = Uart.byteCnt;
return TRUE;
@ -1128,7 +1128,7 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
// Modulate Manchester
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
SSC_TRANSMIT_HOLDING = 0x00;
AT91C_BASE_SSC->SSC_THR = 0x00;
FpgaSetupSsc();
// ### Transmit the response ###
@ -1136,11 +1136,11 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
b = 0x00;
fdt_indicator = FALSE;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
volatile BYTE b = (BYTE)SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR;
(void)b;
}
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
if(i > respLen) {
b = 0x00;
u++;
@ -1148,7 +1148,7 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
b = resp[i];
i++;
}
SSC_TRANSMIT_HOLDING = b;
AT91C_BASE_SSC->SSC_THR = b;
if(u > 4) {
break;
@ -1177,12 +1177,12 @@ static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait)
if(*wait < 10) { *wait = 10; }
for(c = 0; c < *wait;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x00; // For exact timing!
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
c++;
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
volatile DWORD r = SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
(void)r;
}
WDT_HIT();
@ -1190,15 +1190,15 @@ static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait)
c = 0;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = cmd[c];
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = cmd[c];
c++;
if(c >= len) {
break;
}
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
volatile DWORD r = SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
(void)r;
}
WDT_HIT();
@ -1454,13 +1454,13 @@ static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *s
for(;;) {
WDT_HIT();
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x00; // To make use of exact timing of next command from reader!!
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00; // To make use of exact timing of next command from reader!!
(*elapsed)++;
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
if(c < 512) { c++; } else { return FALSE; }
b = (BYTE)SSC_RECEIVE_HOLDING;
b = (BYTE)AT91C_BASE_SSC->SSC_RHR;
if(ManchesterDecoding((b & 0xf0) >> 4)) {
*samples = ((c - 1) << 3) + 4;
return TRUE;

View file

@ -478,12 +478,12 @@ static void TransmitTo15693Tag(const BYTE *cmd, int len, int *samples, int *wait
if(*wait < 10) { *wait = 10; }
// for(c = 0; c < *wait;) {
// if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
// SSC_TRANSMIT_HOLDING = 0x00; // For exact timing!
// if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
// AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
// c++;
// }
// if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
// volatile DWORD r = SSC_RECEIVE_HOLDING;
// if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
// volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
// (void)r;
// }
// WDT_HIT();
@ -491,15 +491,15 @@ static void TransmitTo15693Tag(const BYTE *cmd, int len, int *samples, int *wait
c = 0;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = cmd[c];
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = cmd[c];
c++;
if(c >= len) {
break;
}
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
volatile DWORD r = SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
(void)r;
}
WDT_HIT();
@ -520,15 +520,15 @@ static void TransmitTo15693Reader(const BYTE *cmd, int len, int *samples, int *w
c = 0;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = cmd[c];
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = cmd[c];
c++;
if(c >= len) {
break;
}
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
volatile DWORD r = SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
(void)r;
}
WDT_HIT();
@ -550,12 +550,12 @@ static int GetIso15693AnswerFromTag(BYTE *receivedResponse, int maxLen, int *sam
c = 0;
getNext = FALSE;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x43;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x43;
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
SBYTE b;
b = (SBYTE)SSC_RECEIVE_HOLDING;
b = (SBYTE)AT91C_BASE_SSC->SSC_RHR;
// The samples are correlations against I and Q versions of the
// tone that the tag AM-modulates, so every other sample is I,
@ -697,12 +697,12 @@ static int GetIso15693AnswerFromSniff(BYTE *receivedResponse, int maxLen, int *s
c = 0;
getNext = FALSE;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x43;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x43;
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
SBYTE b;
b = (SBYTE)SSC_RECEIVE_HOLDING;
b = (SBYTE)AT91C_BASE_SSC->SSC_RHR;
// The samples are correlations against I and Q versions of the
// tone that the tag AM-modulates, so every other sample is I,
@ -855,15 +855,15 @@ void AcquireRawAdcSamplesIso15693(void)
c = 0;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = ToSend[c];
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = ToSend[c];
c++;
if(c == ToSendMax+3) {
break;
}
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
volatile DWORD r = SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;
(void)r;
}
WDT_HIT();
@ -874,12 +874,12 @@ void AcquireRawAdcSamplesIso15693(void)
c = 0;
getNext = FALSE;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x43;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x43;
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
SBYTE b;
b = (SBYTE)SSC_RECEIVE_HOLDING;
b = (SBYTE)AT91C_BASE_SSC->SSC_RHR;
// The samples are correlations against I and Q versions of the
// tone that the tag AM-modulates, so every other sample is I,

View file

@ -42,12 +42,12 @@ void DoAcquisition125k(BOOL at134khz)
memset(dest,0,n);
i = 0;
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x43;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x43;
LED_D_ON();
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
dest[i] = (BYTE)AT91C_BASE_SSC->SSC_RHR;
i++;
LED_D_OFF();
if(i >= n) {
@ -274,17 +274,17 @@ void WriteTIbyte(BYTE b)
{
if (b&(1<<i)) {
// stop modulating antenna
PIO_OUTPUT_DATA_CLEAR = (1<<GPIO_SSC_DOUT);
LOW(GPIO_SSC_DOUT);
SpinDelayUs(1000);
// modulate antenna
PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
HIGH(GPIO_SSC_DOUT);
SpinDelayUs(1000);
} else {
// stop modulating antenna
PIO_OUTPUT_DATA_CLEAR = (1<<GPIO_SSC_DOUT);
LOW(GPIO_SSC_DOUT);
SpinDelayUs(300);
// modulate antenna
PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
HIGH(GPIO_SSC_DOUT);
SpinDelayUs(1700);
}
}
@ -301,50 +301,50 @@ void AcquireTiType(void)
memset(BigBuf,0,sizeof(BigBuf));
// Set up the synchronous serial port
PIO_DISABLE = (1<<GPIO_SSC_DIN);
PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN);
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN;
AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN;
// steal this pin from the SSP and use it to control the modulation
PIO_ENABLE = (1<<GPIO_SSC_DOUT);
PIO_OUTPUT_ENABLE = (1<<GPIO_SSC_DOUT);
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
SSC_CONTROL = SSC_CONTROL_RESET;
SSC_CONTROL = SSC_CONTROL_RX_ENABLE | SSC_CONTROL_TX_ENABLE;
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
// Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
// 48/2 = 24 MHz clock must be divided by 12
SSC_CLOCK_DIVISOR = 12;
// Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
// 48/2 = 24 MHz clock must be divided by 12
AT91C_BASE_SSC->SSC_CMR = 12;
SSC_RECEIVE_CLOCK_MODE = SSC_CLOCK_MODE_SELECT(0);
SSC_RECEIVE_FRAME_MODE = SSC_FRAME_MODE_BITS_IN_WORD(32) | SSC_FRAME_MODE_MSB_FIRST;
SSC_TRANSMIT_CLOCK_MODE = 0;
SSC_TRANSMIT_FRAME_MODE = 0;
AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0);
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF;
AT91C_BASE_SSC->SSC_TCMR = 0;
AT91C_BASE_SSC->SSC_TFMR = 0;
LED_D_ON();
// modulate antenna
PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
HIGH(GPIO_SSC_DOUT);
// Charge TI tag for 50ms.
SpinDelay(50);
// stop modulating antenna and listen
PIO_OUTPUT_DATA_CLEAR = (1<<GPIO_SSC_DOUT);
LOW(GPIO_SSC_DOUT);
LED_D_OFF();
i = 0;
for(;;) {
if(SSC_STATUS & SSC_STATUS_RX_READY) {
BigBuf[i] = SSC_RECEIVE_HOLDING; // store 32 bit values in buffer
i++; if(i >= TIBUFLEN) break;
}
WDT_HIT();
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer
i++; if(i >= TIBUFLEN) break;
}
WDT_HIT();
}
// return stolen pin to SSP
PIO_DISABLE = (1<<GPIO_SSC_DOUT);
PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN) | (1<<GPIO_SSC_DOUT);
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT;
char *dest = (char *)BigBuf;
n = TIBUFLEN*32;
@ -394,8 +394,8 @@ void WriteTItag(DWORD idhi, DWORD idlo, WORD crc)
LED_A_ON();
// steal this pin from the SSP and use it to control the modulation
PIO_ENABLE = (1<<GPIO_SSC_DOUT);
PIO_OUTPUT_ENABLE = (1<<GPIO_SSC_DOUT);
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
// writing algorithm:
// a high bit consists of a field off for 1ms and field on for 1ms
@ -408,7 +408,7 @@ void WriteTItag(DWORD idhi, DWORD idlo, WORD crc)
// finish with 15ms programming time
// modulate antenna
PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
HIGH(GPIO_SSC_DOUT);
SpinDelay(50); // charge time
WriteTIbyte(0xbb); // keyword
@ -425,7 +425,7 @@ void WriteTItag(DWORD idhi, DWORD idlo, WORD crc)
WriteTIbyte( (crc>>8 )&0xff ); // crc hi
WriteTIbyte(0x00); // write frame lo
WriteTIbyte(0x03); // write frame hi
PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
HIGH(GPIO_SSC_DOUT);
SpinDelay(50); // programming time
LED_A_OFF();
@ -444,17 +444,17 @@ void SimulateTagLowFrequency(int period, int ledcontrol)
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
PIO_ENABLE = (1 << GPIO_SSC_DOUT) | (1 << GPIO_SSC_CLK);
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
PIO_OUTPUT_ENABLE = (1 << GPIO_SSC_DOUT);
PIO_OUTPUT_DISABLE = (1 << GPIO_SSC_CLK);
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
i = 0;
for(;;) {
while(!(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK))) {
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
if(BUTTON_PRESS()) {
DbpString("Stopped");
return;
@ -473,7 +473,7 @@ void SimulateTagLowFrequency(int period, int ledcontrol)
if (ledcontrol)
LED_D_OFF();
while(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK)) {
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
if(BUTTON_PRESS()) {
DbpString("Stopped");
return;
@ -529,7 +529,7 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0)
hitag2_init();
/* Set up simulator mode, frequency divisor which will drive the FPGA
* and analog mux selection.
* and analog mux selection.
*/
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
@ -539,15 +539,19 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0)
/* Set up Timer 1:
* Capture mode, timer source MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
* external trigger rising edge, load RA on rising edge of TIOA, load RB on rising
* edge of TIOA. Assign PA15 to TIOA1 (peripheral B)
* edge of TIOA. Assign PA15 to TIOA1 (peripheral B)
*/
PMC_PERIPHERAL_CLK_ENABLE = (1 << PERIPH_TC1);
PIO_PERIPHERAL_B_SEL = (1 << GPIO_SSC_FRAME);
TC1_CCR = TC_CCR_CLKDIS;
TC1_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_ETRGEDG_RISING | TC_CMR_ABETRG |
TC_CMR_LDRA_RISING | TC_CMR_LDRB_RISING;
TC1_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC1->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 |
AT91C_TC_ETRGEDG_RISING |
AT91C_TC_ABETRG |
AT91C_TC_LDRA_RISING |
AT91C_TC_LDRB_RISING;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN |
AT91C_TC_SWTRG;
/* calculate the new value for the carrier period in terms of TC1 values */
t0 = t0/2;
@ -555,8 +559,8 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0)
int overflow = 0;
while(!BUTTON_PRESS()) {
WDT_HIT();
if(TC1_SR & TC_SR_LDRAS) {
int ra = TC1_RA;
if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
int ra = AT91C_BASE_TC1->TC_RA;
if((ra > t0*HITAG_T_EOF) | overflow) ra = t0*HITAG_T_EOF+1;
#if DEBUG_RA_VALUES
if(ra > 255 || overflow) ra = 255;
@ -583,14 +587,14 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0)
overflow = 0;
LED_D_ON();
} else {
if(TC1_CV > t0*HITAG_T_EOF) {
if(AT91C_BASE_TC1->TC_CV > t0*HITAG_T_EOF) {
/* Minor nuisance: In Capture mode, the timer can not be
* stopped by a Compare C. There's no way to stop the clock
* in software, so we'll just have to note the fact that an
* overflow happened and the next loaded timer value might
* have wrapped. Also, this marks the end of frame, and the
* still running counter can be used to determine the correct
* time for the start of the reply.
* time for the start of the reply.
*/
overflow = 1;
@ -619,37 +623,37 @@ static void hitag_send_bit(int t0, int bit) {
/* Manchester: Loaded, then unloaded */
LED_A_ON();
SHORT_COIL();
while(TC1_CV < t0*15);
while(AT91C_BASE_TC1->TC_CV < t0*15);
OPEN_COIL();
while(TC1_CV < t0*31);
while(AT91C_BASE_TC1->TC_CV < t0*31);
LED_A_OFF();
} else if(bit == 0) {
/* Manchester: Unloaded, then loaded */
LED_B_ON();
OPEN_COIL();
while(TC1_CV < t0*15);
while(AT91C_BASE_TC1->TC_CV < t0*15);
SHORT_COIL();
while(TC1_CV < t0*31);
while(AT91C_BASE_TC1->TC_CV < t0*31);
LED_B_OFF();
}
TC1_CCR = TC_CCR_SWTRG; /* Reset clock for the next bit */
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; /* Reset clock for the next bit */
}
static void hitag_send_frame(int t0, int frame_len, const char const * frame, int fdt)
{
OPEN_COIL();
PIO_OUTPUT_ENABLE = (1 << GPIO_SSC_DOUT);
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
/* Wait for HITAG_T_WRESP carrier periods after the last reader bit,
* not that since the clock counts since the rising edge, but T_wresp is
* with respect to the falling edge, we need to wait actually (T_wresp - T_g)
* periods. The gap time T_g varies (4..10).
* periods. The gap time T_g varies (4..10).
*/
while(TC1_CV < t0*(fdt-8));
while(AT91C_BASE_TC1->TC_CV < t0*(fdt-8));
int saved_cmr = TC1_CMR;
TC1_CMR &= ~TC_CMR_ETRGEDG; /* Disable external trigger for the clock */
TC1_CCR = TC_CCR_SWTRG; /* Reset the clock and use it for response timing */
int saved_cmr = AT91C_BASE_TC1->TC_CMR;
AT91C_BASE_TC1->TC_CMR &= ~AT91C_TC_ETRGEDG; /* Disable external trigger for the clock */
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; /* Reset the clock and use it for response timing */
int i;
for(i=0; i<5; i++)
@ -660,7 +664,7 @@ static void hitag_send_frame(int t0, int frame_len, const char const * frame, in
}
OPEN_COIL();
TC1_CMR = saved_cmr;
AT91C_BASE_TC1->TC_CMR = saved_cmr;
}
/* Callback structure to cleanly separate tag emulation code from the radio layer. */
@ -813,13 +817,13 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
m = sizeof(BigBuf);
memset(dest,128,m);
for(;;) {
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
SSC_TRANSMIT_HOLDING = 0x43;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x43;
if (ledcontrol)
LED_D_ON();
}
if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
dest[i] = (BYTE)AT91C_BASE_SSC->SSC_RHR;
// we don't care about actual value, only if it's more or less than a
// threshold essentially we capture zero crossings for later analysis
if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;

View file

@ -115,18 +115,18 @@ int BUTTON_CLICKED(int ms)
return BUTTON_NO_CLICK;
// Borrow a PWM unit for my real-time clock
PWM_ENABLE = PWM_CHANNEL(0);
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
// 48 MHz / 1024 gives 46.875 kHz
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
PWM_CH_DUTY_CYCLE(0) = 0;
PWM_CH_PERIOD(0) = 0xffff;
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
WORD start = (WORD)PWM_CH_COUNTER(0);
WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
int letoff = 0;
for(;;)
{
WORD now = (WORD)PWM_CH_COUNTER(0);
WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
// We haven't let off the button yet
if (!letoff)
@ -137,7 +137,7 @@ int BUTTON_CLICKED(int ms)
letoff = 1;
// reset our timer for 500ms
start = (WORD)PWM_CH_COUNTER(0);
start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
ticks = (48000 * (500)) >> 10;
}
@ -178,17 +178,17 @@ int BUTTON_HELD(int ms)
return BUTTON_NO_CLICK;
// Borrow a PWM unit for my real-time clock
PWM_ENABLE = PWM_CHANNEL(0);
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
// 48 MHz / 1024 gives 46.875 kHz
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
PWM_CH_DUTY_CYCLE(0) = 0;
PWM_CH_PERIOD(0) = 0xffff;
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
WORD start = (WORD)PWM_CH_COUNTER(0);
WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
for(;;)
{
WORD now = (WORD)PWM_CH_COUNTER(0);
WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
// As soon as our button let go, we didn't hold long enough
if (!BUTTON_PRESS())
@ -213,16 +213,16 @@ void SpinDelayUs(int us)
int ticks = (48*us) >> 10;
// Borrow a PWM unit for my real-time clock
PWM_ENABLE = PWM_CHANNEL(0);
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
// 48 MHz / 1024 gives 46.875 kHz
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
PWM_CH_DUTY_CYCLE(0) = 0;
PWM_CH_PERIOD(0) = 0xffff;
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
WORD start = (WORD)PWM_CH_COUNTER(0);
WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
for(;;) {
WORD now = (WORD)PWM_CH_COUNTER(0);
WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
if (now == (WORD)(start + ticks))
return;
@ -239,7 +239,7 @@ void SpinDelay(int ms)
/* Similar to FpgaGatherVersion this formats stored version information
* into a string representation. It takes a pointer to the struct version_information,
* verifies the magic properties, then stores a formatted string, prefixed by
* prefix in dst.
* prefix in dst.
*/
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information)
{