Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: ADF4350 SDR Code Issues

  1. #1
    Junior Member
    Join Date
    Sep 2018
    Posts
    4

    ADF4350 SDR Code Issues

    I've been working on an SDR project for a while and got some help to get my code up to a better state and I can't seem to get it to work on my Teensy 3.2. On an Arduino Uno, it will compile but won't display anything. I can't find the issues as I'm not much of a programmer. Would you all mind looking over it and passing along some advice or pointing out possible issues?

    Code:
    //Libraries
    #include <unistd.h>
    #include <stdio.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <U8g2lib.h>
    #include <SPI.h>
    #include <ADF4350.h>
    #include "freq_arrays.h" // include global arrays from header file
    
    //Define ADF4350 library/hardware interface
    #define PLL_LE_PIN 10 //add pin number 10 is already taken
    #define CLK_PIN 11 //add pin number 11 is already taken
    #define DATA_PIN 12
    ADF4350 PLL(PLL_LE_PIN);
    
    // Pinouts for lcd library - change these if rewiring display circuit
    #define U8G2_CLOCK_PIN 13
    #define U8G2_DATA_PIN 11
    #define U8G2_CS_PIN 10
    #define U8G2_DC_PIN 9 
    #define U8G2_RESET_PIN 8
    
    //OLED library
    U8G2_SSD1327_MIDAS_128X128_1_4W_SW_SPI u8g2(U8G2_R0, U8G2_CLOCK_PIN, U8G2_DATA_PIN, U8G2_CS_PIN, U8G2_DC_PIN, U8G2_RESET_PIN);
    
    // Each one of these indicates 1 based index position in array of menu text items
    //   if these change the switch(){} statement in the loop function and the menu text 
    //   array must be updated to reflect the changes
    #define COMBINED_ACTION 1
    #define WIFI_ACTION 2
    #define NA_ACTION 3
    #define GPS_ACTION 4
    #define STOP_ACTION 5
    
    
    
    // global variables
    char* menu_title1 = "Frequencies";
    char* menu_title2 = "Frequencies .....";
    // TODO: sort out menu text so that a single array of strings is used for all purposes
    char* menu_txt[] = {"All", "Wifi", "NA", "GPS", "STOP"};
    char* menu_txt_str1 = "All\nWifi\nNA\nGPS\nSTOP";
    char* menu_txt_str2 = "All\nWifi\nNA\nGPS";
    
    boolean WORKING = false;
    int J_ACTION = STOP_ACTION;
    int last_menu_selection = STOP_ACTION;
    int menu_selection = STOP_ACTION;
    int user_selection = 0;
    int timer1_counter = 0;
    
    int array_size = 0; 
    volatile int array_pos = 0;
    
    void setup () {
    
       //Define Button(menu) library/hardware interface
      u8g2.begin(/*Select=*/ 6, /*Right/Next=*/ U8X8_PIN_NONE, /*Left/Prev=*/ U8X8_PIN_NONE, /*Up=*/ 4, /*Down=*/ 3, /*Home/Cancel=*/ U8X8_PIN_NONE); 
    
      //Define Font size
      u8g2.setFont(u8g2_font_6x12_tr);
    
      // Set timer1_counter to the correct value for our interrupt interval
      // NOTE: Timer 1 is a 16 bit timer, max value is 65536 
      // firing interrupt every 50ms === 200Hz interrupt rate
      //      timer = 65536 - ( (16MHz/256) / 200Hz)
      //               = 65536 - (62500 / 200)
      //               = 65536 - 312.5
      timer1_counter = 65223;  // rounded up  
    
      // Pretty standard interrupt code, 
      // setup and ISR copied from https://www.robotshop.com/letsmakero...and-interrupts
      // initialize timer1 
      noInterrupts();           // disable all interrupts
      TCCR1A = 0;
      TCCR1B = 0;
      TCNT1  = 0;
    
      OCR1A = timer1_counter;            // compare match register with timer1_counter
      TCCR1B |= (1 << WGM12);   // CTC mode
      TCCR1B |= (1 << CS12);    // 256 prescaler 
      TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
      interrupts();             // enable all interrupts
    
      // enable PLL output
      // Q: should this be here?
      PLL.rfEnable(1); //Sets the ADF4350 to enable output
    
    }
    
    void loop() {
      
    
      // display menu, wait for input
      user_selection = get_menu_choice();
    
      // only act on menu choices if they are not same as last choice
      if (user_selection != last_menu_selection) {
    
        stop_action();
    
        menu_selection = user_selection;
      
        // setup array sizes
        switch (menu_selection) {
    
          case COMBINED_ACTION:
            array_size = sizeof(COMBINED_ARRAY); //Gives the number of the last element in the array
            break;
      
          case WIFI_ACTION:
      array_size = sizeof(WIFI_ARRAY); //Gives the number of the last element in the array
      break;
    
          case NA_ACTION:
            array_size = sizeof(NA_ARRAY); //Gives the number of the last element in the array
            break;
    
          case GPS_ACTION:
            array_size = sizeof(GPS_ARRAY); //Gives the number of the last element in the array
      break;
    
          default:
            array_size = 0;
            break;
    
        }
    
        // only start if menu choice indicates jamming action chosen
        if (menu_selection != STOP_ACTION) {
    
          // give user some feedback
          user_selection = display_menu_action(menu_selection);
    
          // user canceled action
          if (user_selection == 0) { 
            stop_action();
    
            } else  {
              start_action(menu_selection);
        
          }
    
        }
    
        // store last selection so we can show it as part of STOP menu choice
        last_menu_selection = menu_selection;
    
      }
    
    
    }
    
    
    int get_menu_choice() { 
    //Logic for menu choices
      int selection = 0;
    /*
    char buf[30];
      const char *first = "sent ";
      const char *second = "message";
      strcpy(buf,first);
      strcat(buf,second);
    */
      
      if (WORKING) {
      // 5 periods indictes ACTION is active
      // TODO: animate periods, scroll txt, etc. to show ACTION is active
      // include STOP choice
         selection = u8g2.userInterfaceSelectionList(menu_title1, 1,  menu_txt_str1);
    
        } else {
            // do not include stop
            selection = u8g2.userInterfaceSelectionList(menu_title2, 1, menu_txt_str2);
        }
        
        return (selection);
    
    }
    
    // Give the user some feedback and allow to confirm/cancel the action
    int display_menu_action(int menu_selection) {
    
      int ret_val = 0;
      
      ret_val = u8g2.userInterfaceMessage("Start Action", menu_txt[menu_selection -1]," ", " Ok \n Cancel ");
      return (ret_val);
    
    }
    
    // Start WORKING
    void start_action (int action) {
        array_pos = 0;
        J_ACTION = action;
        WORKING = true;
    
        // enable PLL output
        PLL.rfEnable(0);
        
        interrupts();             // enable all interrupts
    
    }
    
    // Stop WORKING
    void stop_action () {
        noInterrupts();           // disable all interrupts
        
        // enable PLL output
        PLL.rfEnable(1);
    
        J_ACTION = STOP_ACTION;
        WORKING = false;
        array_pos = 0;
    }
    
    
    // Interrupt code
    //
    ISR(TIMER1_COMPA_vect) {         // timer compare interrupt service routine
    
      // check which frequency array is being used and continue sweeping
      // though frequencies
     switch (J_ACTION) {
    
        case COMBINED_ACTION:
          combined_array_loop();
          break;
    
        case WIFI_ACTION:
          wifi_array_loop();
          break;
    
        case NA_ACTION:
          na_array_loop();
          break;
    
        case GPS_ACTION:
          gps_array_loop();
          break;
    
        case STOP_ACTION:
          break;
    
        default:
          // statements
          break;
      }
    
      //Checks if the current array index is the last, if so, it resets to the first index position,
      //  otherwise it increments index counter
      if (array_pos >= (array_size - 1) ) {
        array_pos = 0;
      } else {
        array_pos++;
      }
    
    }
    
    
    //actual working loops    
    void combined_array_loop() {
    
        PLL.setFreq(pgm_read_word(&COMBINED_ARRAY[array_pos])); //Feeds the frequency to the ADF4350
    
    }
    
    void wifi_array_loop() {
        PLL.setFreq(pgm_read_word(&WIFI_ARRAY[array_pos])); //Feeds the frequency to the ADF4350
    
    }
    
    void na_array_loop() {
        PLL.setFreq(pgm_read_word(&NA_ARRAY[array_pos])); //Feeds the frequency to the ADF4350
    
    }
    
    void  gps_array_loop() {
        PLL.setFreq(pgm_read_word(&GPS_ARRAY[array_pos])); //Feeds the frequency to the ADF4350
    
    }
    Last edited by Theremingenieur; 09-29-2018 at 11:25 PM. Reason: Added code tags for better readabilty

  2. #2
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,442
    This code is obviously written for these old and underpowered 8bit AVR MCUs like Arduino. The Teensy 3.x MCUs have a modern 32bit ARM core. Some of that timer and interrupt stuff which is directly addressing the AVR timer registers must be rewritten for the KINETIS hardware.

  3. #3
    Junior Member
    Join Date
    Sep 2018
    Posts
    4
    Thank you, I will look into some sample code and try and figure that out.

  4. #4
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,442
    One problem is that timer interrupt every 50ms.

    You might declare before setup():
    Code:
    IntevalTimer avrTimerEmu;
    In setup(), you might erase all that AVR timer configuration:
    Code:
    // Set timer1_counter to the correct value for our interrupt interval
    // NOTE: Timer 1 is a 16 bit timer, max value is 65536 
    // firing interrupt every 50ms === 200Hz interrupt rate
    // timer = 65536 - ( (16MHz/256) / 200Hz)
    // = 65536 - (62500 / 200)
    // = 65536 - 312.5
    timer1_counter = 65223; // rounded up  
    
    // Pretty standard interrupt code, 
    // setup and ISR copied from https://www.robotshop.com/letsmakero...and-interrupts
    // initialize timer1 
    noInterrupts(); // disable all interrupts
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1 = 0;
    
    OCR1A = timer1_counter; // compare match register with timer1_counter
    TCCR1B |= (1 << WGM12); // CTC mode
    TCCR1B |= (1 << CS12); // 256 prescaler 
    TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
    interrupts(); // enable all interrupts
    and replace it with
    Code:
    avrTimerEMu.begin(avrIntEmu, 50000); //50000us = 50ms like 200Hz
    Finally, you rename the corresponding interrupt handler. Instead of
    Code:
    ISR(TIMER1_COMPA_vect){…
    call it
    Code:
    void avrIntEmu(){…
    Last edited by Theremingenieur; 09-29-2018 at 11:43 PM.

  5. #5
    Junior Member
    Join Date
    Sep 2018
    Posts
    4
    Wow, thank you so much! I'll start putting that in place now. I really appreciate your help with the timer portion of my programming issues.

  6. #6
    Junior Member
    Join Date
    Sep 2018
    Posts
    4

    Thank you!

    Thank you so much! My code compiles now! It still doesn't display on a working display (I tested the pin out/display with "Hello World" and it works fine). Thank you again.


    Quote Originally Posted by Theremingenieur View Post
    One problem is that timer interrupt every 50ms.

    You might declare before setup():
    Code:
    IntevalTimer avrTimerEmu;
    In setup(), you might erase all that AVR timer configuration:
    Code:
    // Set timer1_counter to the correct value for our interrupt interval
    // NOTE: Timer 1 is a 16 bit timer, max value is 65536 
    // firing interrupt every 50ms === 200Hz interrupt rate
    // timer = 65536 - ( (16MHz/256) / 200Hz)
    // = 65536 - (62500 / 200)
    // = 65536 - 312.5
    timer1_counter = 65223; // rounded up  
    
    // Pretty standard interrupt code, 
    // setup and ISR copied from https://www.robotshop.com/letsmakero...and-interrupts
    // initialize timer1 
    noInterrupts(); // disable all interrupts
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1 = 0;
    
    OCR1A = timer1_counter; // compare match register with timer1_counter
    TCCR1B |= (1 << WGM12); // CTC mode
    TCCR1B |= (1 << CS12); // 256 prescaler 
    TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
    interrupts(); // enable all interrupts
    and replace it with
    Code:
    avrTimerEMu.begin(avrIntEmu, 50000); //50000us = 50ms like 200Hz
    Finally, you rename the corresponding interrupt handler. Instead of
    Code:
    ISR(TIMER1_COMPA_vect){
    call it
    Code:
    void avrIntEmu(){

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •