/* ******************************************************************************************** * (c) Bob Larkin W7PUA 2018 * Test of hardware for SDR Control Box * * W7PUA Ver 3 Feb 2018 Added #defines for Teensy pins *********************************************************************************************/ #include #include #include #include #include #include #include "font_Arial.h" #include #include // Change to Bounce2 ? #include // Serial1 is the RS-232 serial through pins 0 & 1 // Serial4 pins 31,32 // Serial5 pins 34,33 // Change this to test other RS-232 ports #define PC_SERIAL Serial4 // For I2C "Wire" library, default Teensy 3.6 uses: // SDA Data Pin 18 // SCL Clock Pin 19 #define TFT_DC 10 #define TFT_CS 20 #define TFT_MOSI 7 #define TFT_SCLK 14 #define TFT_MISO 8 // Data and clock are set by SPI (or SPI1 or SPI2) #define SPI_MOSI 7 // Shared SPI MOSI #define SPI_MISO 8 // Shared SPI MISO #define SPI_CLOCK 14 // Shared SPI SCK // The chip select is any digital pin: #define BOX_SPI_CS 28 // Push-buttons #define BUTTON_1_PIN 35 // Left #define BUTTON_2_PIN 36 // Right #define BUTTON_3_PIN 37 // Down #define BUTTON_4_PIN 38 // Up #define BUTTON_5_PIN 41 // the pushbutton pin of the tune encoder (ALT) #define BUTTON_6_PIN 26 // the pushbutton pin of the filter encoder (FCN) #define BUTTON_7_PIN 43 // the menu button pin #define BUTTON_8_PIN 27 // the pushbutton pin of encoder 3 (GAIN?) #define ENCODER_TUNE_I 3 #define ENCODER_TUNE_Q 2 #define ENCODER_FILTER_I 4 #define ENCODER_FILTER_Q 5 #define ENCODER_3_I 47 #define ENCODER_3_Q 48 /* ****** End Pin Defines************************************ */ /* SPI - Setup "transactional" structure to simplify having multiple SPI devices with different * settings. See https://www.pjrc.com/teensy/td_libs_SPI.html * Here we have just one device, the internal SPI lines for the cascaded 74LVC595 and the * programable LTC6912-2 programmable audio amplifier. */ // using two incompatible SPI devices, A and B const int slaveAPin = 20; const int slaveBPin = 21; // set up the speed, mode and endianness of each device // A quick check for the SDR_Control box showed 5 MHz worked and 10 MHz did not. // For SPI through the 25-pin D connector, something around 2 MHz is the limit. SPISettings settingsA(5000000, MSBFIRST, SPI_MODE0); // Optical Encoder objects Encoder tune (ENCODER_TUNE_I, ENCODER_TUNE_Q); Encoder filter (ENCODER_FILTER_I, ENCODER_FILTER_Q); Encoder encoder3 (ENCODER_3_I, ENCODER_3_Q); ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC, 255, TFT_MOSI, TFT_SCLK, TFT_MISO); //255 for TFT_RST Bounce button1 = Bounce(BUTTON_1_PIN, 50); Bounce button2 = Bounce(BUTTON_2_PIN, 50); Bounce button3 = Bounce(BUTTON_3_PIN, 50); Bounce button4 = Bounce(BUTTON_4_PIN, 50); Bounce button5 = Bounce(BUTTON_5_PIN, 50); Bounce button6 = Bounce(BUTTON_6_PIN, 50); Bounce button7 = Bounce(BUTTON_7_PIN, 50); Bounce button8 = Bounce(BUTTON_8_PIN, 50); AudioInputI2S i2s_in; // Generates timing. No input AudioSynthWaveformSine sine1; //xy=352,639 AudioOutputI2S i2s_out; //xy=545,636 AudioConnection patchCord1(sine1, 0, i2s_out, 0); AudioConnection patchCord2(sine1, 0, i2s_out, 1); AudioControlSGTL5000 sgtl5000_1; //xy=540,779 // Variables for button tests byte previousState1 = HIGH; // what state was the button last time unsigned int count1 = 0; // how many times has it changed to low unsigned int countPrinted1 = 0; // last count printed byte previousState2 = HIGH; // what state was the button last time unsigned int count2 = 0; // how many times has it changed to low unsigned int countPrinted2 = 0; // last count printed byte previousState3 = HIGH; // what state was the button last time unsigned int count3 = 0; // how many times has it changed to low unsigned int countPrinted3 = 0; // last count printed byte previousState4 = HIGH; // what state was the button last time unsigned int count4 = 0; // how many times has it changed to low unsigned int countPrinted4 = 0; // last count printed byte previousState5 = HIGH; // what state was the button last time unsigned int count5 = 0; // how many times has it changed to low unsigned int countPrinted5 = 0; // last count printed byte previousState6 = HIGH; // what state was the button last time unsigned int count6 = 0; // how many times has it changed to low unsigned int countPrinted6 = 0; // last count printed byte previousState7 = HIGH; // what state was the button last time unsigned int count7 = 0; // how many times has it changed to low unsigned int countPrinted7 = 0; // last count printed byte previousState8 = HIGH; // what state was the button last time unsigned int count8 = 0; // how many times has it changed to low unsigned int countPrinted8 = 0; // last count printed unsigned long countAt = 0; // when count changed // Variables for encoder tests long tunePosition = -999; long filterPosition = -999; long encoder3Position = -999; /* ************************** SETUP ******************************* */ void setup() { Serial.begin(115200); delay(1000); PC_SERIAL.begin(9600); // RS-232 with PC (not USB) // set the ChipSelectPin for the Control Box SPI as an output: pinMode(BOX_SPI_CS, OUTPUT); /* There are 3 SPI ports, each of which serve multiple devices at separate times. * SPI corresponds to zero case, MOSI0, MISO0, SCK0 (Pins 7, 8, 14 (alternates to 11,12,13)) * Ref: https://www.pjrc.com/teensy/td_libs_SPI.html */ SPI.setMOSI(SPI_MOSI); SPI.setMISO(SPI_MISO); // Not used here (data back to Teensy) SPI.setSCK(SPI_CLOCK); SPI.begin(); // Init SPI interface in general // For this basic test, we will leave the sample rate at the default 44.1 kHz AudioMemory(15); sgtl5000_1.enable(); sgtl5000_1.volume(0.5); sgtl5000_1.lineOutLevel(24); sine1.frequency(440); // Generate a sine wave sine1.amplitude(0.5); // audible in the headphones pinMode(BUTTON_1_PIN, INPUT_PULLUP); pinMode(BUTTON_2_PIN, INPUT_PULLUP); pinMode(BUTTON_3_PIN, INPUT_PULLUP); pinMode(BUTTON_4_PIN, INPUT_PULLUP); pinMode(BUTTON_5_PIN, INPUT_PULLUP); pinMode(BUTTON_6_PIN, INPUT_PULLUP); pinMode(BUTTON_7_PIN, INPUT_PULLUP); pinMode(BUTTON_8_PIN, INPUT_PULLUP); // Basic ILI9341 Screen Print Test tft.begin(); tft.setRotation(1); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_YELLOW); tft.setCursor(30, 100); tft.setFont(Arial_14); tft.print("Test SDR_Control Hardware"); Serial.println("Push buttons or rotate encoders"); } // END SETUP void loop() { int incomingByte; // ====== RS-232 #1, #4 or #5 depending on PC_SERIAL // Write USB incoming to RS-232 if (Serial.available() > 0) // USB serial { incomingByte = Serial.read(); Serial.print("USB received: "); Serial.println(incomingByte, DEC); PC_SERIAL.print("USB received:"); PC_SERIAL.println(incomingByte, DEC); } // Write RS-232 (Pins 0,1) back to USB if (PC_SERIAL.available() > 0) { incomingByte = PC_SERIAL.read(); Serial.print("RS-232 #1 rcvd: "); Serial.println(incomingByte, DEC); } // ======== SPI Test ============ // Load Load // First Last //boxSPIWrite(0B00100000, 0B01000100); // E10 high, Av=8 // ^--E10 // LVC595 LTC6912 // // 595 byte, in order, QH QG QF QE QD QC QB QA // Green LED is 0B00000001; Red LED is 0B00000010 (bits 0 & 1) // For more tests, used the following alternatives: boxSPIWrite(0B01000001, 0B00000000); // E11 High, Green LED, Av=0 // boxSPIWrite(0B00100000, 0B00100010); // E10 High, LED off, Av=2 delay(1); // Makes it easier to trigger SPI on 'scope checkButtons(); // Check all 8 buttons checkEncoders(); // Check 3 encoders } /* ************************* END LOOP *************************** */ void checkButtons(void) { // Button Tests if (button1.update()) { if (button1.fallingEdge()) { count1 = count1 + 1; countAt = millis(); } } else { if (count1 != countPrinted1) { if (millis() - countAt > 100) { Serial.print("count 1: "); Serial.println(count1); countPrinted1 = count1; } } } if (button2.update()) { if (button2.fallingEdge()) { count2 = count2 + 1; countAt = millis(); } } else { if (count2 != countPrinted2) { if (millis() - countAt > 100) { Serial.print("count 2: "); Serial.println(count2); countPrinted2 = count2; } } } if (button3.update()) { if (button3.fallingEdge()) { count3 = count3 + 1; countAt = millis(); } } else { if (count3 != countPrinted3) { if (millis() - countAt > 100) { Serial.print("count 3: "); Serial.println(count3); countPrinted3 = count3; } } } if (button4.update()) { if (button4.fallingEdge()) { count4 = count4 + 1; countAt = millis(); } } else { if (count4 != countPrinted4) { if (millis() - countAt > 100) { Serial.print("count 4: "); Serial.println(count4); countPrinted4 = count4; } } } if (button5.update()) { if (button5.fallingEdge()) { count5 = count5 + 1; countAt = millis(); } } else { if (count5 != countPrinted5) { if (millis() - countAt > 100) { Serial.print("count 5: "); Serial.println(count5); countPrinted5 = count5; } } } if (button6.update()) { if (button6.fallingEdge()) { count6 = count6 + 1; countAt = millis(); } } else { if (count6 != countPrinted6) { if (millis() - countAt > 100) { Serial.print("count 6: "); Serial.println(count6); countPrinted6 = count6; } } } if (button7.update()) { if (button7.fallingEdge()) { count7 = count7 + 1; countAt = millis(); } } else { if (count7 != countPrinted7) { if (millis() - countAt > 100) { Serial.print("count 7: "); Serial.println(count7); countPrinted7 = count7; } } } if (button8.update()) { if (button8.fallingEdge()) { count8 = count8 + 1; countAt = millis(); } } else { if (count8 != countPrinted8) { if (millis() - countAt > 100) { Serial.print("count8: "); Serial.println(count8); countPrinted8 = count8; } } } } // End checkButtons() void checkEncoders(void) { long newTune, newFilter, newEncoder3; newTune = tune.read(); newFilter = filter.read(); newEncoder3 = encoder3.read(); if (newTune != tunePosition || newFilter != filterPosition || newEncoder3 != encoder3Position) { Serial.print("tune = "); Serial.print(newTune); Serial.print(", filter = "); Serial.print(newFilter); Serial.print(", encoder3 = "); Serial.print(newEncoder3); Serial.println(); tunePosition = newTune; filterPosition = newFilter; encoder3Position = newEncoder3; } } /* boxSPIWrite(data1, data2) * Write 2 bytes to the SPI port in the Control Box. Two bytes are written, * the first, data1, loading the 74LVC595 shift register, and the second, data2, controls * the gain of the LTC6912 audio preamp. * * Loads Loads` * First Last * boxSPIWrite(0B00100000, 0B00000000); * ^--E10 * ^--E11 * LVC595 LTC6912 */ void boxSPIWrite(uint8_t data1, uint8_t data2) { SPI.beginTransaction(settingsA); // take the SS pin low to select the chip: digitalWrite(BOX_SPI_CS, LOW); // send data via SPI: SPI.transfer(data1); SPI.transfer(data2); // take the SS pin high to de-select the chip: digitalWrite(BOX_SPI_CS, HIGH); SPI.endTransaction(); }