Files
2026-08-29 17:42:29 +02:00

30 lines
1.4 KiB
C

#include "rssi_apis.h"
#include "at91sam7s512.h"
#include "proxmark3_arm.h"
void AdcSetupRssiChannel(adc_rssi_ch_t 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
// 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:
// If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be
//
// v_cap = v_in * (1 - exp(-SHTIM/RC)) = v_in * (1 - exp(-40us/10.9us)) = v_in * 0,97 (i.e. an error of 3%)
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
AT91C_BASE_ADC->ADC_MR =
ADC_MODE_PRESCALE(63) // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
| ADC_MODE_STARTUP_TIME(1) // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us
| ADC_MODE_SAMPLE_HOLD_TIME(15); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us
if (ch == ADC_RSSI_CH_HF) {
AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF);
} else {
AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_LF);
}
AdcRssiConversionStart();
}