├── README.md └── erasynth_micro └── erasynth_micro.ino /README.md: -------------------------------------------------------------------------------- 1 | # ERASynth Micro Arduino Firmware 2 | 3 | Please check our firmware update instructions document 4 | https://github.com/erainstruments/erasynth-micro-docs/blob/master/erasynth-micro-firmware-update-instructions.pdf 5 | -------------------------------------------------------------------------------- /erasynth_micro/erasynth_micro.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define ledPin 13 4 | #define currentPin A2 5 | #define adf4002_LE 4 6 | #define lmx_LE 8 7 | #define eeprom_LE 5 8 | #define dac1_LE 12 9 | #define rfsa_LE 6 10 | #define tcxoPin 11 11 | #define ampPin 9 12 | #define trigPin 7 13 | #define micPin A1 14 | #define extPin A0 15 | #define vibMotor 10 16 | #define temp_LE A5 17 | #define lmxRead A4 18 | #define adfRead A3 19 | 20 | #define ledBlinkInterval 500000 21 | #define maxSamplesNum 120 22 | #define cmdCharBuffer 25 23 | 24 | #define MODULATION_ON 1 25 | #define MODULATION_OFF 0 26 | 27 | #define MODULATION_AM 0 28 | #define MODULATION_FM 1 29 | #define MODULATION_PULSE 2 30 | 31 | #define MODULATION_INTERNAL 0 32 | #define MODULATION_EXTERNAL 1 33 | #define MODULATION_MICROPHONE 2 34 | 35 | #define MODULATION_SINE 0 36 | #define MODULATION_RAMP 1 37 | #define MODULATION_SQUARE 2 38 | #define MODULATION_TRIANGLE 3 39 | 40 | #define FSK_ADDRESS 0x7C 41 | 42 | #define EEPROM_START_ADDR 20 43 | #define VERSION_SIZE 10 44 | #define VERSION_ADDR 2 45 | 46 | #define EXTERNAL_EEPROM_READ 0x03 47 | #define EXTERNAL_EEPROM_WRITE 0x02 48 | #define EXTERNAL_EEPROM_WREN 0x06 49 | #define EXTERNAL_EEPROM_MAX_CLOCK 5e6 50 | 51 | #define LMX_CAL_15 32000 52 | #define LMX_CAL_21 33000 53 | #define F2250_CAL_15 34000 54 | #define F2250_CAL_14 36000 55 | #define F2250_CAL_13 38000 56 | #define F2250_CAL_12 40000 57 | #define F2250_CAL_11 42000 58 | #define F2250_CAL_10 44000 59 | #define F2250_CAL_21 46000 60 | 61 | #define LMX_REG_ADDR 51 62 | #define ADF_REG_ADDR 500 63 | 64 | #define SINE_WAVEFORM_ADDR 601 65 | #define RAMP_WAVEFORM_ADDR 1001 66 | #define SQUARE_WAVEFORM_ADDR 1401 67 | #define TRIANGLE_WAVEFORM_ADDR 1801 68 | 69 | #define SETTINGS_ADDR 2201 70 | #define SETTINGS_LENGTH 800 71 | #define INITIATION_ADDR 0 72 | #define REMEMBER_ADDR 1 73 | 74 | #define MINUMUM_FREQUENCY 12500000 75 | #define MAXIMUM_FREQUENCY 6400000000 76 | #define MAXIMUM_INT_MOD_FREQ 20000 77 | #define MINUMUM_DWELL 1000 78 | #define MAXIMUM_DEVIATION 100000000000 79 | #define MINUMUM_PULSE 50 80 | 81 | #define DEFAULT_DELAY_AM 6000 // nanosecond 82 | #define DEFAULT_DELAY_FM 5250 // nanosecond 83 | 84 | uint8_t ledState = LOW; 85 | 86 | uint32_t LMX_R0_reset = 0x00211E; 87 | uint32_t LMX_R0 = 0x00211C; 88 | uint32_t LMX_R0_ADDR_HOLD = 0x00291C; 89 | uint32_t LMX_R0_ADDR_HOLD_mute = 0x00291D; 90 | uint32_t LMX_R0_mute = 0x00211D; 91 | 92 | // Serial interface parameters 93 | bool stringComplete = false; 94 | bool isCmdExist = false; 95 | bool serialActivityExist = false; 96 | char commandInString[32] = { 0 }; 97 | char cmdString[32] = { 0 }; 98 | char cmd1String[32] = { 0 }; 99 | char lcdCommand[32]; 100 | uint8_t termCount = 0; 101 | 102 | bool isModulationEnable = false; 103 | uint8_t modType = 0; 104 | uint8_t modInput = 0; 105 | uint8_t modWaveForm = 0; 106 | uint32_t modIntFreq = 1000; 107 | 108 | uint8_t amDepth = 99; 109 | uint32_t fmDev = 50000; 110 | uint32_t pulseWidth = 5000; 111 | uint32_t pulsePeriod = 10000; 112 | 113 | // 120 for internal 114 | // 128 for external 115 | uint16_t modArray[maxSamplesNum + 8]; 116 | uint32_t modDelayVal = 0; 117 | 118 | uint64_t sweepStartFrequency = 1e9; 119 | uint64_t sweepStopFrequency = 2e9; 120 | uint64_t sweepStepFrequency = 100e6; 121 | uint64_t sweepPoints = 100; 122 | uint32_t sweepDwellTime = 1000000; 123 | int32_t sweepIndex = 0; 124 | uint8_t sweepType = 0; 125 | bool isSweepOn = false; 126 | 127 | uint32_t LMXOutPwr = 0; 128 | uint64_t Frequency = 1e9; 129 | bool isRFOnOff = true; 130 | int amplitude = 0; 131 | 132 | uint8_t reference = 0; 133 | uint16_t valueOfDAC = 0; 134 | uint8_t valueofRFSA = 0; 135 | bool isVibrationOn = true; 136 | uint16_t eepromAddr = 0; 137 | bool isExtModAttch = false; 138 | float fskMultiplier = 0; 139 | bool nextFreq = false; 140 | char firmwareVersion[VERSION_SIZE] = "v1.0.8"; 141 | bool isUploadCode = false; 142 | 143 | uint8_t decimationValue = 0; 144 | 145 | void setup() 146 | { 147 | Serial.begin(9600); 148 | Serial1.begin(9600); 149 | SPI.begin(); 150 | 151 | pinMode(eeprom_LE, OUTPUT); 152 | digitalWrite(eeprom_LE, HIGH); 153 | 154 | pinMode(temp_LE, OUTPUT); 155 | digitalWrite(temp_LE, HIGH); 156 | 157 | pinMode(rfsa_LE, OUTPUT); 158 | digitalWrite(rfsa_LE, HIGH); 159 | 160 | pinMode(ledPin, OUTPUT); 161 | digitalWrite(ledPin, LOW); 162 | 163 | pinMode(tcxoPin, OUTPUT); 164 | digitalWrite(tcxoPin, LOW); 165 | 166 | pinMode(ampPin, OUTPUT); 167 | digitalWrite(ampPin, HIGH); 168 | 169 | pinMode(vibMotor, OUTPUT); 170 | digitalWrite(vibMotor, HIGH); 171 | 172 | pinMode(adf4002_LE, OUTPUT); 173 | digitalWrite(adf4002_LE, HIGH); 174 | 175 | pinMode(lmx_LE, OUTPUT); 176 | digitalWrite(lmx_LE, HIGH); 177 | 178 | pinMode(dac1_LE, OUTPUT); 179 | digitalWrite(dac1_LE, HIGH); 180 | 181 | // 182 | // Load or Reset the EEPROM due to version difference 183 | // 184 | if (readFromExEEPROM(0) == 0x12) 185 | { 186 | uint16_t a1, a2 = 0; 187 | 188 | char tmp[VERSION_SIZE] = { 0 }; 189 | for (int i = 0; i < strlen(firmwareVersion); i++) { if (isdigit(firmwareVersion[i])) { strncat(tmp, &firmwareVersion[i], 1); } } 190 | a1 = get64Bit(&tmp[0]); 191 | 192 | tmp[0] = 0; 193 | for (uint16_t i = VERSION_ADDR; i < (VERSION_ADDR + VERSION_SIZE); i++) 194 | { 195 | uint8_t ch = readFromExEEPROM(i); 196 | if (isdigit(ch)) { strncat(tmp, (char*)&ch, 1); } 197 | } 198 | a2 = get64Bit(&tmp[0]); 199 | 200 | if (a1 != a2) 201 | { 202 | eepromClear(); 203 | 204 | writeToExEEPROM(INITIATION_ADDR, 0x12); 205 | 206 | for (uint8_t i = 0; i < sizeof(firmwareVersion); i++) { writeToExEEPROM(VERSION_ADDR + i, firmwareVersion[i]); } 207 | eepromSave(); 208 | } 209 | 210 | if (readFromExEEPROM(REMEMBER_ADDR) == 1) { eepromLoad(); } 211 | } 212 | else 213 | { 214 | eepromClear(); 215 | writeToExEEPROM(INITIATION_ADDR, 0x12); 216 | for (uint8_t i = 0; i < sizeof(firmwareVersion); i++) { writeToExEEPROM(VERSION_ADDR + i, firmwareVersion[i]); } 217 | eepromSave(); 218 | } 219 | 220 | SPI.beginTransaction(SPISettings(5e6, MSBFIRST, SPI_MODE0)); 221 | for (uint8_t i = 0; i < 4; i++) 222 | { 223 | digitalWrite(adf4002_LE, LOW); 224 | uint8_t b1 = readFromExEEPROM((ADF_REG_ADDR + (3 * i) + 0)); 225 | uint8_t b2 = readFromExEEPROM((ADF_REG_ADDR + (3 * i) + 1)); 226 | uint8_t b3 = readFromExEEPROM((ADF_REG_ADDR + (3 * i) + 2)); 227 | 228 | SPI.transfer(b1); 229 | SPI.transfer(b2); 230 | SPI.transfer(b3); 231 | digitalWrite(adf4002_LE, HIGH); 232 | } 233 | SPI.endTransaction(); 234 | 235 | spiWrite_LMX(&LMX_R0_reset); 236 | spiWrite_LMX(&LMX_R0); 237 | 238 | for (uint16_t i = 0; i < 126; i++) 239 | { 240 | uint32_t reg = 0; 241 | readFromExEEPROM(((3 * i) + LMX_REG_ADDR), (uint8_t*)®); 242 | spiWrite_LMX(®); 243 | delay(1); 244 | } 245 | 246 | spiWrite_LMX(&LMX_R0); 247 | 248 | setRFSA3714(0); 249 | setF2250(0); 250 | setReferenceType(reference); 251 | setAmplitude(); 252 | setLMX(Frequency); 253 | rfOnOff(); 254 | 255 | //// Set Timer1 for Led Blink 256 | TCCR1B = _BV(WGM13) | _BV(CS11) | _BV(CS10); 257 | TCCR1A = 0; 258 | ICR1 = 62500; 259 | TIMSK1 = _BV(TOIE1); 260 | 261 | // Setup ADC for Free Running Mode.Default is ADC 5 262 | ADMUX = 0x45; 263 | ADCSRA = 0xE1; 264 | ADCSRB = 0x80; 265 | 266 | if (isSweepOn) { setSweepParams(); } 267 | if (isModulationEnable) { setModulationSettings(); } 268 | } 269 | 270 | void loop() 271 | { 272 | handleSerial(); 273 | if (!isUploadCode) 274 | { 275 | startModulation(); 276 | } 277 | 278 | } 279 | 280 | void setDAC1(uint16_t value) 281 | { 282 | // 12 bit DAC 283 | // Last 2 bit (MSB) 284 | valueOfDAC = value; 285 | 286 | byte DAC[2] = { 0 }; 287 | 288 | value = value << 2; 289 | 290 | DAC[1] = (byte)value; //LSB of DAC_Value 291 | DAC[0] = (byte)(value >> 8); //MSB of DAC_Value 292 | 293 | cli(); 294 | SPI.beginTransaction(SPISettings(10e6, MSBFIRST, SPI_MODE1)); 295 | PORTD &= ~(1 << PORTD6); 296 | SPI.transfer(DAC, 2); 297 | PORTD |= (1 << PORTD6); 298 | SPI.endTransaction(); 299 | sei(); 300 | } 301 | 302 | void setMinAmplitude() 303 | { 304 | LMXOutPwr = 0; 305 | setLMXPower(); 306 | setF2250(4095); 307 | setRFSA3714(127); 308 | } 309 | 310 | void setLMX(uint64_t freq) 311 | { 312 | cli(); 313 | 314 | Frequency = freq; 315 | if (Frequency < MINUMUM_FREQUENCY) { Frequency = MINUMUM_FREQUENCY; } 316 | if (Frequency > MAXIMUM_FREQUENCY) { Frequency = MAXIMUM_FREQUENCY; } 317 | freq = Frequency; 318 | 319 | setMinAmplitude(); 320 | 321 | uint32_t CHDIV = 0, DIVRAT = 1; 322 | 323 | if (freq < 25e6 && freq >= 125e5) { DIVRAT = 256; CHDIV = 14; } 324 | else if (freq < 50e6 && freq >= 25e6) { DIVRAT = 128; CHDIV = 12; } 325 | else if (freq < 100e6 && freq >= 50e6) { DIVRAT = 64; CHDIV = 9; } 326 | else if (freq < 200e6 && freq >= 100e6) { DIVRAT = 32; CHDIV = 7; } 327 | else if (freq < 400e6 && freq >= 200e6) { DIVRAT = 16; CHDIV = 5; } 328 | else if (freq < 800e6 && freq >= 400e6) { DIVRAT = 8; CHDIV = 3; } 329 | else if (freq < 1600e6 && freq >= 800e6) { DIVRAT = 4; CHDIV = 1; } 330 | else if (freq < 3200e6 && freq >= 1600e6) { DIVRAT = 2; CHDIV = 0; } 331 | 332 | uint64_t freq_vco = (uint64_t)DIVRAT * freq; 333 | 334 | uint32_t R75 = 0x4B0800 | (CHDIV << 6); 335 | 336 | uint64_t Nlmx = freq_vco / 100000000; 337 | uint32_t R36 = (uint32_t)Nlmx + 2359296; 338 | uint64_t pll_num = freq_vco % 100000000; 339 | 340 | // PLL_DEN registers. These are set to 100MHz 341 | uint32_t R39 = 0x27E100; 342 | uint32_t R38 = 0x2605F5; 343 | 344 | if (isModulationEnable && modType == 1) 345 | { 346 | // 1 MHz 347 | R39 = 0x274240; 348 | R38 = 0x26000F; 349 | pll_num /= 100; 350 | } 351 | 352 | uint32_t R42 = 0x2A0000 | (pll_num >> 16); 353 | uint32_t R43 = 0x2B0000 | (pll_num & (0x00FFFF)); 354 | uint32_t R45 = 0x2DC601; 355 | 356 | if (DIVRAT == 1) { R45 = 0x2DCE01; } 357 | R45 &= (LMXOutPwr | 0xFFFF00); 358 | 359 | uint32_t r0 = isRFOnOff ? LMX_R0 : LMX_R0_mute; 360 | if (isModulationEnable && modType == 1) 361 | { 362 | r0 = isRFOnOff ? LMX_R0_ADDR_HOLD : LMX_R0_ADDR_HOLD_mute; 363 | } 364 | 365 | spiWrite_LMX(&R39); 366 | spiWrite_LMX(&R38); 367 | spiWrite_LMX(&R75); 368 | spiWrite_LMX(&R45); 369 | spiWrite_LMX(&R43); 370 | spiWrite_LMX(&R42); 371 | spiWrite_LMX(&R36); 372 | spiWrite_LMX(&r0); 373 | 374 | setAmplitude(); 375 | sei(); 376 | } 377 | 378 | void setLMXPower() 379 | { 380 | uint32_t R44 = 0x2C3FA3; 381 | uint32_t R45 = 0x2DC63F; 382 | if (Frequency >= 3200e6) { R45 = 0x2DCE3F; } 383 | 384 | R44 &= ((LMXOutPwr << 8) | 0xFF00FF); 385 | R45 &= (LMXOutPwr | 0xFFFF00); 386 | 387 | spiWrite_LMX(&R44); 388 | spiWrite_LMX(&R45); 389 | } 390 | 391 | void rfOnOff() 392 | { 393 | if (!isRFOnOff) 394 | { 395 | PORTB |= (1 << PORTB5); 396 | spiWrite_LMX(&LMX_R0_mute); 397 | } 398 | else 399 | { 400 | PORTB &= ~(1 << PORTB5); 401 | spiWrite_LMX(&LMX_R0); 402 | } 403 | } 404 | 405 | void setRFSA3714(int value) 406 | { 407 | valueofRFSA = value; 408 | cli(); 409 | SPI.beginTransaction(SPISettings(10e6, LSBFIRST, SPI_MODE0)); 410 | PORTD &= ~(1 << PORTD7); 411 | SPI.transfer(value); 412 | PORTD |= (1 << PORTD7); 413 | SPI.endTransaction(); 414 | sei(); 415 | } 416 | 417 | void setF2250(int value) 418 | { 419 | setDAC1(value); 420 | } 421 | 422 | void setReferenceType(int type) 423 | { 424 | if (type == 0) 425 | { 426 | // INTERNAL 427 | digitalWrite(tcxoPin, HIGH); 428 | } 429 | else 430 | { 431 | // EXTERNAL 432 | digitalWrite(tcxoPin, LOW); 433 | } 434 | } 435 | 436 | void startModulation() 437 | { 438 | if (isModulationEnable) 439 | { 440 | setModulationSettings(); 441 | 442 | if (modType == MODULATION_AM) 443 | { 444 | if (modInput == MODULATION_INTERNAL) 445 | { 446 | while (isModulationEnable) 447 | { 448 | SPI.beginTransaction(SPISettings(10e6, MSBFIRST, SPI_MODE1)); 449 | for (int i = 0; i < maxSamplesNum; i += decimationValue) 450 | { 451 | uint16_t value = modArray[i] << 2; 452 | PORTD &= ~(1 << PORTD6); 453 | SPI.transfer((uint8_t)(value >> 8)); 454 | SPI.transfer((uint8_t)value); 455 | PORTD |= (1 << PORTD6); 456 | delayNanoseconds(modDelayVal); 457 | } 458 | if (nextFreq) { sweep(); } 459 | if (Serial.available() || Serial1.available()) { break; } 460 | } 461 | SPI.endTransaction(); 462 | 463 | setAmplitude(); 464 | } 465 | else if (modInput == MODULATION_EXTERNAL || modInput == MODULATION_MICROPHONE) // External 466 | { 467 | ADMUX = modInput == MODULATION_EXTERNAL ? 0x47 : 0x46; 468 | ADCSRA = 0xE2; 469 | 470 | SPI.beginTransaction(SPISettings(10e6, MSBFIRST, SPI_MODE1)); 471 | 472 | float volt = (float)valueOfDAC * (3.3 / 4096.0); 473 | volt = ((volt - 0.8) * 30) + 5; 474 | 475 | for (uint8_t i = 0; i < (maxSamplesNum + 8); i++) 476 | { 477 | float sample = (5.0 / 1024.0) * i * 8; 478 | sample -= 2.5; // substract the 2.5V offset 479 | sample /= 5; // Scale down to 1V 480 | sample *= ((float)amDepth / 100.0); 481 | sample += 0.5; 482 | 483 | sample = 10 + 20 * log10(sample); 484 | 485 | sample = (10 - sample + volt) * (1.0 / 30.0); 486 | sample = (sample + 0.65) / (3.3 / 4096.0); 487 | 488 | modArray[i] = ((uint16_t)sample) << 2; 489 | } 490 | 491 | while (isModulationEnable) 492 | { 493 | if (Serial.available() || Serial1.available()) { break; } 494 | if (nextFreq) { sweep(); SPI.beginTransaction(SPISettings(10e6, MSBFIRST, SPI_MODE1)); } 495 | while (!(ADCSRA & (1 << ADIF))); 496 | 497 | //uint16_t sample = (ADCL | (ADCH << 8)); 498 | //uint16_t value = modArray[sample >> 3]; 499 | uint16_t value = modArray[(ADCL >> 3) | (ADCH << 5)]; 500 | 501 | PORTD &= ~(1 << PORTD6); 502 | SPI.transfer((uint8_t)(value >> 8)); 503 | SPI.transfer((uint8_t)value); 504 | PORTD |= (1 << PORTD6); 505 | } 506 | 507 | SPI.endTransaction(); 508 | 509 | setAmplitude(); 510 | } 511 | } 512 | else if (modType == MODULATION_FM) 513 | { 514 | if (modInput == MODULATION_INTERNAL) // Internal 515 | { 516 | SPI.beginTransaction(SPISettings(10e6, MSBFIRST, SPI_MODE0)); 517 | 518 | while (isModulationEnable) 519 | { 520 | PORTB &= ~(1 << PORTB4); 521 | SPI.transfer(FSK_ADDRESS); 522 | 523 | for (int i = 0; i < maxSamplesNum; i += decimationValue) 524 | { 525 | SPI.transfer((uint8_t)(modArray[i] >> 8)); 526 | SPI.transfer((uint8_t)modArray[i]); 527 | delayNanoseconds(modDelayVal); 528 | } 529 | 530 | PORTB |= (1 << PORTB4); 531 | 532 | if (nextFreq) { sweep(); setModulationSettings(); } 533 | if (Serial.available() || Serial1.available()) { break; } 534 | } 535 | 536 | SPI.endTransaction(); 537 | 538 | // Write FSK Disable 539 | uint32_t R114 = 0x727C03 & 0xFFFBFF; 540 | spiWrite_LMX(&R114); 541 | setLMX(Frequency); 542 | } 543 | else if (modInput == MODULATION_EXTERNAL || modInput == MODULATION_MICROPHONE) // External 544 | { 545 | ADMUX = modInput == MODULATION_EXTERNAL ? 0x47 : 0x46; 546 | ADCSRA = 0xE2; 547 | 548 | SPI.beginTransaction(SPISettings(10e6, MSBFIRST, SPI_MODE0)); 549 | PORTB &= ~(1 << PORTB4); 550 | SPI.transfer(FSK_ADDRESS); 551 | 552 | uint64_t fmDev_scaled = fmDev / (5.0 / 1024.0); 553 | uint64_t fskMultiplier_scaled = fskMultiplier / (5.0 / 1024.0); 554 | 555 | for (uint8_t i = 0; i < (maxSamplesNum + 8); i++) 556 | { 557 | float micVal = (5.0 / 1024.0) * i * 8; 558 | micVal -= 2.5; 559 | micVal /= 2.5; // Scale down to 1V 560 | micVal *= (float)fmDev; 561 | 562 | // This converts deviation frequency to register value 563 | uint16_t fskValue = 0; 564 | if (micVal < 0) { fskValue = (65536 + ((uint16_t)round(micVal * fskMultiplier))); } 565 | else { fskValue = ((uint16_t)round(micVal * fskMultiplier)); } 566 | 567 | modArray[i] = fskValue; 568 | } 569 | 570 | while (isModulationEnable) 571 | { 572 | if (Serial.available() || Serial1.available() || nextFreq) { break; } 573 | 574 | while (!(ADCSRA & (1 << ADIF))); 575 | // Read external input 576 | uint16_t m = ADCL | (ADCH << 8); 577 | 578 | uint16_t fskValue = modArray[m >> 3]; 579 | 580 | SPI.transfer((uint8_t)(fskValue >> 8)); 581 | SPI.transfer((uint8_t)fskValue); 582 | } 583 | 584 | PORTB |= (1 << PORTB4); 585 | SPI.endTransaction(); 586 | 587 | if (nextFreq) { sweep(); } 588 | 589 | // Write FSK Disable 590 | uint32_t R114 = 0x727C03 & 0xFFFBFF; 591 | spiWrite_LMX(&R114); 592 | setLMX(Frequency); 593 | } 594 | } 595 | else if (modType == MODULATION_PULSE) 596 | { 597 | if (modInput == MODULATION_INTERNAL) 598 | { 599 | detachInterrupt(digitalPinToInterrupt(trigPin)); 600 | isExtModAttch = false; 601 | 602 | uint32_t offTime = pulsePeriod - pulseWidth - 15; // 15 is default delay because of transactions 603 | uint32_t waitTime = pulseWidth - 10; // 10 is default delay because of transactions 604 | uint16_t dac = valueOfDAC; 605 | uint8_t rfsa = valueofRFSA; 606 | 607 | while (isModulationEnable) 608 | { 609 | setDAC1(dac); 610 | setRFSA3714(rfsa); 611 | delay_micro(waitTime); 612 | 613 | setDAC1(4095); 614 | setRFSA3714(127); 615 | delay_micro(offTime); 616 | 617 | if (nextFreq) { sweep(); } 618 | if (Serial.available() || Serial1.available()) { break; } 619 | } 620 | setAmplitude(); 621 | } 622 | else 623 | { 624 | if (!isExtModAttch) { attachInterrupt(digitalPinToInterrupt(trigPin), pulse_rising, RISING); isExtModAttch = true; } 625 | } 626 | } 627 | } 628 | } 629 | 630 | void pulse_rising() 631 | { 632 | if (nextFreq) { sweep(); } 633 | setF2250(valueOfDAC); 634 | setRFSA3714(valueofRFSA); 635 | attachInterrupt(digitalPinToInterrupt(trigPin), pulse_falling, FALLING); 636 | } 637 | 638 | void pulse_falling() 639 | { 640 | if (nextFreq) { sweep(); } 641 | byte DAC[2] = { 0 }; 642 | 643 | uint16_t value = 4095 << 2; 644 | 645 | DAC[1] = (byte)value; //LSB of DAC_Value 646 | DAC[0] = (byte)(value >> 8); //MSB of DAC_Value 647 | 648 | SPI.beginTransaction(SPISettings(10e6, MSBFIRST, SPI_MODE1)); 649 | PORTD &= ~(1 << PORTD6); 650 | SPI.transfer(DAC, 2); 651 | PORTD |= (1 << PORTD6); 652 | SPI.endTransaction(); 653 | 654 | SPI.beginTransaction(SPISettings(10e6, LSBFIRST, SPI_MODE0)); 655 | PORTD &= ~(1 << PORTD7); 656 | SPI.transfer(127); 657 | PORTD |= (1 << PORTD7); 658 | SPI.endTransaction(); 659 | 660 | attachInterrupt(digitalPinToInterrupt(trigPin), pulse_rising, RISING); 661 | } 662 | 663 | float getFSKMultiplier() 664 | { 665 | float pll_den = 1e6; 666 | float chdiv = 1; 667 | float f_pd = 100e6; 668 | float scale = pow(2, 0); 669 | 670 | if (Frequency < 25e6 && Frequency >= 125e5) { chdiv = 256; if (fmDev > 10e3) { fmDev = 10e3; } } 671 | else if (Frequency < 50e6 && Frequency >= 25e6) { chdiv = 128; if (fmDev > 25e3) { fmDev = 25e3; } } 672 | else if (Frequency < 100e6 && Frequency >= 50e6) { chdiv = 64; if (fmDev > 50e3) { fmDev = 50e3; } } 673 | else if (Frequency < 200e6 && Frequency >= 100e6) { chdiv = 32; if (fmDev > 100e3) { fmDev = 100e3; } } 674 | else if (Frequency < 400e6 && Frequency >= 200e6) { chdiv = 16; if (fmDev > 200e3) { fmDev = 200e3; } } 675 | else if (Frequency < 800e6 && Frequency >= 400e6) { chdiv = 8; if (fmDev > 400e3) { fmDev = 400e3; } } 676 | else if (Frequency < 1600e6 && Frequency >= 800e6) { chdiv = 4; if (fmDev > 800e3) { fmDev = 800e3; } } 677 | else if (Frequency < 3200e6 && Frequency >= 1600e6) { chdiv = 2; if (fmDev > 1600e3) { fmDev = 1600e3; } } 678 | else if (Frequency < 6400e6 && Frequency >= 3200e6) { chdiv = 1; if (fmDev > 3200e3) { fmDev = 3200e3; } } 679 | 680 | return (pll_den * chdiv) / (f_pd * scale); 681 | } 682 | 683 | uint16_t getWaveform(uint8_t index) 684 | { 685 | uint16_t addr = (400 * modWaveForm) + (2 * index) + SINE_WAVEFORM_ADDR; 686 | uint16_t a1 = readFromExEEPROM(addr); addr++; 687 | uint16_t a2 = readFromExEEPROM(addr); 688 | return a1 | (a2 << 8); 689 | } 690 | 691 | void setModulationSettings() 692 | { 693 | if (modType == MODULATION_AM) 694 | { 695 | decimationValue = ceil((float)modIntFreq / 1000.0); 696 | float delayAmount = (1e9 / (modIntFreq * ceil((float)maxSamplesNum / decimationValue))); 697 | modDelayVal = ((delayAmount - DEFAULT_DELAY_AM) < 0 ? 0 : round(delayAmount - DEFAULT_DELAY_AM)) / 250; 698 | 699 | float v[maxSamplesNum]; 700 | for (int i = 0; i < maxSamplesNum; i++) 701 | { 702 | // Convert samples as 1V peek sine wave 703 | v[i] = (((getWaveform(i) * (1.0 / 4096.0)) - 0.5)); 704 | // Apply AM Depth 705 | v[i] *= ((float)amDepth / 100.0); 706 | // Add center voltage offset 707 | v[i] += 0.5; 708 | 709 | //Current F2250 dB calculation from calibration data 710 | float volt = (float)valueOfDAC * (3.3 / 4096.0); 711 | volt = ((volt - 0.8) * 30) + 5; 712 | 713 | // Convert to Decibel 714 | v[i] = 10 + 20 * log10(v[i]); 715 | // 10 is the max db for max 1V. Then we multiply subtraction with slope of the attenuater 716 | // thus it gives the voltage for necessery attenuation 717 | 718 | v[i] = ((10 - v[i]) + volt) * (1.0 / 30.0); // Slope of the F2250 this function gives the voltage for attn 719 | // Slope calculation of attenutor starts the voltage from 0.8. so we add them up. then convert samples to bits for DAC 720 | v[i] = (v[i] + 0.65) / (3.3 / 4096.0); 721 | } 722 | 723 | for (int i = 0; i < maxSamplesNum; i++) { modArray[i] = (uint16_t)v[i]; } 724 | } 725 | else if (modType == MODULATION_FM) 726 | { 727 | // Set the frequency therefore pll_den will be calculated again as 1 MHz 728 | setLMX(Frequency); 729 | 730 | fskMultiplier = getFSKMultiplier(); 731 | 732 | // To be able to use block programming, first write this value to register otherwise write LMX_R0 733 | uint32_t R0 = 0x00291C; // For ADD_HOLD value 734 | uint32_t R114 = 0x727C03; 735 | uint32_t R115 = 0x730000; 736 | spiWrite_LMX(&R114); 737 | spiWrite_LMX(&R115); 738 | spiWrite_LMX(&R0); 739 | 740 | float samples[maxSamplesNum]; 741 | 742 | for (int i = 0; i < maxSamplesNum; i++) 743 | { 744 | samples[i] = ((getWaveform(i) * (1.0 / 4096.0)) - 0.5) * 2 * fmDev; 745 | } 746 | 747 | // This converts deviation frequency to register value 748 | for (int i = 0; i < maxSamplesNum; i++) 749 | { 750 | if (samples[i] < 0) { modArray[i] = (65536 + (round(samples[i] * fskMultiplier))); } 751 | else { modArray[i] = (round(samples[i] * fskMultiplier)); } 752 | } 753 | 754 | // Calculate the sampling period 755 | decimationValue = ceil((float)modIntFreq / 1000.0); 756 | //decimationValue = 4; 757 | float delayAmount = (1e9 / (modIntFreq * ceil((float)maxSamplesNum / decimationValue))); 758 | modDelayVal = ((delayAmount - DEFAULT_DELAY_FM) < 0 ? 0 : round(delayAmount - DEFAULT_DELAY_FM)) / 250; 759 | } 760 | 761 | if (isSweepOn) { setSweepParams(); } 762 | } 763 | 764 | float getTemp() 765 | { 766 | cli(); 767 | SPI.beginTransaction(SPISettings(EXTERNAL_EEPROM_MAX_CLOCK, MSBFIRST, SPI_MODE0)); 768 | digitalWrite(temp_LE, LOW); 769 | uint8_t a1 = SPI.transfer(0x00); 770 | uint8_t a2 = SPI.transfer(0x00); 771 | digitalWrite(temp_LE, HIGH); 772 | SPI.endTransaction(); 773 | 774 | int a3 = ((a1 << 8) | (a2 & (0xF8))) >> 3; 775 | sei(); 776 | return (float)a3 * 0.0625; 777 | } 778 | 779 | float getCurrent() 780 | { 781 | ADMUX = 0x45; 782 | ADCSRA = 0xE7; 783 | 784 | while (!(ADCSRA & (1 << ADIF))); 785 | 786 | int val = ADCL | (ADCH << 8); 787 | return (5.0 / 1024.0) * val / 20 / 0.3; 788 | } 789 | 790 | void blinkLed() 791 | { 792 | ledState = !ledState; 793 | digitalWrite(ledPin, ledState); 794 | } 795 | 796 | void spiWrite_LMX(uint32_t* data_u32) 797 | { 798 | cli(); 799 | SPI.beginTransaction(SPISettings(10e6, MSBFIRST, SPI_MODE0)); 800 | digitalWrite(lmx_LE, LOW); 801 | SPI.transfer(((uint8_t*)data_u32)[2]); 802 | SPI.transfer(((uint8_t*)data_u32)[1]); 803 | SPI.transfer(((uint8_t*)data_u32)[0]); 804 | digitalWrite(lmx_LE, HIGH); 805 | SPI.endTransaction(); 806 | sei(); 807 | } 808 | 809 | void spiWrite_FSK(uint16_t* data_u16) 810 | { 811 | cli(); 812 | SPI.beginTransaction(SPISettings(10e6, MSBFIRST, SPI_MODE0)); 813 | digitalWrite(lmx_LE, LOW); 814 | SPI.transfer(FSK_ADDRESS); 815 | SPI.transfer(((uint8_t*)data_u16)[1]); 816 | SPI.transfer(((uint8_t*)data_u16)[0]); 817 | digitalWrite(lmx_LE, HIGH); 818 | SPI.endTransaction(); 819 | sei(); 820 | } 821 | 822 | void handleSerial() 823 | { 824 | if (Serial.available()) 825 | { 826 | if (isUploadCode) { Serial1.write(Serial.read()); } 827 | else 828 | { 829 | while (Serial.available()) 830 | { 831 | 832 | char inChar = (char)Serial.read(); 833 | 834 | if (inChar == '\r' || inChar == '\n') { serialActivityExist = true; } 835 | if (inChar == '>' || isCmdExist) { isCmdExist = true; if (inChar != '\r' && inChar != '\n') { strncat(cmdString, &inChar, 1); } } 836 | if (inChar == '\r' && isCmdExist) { stringComplete = true; } 837 | 838 | } 839 | 840 | if (stringComplete) 841 | { 842 | stringComplete = false; 843 | command(cmdString); 844 | cmdString[0] = 0; 845 | isCmdExist = false; 846 | } 847 | } 848 | } 849 | 850 | if (Serial1.available()) 851 | { 852 | if (isUploadCode) { Serial.write(Serial1.read()); } 853 | else 854 | { 855 | while (Serial1.available()) 856 | { 857 | unsigned char inChar = Serial1.read(); 858 | if (inChar == 0xFF) { termCount++; } 859 | else { strncat(cmd1String, &inChar, 1); } 860 | if (termCount == 3) 861 | { 862 | termCount = 0; 863 | if (cmd1String[0] == 0x70) { command(&cmd1String[1]); } 864 | cmd1String[0] = 0; 865 | } 866 | } 867 | } 868 | } 869 | } 870 | 871 | uint64_t get64Bit(char *input) 872 | { 873 | uint64_t result = 0; 874 | uint64_t len = strlen(input); 875 | 876 | for (int i = len - 1; i >= 0; i--) 877 | { 878 | uint64_t multiplier = 1; 879 | for (int j = 0; j < (len - i - 1); j++) multiplier *= 10; 880 | result += (input[i] - '0') * multiplier; 881 | } 882 | 883 | return result; 884 | } 885 | 886 | void uint64ToString(uint64_t input, char* chr) 887 | { 888 | unsigned char tmp = 0; 889 | uint8_t index = 0; 890 | 891 | chr[0] = '\0'; 892 | 893 | do { 894 | tmp = input % 10; 895 | input /= 10; 896 | 897 | if (tmp < 10) 898 | tmp += '0'; 899 | else 900 | tmp += 'A' - 10; 901 | 902 | index++; 903 | strncat(chr, &tmp, 1); 904 | } while (input); 905 | 906 | strrev(chr); 907 | } 908 | 909 | void delay_micro(uint32_t val) 910 | { 911 | if (val < 16000) { delayMicroseconds(val); } 912 | else { delay(val / 1000); } 913 | } 914 | 915 | void delayNanoseconds(unsigned int it) // Delay = (250 x it) ns 916 | { 917 | // busy wait 918 | __asm__ __volatile__( 919 | "1: sbiw %0,1" "\n\t" // 2 cycles 920 | "brne 1b" : "=w" (it) : "0" (it) // 2 cycles 921 | ); 922 | // return = 4 cycles 923 | } 924 | 925 | void command(char* commandBuffer) 926 | { 927 | char commandID = commandBuffer[1]; 928 | commandInString[0] = 0; 929 | char tmp[32] = { 0 }; 930 | 931 | if (commandID == 'F') 932 | { 933 | // Set the frequency of LMX 934 | strcat(commandInString, &commandBuffer[2]); 935 | setLMX(get64Bit(commandInString)); 936 | } 937 | else if (commandID == 'A') 938 | { 939 | strcat(commandInString, &commandBuffer[3]); 940 | 941 | if (commandBuffer[2] == '1') 942 | { 943 | // Set RFSA3714 944 | setRFSA3714(get64Bit(commandInString)); 945 | } 946 | else if (commandBuffer[2] == '2') 947 | { 948 | // Set F2250 949 | setF2250(get64Bit(commandInString)); 950 | } 951 | } 952 | else if (commandID == 'S') 953 | { 954 | if (commandBuffer[2] == 'A') 955 | { 956 | // Set Amplitude 957 | if (commandBuffer[3] == '-') 958 | { 959 | strcat(commandInString, &commandBuffer[4]); 960 | amplitude = get64Bit(commandInString) * -1; 961 | } 962 | else 963 | { 964 | strcat(commandInString, &commandBuffer[3]); 965 | amplitude = get64Bit(commandInString); 966 | } 967 | setAmplitude(); 968 | } 969 | else if (commandBuffer[2] == 'R') 970 | { 971 | // Set Reference 972 | reference = commandBuffer[3] - '0'; 973 | setReferenceType(reference); 974 | } 975 | else if (commandBuffer[2] == 'M') 976 | { 977 | // Modulation Settings 978 | if (commandBuffer[3] == '0') // DISABLE MODULATION 979 | { 980 | isModulationEnable = false; 981 | detachInterrupt(digitalPinToInterrupt(trigPin)); 982 | setAmplitude(); 983 | } 984 | else if (commandBuffer[3] == '1') // ENABLE MODULATION 985 | { 986 | isModulationEnable = true; 987 | } 988 | else if (commandBuffer[3] == 'F') 989 | { 990 | if (commandBuffer[4] == 'D') 991 | { 992 | // FM Deviation Frequency 993 | strcat(commandInString, &commandBuffer[5]); 994 | fmDev = get64Bit(commandInString); 995 | if (fmDev < 1) { fmDev = 1; } 996 | if (fmDev > MAXIMUM_DEVIATION) { fmDev = MAXIMUM_DEVIATION; } 997 | } 998 | else 999 | { 1000 | // Internal Modulation Frequency 1001 | strcat(commandInString, &commandBuffer[4]); 1002 | modIntFreq = get64Bit(commandInString); 1003 | if (modIntFreq < 1) { modIntFreq = 1; } 1004 | if (modIntFreq > MAXIMUM_INT_MOD_FREQ) { modIntFreq = MAXIMUM_INT_MOD_FREQ; } 1005 | } 1006 | } 1007 | else if (commandBuffer[3] == 'T') 1008 | { 1009 | // Modulation Type 1010 | modType = commandBuffer[4] - '0'; 1011 | } 1012 | else if (commandBuffer[3] == 'I') 1013 | { 1014 | // Modulation Input 1015 | modInput = commandBuffer[4] - '0'; 1016 | } 1017 | else if (commandBuffer[3] == 'W') 1018 | { 1019 | // Modulation Waveform Type 1020 | modWaveForm = commandBuffer[4] - '0'; 1021 | } 1022 | else if (commandBuffer[3] == 'A') 1023 | { 1024 | // AM Depth 1025 | strcat(commandInString, &commandBuffer[4]); 1026 | amDepth = get64Bit(commandInString); 1027 | if (amDepth < 1) { amDepth = 1; } 1028 | if (amDepth > 99) { amDepth = 99; } 1029 | } 1030 | else if (commandBuffer[3] == 'P') 1031 | { 1032 | if (commandBuffer[4] == 'P') 1033 | { 1034 | // Pulse Period 1035 | strcat(commandInString, &commandBuffer[5]); 1036 | pulsePeriod = get64Bit(commandInString); 1037 | if (pulsePeriod < pulseWidth) { pulsePeriod = pulseWidth + MINUMUM_PULSE; } 1038 | if (pulsePeriod - pulseWidth < MINUMUM_PULSE) { pulsePeriod += (MINUMUM_PULSE - (pulsePeriod - pulseWidth)); } 1039 | } 1040 | else if (commandBuffer[4] == 'W') 1041 | { 1042 | // Pulse Width 1043 | strcat(commandInString, &commandBuffer[5]); 1044 | pulseWidth = get64Bit(commandInString); 1045 | if (pulseWidth < MINUMUM_PULSE) { pulseWidth = MINUMUM_PULSE; } 1046 | if (pulsePeriod < pulseWidth) { pulsePeriod = pulseWidth + MINUMUM_PULSE; } 1047 | if (pulsePeriod - pulseWidth < MINUMUM_PULSE) { pulsePeriod += (MINUMUM_PULSE - (pulsePeriod - pulseWidth)); } 1048 | } 1049 | } 1050 | fskMultiplier = getFSKMultiplier(); 1051 | 1052 | if (isModulationEnable) 1053 | { 1054 | detachInterrupt(digitalPinToInterrupt(trigPin)); 1055 | isExtModAttch = false; 1056 | setModulationSettings(); 1057 | } 1058 | } 1059 | else if (commandBuffer[2] == 'P') 1060 | { 1061 | strcat(commandInString, &commandBuffer[3]); 1062 | LMXOutPwr = get64Bit(commandInString); 1063 | setLMXPower(); 1064 | } 1065 | else if (commandBuffer[2] == 'S') // Set Sweep 1066 | { 1067 | strcat(commandInString, &commandBuffer[4]); 1068 | 1069 | if (commandBuffer[3] == '1') // Start Freq 1070 | { 1071 | sweepStartFrequency = get64Bit(commandInString); 1072 | if (sweepStartFrequency < MINUMUM_FREQUENCY) { sweepStartFrequency = MINUMUM_FREQUENCY; } 1073 | if (sweepStartFrequency > MAXIMUM_FREQUENCY) { sweepStartFrequency = MAXIMUM_FREQUENCY; } 1074 | } 1075 | else if (commandBuffer[3] == '2') // Stop Freq 1076 | { 1077 | sweepStopFrequency = get64Bit(commandInString); 1078 | if (sweepStopFrequency < MINUMUM_FREQUENCY) { sweepStopFrequency = MINUMUM_FREQUENCY; } 1079 | if (sweepStopFrequency > MAXIMUM_FREQUENCY) { sweepStopFrequency = MAXIMUM_FREQUENCY; } 1080 | } 1081 | else if (commandBuffer[3] == '3') // Step Freq 1082 | { 1083 | sweepStepFrequency = get64Bit(commandInString); 1084 | if (sweepStepFrequency < 1) { sweepStepFrequency = 1; } 1085 | if (sweepStepFrequency > MAXIMUM_FREQUENCY) { sweepStepFrequency = MAXIMUM_FREQUENCY; } 1086 | } 1087 | else if (commandBuffer[3] == '4') // Dwell Time 1088 | { 1089 | sweepDwellTime = get64Bit(commandInString); 1090 | if (sweepDwellTime < MINUMUM_DWELL) { sweepDwellTime = MINUMUM_DWELL; } 1091 | } 1092 | else if (commandBuffer[3] == '5') // Sweep ON 1093 | { 1094 | isSweepOn = true; 1095 | setSweepParams(); 1096 | } 1097 | else if (commandBuffer[3] == '6') // Sweep OFF 1098 | { 1099 | isSweepOn = false; 1100 | //detach timer interrupt 1101 | TIMSK3 = 0; 1102 | sweepIndex = 0; 1103 | detachInterrupt(digitalPinToInterrupt(trigPin)); 1104 | } 1105 | else if (commandBuffer[3] == '7') // Set Sweep Type 0:Free run 1:External 1106 | { 1107 | if (commandBuffer[4] == '0') { sweepType = 0; } 1108 | else if (commandBuffer[4] == '1') { sweepType = 1; } 1109 | } 1110 | 1111 | if (isSweepOn) 1112 | { 1113 | TIMSK3 = 0; 1114 | TCNT3 = 0; 1115 | sweepIndex = 0; 1116 | isExtModAttch = false; 1117 | detachInterrupt(digitalPinToInterrupt(trigPin)); 1118 | setSweepParams(); 1119 | } 1120 | 1121 | } 1122 | else if (commandBuffer[2] == 'F') 1123 | { 1124 | // RF ON OFF 1125 | if (commandBuffer[3] == '0') { isRFOnOff = false; rfOnOff(); } 1126 | else if (commandBuffer[3] == '1') { isRFOnOff = true; rfOnOff(); } 1127 | } 1128 | else if (commandBuffer[2] == 'E') 1129 | { 1130 | // EEPROM Settings 1131 | switch (commandBuffer[3]) 1132 | { 1133 | case 'S': eepromSave(); break; 1134 | case 'C': eepromClear(); break; 1135 | case 'L': 1136 | // Load from EEPROM 1137 | switch (commandBuffer[4]) 1138 | { 1139 | case '0': writeToExEEPROM(REMEMBER_ADDR, 0); break; 1140 | case '1': writeToExEEPROM(REMEMBER_ADDR, 1); break; 1141 | default: eepromLoad(); break; 1142 | } 1143 | break; 1144 | case 'A': 1145 | strcat(commandInString, &commandBuffer[4]); 1146 | eepromAddr = (uint16_t)get64Bit(commandInString); 1147 | break; 1148 | case 'R': 1149 | Serial.println(readFromExEEPROM(eepromAddr)); 1150 | break; 1151 | case 'W': 1152 | strcat(commandInString, &commandBuffer[4]); 1153 | writeToExEEPROM(eepromAddr, (uint8_t)get64Bit(commandInString)); 1154 | break; 1155 | } 1156 | } 1157 | else if (commandBuffer[2] == 'V') 1158 | { 1159 | // Vibration 1160 | switch (commandBuffer[3]) 1161 | { 1162 | case '0': isVibrationOn = false; break; 1163 | case '1': isVibrationOn = true; break; 1164 | } 1165 | } 1166 | } 1167 | else if (commandID == 'R') 1168 | { 1169 | if (commandBuffer[2] == 'C') 1170 | { 1171 | Serial.println(getCurrent(), 5); 1172 | } 1173 | else if (commandBuffer[2] == 'T') 1174 | { 1175 | Serial.println(getTemp(), 4); 1176 | } 1177 | } 1178 | else if (commandID == 'G') 1179 | { 1180 | // LCD ReadBacks 1181 | if (commandBuffer[2] == 'H') 1182 | { 1183 | strcpy(lcdCommand, "freqIN.txt=\""); 1184 | uint64ToString(Frequency, tmp); 1185 | strcat(lcdCommand, tmp); 1186 | strcat(lcdCommand, "\""); 1187 | sendLCDCommand(lcdCommand); 1188 | 1189 | if (amplitude < 0) 1190 | { 1191 | strcpy(lcdCommand, "ampIN.txt=\"-"); 1192 | uint64ToString((amplitude*(-1)), tmp); 1193 | 1194 | } 1195 | else 1196 | { 1197 | strcpy(lcdCommand, "ampIN.txt=\""); 1198 | uint64ToString(amplitude, tmp); 1199 | } 1200 | 1201 | strcat(lcdCommand, tmp); 1202 | strcat(lcdCommand, "\""); 1203 | sendLCDCommand(lcdCommand); 1204 | 1205 | sendLCDCommand("unit1.val=0"); 1206 | 1207 | if (isRFOnOff) 1208 | { 1209 | sendLCDCommand("b11.pic=99"); 1210 | } 1211 | else 1212 | { 1213 | sendLCDCommand("b11.pic=98"); 1214 | } 1215 | } 1216 | else if (commandBuffer[2] == 'S') 1217 | { 1218 | if (sweepType == 0) 1219 | { 1220 | // FREE RUN 1221 | sendLCDCommand("b4.pic=17"); 1222 | sendLCDCommand("b5.pic=67"); 1223 | } 1224 | else if (sweepType == 1) 1225 | { 1226 | // External 1227 | sendLCDCommand("b4.pic=66"); 1228 | sendLCDCommand("b5.pic=18"); 1229 | } 1230 | 1231 | if (isSweepOn) 1232 | { 1233 | sendLCDCommand("b6.pic=19"); 1234 | sendLCDCommand("b7.pic=69"); 1235 | } 1236 | else 1237 | { 1238 | sendLCDCommand("b6.pic=68"); 1239 | sendLCDCommand("b7.pic=20"); 1240 | } 1241 | 1242 | strcpy(lcdCommand, "t5.txt=\""); 1243 | uint64ToString(sweepStartFrequency, tmp); 1244 | strcat(lcdCommand, tmp); 1245 | strcat(lcdCommand, "\""); 1246 | sendLCDCommand(lcdCommand); 1247 | 1248 | strcpy(lcdCommand, "t6.txt=\""); 1249 | uint64ToString(sweepStopFrequency, tmp); 1250 | strcat(lcdCommand, tmp); 1251 | strcat(lcdCommand, "\""); 1252 | sendLCDCommand(lcdCommand); 1253 | 1254 | strcpy(lcdCommand, "t7.txt=\""); 1255 | uint64ToString(sweepStepFrequency, tmp); 1256 | strcat(lcdCommand, tmp); 1257 | strcat(lcdCommand, "\""); 1258 | sendLCDCommand(lcdCommand); 1259 | 1260 | strcpy(lcdCommand, "t8.txt=\""); 1261 | uint64ToString(sweepDwellTime, tmp); 1262 | strcat(lcdCommand, tmp); 1263 | strcat(lcdCommand, "\""); 1264 | sendLCDCommand(lcdCommand); 1265 | 1266 | sendLCDCommand("unit1.val=0"); 1267 | sendLCDCommand("unit2.val=0"); 1268 | sendLCDCommand("unit3.val=0"); 1269 | sendLCDCommand("unit4.val=0"); 1270 | } 1271 | else if (commandBuffer[2] == 'D') 1272 | { 1273 | float t = getTemp(); 1274 | 1275 | Serial1.print("t0.txt=\""); 1276 | Serial1.print(t, 1); 1277 | Serial1.print("C / "); 1278 | t *= (float)(9.0 / 5.0); 1279 | t += 32; 1280 | Serial1.print(t, 1); 1281 | Serial1.print("F"); 1282 | Serial1.print("\""); 1283 | Serial1.write(0xFF); 1284 | Serial1.write(0xFF); 1285 | Serial1.write(0xFF); 1286 | 1287 | int lmx = digitalRead(lmxRead); 1288 | int adf = digitalRead(adfRead); 1289 | 1290 | Serial1.print("t3.txt=\""); 1291 | if (lmx == LOW) { Serial1.print("Not Locked \""); } 1292 | else { Serial1.print("Locked \""); } 1293 | Serial1.write(0xFF); 1294 | Serial1.write(0xFF); 1295 | Serial1.write(0xFF); 1296 | 1297 | Serial1.print("t3.pco="); 1298 | Serial1.print(lmx == LOW ? "63488" : "8002"); 1299 | Serial1.write(0xFF); 1300 | Serial1.write(0xFF); 1301 | Serial1.write(0xFF); 1302 | 1303 | Serial1.print("t2.txt=\""); 1304 | if (adf == LOW) { Serial1.print("Not Locked \""); } 1305 | else { Serial1.print("Locked \""); } 1306 | Serial1.write(0xFF); 1307 | Serial1.write(0xFF); 1308 | Serial1.write(0xFF); 1309 | 1310 | Serial1.print("t2.pco="); 1311 | Serial1.print(adf == LOW ? "63488" : "8002"); 1312 | Serial1.write(0xFF); 1313 | Serial1.write(0xFF); 1314 | Serial1.write(0xFF); 1315 | 1316 | float c = getCurrent(); 1317 | Serial1.print("t1.txt=\"5Vx"); 1318 | Serial1.print(c, 2); 1319 | Serial1.print("A="); 1320 | Serial1.print((c * 5), 2); 1321 | Serial1.print("W\""); 1322 | Serial1.write(0xFF); 1323 | Serial1.write(0xFF); 1324 | Serial1.write(0xFF); 1325 | 1326 | strcpy(lcdCommand, "t5.txt=\""); 1327 | strcat(lcdCommand, firmwareVersion); 1328 | strcat(lcdCommand, "\""); 1329 | sendLCDCommand(lcdCommand); 1330 | } 1331 | else if (commandBuffer[2] == 'R') 1332 | { 1333 | switch (reference) 1334 | { 1335 | case 0: sendLCDCommand("b0.pic=15"); sendLCDCommand("b1.pic=65"); break; 1336 | case 1: sendLCDCommand("b0.pic=64"); sendLCDCommand("b1.pic=16"); break; 1337 | } 1338 | } 1339 | else if (commandBuffer[2] == 'M') 1340 | { 1341 | if (commandBuffer[3] == '0') 1342 | { 1343 | if (isModulationEnable) 1344 | { 1345 | sendLCDCommand("b0.pic=21"); 1346 | sendLCDCommand("b1.pic=71"); 1347 | } 1348 | else 1349 | { 1350 | sendLCDCommand("b0.pic=70"); 1351 | sendLCDCommand("b1.pic=22"); 1352 | } 1353 | 1354 | if (modType == MODULATION_AM) 1355 | { 1356 | sendLCDCommand("b2.pic=26"); 1357 | sendLCDCommand("b3.pic=73"); 1358 | sendLCDCommand("b4.pic=74"); 1359 | } 1360 | else if (modType == MODULATION_FM) 1361 | { 1362 | sendLCDCommand("b2.pic=72"); 1363 | sendLCDCommand("b3.pic=27"); 1364 | sendLCDCommand("b4.pic=74"); 1365 | } 1366 | else if (modType == MODULATION_PULSE) 1367 | { 1368 | sendLCDCommand("b2.pic=72"); 1369 | sendLCDCommand("b3.pic=73"); 1370 | sendLCDCommand("b4.pic=28"); 1371 | } 1372 | } 1373 | else if (commandBuffer[3] == '1') 1374 | { 1375 | if (modInput == MODULATION_INTERNAL) 1376 | { 1377 | sendLCDCommand("b0.pic=23"); 1378 | sendLCDCommand("b1.pic=67"); 1379 | sendLCDCommand("b2.pic=75"); 1380 | } 1381 | else if (modInput == MODULATION_EXTERNAL) 1382 | { 1383 | sendLCDCommand("b0.pic=64"); 1384 | sendLCDCommand("b1.pic=24"); 1385 | sendLCDCommand("b2.pic=75"); 1386 | } 1387 | else if (modInput == MODULATION_MICROPHONE) 1388 | { 1389 | sendLCDCommand("b0.pic=64"); 1390 | sendLCDCommand("b1.pic=67"); 1391 | sendLCDCommand("b2.pic=25"); 1392 | } 1393 | 1394 | if (modWaveForm == MODULATION_SINE) 1395 | { 1396 | sendLCDCommand("b3.pic=29"); 1397 | sendLCDCommand("b5.pic=77"); 1398 | sendLCDCommand("b6.pic=78"); 1399 | sendLCDCommand("b4.pic=79"); 1400 | } 1401 | else if (modWaveForm == MODULATION_RAMP) 1402 | { 1403 | sendLCDCommand("b3.pic=76"); 1404 | sendLCDCommand("b5.pic=30"); 1405 | sendLCDCommand("b6.pic=78"); 1406 | sendLCDCommand("b4.pic=79"); 1407 | } 1408 | else if (modWaveForm == MODULATION_SQUARE) 1409 | { 1410 | sendLCDCommand("b3.pic=76"); 1411 | sendLCDCommand("b5.pic=77"); 1412 | sendLCDCommand("b6.pic=32"); 1413 | sendLCDCommand("b4.pic=79"); 1414 | } 1415 | else if (modWaveForm == MODULATION_TRIANGLE) 1416 | { 1417 | sendLCDCommand("b3.pic=76"); 1418 | sendLCDCommand("b5.pic=77"); 1419 | sendLCDCommand("b6.pic=78"); 1420 | sendLCDCommand("b4.pic=31"); 1421 | } 1422 | 1423 | 1424 | strcpy(lcdCommand, "t2.txt=\""); 1425 | uint64ToString(modIntFreq, tmp); 1426 | strcat(lcdCommand, tmp); 1427 | strcat(lcdCommand, "\""); 1428 | sendLCDCommand(lcdCommand); 1429 | 1430 | sendLCDCommand("unit1.val=0"); 1431 | 1432 | strcpy(lcdCommand, "t4.txt=\""); 1433 | uint64ToString(amDepth, tmp); 1434 | strcat(lcdCommand, tmp); 1435 | strcat(lcdCommand, "\""); 1436 | sendLCDCommand(lcdCommand); 1437 | 1438 | } 1439 | else if (commandBuffer[3] == '2') 1440 | { 1441 | if (modInput == MODULATION_INTERNAL) 1442 | { 1443 | sendLCDCommand("b0.pic=23"); 1444 | sendLCDCommand("b1.pic=67"); 1445 | sendLCDCommand("b2.pic=75"); 1446 | } 1447 | else if (modInput == MODULATION_EXTERNAL) 1448 | { 1449 | sendLCDCommand("b0.pic=64"); 1450 | sendLCDCommand("b1.pic=24"); 1451 | sendLCDCommand("b2.pic=75"); 1452 | } 1453 | else if (modInput == MODULATION_MICROPHONE) 1454 | { 1455 | sendLCDCommand("b0.pic=64"); 1456 | sendLCDCommand("b1.pic=67"); 1457 | sendLCDCommand("b2.pic=25"); 1458 | } 1459 | 1460 | if (modWaveForm == MODULATION_SINE) 1461 | { 1462 | sendLCDCommand("b3.pic=29"); 1463 | sendLCDCommand("b5.pic=77"); 1464 | sendLCDCommand("b6.pic=78"); 1465 | sendLCDCommand("b4.pic=79"); 1466 | } 1467 | else if (modWaveForm == MODULATION_RAMP) 1468 | { 1469 | sendLCDCommand("b3.pic=76"); 1470 | sendLCDCommand("b5.pic=30"); 1471 | sendLCDCommand("b6.pic=78"); 1472 | sendLCDCommand("b4.pic=79"); 1473 | } 1474 | else if (modWaveForm == MODULATION_SQUARE) 1475 | { 1476 | sendLCDCommand("b3.pic=76"); 1477 | sendLCDCommand("b5.pic=77"); 1478 | sendLCDCommand("b6.pic=32"); 1479 | sendLCDCommand("b4.pic=79"); 1480 | } 1481 | else if (modWaveForm == MODULATION_TRIANGLE) 1482 | { 1483 | sendLCDCommand("b3.pic=76"); 1484 | sendLCDCommand("b5.pic=77"); 1485 | sendLCDCommand("b6.pic=78"); 1486 | sendLCDCommand("b4.pic=31"); 1487 | } 1488 | 1489 | strcpy(lcdCommand, "t2.txt=\""); 1490 | uint64ToString(modIntFreq, tmp); 1491 | strcat(lcdCommand, tmp); 1492 | strcat(lcdCommand, "\""); 1493 | sendLCDCommand(lcdCommand); 1494 | 1495 | sendLCDCommand("unit1.val=0"); 1496 | 1497 | strcpy(lcdCommand, "t4.txt=\""); 1498 | uint64ToString(fmDev, tmp); 1499 | strcat(lcdCommand, tmp); 1500 | strcat(lcdCommand, "\""); 1501 | sendLCDCommand(lcdCommand); 1502 | 1503 | sendLCDCommand("unit2.val=0"); 1504 | 1505 | } 1506 | else if (commandBuffer[3] == '3') 1507 | { 1508 | if (modInput == MODULATION_INTERNAL) 1509 | { 1510 | sendLCDCommand("b0.pic=23"); 1511 | sendLCDCommand("b1.pic=67"); 1512 | } 1513 | else if (modInput == MODULATION_EXTERNAL) 1514 | { 1515 | sendLCDCommand("b0.pic=64"); 1516 | sendLCDCommand("b1.pic=24"); 1517 | } 1518 | 1519 | strcpy(lcdCommand, "t2.txt=\""); 1520 | uint64ToString(pulsePeriod, tmp); 1521 | strcat(lcdCommand, tmp); 1522 | strcat(lcdCommand, "\""); 1523 | sendLCDCommand(lcdCommand); 1524 | 1525 | sendLCDCommand("unit1.val=0"); 1526 | 1527 | strcpy(lcdCommand, "t4.txt=\""); 1528 | uint64ToString(pulseWidth, tmp); 1529 | strcat(lcdCommand, tmp); 1530 | strcat(lcdCommand, "\""); 1531 | sendLCDCommand(lcdCommand); 1532 | 1533 | sendLCDCommand("unit2.val=0"); 1534 | } 1535 | } 1536 | else if (commandBuffer[2] == 'E') 1537 | { 1538 | if (readFromExEEPROM(REMEMBER_ADDR) == 0x01) 1539 | { 1540 | sendLCDCommand("b3.pic=122"); 1541 | sendLCDCommand("b2.pic=124"); 1542 | } 1543 | else 1544 | { 1545 | sendLCDCommand("b3.pic=121"); 1546 | sendLCDCommand("b2.pic=123"); 1547 | } 1548 | 1549 | if (isVibrationOn) 1550 | { 1551 | sendLCDCommand("b4.pic=95"); 1552 | } 1553 | else 1554 | { 1555 | sendLCDCommand("b4.pic=96"); 1556 | } 1557 | } 1558 | else if (commandBuffer[2] == 'V') 1559 | { 1560 | vibrate(); 1561 | } 1562 | } 1563 | else if (commandID == 'P') 1564 | { 1565 | command(">SR0"); // Internal Reference 1566 | command(">SS70"); // Sweep Free Run 1567 | command(">SS6"); // Sweep Stopped 1568 | command(">SS11000000000"); // Sweep Start Freq 1GHz 1569 | command(">SS22000000000"); // Sweep Stop Freq 2 GHz 1570 | command(">SS3100000000"); // Sweep Step Freq 100 MHz 1571 | command(">SS410000"); // Sweep Dwell time 10 ms 1572 | command(">SM0"); // Modulation is OFF 1573 | command(">SMT0"); // Modulation type is AM 1574 | command(">SMI0"); // Modulation input is Internal 1575 | command(">SMW0"); // Modulation waveform is Sine 1576 | command(">SMF1000"); // Modulation Internal Frequency is 1KHz 1577 | command(">SMFD50000"); // Modulation FM Deviation 50KHz 1578 | command(">SMA99"); // AM Depth is 99% 1579 | command(">SMPP10000"); // Pulse Period is 10ms 1580 | command(">SMPW5000"); // Pulse Width is 5ms 1581 | command(">SEL0"); // Remember last settings on start is off 1582 | command(">SV1"); // Vibration is ON 1583 | command(">F1000000000"); // 1GHZ 1584 | command(">SA0"); // 0dBm 1585 | command(">SF1"); // RF ON 1586 | command(">GH"); // send home settings 1587 | } 1588 | else if (commandID == 'X') 1589 | { 1590 | Serial.println("Upload is active"); 1591 | isUploadCode = true; 1592 | Serial.begin(250000); 1593 | Serial1.begin(9600); 1594 | delay(2000); 1595 | sendLCDCommand("baud=115200"); 1596 | delay(2000); 1597 | Serial1.begin(115200); 1598 | } 1599 | } 1600 | 1601 | void sendLCDCommand(char* input) 1602 | { 1603 | Serial1.write(input, strlen(input)); 1604 | Serial1.write(0xFF); 1605 | Serial1.write(0xFF); 1606 | Serial1.write(0xFF); 1607 | delay(5); 1608 | } 1609 | 1610 | void vibrate() 1611 | { 1612 | if (isVibrationOn) 1613 | { 1614 | digitalWrite(vibMotor, LOW); 1615 | delay(30); 1616 | digitalWrite(vibMotor, HIGH); 1617 | } 1618 | } 1619 | 1620 | void setAmplitude() 1621 | { 1622 | if (amplitude < -50) { amplitude = -50; } 1623 | if (amplitude > 15) { amplitude = 15; } 1624 | 1625 | float f1 = Frequency; 1626 | 1627 | f1 /= 1e7; 1628 | f1 = round(f1); 1629 | f1--; 1630 | 1631 | uint16_t lmxAddr = 0; 1632 | uint16_t f2250Addr = 0; 1633 | uint8_t rfsa = 0; 1634 | 1635 | if (amplitude == 15) 1636 | { 1637 | lmxAddr = LMX_CAL_15; 1638 | f2250Addr = F2250_CAL_15; 1639 | } 1640 | else if (amplitude == 14) 1641 | { 1642 | lmxAddr = LMX_CAL_15; 1643 | f2250Addr = F2250_CAL_14; 1644 | } 1645 | else if (amplitude == 13) 1646 | { 1647 | lmxAddr = LMX_CAL_15; 1648 | f2250Addr = F2250_CAL_13; 1649 | } 1650 | else if (amplitude == 12) 1651 | { 1652 | lmxAddr = LMX_CAL_15; 1653 | f2250Addr = F2250_CAL_12; 1654 | } 1655 | else if (amplitude == 11) 1656 | { 1657 | lmxAddr = LMX_CAL_15; 1658 | f2250Addr = F2250_CAL_11; 1659 | } 1660 | else if (amplitude == 10) 1661 | { 1662 | lmxAddr = LMX_CAL_15; 1663 | f2250Addr = F2250_CAL_10; 1664 | } 1665 | else if (amplitude < 10 & amplitude > -21) 1666 | { 1667 | lmxAddr = LMX_CAL_15; 1668 | f2250Addr = F2250_CAL_10; 1669 | rfsa = ((amplitude - 10)*(-4)); 1670 | } 1671 | else if (amplitude == -21) 1672 | { 1673 | lmxAddr = LMX_CAL_21; 1674 | f2250Addr = F2250_CAL_21; 1675 | } 1676 | else if (amplitude < -21 & amplitude >= -50) 1677 | { 1678 | lmxAddr = LMX_CAL_21; 1679 | f2250Addr = F2250_CAL_21; 1680 | rfsa = ((amplitude + 21) * (-4)); 1681 | } 1682 | 1683 | uint16_t addr = f2250Addr + ((uint16_t)f1 * 2); 1684 | 1685 | LMXOutPwr = readFromExEEPROM(lmxAddr + (uint16_t)f1); 1686 | 1687 | uint16_t f2250 = readFromExEEPROM(addr + 1) << 8 | readFromExEEPROM(addr); 1688 | 1689 | setLMXPower(); 1690 | setF2250(f2250); 1691 | setRFSA3714(rfsa); 1692 | } 1693 | 1694 | void setSweepParams() 1695 | { 1696 | if (sweepStopFrequency < sweepStartFrequency) 1697 | { 1698 | sweepPoints = (sweepStartFrequency - sweepStopFrequency) / sweepStepFrequency; 1699 | } 1700 | else 1701 | { 1702 | sweepPoints = (sweepStopFrequency - sweepStartFrequency) / sweepStepFrequency; 1703 | } 1704 | 1705 | if (isModulationEnable && modType == MODULATION_PULSE && modInput == MODULATION_EXTERNAL) 1706 | { 1707 | if (!isExtModAttch) { attachInterrupt(digitalPinToInterrupt(trigPin), pulse_rising, RISING); isExtModAttch = true; } 1708 | } 1709 | 1710 | if (sweepType == 0) 1711 | { 1712 | TCCR3B = _BV(WGM33); 1713 | TCCR3A = 0; 1714 | if (sweepDwellTime < 8192) { TCCR3B |= _BV(CS30); ICR3 = sweepDwellTime * 8; } 1715 | else if (sweepDwellTime < 65536) { TCCR3B |= _BV(CS31); ICR3 = sweepDwellTime; } 1716 | else if (sweepDwellTime < 524288) { TCCR3B |= _BV(CS31) | _BV(CS30); ICR3 = sweepDwellTime / 8; } 1717 | else if (sweepDwellTime < 2097152) { TCCR3B |= _BV(CS32); ICR3 = sweepDwellTime / 32; } 1718 | else if (sweepDwellTime < 8388608) { TCCR3B |= _BV(CS32) | _BV(CS30); ICR3 = sweepDwellTime / 128; } 1719 | else { TCCR3B |= _BV(CS32) | _BV(CS30); ICR3 = 65535; } 1720 | TIMSK3 = _BV(TOIE3); 1721 | } 1722 | else 1723 | { 1724 | attachInterrupt(digitalPinToInterrupt(trigPin), sweepInterrupt, RISING); 1725 | } 1726 | } 1727 | 1728 | void sweepInterrupt() 1729 | { 1730 | if (isModulationEnable && !(modType == MODULATION_PULSE && modInput == MODULATION_EXTERNAL) ) { nextFreq = true; } 1731 | else { sweep(); } 1732 | } 1733 | 1734 | void sweep() 1735 | { 1736 | cli(); 1737 | nextFreq = false; 1738 | setLMX(sweepStartFrequency + (sweepStepFrequency * sweepIndex)); 1739 | if (sweepStartFrequency > sweepStopFrequency) 1740 | { 1741 | sweepIndex--; 1742 | if (abs(sweepIndex) > sweepPoints || (sweepStepFrequency > abs(sweepStartFrequency- sweepStopFrequency))) { sweepIndex = 0; } 1743 | } 1744 | else 1745 | { 1746 | sweepIndex++; 1747 | if (sweepIndex > sweepPoints || (sweepStepFrequency > abs(sweepStartFrequency - sweepStopFrequency))) { sweepIndex = 0; } 1748 | } 1749 | sei(); 1750 | } 1751 | 1752 | ISR(TIMER1_OVF_vect) 1753 | { 1754 | blinkLed(); 1755 | } 1756 | 1757 | ISR(TIMER3_OVF_vect) 1758 | { 1759 | sweepInterrupt(); 1760 | } 1761 | 1762 | void eepromLoad() 1763 | { 1764 | uint16_t address = SETTINGS_ADDR; 1765 | 1766 | // 1 byte 1767 | isModulationEnable = readFromExEEPROM(address); address++; 1768 | isSweepOn = readFromExEEPROM(address); address++; 1769 | isRFOnOff = readFromExEEPROM(address); address++; 1770 | isVibrationOn = readFromExEEPROM(address); address++; 1771 | modType = readFromExEEPROM(address); address++; 1772 | modInput = readFromExEEPROM(address); address++; 1773 | modWaveForm = readFromExEEPROM(address); address++; 1774 | amDepth = readFromExEEPROM(address); address++; 1775 | sweepType = readFromExEEPROM(address); address++; 1776 | reference = readFromExEEPROM(address); address++; 1777 | 1778 | // 2 byte 1779 | recoverLocals((uint8_t*)&sweepIndex, 2, address); address += 2; 1780 | recoverLocals((uint8_t*)&litude, 2, address); address += 2; 1781 | 1782 | // 4 byte 1783 | recoverLocals((uint8_t*)&modDelayVal, 4, address); address += 4; 1784 | recoverLocals((uint8_t*)&modIntFreq, 4, address); address += 4; 1785 | recoverLocals((uint8_t*)&fmDev, 4, address); address += 4; 1786 | recoverLocals((uint8_t*)&pulseWidth, 4, address); address += 4; 1787 | recoverLocals((uint8_t*)&pulsePeriod, 4, address); address += 4; 1788 | recoverLocals((uint8_t*)&sweepDwellTime, 4, address); address += 4; 1789 | 1790 | // 8 byte 1791 | recoverLocals((uint8_t*)&Frequency, 8, address); address += 8; 1792 | recoverLocals((uint8_t*)&sweepStartFrequency, 8, address); address += 8; 1793 | recoverLocals((uint8_t*)&sweepStopFrequency, 8, address); address += 8; 1794 | recoverLocals((uint8_t*)&sweepStepFrequency, 8, address); address += 8; 1795 | recoverLocals((uint8_t*)&sweepPoints, 8, address); address += 8; 1796 | 1797 | setReferenceType(reference); 1798 | setAmplitude(); 1799 | setLMX(Frequency); 1800 | rfOnOff(); 1801 | 1802 | if (isSweepOn) { setSweepParams(); } 1803 | if (isModulationEnable) { setModulationSettings(); } 1804 | } 1805 | 1806 | void recoverLocals(uint8_t* ptr, uint8_t size, uint16_t addr) 1807 | { 1808 | for (uint8_t i = 0; i < size; i++) 1809 | { 1810 | *ptr = readFromExEEPROM(addr); 1811 | ptr++; addr++; 1812 | } 1813 | } 1814 | 1815 | void eepromSave() 1816 | { 1817 | uint16_t address = SETTINGS_ADDR; 1818 | 1819 | // 1 byte 1820 | writeToExEEPROM(address, isModulationEnable); address++; 1821 | writeToExEEPROM(address, isSweepOn); address++; 1822 | writeToExEEPROM(address, isRFOnOff); address++; 1823 | writeToExEEPROM(address, isVibrationOn); address++; 1824 | writeToExEEPROM(address, modType); address++; 1825 | writeToExEEPROM(address, modInput); address++; 1826 | writeToExEEPROM(address, modWaveForm); address++; 1827 | writeToExEEPROM(address, amDepth); address++; 1828 | writeToExEEPROM(address, sweepType); address++; 1829 | writeToExEEPROM(address, reference); address++; 1830 | 1831 | // 2 byte 1832 | for (uint8_t i = 0; i < 2; i++) { writeToExEEPROM(address, (uint8_t)(sweepIndex >> (8 * i))); address++; } 1833 | for (uint8_t i = 0; i < 2; i++) { writeToExEEPROM(address, (uint8_t)(amplitude >> (8 * i))); address++; } 1834 | 1835 | // 4 byte 1836 | for (uint8_t i = 0; i < 4; i++) { writeToExEEPROM(address, (uint8_t)(modDelayVal >> (8 * i))); address++; } 1837 | for (uint8_t i = 0; i < 4; i++) { writeToExEEPROM(address, (uint8_t)(modIntFreq >> (8 * i))); address++; } 1838 | for (uint8_t i = 0; i < 4; i++) { writeToExEEPROM(address, (uint8_t)(fmDev >> (8 * i))); address++; } 1839 | for (uint8_t i = 0; i < 4; i++) { writeToExEEPROM(address, (uint8_t)(pulseWidth >> (8 * i))); address++; } 1840 | for (uint8_t i = 0; i < 4; i++) { writeToExEEPROM(address, (uint8_t)(pulsePeriod >> (8 * i))); address++; } 1841 | for (uint8_t i = 0; i < 4; i++) { writeToExEEPROM(address, (uint8_t)(sweepDwellTime >> (8 * i))); address++; } 1842 | 1843 | // 8 byte 1844 | for (uint8_t i = 0; i < 8; i++) { writeToExEEPROM(address, (uint8_t)(Frequency >> (8 * i))); address++; } 1845 | for (uint8_t i = 0; i < 8; i++) { writeToExEEPROM(address, (uint8_t)(sweepStartFrequency >> (8 * i))); address++; } 1846 | for (uint8_t i = 0; i < 8; i++) { writeToExEEPROM(address, (uint8_t)(sweepStopFrequency >> (8 * i))); address++; } 1847 | for (uint8_t i = 0; i < 8; i++) { writeToExEEPROM(address, (uint8_t)(sweepStepFrequency >> (8 * i))); address++; } 1848 | for (uint8_t i = 0; i < 8; i++) { writeToExEEPROM(address, (uint8_t)(sweepPoints >> (8 * i))); address++; } 1849 | 1850 | } 1851 | 1852 | void eepromClear() 1853 | { 1854 | for (uint16_t i = SETTINGS_ADDR; i < SETTINGS_ADDR + SETTINGS_LENGTH; i++) { writeToExEEPROM(i, 0); } 1855 | } 1856 | 1857 | uint8_t readFromExEEPROM(uint16_t address) 1858 | { 1859 | cli(); 1860 | SPI.beginTransaction(SPISettings(EXTERNAL_EEPROM_MAX_CLOCK, MSBFIRST, SPI_MODE0)); 1861 | digitalWrite(eeprom_LE, LOW); 1862 | SPI.transfer(EXTERNAL_EEPROM_READ); 1863 | SPI.transfer((uint8_t)(address >> 8)); 1864 | SPI.transfer((uint8_t)(address)); 1865 | uint8_t a1 = SPI.transfer(0x00); 1866 | digitalWrite(eeprom_LE, HIGH); 1867 | SPI.endTransaction(); 1868 | sei(); 1869 | return a1; 1870 | } 1871 | 1872 | void readFromExEEPROM(uint16_t address, uint8_t *ptr) 1873 | { 1874 | cli(); 1875 | SPI.beginTransaction(SPISettings(EXTERNAL_EEPROM_MAX_CLOCK, MSBFIRST, SPI_MODE0)); 1876 | digitalWrite(eeprom_LE, LOW); 1877 | SPI.transfer(EXTERNAL_EEPROM_READ); 1878 | SPI.transfer((uint8_t)(address >> 8)); 1879 | SPI.transfer((uint8_t)(address)); 1880 | *ptr = SPI.transfer(0x00); ptr++; 1881 | *ptr = SPI.transfer(0x00); ptr++; 1882 | *ptr = SPI.transfer(0x00); 1883 | digitalWrite(eeprom_LE, HIGH); 1884 | SPI.endTransaction(); 1885 | sei(); 1886 | } 1887 | 1888 | void writeToExEEPROM(uint16_t address, uint8_t data) 1889 | { 1890 | cli(); 1891 | SPI.beginTransaction(SPISettings(EXTERNAL_EEPROM_MAX_CLOCK, MSBFIRST, SPI_MODE0)); 1892 | // SEND WRITE ENABLE FIRST 1893 | digitalWrite(eeprom_LE, LOW); 1894 | SPI.transfer(EXTERNAL_EEPROM_WREN); 1895 | digitalWrite(eeprom_LE, HIGH); 1896 | 1897 | digitalWrite(eeprom_LE, LOW); 1898 | SPI.transfer(EXTERNAL_EEPROM_WRITE); 1899 | SPI.transfer((uint8_t)(address >> 8)); 1900 | SPI.transfer((uint8_t)(address)); 1901 | SPI.transfer(data); 1902 | digitalWrite(eeprom_LE, HIGH); 1903 | sei(); 1904 | delay(10); 1905 | } 1906 | --------------------------------------------------------------------------------