@@ -84,7 +84,8 @@ boolean isTxCacheSatisfied = false; // Will be tr
8484#define ADC_PIN 34 // If this is changed, you may need to manually edit adc1_config_channel_atten() below too.
8585#define PTT_PIN 18 // Keys up the radio module
8686#define PD_PIN 19
87- #define SQ_PIN 32
87+ // #define SQ_PIN 32
88+ uint8_t SQ_PIN = 32 ;
8889#define PHYS_PTT_PIN1 5 // Optional. Buttons may be attached to either or both of this and next pin. They behave the same.
8990#define PHYS_PTT_PIN2 33 // Optional. See above.
9091
@@ -129,6 +130,17 @@ bool lastSquelched = false;
129130#define ADC_ATTEN_DB_12 ADC_ATTEN_DB_11
130131#endif
131132
133+ // Hardware version detection
134+ #define HW_VER_PIN_0 39 // 0xF0
135+ #define HW_VER_PIN_1 36 // 0x0F
136+ typedef uint8_t hw_ver_t ; // This allows us to do a lot more in the future if we want.
137+ // LOW = 0, HIGH = F, 1 <= analog values <= E
138+ #define HW_VER_V1 (0x00 )
139+ #define HW_VER_V2_0C (0xFF )
140+ #define HW_VER_V2_0D (0xF0 )
141+ // #define HW_VER_?? (0x0F) // Unused
142+ hw_ver_t hardware_version = HW_VER_V1; // lowest common denominator
143+
132144// //////////////////////////////////////////////////////////////////////////////
133145// / Forward Declarations
134146// //////////////////////////////////////////////////////////////////////////////
@@ -139,13 +151,34 @@ void tuneTo(float freqTx, float freqRx, int tone, int squelch, String bandwidth)
139151void setMode (int newMode);
140152void processTxAudio (uint8_t tempBuffer[], int bytesRead);
141153void iir_lowpass_reset ();
154+ hw_ver_t get_hardware_version ();
155+ void reportPhysPttState ();
142156
143157void setup () {
158+ // Used for setup, need to know early.
159+ hardware_version = get_hardware_version ();
160+
144161 // Communication with Android via USB cable
145162 Serial.setRxBufferSize (USB_BUFFER_SIZE);
146163 Serial.setTxBufferSize (USB_BUFFER_SIZE);
147164 Serial.begin (230400 );
148165
166+ // Hardware dependent pin assignments.
167+ switch (hardware_version) {
168+ case HW_VER_V1:
169+ SQ_PIN = 32 ;
170+ break ;
171+ case HW_VER_V2_0C:
172+ SQ_PIN = 4 ;
173+ break ;
174+ case HW_VER_V2_0D:
175+ SQ_PIN = 4 ;
176+ break ;
177+ default :
178+ // Unknown version detected. Indicate this some way?
179+ break ;
180+ }
181+
149182 // Configure watch dog timer (WDT), which will reset the system if it gets stuck somehow.
150183 esp_task_wdt_init (10 , true ); // Reboot if locked up for a bit
151184 esp_task_wdt_add (NULL ); // Add the current task to WDT watch
@@ -182,7 +215,12 @@ void initI2SRx() {
182215
183216 // Initialize ADC
184217 adc1_config_width (ADC_WIDTH_BIT_12);
185- adc1_config_channel_atten (ADC1_CHANNEL_6, ADC_ATTEN_DB_12);
218+ if (hardware_version == HW_VER_V2_0C) {
219+ // v2.0c has a lower input ADC range
220+ adc1_config_channel_atten (ADC1_CHANNEL_6, ADC_ATTEN_DB_0);
221+ } else {
222+ adc1_config_channel_atten (ADC1_CHANNEL_6, ADC_ATTEN_DB_12);
223+ }
186224
187225 static const i2s_config_t i2sRxConfig = {
188226 .mode = (i2s_mode_t )(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN),
@@ -339,10 +377,16 @@ void loop() {
339377 radioModuleStatus = RADIO_MODULE_FOUND;
340378 }
341379
380+ if (hardware_version == HW_VER_V2_0C) {
381+ // v2.0c has a lower input ADC range.
382+ result = dra->volume (4 );
383+ } else {
342384 result = dra->volume (8 );
343- // Serial.println("volume: " + String(result));
344- result = dra->filters (false , false , false );
345- // Serial.println("filters: " + String(result));
385+ }
386+
387+ // Serial.println("volume: " + String(result));
388+ result = dra->filters (false , false , false );
389+ // Serial.println("filters: " + String(result));
346390
347391 Serial.write (VERSION_PREFIX, sizeof (VERSION_PREFIX)); // "VERSION"
348392 Serial.write (FIRMWARE_VER, sizeof (FIRMWARE_VER)); // "00000007" (or whatever)
@@ -354,6 +398,7 @@ void loop() {
354398 return ;
355399 }
356400
401+
357402 // TODO get rid of the code duplication here and in MODE_RX below to handle COMMAND_TUNE_TO and COMMAND_FILTERS.
358403 // Should probably just have one standardized way to read any incoming bytes from Android app here, and handle
359404 // commands appropriately. Or at least extract the business logic from them to avoid that duplication.
@@ -774,3 +819,17 @@ void processTxAudio(uint8_t tempBuffer[], int bytesRead) {
774819void reportPhysPttState () {
775820 sendCmdToAndroid (isPhysPttDown ? COMMAND_PHYS_PTT_DOWN : COMMAND_PHYS_PTT_UP);
776821}
822+
823+ hw_ver_t get_hardware_version () {
824+ pinMode (HW_VER_PIN_0, INPUT);
825+ pinMode (HW_VER_PIN_1, INPUT);
826+
827+ hw_ver_t ver = 0x00 ;
828+ ver |= (digitalRead (HW_VER_PIN_0) == HIGH ? 0x0F : 0x00 );
829+ ver |= (digitalRead (HW_VER_PIN_1) == HIGH ? 0xF0 : 0x00 );
830+
831+ // In the future, we're replace these with analogRead()s and
832+ // use values between 0x0 and 0xF. For now, just binary.
833+
834+ return ver;
835+ }
0 commit comments