mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-05 20:51:18 -07:00
RDV40 compatibility fixes (#678)
* detect and use RDV40 higher voltage ADC channel for hw tune, hf tune, hw detectreader * fix mode switching in hw detectreader * detect Smartcard Slot in hw version * i2c changes from https://github.com/RfidResearchGroup/proxmark3 * some formatting in proxmark3.h
This commit is contained in:
parent
2758d83652
commit
050aa18b13
8 changed files with 352 additions and 244 deletions
|
@ -26,11 +26,8 @@ SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c mifares
|
|||
SRC_ISO14443b = iso14443b.c
|
||||
SRC_CRAPTO1 = crypto1.c des.c
|
||||
SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c parity.c
|
||||
ifneq (,$(findstring WITH_SMARTCARD,$(APP_CFLAGS)))
|
||||
SRC_SMARTCARD = i2c.c
|
||||
else
|
||||
SRC_SMARTCARD =
|
||||
endif
|
||||
SRC_SMARTCARD = i2c.c
|
||||
|
||||
#the FPGA bitstream files. Note: order matters!
|
||||
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
|
||||
|
||||
|
|
|
@ -28,12 +28,10 @@
|
|||
#include "BigBuf.h"
|
||||
#include "mifareutil.h"
|
||||
#include "pcf7931.h"
|
||||
#include "i2c.h"
|
||||
#ifdef WITH_LCD
|
||||
#include "LCD.h"
|
||||
#endif
|
||||
#ifdef WITH_SMARTCARD
|
||||
#include "i2c.h"
|
||||
#endif
|
||||
|
||||
|
||||
// Craig Young - 14a stand-alone code
|
||||
|
@ -143,7 +141,7 @@ void Dbhexdump(int len, uint8_t *d, bool bAsci) {
|
|||
static int ReadAdc(int ch)
|
||||
{
|
||||
// Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value.
|
||||
// AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant
|
||||
// AMPL_HI is a high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant
|
||||
// of RC = (0.91MOhm) * 12pF = 10.9us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged.
|
||||
//
|
||||
// The maths are:
|
||||
|
@ -162,7 +160,7 @@ static int ReadAdc(int ch)
|
|||
|
||||
while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) {};
|
||||
|
||||
return AT91C_BASE_ADC->ADC_CDR[ch];
|
||||
return AT91C_BASE_ADC->ADC_CDR[ch] & 0x3ff;
|
||||
}
|
||||
|
||||
int AvgAdc(int ch) // was static - merlok
|
||||
|
@ -177,6 +175,26 @@ int AvgAdc(int ch) // was static - merlok
|
|||
return (a + 15) >> 5;
|
||||
}
|
||||
|
||||
static int AvgAdc_Voltage_HF(void)
|
||||
{
|
||||
int AvgAdc_Voltage_Low, AvgAdc_Voltage_High;
|
||||
|
||||
AvgAdc_Voltage_Low= (MAX_ADC_HF_VOLTAGE_LOW * AvgAdc(ADC_CHAN_HF_LOW)) >> 10;
|
||||
// if voltage range is about to be exceeded, use high voltage ADC channel if available (RDV40 only)
|
||||
if (AvgAdc_Voltage_Low > MAX_ADC_HF_VOLTAGE_LOW - 300) {
|
||||
AvgAdc_Voltage_High = (MAX_ADC_HF_VOLTAGE_HIGH * AvgAdc(ADC_CHAN_HF_HIGH)) >> 10;
|
||||
if (AvgAdc_Voltage_High >= AvgAdc_Voltage_Low) {
|
||||
return AvgAdc_Voltage_High;
|
||||
}
|
||||
}
|
||||
return AvgAdc_Voltage_Low;
|
||||
}
|
||||
|
||||
static int AvgAdc_Voltage_LF(void)
|
||||
{
|
||||
return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10;
|
||||
}
|
||||
|
||||
void MeasureAntennaTuningLfOnly(int *vLf125, int *vLf134, int *peakf, int *peakv, uint8_t LF_Results[])
|
||||
{
|
||||
int i, adcval = 0, peak = 0;
|
||||
|
@ -198,7 +216,7 @@ void MeasureAntennaTuningLfOnly(int *vLf125, int *vLf134, int *peakf, int *peakv
|
|||
WDT_HIT();
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
|
||||
SpinDelay(20);
|
||||
adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
|
||||
adcval = AvgAdc_Voltage_LF();
|
||||
if (i==95) *vLf125 = adcval; // voltage at 125Khz
|
||||
if (i==89) *vLf134 = adcval; // voltage at 134Khz
|
||||
|
||||
|
@ -223,9 +241,8 @@ void MeasureAntennaTuningHfOnly(int *vHf)
|
|||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||
SpinDelay(20);
|
||||
*vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
|
||||
*vHf = AvgAdc_Voltage_HF();
|
||||
LED_A_OFF();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -267,8 +284,8 @@ void MeasureAntennaTuningHf(void)
|
|||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||
|
||||
for (;;) {
|
||||
SpinDelay(20);
|
||||
vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
|
||||
SpinDelay(500);
|
||||
vHf = AvgAdc_Voltage_HF();
|
||||
|
||||
Dbprintf("%d mV",vHf);
|
||||
if (BUTTON_PRESS()) break;
|
||||
|
@ -293,6 +310,7 @@ extern struct version_information version_information;
|
|||
/* bootrom version information is pointed to from _bootphase1_version_pointer */
|
||||
extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
|
||||
|
||||
|
||||
void SendVersion(void)
|
||||
{
|
||||
char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
|
||||
|
@ -315,11 +333,16 @@ void SendVersion(void)
|
|||
|
||||
for (int i = 0; i < fpga_bitstream_num; i++) {
|
||||
strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1);
|
||||
if (i < fpga_bitstream_num - 1) {
|
||||
strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||
}
|
||||
strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||
}
|
||||
|
||||
|
||||
// test availability of SmartCard slot
|
||||
if (I2C_is_available()) {
|
||||
strncat(VersionString, "SmartCard Slot: available\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||
} else {
|
||||
strncat(VersionString, "SmartCard Slot: not available\n", sizeof(VersionString) - strlen(VersionString) - 1);
|
||||
}
|
||||
|
||||
// Send Chip ID and used flash memory
|
||||
uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start;
|
||||
uint32_t compressed_data_section_size = common_area.arg1;
|
||||
|
@ -828,13 +851,15 @@ static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]);
|
|||
|
||||
void ListenReaderField(int limit)
|
||||
{
|
||||
int lf_av, lf_av_new, lf_baseline= 0, lf_max;
|
||||
int hf_av, hf_av_new, hf_baseline= 0, hf_max;
|
||||
int lf_av, lf_av_new=0, lf_baseline= 0, lf_max;
|
||||
int hf_av, hf_av_new=0, hf_baseline= 0, hf_max;
|
||||
int mode=1, display_val, display_max, i;
|
||||
|
||||
#define LF_ONLY 1
|
||||
#define HF_ONLY 2
|
||||
#define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE
|
||||
#define LF_ONLY 1
|
||||
#define HF_ONLY 2
|
||||
#define REPORT_CHANGE_PERCENT 5 // report new values only if they have changed at least by REPORT_CHANGE_PERCENT
|
||||
#define MIN_HF_FIELD 300 // in mode 1 signal HF field greater than MIN_HF_FIELD above baseline
|
||||
#define MIN_LF_FIELD 1200 // in mode 1 signal LF field greater than MIN_LF_FIELD above baseline
|
||||
|
||||
|
||||
// switch off FPGA - we don't want to measure our own signal
|
||||
|
@ -843,23 +868,23 @@ void ListenReaderField(int limit)
|
|||
|
||||
LEDsoff();
|
||||
|
||||
lf_av = lf_max = AvgAdc(ADC_CHAN_LF);
|
||||
lf_av = lf_max = AvgAdc_Voltage_LF();
|
||||
|
||||
if(limit != HF_ONLY) {
|
||||
Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10);
|
||||
Dbprintf("LF 125/134kHz Baseline: %dmV", lf_av);
|
||||
lf_baseline = lf_av;
|
||||
}
|
||||
|
||||
hf_av = hf_max = AvgAdc(ADC_CHAN_HF);
|
||||
|
||||
hf_av = hf_max = AvgAdc_Voltage_HF();
|
||||
|
||||
if (limit != LF_ONLY) {
|
||||
Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10);
|
||||
Dbprintf("HF 13.56MHz Baseline: %dmV", hf_av);
|
||||
hf_baseline = hf_av;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
SpinDelay(500);
|
||||
if (BUTTON_PRESS()) {
|
||||
SpinDelay(500);
|
||||
switch (mode) {
|
||||
case 1:
|
||||
mode=2;
|
||||
|
@ -872,21 +897,22 @@ void ListenReaderField(int limit)
|
|||
return;
|
||||
break;
|
||||
}
|
||||
while (BUTTON_PRESS());
|
||||
}
|
||||
WDT_HIT();
|
||||
|
||||
if (limit != HF_ONLY) {
|
||||
if(mode == 1) {
|
||||
if (ABS(lf_av - lf_baseline) > REPORT_CHANGE)
|
||||
if (lf_av - lf_baseline > MIN_LF_FIELD)
|
||||
LED_D_ON();
|
||||
else
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
lf_av_new = AvgAdc(ADC_CHAN_LF);
|
||||
lf_av_new = AvgAdc_Voltage_LF();
|
||||
// see if there's a significant change
|
||||
if(ABS(lf_av - lf_av_new) > REPORT_CHANGE) {
|
||||
Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10);
|
||||
if (ABS((lf_av - lf_av_new)*100/(lf_av?lf_av:1)) > REPORT_CHANGE_PERCENT) {
|
||||
Dbprintf("LF 125/134kHz Field Change: %5dmV", lf_av_new);
|
||||
lf_av = lf_av_new;
|
||||
if (lf_av > lf_max)
|
||||
lf_max = lf_av;
|
||||
|
@ -895,16 +921,17 @@ void ListenReaderField(int limit)
|
|||
|
||||
if (limit != LF_ONLY) {
|
||||
if (mode == 1){
|
||||
if (ABS(hf_av - hf_baseline) > REPORT_CHANGE)
|
||||
if (hf_av - hf_baseline > MIN_HF_FIELD)
|
||||
LED_B_ON();
|
||||
else
|
||||
LED_B_OFF();
|
||||
}
|
||||
|
||||
hf_av_new = AvgAdc(ADC_CHAN_HF);
|
||||
hf_av_new = AvgAdc_Voltage_HF();
|
||||
|
||||
// see if there's a significant change
|
||||
if(ABS(hf_av - hf_av_new) > REPORT_CHANGE) {
|
||||
Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10);
|
||||
if (ABS((hf_av - hf_av_new)*100/(hf_av?hf_av:1)) > REPORT_CHANGE_PERCENT) {
|
||||
Dbprintf("HF 13.56MHz Field Change: %5dmV", hf_av_new);
|
||||
hf_av = hf_av_new;
|
||||
if (hf_av > hf_max)
|
||||
hf_max = hf_av;
|
||||
|
@ -1436,7 +1463,7 @@ void __attribute__((noreturn)) AppMain(void)
|
|||
LED_A_OFF();
|
||||
|
||||
// Init USB device
|
||||
usb_enable();
|
||||
usb_enable();
|
||||
|
||||
// The FPGA gets its clock from us from PCK0 output, so set that up.
|
||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
|
||||
|
|
|
@ -42,9 +42,10 @@ void Dbprintf(const char *fmt, ...);
|
|||
void Dbhexdump(int len, uint8_t *d, bool bAsci);
|
||||
|
||||
// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV
|
||||
#define MAX_ADC_HF_VOLTAGE 36300
|
||||
#define MAX_ADC_HF_VOLTAGE_LOW 36300
|
||||
// ADC Vref = 3300mV, and an (10000k+240k):240k voltage divider on the LF input can measure voltages up to 140800 mV
|
||||
#define MAX_ADC_LF_VOLTAGE 140800
|
||||
#define MAX_ADC_HF_VOLTAGE_HIGH 140800
|
||||
#define MAX_ADC_LF_VOLTAGE 140800
|
||||
int AvgAdc(int ch);
|
||||
|
||||
void ToSendStuffBit(int b);
|
||||
|
|
339
armsrc/i2c.c
339
armsrc/i2c.c
|
@ -8,9 +8,21 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// The main i2c code, for communications with smart card module
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "i2c.h"
|
||||
#include "mifareutil.h" //for mf_dbglevel
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "string.h" //for memset memcmp
|
||||
#include "proxmark3.h"
|
||||
#include "mifareutil.h" // for MF_DBGLEVEL
|
||||
#include "BigBuf.h"
|
||||
#include "apps.h"
|
||||
|
||||
#ifdef WITH_SMARTCARD
|
||||
#include "smartcard.h"
|
||||
#endif
|
||||
|
||||
|
||||
// 定义连接引脚
|
||||
#define GPIO_RST AT91C_PIO_PA1
|
||||
|
@ -27,13 +39,13 @@
|
|||
|
||||
#define I2C_ERROR "I2C_WaitAck Error"
|
||||
|
||||
volatile unsigned long c;
|
||||
static volatile unsigned long c;
|
||||
|
||||
// 直接使用循环来延时,一个循环 6 条指令,48M, Delay=1 大概为 200kbps
|
||||
// timer.
|
||||
// I2CSpinDelayClk(4) = 12.31us
|
||||
// I2CSpinDelayClk(1) = 3.07us
|
||||
void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
|
||||
static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
|
||||
for (c = delay * 2; c; c--) {};
|
||||
}
|
||||
|
||||
|
@ -45,23 +57,19 @@ void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
|
|||
|
||||
#define ISO7618_MAX_FRAME 255
|
||||
|
||||
void I2C_init(void) {
|
||||
// 配置复位引脚,关闭上拉,推挽输出,默认高
|
||||
// Configure reset pin, close up pull up, push-pull output, default high
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = GPIO_RST;
|
||||
AT91C_BASE_PIOA->PIO_MDDR = GPIO_RST;
|
||||
static void I2C_init(void) {
|
||||
// Configure reset pin
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = GPIO_RST; // disable pull up resistor
|
||||
AT91C_BASE_PIOA->PIO_MDDR = GPIO_RST; // push-pull output (multidriver disabled)
|
||||
|
||||
// 配置 I2C 引脚,开启上拉,开漏输出
|
||||
// Configure I2C pin, open up, open leakage
|
||||
AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_SCL | GPIO_SDA); // 打开上拉 Open up the pull up
|
||||
AT91C_BASE_PIOA->PIO_MDER |= (GPIO_SCL | GPIO_SDA);
|
||||
// Configure SCL and SDA pins
|
||||
AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_SCL | GPIO_SDA); // enable pull up resistor
|
||||
AT91C_BASE_PIOA->PIO_MDER |= (GPIO_SCL | GPIO_SDA); // open drain output (multidriver enabled) - requires external pull up resistor
|
||||
|
||||
// 默认三根线全部拉高
|
||||
// default three lines all pull up
|
||||
// set all three outputs to high
|
||||
AT91C_BASE_PIOA->PIO_SODR |= (GPIO_SCL | GPIO_SDA | GPIO_RST);
|
||||
|
||||
// 允许输出
|
||||
// allow output
|
||||
// configure all three pins as output, controlled by PIOA
|
||||
AT91C_BASE_PIOA->PIO_OER |= (GPIO_SCL | GPIO_SDA | GPIO_RST);
|
||||
AT91C_BASE_PIOA->PIO_PER |= (GPIO_SCL | GPIO_SDA | GPIO_RST);
|
||||
}
|
||||
|
@ -69,7 +77,7 @@ void I2C_init(void) {
|
|||
|
||||
// 设置复位状态
|
||||
// set the reset state
|
||||
void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) {
|
||||
static void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) {
|
||||
if (LineRST)
|
||||
HIGH(GPIO_RST);
|
||||
else
|
||||
|
@ -89,7 +97,7 @@ void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) {
|
|||
// 复位进入主程序
|
||||
// Reset the SIM_Adapter, then enter the main program
|
||||
// Note: the SIM_Adapter will not enter the main program after power up. Please run this function before use SIM_Adapter.
|
||||
void I2C_Reset_EnterMainProgram(void) {
|
||||
static void I2C_Reset_EnterMainProgram(void) {
|
||||
I2C_SetResetStatus(0, 0, 0); // 拉低复位线
|
||||
SpinDelay(30);
|
||||
I2C_SetResetStatus(1, 0, 0); // 解除复位
|
||||
|
@ -98,19 +106,9 @@ void I2C_Reset_EnterMainProgram(void) {
|
|||
SpinDelay(10);
|
||||
}
|
||||
|
||||
// 复位进入引导模式
|
||||
// Reset the SIM_Adapter, then enter the bootloader program
|
||||
// Reserve:For firmware update.
|
||||
void I2C_Reset_EnterBootloader(void) {
|
||||
I2C_SetResetStatus(0, 1, 1); // 拉低复位线
|
||||
SpinDelay(100);
|
||||
I2C_SetResetStatus(1, 1, 1); // 解除复位
|
||||
SpinDelay(10);
|
||||
}
|
||||
|
||||
// 等待时钟变高
|
||||
// Wait for the clock to go High.
|
||||
bool WaitSCL_H_delay(uint32_t delay) {
|
||||
static bool WaitSCL_H_delay(uint32_t delay) {
|
||||
while (delay--) {
|
||||
if (SCL_read) {
|
||||
return true;
|
||||
|
@ -120,26 +118,26 @@ bool WaitSCL_H_delay(uint32_t delay) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// 5000 * 3.07us = 15350us. 15.35ms
|
||||
bool WaitSCL_H(void) {
|
||||
return WaitSCL_H_delay(5000);
|
||||
// 15000 * 3.07us = 46050us. 46.05ms
|
||||
static bool WaitSCL_H(void) {
|
||||
return WaitSCL_H_delay(15000);
|
||||
}
|
||||
|
||||
// Wait max 300ms or until SCL goes LOW.
|
||||
// Which ever comes first
|
||||
bool WaitSCL_L_300ms(void) {
|
||||
volatile uint16_t delay = 300;
|
||||
while ( delay-- ) {
|
||||
// exit on SCL LOW
|
||||
if (!SCL_read)
|
||||
bool WaitSCL_L_delay(uint32_t delay) {
|
||||
while (delay--) {
|
||||
if (!SCL_read) {
|
||||
return true;
|
||||
|
||||
SpinDelay(1);
|
||||
}
|
||||
I2C_DELAY_1CLK;
|
||||
}
|
||||
return (delay == 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool I2C_Start(void) {
|
||||
bool WaitSCL_L(void) {
|
||||
return WaitSCL_L_delay(15000);
|
||||
}
|
||||
|
||||
static bool I2C_Start(void) {
|
||||
|
||||
I2C_DELAY_XCLK(4);
|
||||
SDA_H; I2C_DELAY_1CLK;
|
||||
|
@ -155,22 +153,8 @@ bool I2C_Start(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool I2C_WaitForSim() {
|
||||
// variable delay here.
|
||||
if (!WaitSCL_L_300ms())
|
||||
return false;
|
||||
|
||||
// 8051 speaks with smart card.
|
||||
// 1000*50*3.07 = 153.5ms
|
||||
// 1byte transfer == 1ms
|
||||
if (!WaitSCL_H_delay(2000*50) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// send i2c STOP
|
||||
void I2C_Stop(void) {
|
||||
static void I2C_Stop(void) {
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
SDA_L; I2C_DELAY_2CLK;
|
||||
SCL_H; I2C_DELAY_2CLK;
|
||||
|
@ -179,29 +163,14 @@ void I2C_Stop(void) {
|
|||
I2C_DELAY_XCLK(8);
|
||||
}
|
||||
|
||||
// Send i2c ACK
|
||||
void I2C_Ack(void) {
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
SDA_L; I2C_DELAY_2CLK;
|
||||
SCL_H; I2C_DELAY_2CLK;
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
}
|
||||
|
||||
// Send i2c NACK
|
||||
void I2C_NoAck(void) {
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
SDA_H; I2C_DELAY_2CLK;
|
||||
SCL_H; I2C_DELAY_2CLK;
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
}
|
||||
|
||||
bool I2C_WaitAck(void) {
|
||||
static bool I2C_WaitAck(void) {
|
||||
SCL_L; I2C_DELAY_1CLK;
|
||||
SDA_H; I2C_DELAY_1CLK;
|
||||
SCL_H;
|
||||
if (!WaitSCL_H())
|
||||
return false;
|
||||
|
||||
I2C_DELAY_2CLK;
|
||||
I2C_DELAY_2CLK;
|
||||
if (SDA_read) {
|
||||
SCL_L;
|
||||
|
@ -211,10 +180,10 @@ bool I2C_WaitAck(void) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void I2C_SendByte(uint8_t data) {
|
||||
uint8_t i = 8;
|
||||
static void I2C_SendByte(uint8_t data) {
|
||||
uint8_t bits = 8;
|
||||
|
||||
while (i--) {
|
||||
while (bits--) {
|
||||
SCL_L; I2C_DELAY_1CLK;
|
||||
|
||||
if (data & 0x80)
|
||||
|
@ -223,6 +192,7 @@ void I2C_SendByte(uint8_t data) {
|
|||
SDA_L;
|
||||
|
||||
data <<= 1;
|
||||
|
||||
I2C_DELAY_1CLK;
|
||||
|
||||
SCL_H;
|
||||
|
@ -234,18 +204,92 @@ void I2C_SendByte(uint8_t data) {
|
|||
SCL_L;
|
||||
}
|
||||
|
||||
uint8_t I2C_ReadByte(void) {
|
||||
uint8_t i = 8, b = 0;
|
||||
bool I2C_is_available(void) {
|
||||
I2C_init();
|
||||
I2C_Reset_EnterMainProgram();
|
||||
if (!I2C_Start()) // some other device is active on the bus
|
||||
return true;
|
||||
I2C_SendByte(I2C_DEVICE_ADDRESS_MAIN & 0xFE);
|
||||
if (!I2C_WaitAck()) { // no response from smartcard reader
|
||||
I2C_Stop();
|
||||
return false;
|
||||
}
|
||||
I2C_Stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef WITH_SMARTCARD
|
||||
// 复位进入引导模式
|
||||
// Reset the SIM_Adapter, then enter the bootloader program
|
||||
// Reserve:For firmware update.
|
||||
static void I2C_Reset_EnterBootloader(void) {
|
||||
I2C_SetResetStatus(0, 1, 1); // 拉低复位线
|
||||
SpinDelay(100);
|
||||
I2C_SetResetStatus(1, 1, 1); // 解除复位
|
||||
SpinDelay(10);
|
||||
}
|
||||
|
||||
// Wait max 300ms or until SCL goes LOW.
|
||||
// Which ever comes first
|
||||
static bool WaitSCL_L_300ms(void) {
|
||||
volatile uint16_t delay = 310;
|
||||
while ( delay-- ) {
|
||||
// exit on SCL LOW
|
||||
if (!SCL_read)
|
||||
return true;
|
||||
|
||||
SpinDelay(1);
|
||||
}
|
||||
return (delay == 0);
|
||||
}
|
||||
|
||||
static bool I2C_WaitForSim() {
|
||||
// variable delay here.
|
||||
if (!WaitSCL_L_300ms())
|
||||
return false;
|
||||
|
||||
// 8051 speaks with smart card.
|
||||
// 1000*50*3.07 = 153.5ms
|
||||
// 1byte transfer == 1ms with max frame being 256bytes
|
||||
if (!WaitSCL_H_delay(10 * 1000 * 50))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Send i2c ACK
|
||||
static void I2C_Ack(void) {
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
SDA_L; I2C_DELAY_2CLK;
|
||||
SCL_H; I2C_DELAY_2CLK;
|
||||
if (!WaitSCL_H()) return;
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
}
|
||||
|
||||
// Send i2c NACK
|
||||
static void I2C_NoAck(void) {
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
SDA_H; I2C_DELAY_2CLK;
|
||||
SCL_H; I2C_DELAY_2CLK;
|
||||
if (!WaitSCL_H()) return;
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
}
|
||||
|
||||
static int16_t I2C_ReadByte(void) {
|
||||
uint8_t bits = 8, b = 0;
|
||||
|
||||
SDA_H;
|
||||
while (i--) {
|
||||
while (bits--) {
|
||||
b <<= 1;
|
||||
SCL_L; I2C_DELAY_2CLK;
|
||||
SCL_H;
|
||||
if (!WaitSCL_H())
|
||||
return 0;
|
||||
SCL_L;
|
||||
if (!WaitSCL_L()) return -2;
|
||||
|
||||
I2C_DELAY_1CLK;
|
||||
|
||||
I2C_DELAY_2CLK;
|
||||
SCL_H;
|
||||
if (!WaitSCL_H()) return -1;
|
||||
|
||||
I2C_DELAY_1CLK;
|
||||
if (SDA_read)
|
||||
b |= 0x01;
|
||||
}
|
||||
|
@ -254,7 +298,7 @@ uint8_t I2C_ReadByte(void) {
|
|||
}
|
||||
|
||||
// Sends one byte ( command to be written, SlaveDevice address)
|
||||
bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address) {
|
||||
static bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address) {
|
||||
bool bBreak = true;
|
||||
do {
|
||||
if (!I2C_Start())
|
||||
|
@ -281,7 +325,7 @@ bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address) {
|
|||
|
||||
// 写入1字节数据 (待写入数据,待写入地址,器件类型)
|
||||
// Sends 1 byte data (Data to be written, command to be written , SlaveDevice address ).
|
||||
bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) {
|
||||
static bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) {
|
||||
bool bBreak = true;
|
||||
do {
|
||||
if (!I2C_Start())
|
||||
|
@ -313,7 +357,7 @@ bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) {
|
|||
// 写入1串数据(待写入数组地址,待写入长度,待写入地址,器件类型)
|
||||
//Sends a string of data (Array, length, command to be written , SlaveDevice address ).
|
||||
// len = uint8 (max buffer to write 256bytes)
|
||||
bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) {
|
||||
static bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) {
|
||||
bool bBreak = true;
|
||||
do {
|
||||
if (!I2C_Start())
|
||||
|
@ -352,16 +396,16 @@ bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t dev
|
|||
// 读出1串数据(存放读出数据,待读出长度,带读出地址,器件类型)
|
||||
// read 1 strings of data (Data array, Readout length, command to be written , SlaveDevice address ).
|
||||
// len = uint8 (max buffer to read 256bytes)
|
||||
uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) {
|
||||
static int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) {
|
||||
|
||||
if ( !data || len == 0 )
|
||||
return 0;
|
||||
|
||||
// extra wait 500us (514us measured)
|
||||
// 200us (xx measured)
|
||||
SpinDelayUs(200);
|
||||
SpinDelayUs(600);
|
||||
bool bBreak = true;
|
||||
uint8_t readcount = 0;
|
||||
uint16_t readcount = 0;
|
||||
|
||||
do {
|
||||
if (!I2C_Start())
|
||||
|
@ -391,11 +435,14 @@ uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
|
|||
return 0;
|
||||
}
|
||||
|
||||
// reading
|
||||
while (len) {
|
||||
|
||||
*data = I2C_ReadByte();
|
||||
|
||||
int16_t tmp = I2C_ReadByte();
|
||||
if ( tmp < 0 )
|
||||
return tmp;
|
||||
|
||||
*data = (uint8_t)tmp & 0xFF;
|
||||
|
||||
len--;
|
||||
|
||||
// 读取的第一个字节为后续长度
|
||||
|
@ -416,10 +463,10 @@ uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d
|
|||
|
||||
I2C_Stop();
|
||||
// return bytecount - first byte (which is length byte)
|
||||
return (readcount) ? --readcount : 0;
|
||||
return --readcount;
|
||||
}
|
||||
|
||||
uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) {
|
||||
static int16_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) {
|
||||
//START, 0xB0, 0x00, 0x00, START, 0xB1, xx, yy, zz, ......, STOP
|
||||
bool bBreak = true;
|
||||
uint8_t readcount = 0;
|
||||
|
@ -461,8 +508,13 @@ uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t
|
|||
|
||||
// reading
|
||||
while (len) {
|
||||
*data = I2C_ReadByte();
|
||||
|
||||
|
||||
int16_t tmp = I2C_ReadByte();
|
||||
if ( tmp < 0 )
|
||||
return tmp;
|
||||
|
||||
*data = (uint8_t)tmp & 0xFF;
|
||||
|
||||
data++;
|
||||
readcount++;
|
||||
len--;
|
||||
|
@ -478,7 +530,7 @@ uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t
|
|||
return readcount;
|
||||
}
|
||||
|
||||
bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) {
|
||||
static bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) {
|
||||
//START, 0xB0, 0x00, 0x00, xx, yy, zz, ......, STOP
|
||||
bool bBreak = true;
|
||||
|
||||
|
@ -534,13 +586,40 @@ void I2C_print_status(void) {
|
|||
DbpString(" version.................FAILED");
|
||||
}
|
||||
|
||||
bool GetATR(smart_card_atr_t *card_ptr) {
|
||||
|
||||
// clear
|
||||
if ( card_ptr ) {
|
||||
card_ptr->atr_len = 0;
|
||||
memset(card_ptr->atr, 0, sizeof(card_ptr->atr));
|
||||
// Will read response from smart card module, retries 3 times to get the data.
|
||||
static bool sc_rx_bytes(uint8_t* dest, uint8_t *destlen) {
|
||||
uint8_t i = 3;
|
||||
int16_t len = 0;
|
||||
while (i--) {
|
||||
|
||||
I2C_WaitForSim();
|
||||
|
||||
len = I2C_BufferRead(dest, *destlen, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN);
|
||||
|
||||
if ( len > 1 ){
|
||||
break;
|
||||
} else if ( len == 1 ) {
|
||||
continue;
|
||||
} else if ( len <= 0 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// after three
|
||||
if ( len <= 1 )
|
||||
return false;
|
||||
|
||||
*destlen = (uint8_t)len & 0xFF;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GetATR(smart_card_atr_t *card_ptr) {
|
||||
|
||||
if ( !card_ptr ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
card_ptr->atr_len = 0;
|
||||
memset(card_ptr->atr, 0, sizeof(card_ptr->atr));
|
||||
|
||||
// Send ATR
|
||||
// start [C0 01] stop start C1 len aa bb cc stop]
|
||||
|
@ -548,16 +627,38 @@ bool GetATR(smart_card_atr_t *card_ptr) {
|
|||
uint8_t cmd[1] = {1};
|
||||
LogTrace(cmd, 1, 0, 0, NULL, true);
|
||||
|
||||
//wait for sim card to answer.
|
||||
// wait for sim card to answer.
|
||||
// 1byte = 1ms, max frame 256bytes. Should wait 256ms at least just in case.
|
||||
if (!I2C_WaitForSim())
|
||||
return false;
|
||||
|
||||
// read answer
|
||||
uint8_t len = I2C_BufferRead(card_ptr->atr, sizeof(card_ptr->atr), I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN);
|
||||
|
||||
if ( len == 0 )
|
||||
// read bytes from module
|
||||
uint8_t len = sizeof(card_ptr->atr);
|
||||
if ( !sc_rx_bytes(card_ptr->atr, &len) )
|
||||
return false;
|
||||
|
||||
uint8_t pos_td = 1;
|
||||
if ( (card_ptr->atr[1] & 0x10) == 0x10) pos_td++;
|
||||
if ( (card_ptr->atr[1] & 0x20) == 0x20) pos_td++;
|
||||
if ( (card_ptr->atr[1] & 0x40) == 0x40) pos_td++;
|
||||
|
||||
// T0 indicate presence T=0 vs T=1. T=1 has checksum TCK
|
||||
if ( (card_ptr->atr[1] & 0x80) == 0x80) {
|
||||
|
||||
pos_td++;
|
||||
|
||||
// 1 == T1 , presence of checksum TCK
|
||||
if ( (card_ptr->atr[pos_td] & 0x01) == 0x01) {
|
||||
uint8_t chksum = 0;
|
||||
// xor property. will be zero when xored with chksum.
|
||||
for (uint8_t i = 1; i < len; ++i)
|
||||
chksum ^= card_ptr->atr[i];
|
||||
if ( chksum ) {
|
||||
if ( MF_DBGLEVEL > 2) DbpString("Wrong ATR checksum");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for some reason we only get first byte of atr, if that is so, send dummy command to retrieve the rest of the atr
|
||||
if (len == 1) {
|
||||
|
||||
|
@ -571,10 +672,8 @@ bool GetATR(smart_card_atr_t *card_ptr) {
|
|||
len = len + len2;
|
||||
}
|
||||
|
||||
if ( card_ptr ) {
|
||||
card_ptr->atr_len = len;
|
||||
LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false);
|
||||
}
|
||||
card_ptr->atr_len = len;
|
||||
LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -631,7 +730,9 @@ void SmartCardRaw( uint64_t arg0, uint64_t arg1, uint8_t *data ) {
|
|||
if ( !I2C_WaitForSim() )
|
||||
goto OUT;
|
||||
|
||||
len = I2C_BufferRead(resp, ISO7618_MAX_FRAME, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN);
|
||||
// read bytes from module
|
||||
len = ISO7618_MAX_FRAME;
|
||||
sc_rx_bytes(resp, &len);
|
||||
LogTrace(resp, len, 0, 0, NULL, false);
|
||||
}
|
||||
OUT:
|
||||
|
@ -652,7 +753,7 @@ void SmartCardUpgrade(uint64_t arg0) {
|
|||
I2C_Reset_EnterBootloader();
|
||||
|
||||
bool isOK = true;
|
||||
uint8_t res = 0;
|
||||
int16_t res = 0;
|
||||
uint16_t length = arg0;
|
||||
uint16_t pos = 0;
|
||||
uint8_t *fwdata = BigBuf_get_addr();
|
||||
|
@ -680,7 +781,7 @@ void SmartCardUpgrade(uint64_t arg0) {
|
|||
|
||||
// read
|
||||
res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT);
|
||||
if ( res == 0) {
|
||||
if ( res <= 0) {
|
||||
DbpString("Reading back failed");
|
||||
isOK = false;
|
||||
break;
|
||||
|
@ -718,3 +819,5 @@ void SmartCardSetClock(uint64_t arg0) {
|
|||
set_tracing(false);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
#endif
|
33
armsrc/i2c.h
33
armsrc/i2c.h
|
@ -11,12 +11,8 @@
|
|||
#ifndef __I2C_H
|
||||
#define __I2C_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "BigBuf.h"
|
||||
#include "smartcard.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define I2C_DEVICE_ADDRESS_BOOT 0xB0
|
||||
#define I2C_DEVICE_ADDRESS_MAIN 0xC0
|
||||
|
@ -28,31 +24,14 @@
|
|||
#define I2C_DEVICE_CMD_SIM_CLC 0x05
|
||||
#define I2C_DEVICE_CMD_GETVERSION 0x06
|
||||
|
||||
bool I2C_is_available(void);
|
||||
|
||||
void I2C_init(void);
|
||||
void I2C_Reset(void);
|
||||
void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA);
|
||||
|
||||
void I2C_Reset_EnterMainProgram(void);
|
||||
void I2C_Reset_EnterBootloader(void);
|
||||
|
||||
bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address);
|
||||
|
||||
bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address);
|
||||
bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address);
|
||||
uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address);
|
||||
|
||||
// for firmware
|
||||
uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address);
|
||||
bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address);
|
||||
|
||||
bool GetATR(smart_card_atr_t *card_ptr);
|
||||
|
||||
// generic functions
|
||||
#ifdef WITH_SMARTCARD
|
||||
void SmartCardAtr(void);
|
||||
void SmartCardRaw(uint64_t arg0, uint64_t arg1, uint8_t *data);
|
||||
void SmartCardUpgrade(uint64_t arg0);
|
||||
//void SmartCardSetBaud(uint64_t arg0);
|
||||
void SmartCardSetClock(uint64_t arg0);
|
||||
void I2C_print_status(void);
|
||||
#endif
|
||||
|
||||
#endif // __I2C_H
|
||||
|
|
|
@ -1405,7 +1405,7 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity)
|
|||
ADC_MODE_PRESCALE(63) |
|
||||
ADC_MODE_STARTUP_TIME(1) |
|
||||
ADC_MODE_SAMPLE_HOLD_TIME(15);
|
||||
AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF);
|
||||
AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF_LOW);
|
||||
// start ADC
|
||||
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
|
||||
|
||||
|
@ -1432,12 +1432,12 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity)
|
|||
if (BUTTON_PRESS()) return 1;
|
||||
|
||||
// test if the field exists
|
||||
if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) {
|
||||
if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF_LOW)) {
|
||||
analogCnt++;
|
||||
analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF];
|
||||
analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF_LOW];
|
||||
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
|
||||
if (analogCnt >= 32) {
|
||||
if ((MAX_ADC_HF_VOLTAGE * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) {
|
||||
if ((MAX_ADC_HF_VOLTAGE_LOW * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) {
|
||||
vtime = GetTickCount();
|
||||
if (!timer) timer = vtime;
|
||||
// 50ms no field --> card to idle state
|
||||
|
|
|
@ -347,7 +347,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
|
||||
// find reader field
|
||||
if (cardSTATE == MFEMUL_NOFIELD) {
|
||||
int vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
|
||||
int vHf = (MAX_ADC_HF_VOLTAGE_LOW * AvgAdc(ADC_CHAN_HF_LOW)) >> 10;
|
||||
if (vHf > MF_MINFIELDV) {
|
||||
LED_A_ON();
|
||||
cardSTATE_TO_IDLE();
|
||||
|
|
|
@ -16,70 +16,71 @@
|
|||
#include "config_gpio.h"
|
||||
#include "usb_cmd.h"
|
||||
|
||||
#define WDT_HIT() AT91C_BASE_WDTC->WDTC_WDCR = 0xa5000001
|
||||
#define WDT_HIT() AT91C_BASE_WDTC->WDTC_WDCR = 0xa5000001
|
||||
|
||||
#define PWM_CH_MODE_PRESCALER(x) ((x)<<0)
|
||||
#define PWM_CHANNEL(x) (1<<(x))
|
||||
#define PWM_CH_MODE_PRESCALER(x) ((x)<<0)
|
||||
#define PWM_CHANNEL(x) (1<<(x))
|
||||
|
||||
#define ADC_CHAN_LF 4
|
||||
#define ADC_CHAN_HF 5
|
||||
#define ADC_MODE_PRESCALE(x) ((x)<<8)
|
||||
#define ADC_MODE_STARTUP_TIME(x) ((x)<<16)
|
||||
#define ADC_MODE_SAMPLE_HOLD_TIME(x) ((x)<<24)
|
||||
#define ADC_CHANNEL(x) (1<<(x))
|
||||
#define ADC_END_OF_CONVERSION(x) (1<<(x))
|
||||
#define ADC_CHAN_LF 4
|
||||
#define ADC_CHAN_HF_LOW 5
|
||||
#define ADC_CHAN_HF_HIGH 7
|
||||
#define ADC_MODE_PRESCALE(x) ((x)<<8)
|
||||
#define ADC_MODE_STARTUP_TIME(x) ((x)<<16)
|
||||
#define ADC_MODE_SAMPLE_HOLD_TIME(x) ((x)<<24)
|
||||
#define ADC_CHANNEL(x) (1<<(x))
|
||||
#define ADC_END_OF_CONVERSION(x) (1<<(x))
|
||||
|
||||
#define SSC_CLOCK_MODE_START(x) ((x)<<8)
|
||||
#define SSC_FRAME_MODE_WORDS_PER_TRANSFER(x) ((x)<<8)
|
||||
#define SSC_CLOCK_MODE_SELECT(x) ((x)<<0)
|
||||
#define SSC_FRAME_MODE_BITS_IN_WORD(x) (((x)-1)<<0)
|
||||
#define SSC_CLOCK_MODE_START(x) ((x)<<8)
|
||||
#define SSC_FRAME_MODE_WORDS_PER_TRANSFER(x) ((x)<<8)
|
||||
#define SSC_CLOCK_MODE_SELECT(x) ((x)<<0)
|
||||
#define SSC_FRAME_MODE_BITS_IN_WORD(x) (((x)-1)<<0)
|
||||
|
||||
#define MC_FLASH_COMMAND_KEY ((0x5a)<<24)
|
||||
#define MC_FLASH_MODE_FLASH_WAIT_STATES(x) ((x)<<8)
|
||||
#define MC_FLASH_MODE_MASTER_CLK_IN_MHZ(x) (((x)+((x)/2))<<16)
|
||||
#define MC_FLASH_COMMAND_PAGEN(x) ((x)<<8)
|
||||
#define MC_FLASH_COMMAND_KEY ((0x5a)<<24)
|
||||
#define MC_FLASH_MODE_FLASH_WAIT_STATES(x) ((x)<<8)
|
||||
#define MC_FLASH_MODE_MASTER_CLK_IN_MHZ(x) (((x)+((x)/2))<<16)
|
||||
#define MC_FLASH_COMMAND_PAGEN(x) ((x)<<8)
|
||||
|
||||
#define RST_CONTROL_KEY (0xa5<<24)
|
||||
#define RST_CONTROL_KEY (0xa5<<24)
|
||||
|
||||
#define PMC_MAIN_OSC_STARTUP_DELAY(x) ((x)<<8)
|
||||
#define PMC_PLL_DIVISOR(x) (x)
|
||||
#define PMC_PLL_MULTIPLIER(x) (((x)-1)<<16)
|
||||
#define PMC_PLL_COUNT_BEFORE_LOCK(x) ((x)<<8)
|
||||
#define PMC_PLL_FREQUENCY_RANGE(x) ((x)<<14)
|
||||
#define PMC_PLL_USB_DIVISOR(x) ((x)<<28)
|
||||
#define PMC_MAIN_OSC_STARTUP_DELAY(x) ((x)<<8)
|
||||
#define PMC_PLL_DIVISOR(x) (x)
|
||||
#define PMC_PLL_MULTIPLIER(x) (((x)-1)<<16)
|
||||
#define PMC_PLL_COUNT_BEFORE_LOCK(x) ((x)<<8)
|
||||
#define PMC_PLL_FREQUENCY_RANGE(x) ((x)<<14)
|
||||
#define PMC_PLL_USB_DIVISOR(x) ((x)<<28)
|
||||
|
||||
#define UDP_INTERRUPT_ENDPOINT(x) (1<<(x))
|
||||
#define UDP_CSR_BYTES_RECEIVED(x) (((x) >> 16) & 0x7ff)
|
||||
#define UDP_INTERRUPT_ENDPOINT(x) (1<<(x))
|
||||
#define UDP_CSR_BYTES_RECEIVED(x) (((x) >> 16) & 0x7ff)
|
||||
//**************************************************************
|
||||
|
||||
#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x)
|
||||
#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x)
|
||||
#define GETBIT(x) (AT91C_BASE_PIOA->PIO_ODSR & (x)) ? 1:0
|
||||
#define SETBIT(x, y) (y) ? (HIGH(x)):(LOW(x))
|
||||
#define INVBIT(x) SETBIT((x), !(GETBIT(x)))
|
||||
#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x)
|
||||
#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x)
|
||||
#define GETBIT(x) (AT91C_BASE_PIOA->PIO_ODSR & (x)) ? 1:0
|
||||
#define SETBIT(x, y) (y) ? (HIGH(x)):(LOW(x))
|
||||
#define INVBIT(x) SETBIT((x), !(GETBIT(x)))
|
||||
|
||||
#define SPI_FPGA_MODE 0
|
||||
#define SPI_LCD_MODE 1
|
||||
#define SPI_FPGA_MODE 0
|
||||
#define SPI_LCD_MODE 1
|
||||
|
||||
//#define PACKED __attribute__((__packed__))
|
||||
|
||||
#define LED_A_ON() HIGH(GPIO_LED_A)
|
||||
#define LED_A_OFF() LOW(GPIO_LED_A)
|
||||
#define LED_A_INV() INVBIT(GPIO_LED_A)
|
||||
#define LED_B_ON() HIGH(GPIO_LED_B)
|
||||
#define LED_B_OFF() LOW(GPIO_LED_B)
|
||||
#define LED_B_INV() INVBIT(GPIO_LED_B)
|
||||
#define LED_C_ON() HIGH(GPIO_LED_C)
|
||||
#define LED_C_OFF() LOW(GPIO_LED_C)
|
||||
#define LED_C_INV() INVBIT(GPIO_LED_C)
|
||||
#define LED_D_ON() HIGH(GPIO_LED_D)
|
||||
#define LED_D_OFF() LOW(GPIO_LED_D)
|
||||
#define LED_D_INV() INVBIT(GPIO_LED_D)
|
||||
#define RELAY_ON() HIGH(GPIO_RELAY)
|
||||
#define RELAY_OFF() LOW(GPIO_RELAY)
|
||||
#define BUTTON_PRESS() !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON)
|
||||
#define LED_A_ON() HIGH(GPIO_LED_A)
|
||||
#define LED_A_OFF() LOW(GPIO_LED_A)
|
||||
#define LED_A_INV() INVBIT(GPIO_LED_A)
|
||||
#define LED_B_ON() HIGH(GPIO_LED_B)
|
||||
#define LED_B_OFF() LOW(GPIO_LED_B)
|
||||
#define LED_B_INV() INVBIT(GPIO_LED_B)
|
||||
#define LED_C_ON() HIGH(GPIO_LED_C)
|
||||
#define LED_C_OFF() LOW(GPIO_LED_C)
|
||||
#define LED_C_INV() INVBIT(GPIO_LED_C)
|
||||
#define LED_D_ON() HIGH(GPIO_LED_D)
|
||||
#define LED_D_OFF() LOW(GPIO_LED_D)
|
||||
#define LED_D_INV() INVBIT(GPIO_LED_D)
|
||||
#define RELAY_ON() HIGH(GPIO_RELAY)
|
||||
#define RELAY_OFF() LOW(GPIO_RELAY)
|
||||
#define BUTTON_PRESS() !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON)
|
||||
|
||||
#define VERSION_INFORMATION_MAGIC 0x56334d50
|
||||
#define VERSION_INFORMATION_MAGIC 0x56334d50
|
||||
struct version_information {
|
||||
int magic; /* Magic sequence to identify this as a correct version information structure. Must be VERSION_INFORMATION_MAGIC */
|
||||
char versionversion; /* Must be 1 */
|
||||
|
@ -89,9 +90,9 @@ struct version_information {
|
|||
char buildtime[30]; /* string with the build time */
|
||||
} __attribute__((packed));
|
||||
|
||||
#define COMMON_AREA_MAGIC 0x43334d50
|
||||
#define COMMON_AREA_COMMAND_NONE 0
|
||||
#define COMMON_AREA_COMMAND_ENTER_FLASH_MODE 1
|
||||
#define COMMON_AREA_MAGIC 0x43334d50
|
||||
#define COMMON_AREA_COMMAND_NONE 0
|
||||
#define COMMON_AREA_COMMAND_ENTER_FLASH_MODE 1
|
||||
struct common_area {
|
||||
int magic; /* Magic sequence, to distinguish against random uninitialized memory */
|
||||
char version; /* Must be 1 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue