ADF4350 SDR Code Issues

Status
Not open for further replies.

3s10

New member
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 [URL]https://www.robotshop.com/letsmakerobots/arduino-101-timers-and-interrupts[/URL]
  // 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 a moderator:
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.
 
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 [URL="https://www.robotshop.com/letsmakerobots/arduino-101-timers-and-interrupts"]https://www.robotshop.com/letsmakero...and-interrupts[/URL]
// 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:
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.
 
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.


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 [URL="https://www.robotshop.com/letsmakerobots/arduino-101-timers-and-interrupts"]https://www.robotshop.com/letsmakero...and-interrupts[/URL]
// 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(){…
 
Status
Not open for further replies.
Back
Top