From 21ffdec1cdbabd6e18620c82ce662fd835a398d0 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 1 Jan 2020 18:18:34 +0100 Subject: [PATCH] chg: hitag refactoring (@anon) --- armsrc/appmain.c | 4 +-- armsrc/fpgaloader.h | 3 +- armsrc/lfops.c | 8 ++--- armsrc/lfsampling.c | 2 +- fpga/fpga_lf.v | 80 ++++++++++++++++++++++++++++-------------- fpga/lo_adc.v | 48 +++++++++++++++---------- fpga/min_max_tracker.v | 6 ++-- 7 files changed, 95 insertions(+), 56 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 62feed4d0..a405db12e 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -175,7 +175,7 @@ void MeasureAntennaTuning(void) { */ FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); SpinDelay(50); for (uint8_t i = 255; i >= 19; i--) { @@ -1518,7 +1518,7 @@ static void PacketReceived(PacketCommandNG *packet) { case 1: // MEASURE_ANTENNA_TUNING_LF_START // Let the FPGA drive the low-frequency antenna around 125kHz FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, packet->data.asBytes[1]); reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, NULL, 0); break; diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 83c5bb2e4..6f27c10ee 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -28,9 +28,10 @@ #define FPGA_CMD_SET_USER_BYTE1 (3<<12) // Definitions for the FPGA configuration word. // LF -#define FPGA_MAJOR_MODE_LF_ADC (0<<5) +#define FPGA_MAJOR_MODE_LF_READER (0<<5) #define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5) #define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<5) +#define FPGA_MAJOR_MODE_LF_ADC (3<<5) // HF #define FPGA_MAJOR_MODE_HF_READER_TX (0<<5) #define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (1<<5) diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 4c869d9d6..94f7ece2a 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -446,7 +446,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint } else { // if field already on leave alone (affects timing otherwise) if (off) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); off = false; } @@ -470,7 +470,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); } - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // now do the read DoAcquisition_config(false, 0); @@ -1524,7 +1524,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { */ void TurnReadLFOn(uint32_t delay) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // measure antenna strength. //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); @@ -2482,7 +2482,7 @@ void Cotag(uint32_t arg0) { # define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } #endif #ifndef ON -# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } +# define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } #endif uint8_t rawsignal = arg0 & 0xF; diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 48a3f0d97..bdce67ef9 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -104,7 +104,7 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) { else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); // Connect the A/D to the peak-detected low-frequency path. SetAdcMuxFor(GPIO_MUXSEL_LOPKD); diff --git a/fpga/fpga_lf.v b/fpga/fpga_lf.v index 88b22b7ca..9c1c2528f 100644 --- a/fpga/fpga_lf.v +++ b/fpga/fpga_lf.v @@ -1,7 +1,29 @@ //----------------------------------------------------------------------------- // Jonathan Westhues, March 2006 // iZsh , June 2014 +// Piwi, Feb 2019 +// Anon, 2019 //----------------------------------------------------------------------------- +// Defining commands, modes and options. This must be aligned to the definitions in fpgaloader.h +// Note: the definitions here are without shifts + +// Commands: +`define FPGA_CMD_SET_CONFREG 1 +`define FPGA_CMD_SET_DIVISOR 2 +`define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD 3 + +// Major modes: +`define FPGA_MAJOR_MODE_LF_READER 0 +`define FPGA_MAJOR_MODE_LF_EDGE_DETECT 1 +`define FPGA_MAJOR_MODE_LF_PASSTHRU 2 +`define FPGA_MAJOR_MODE_LF_ADC 3 + +// Options for LF_ADC +`define FPGA_LF_ADC_READER_FIELD 1 + +// Options for LF_EDGE_DETECT +`define FPGA_LF_EDGE_DETECT_READER_FIELD 1 +`define FPGA_LF_EDGE_DETECT_TOGGLE_MODE 2 `include "lo_read.v" `include "lo_passthru.v" @@ -30,39 +52,44 @@ module fpga_lf( reg [15:0] shift_reg; reg [7:0] divisor; -reg [7:0] conf_word; -reg [7:0] user_byte1; +reg [8:0] conf_word; + +// threshold edge detect +reg [7:0] lf_ed_threshold; always @(posedge ncs) begin - case(shift_reg[15:12]) - 4'b0001: + case (shift_reg[15:12]) + `FPGA_CMD_SET_CONFREG: + begin + conf_word <= shift_reg[8:0]; + if (shift_reg[8:6] == `FPGA_MAJOR_MODE_LF_EDGE_DETECT) begin - conf_word <= shift_reg[7:0]; - if (shift_reg[7:0] == 8'b00000001) begin // LF edge detect - user_byte1 <= 127; // default threshold - end + lf_ed_threshold <= 127; // default threshold end - 4'b0010: divisor <= shift_reg[7:0]; // FPGA_CMD_SET_DIVISOR - 4'b0011: user_byte1 <= shift_reg[7:0]; // FPGA_CMD_SET_USER_BYTE1 + end + `FPGA_CMD_SET_DIVISOR: + divisor <= shift_reg[7:0]; + `FPGA_CMD_SET_EDGE_DETECT_THRESHOLD: + lf_ed_threshold <= shift_reg[7:0]; endcase end +// always @(posedge spck) begin - if(~ncs) + if (~ncs) begin shift_reg[15:1] <= shift_reg[14:0]; shift_reg[0] <= mosi; end end -wire [2:0] major_mode = conf_word[7:5]; +wire [2:0] major_mode = conf_word[8:6]; // For the low-frequency configuration: wire lf_field = conf_word[0]; wire lf_ed_toggle_mode = conf_word[1]; // for lo_edge_detect -wire [7:0] lf_ed_threshold = user_byte1; //----------------------------------------------------------------------------- // And then we instantiate the modules corresponding to each of the FPGA's @@ -106,9 +133,8 @@ lo_adc la( la_pwr_lo, la_pwr_hi, la_pwr_oe1, la_pwr_oe2, la_pwr_oe3, la_pwr_oe4, adc_d, la_adc_clk, la_ssp_frame, la_ssp_din, ssp_dout, la_ssp_clk, - cross_hi, cross_lo, la_dbg, divisor, - lo_is_125khz, lf_field + lf_field ); // Major modes: @@ -118,18 +144,18 @@ lo_adc la( // 011 -- LF ADC (read/write) // 110 -- FPGA_MAJOR_MODE_OFF_LF (rdv40 specific) // 111 -- FPGA_MAJOR_MODE_OFF -// 000 001 010 011 100 101 110 111 -mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, la_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, la_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, la_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, la_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, la_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, la_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, la_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, la_pwr_lo, 1'b0, 1'b0, 1'b1, 1'b0); -mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, la_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, la_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); -mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, la_dbg, 1'b0, 1'b0, 1'b0, 1'b0); +// 000 001 010 011 100 101 110 111 +mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, la_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, la_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_ssp_frame (major_mode, ssp_frame, lr_ssp_frame, le_ssp_frame, 1'b0, la_ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe1 (major_mode, pwr_oe1, lr_pwr_oe1, le_pwr_oe1, lp_pwr_oe1, la_pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe2 (major_mode, pwr_oe2, lr_pwr_oe2, le_pwr_oe2, lp_pwr_oe2, la_pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe3 (major_mode, pwr_oe3, lr_pwr_oe3, le_pwr_oe3, lp_pwr_oe3, la_pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_oe4 (major_mode, pwr_oe4, lr_pwr_oe4, le_pwr_oe4, lp_pwr_oe4, la_pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_pwr_lo (major_mode, pwr_lo, lr_pwr_lo, le_pwr_lo, lp_pwr_lo, la_pwr_lo, 1'b0, 1'b0, 1'b1, 1'b0); +mux8 mux_pwr_hi (major_mode, pwr_hi, lr_pwr_hi, le_pwr_hi, lp_pwr_hi, la_pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_adc_clk (major_mode, adc_clk, lr_adc_clk, le_adc_clk, lp_adc_clk, la_adc_clk, 1'b0, 1'b0, 1'b0, 1'b0); +mux8 mux_dbg (major_mode, dbg, lr_dbg, le_dbg, lp_dbg, la_dbg, 1'b0, 1'b0, 1'b0, 1'b0); // In all modes, let the ADC's outputs be enabled. assign adc_noe = 1'b0; diff --git a/fpga/lo_adc.v b/fpga/lo_adc.v index 57e9eebc8..8c1dd12e2 100644 --- a/fpga/lo_adc.v +++ b/fpga/lo_adc.v @@ -11,9 +11,8 @@ module lo_adc( pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4, adc_d, adc_clk, ssp_frame, ssp_din, ssp_dout, ssp_clk, - cross_hi, cross_lo, dbg, divisor, - lo_is_125khz, lf_field + lf_field ); input pck0; output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4; @@ -21,10 +20,8 @@ module lo_adc( output adc_clk; input ssp_dout; output ssp_frame, ssp_din, ssp_clk; - input cross_hi, cross_lo; output dbg; input [7:0] divisor; - input lo_is_125khz; // redundant signal, no longer used anywhere input lf_field; reg [7:0] to_arm_shiftreg; @@ -34,28 +31,39 @@ reg clk_state; // Antenna logic, depending on "lf_field" (in arm defined as FPGA_LF_READER_FIELD) wire tag_modulation; assign tag_modulation = ssp_dout & !lf_field; + wire reader_modulation; assign reader_modulation = !ssp_dout & lf_field & clk_state; -assign pwr_oe1 = 1'b0; // not used in LF mode -assign pwr_oe2 = 1'b0; //tag_modulation; -assign pwr_oe3 = tag_modulation; -assign pwr_oe4 = 1'b0; //tag_modulation; -assign pwr_lo = reader_modulation; + +// always on (High Frequency outputs, unused) +assign pwr_oe1 = 1'b0; assign pwr_hi = 1'b0; + +// low frequency outputs +assign pwr_lo = reader_modulation; +assign pwr_oe2 = 1'b0; // 33 Ohms +assign pwr_oe3 = tag_modulation; // base antenna load = 33 Ohms +assign pwr_oe4 = 1'b0; // 10k Ohms + +// Debug Output ADC clock assign dbg = adc_clk; // ADC clock out of phase with antenna driver assign adc_clk = ~clk_state; + // serialized SSP data is gated by clk_state to suppress unwanted signal assign ssp_din = to_arm_shiftreg[7] && !clk_state; + // SSP clock always runs at 24MHz assign ssp_clk = pck0; + // SSP frame is gated by clk_state and goes high when pck_divider=8..15 assign ssp_frame = (pck_divider[7:3] == 5'd1) && !clk_state; +// divide 24mhz down to 3mhz always @(posedge pck0) begin - if(pck_divider == divisor[7:0]) + if (pck_divider == divisor[7:0]) begin pck_divider <= 8'd0; clk_state = !clk_state; @@ -66,16 +74,20 @@ begin end end +// this task also runs at pck0 frequency (24Mhz) and is used to serialize +// the ADC output which is then clocked into the ARM SSP. always @(posedge pck0) begin - if((pck_divider == 8'd7) && !clk_state) - begin - to_arm_shiftreg <= adc_d; - end - else - begin - to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; - to_arm_shiftreg[0] <= 1'b0; + if ((pck_divider == 8'd7) && !clk_state) + to_arm_shiftreg <= adc_d; + else begin + to_arm_shiftreg[7:1] <= to_arm_shiftreg[6:0]; + // simulation showed a glitch occuring due to the LSB of the shifter + // not being set as we shift bits out + // this ensures the ssp_din remains low after a transfer and suppresses + // the glitch that would occur when the last data shifted out ended in + // a 1 bit and the next data shifted out started with a 0 bit + to_arm_shiftreg[0] <= 1'b0; end end diff --git a/fpga/min_max_tracker.v b/fpga/min_max_tracker.v index 06a395a70..5e8bbedf1 100644 --- a/fpga/min_max_tracker.v +++ b/fpga/min_max_tracker.v @@ -25,7 +25,7 @@ module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, always @(posedge clk) begin case (state) - 0: + 0: // initialize begin if (cur_max_val >= ({1'b0, adc_d} + threshold)) state <= 2; @@ -36,7 +36,7 @@ module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, else if (adc_d <= cur_min_val) cur_min_val <= adc_d; end - 1: + 1: // high phase begin if (cur_max_val <= adc_d) cur_max_val <= adc_d; @@ -46,7 +46,7 @@ module min_max_tracker(input clk, input [7:0] adc_d, input [7:0] threshold, max_val <= cur_max_val; end end - 2: + 2: // low phase begin if (adc_d <= cur_min_val) cur_min_val <= adc_d;