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

Thread: F_CPU_ACTUAL error in Teensy 4 but not Teensy 3

  1. #1
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    190

    F_CPU_ACTUAL error in Teensy 4 but not Teensy 3

    I've got a library that compiles fine under Teensy 3.6 but won't compile until Teensy 4.0. It's giving errors about not knowing F_CPU_ACTUAL. I suspect that this is a symptom of a larger problem, but I don't know how to chase it down. Why would I get compile errors for Teensy 4 but not for Teensy 3?

    More Info...

    My library is a float32 extension of the teensy audio library (https://github.com/Tympan/Tympan_Library), which means that most of its classes inherit (after a couple steps) from AudioStream from the Teensy Audio library.

    The simplest way to expose this problem is to simply open the PassThroughStereo example from the Teensy Audio library. It compiles fine as either Teensy 3.6 or Teensy 4.0.

    Now, to cause the error, I add the #include referencing my own library...not any actual code, just the #include:

    Code:
    //This is the beginning of PassThroughStereo.ino
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <Tympan_Library.h> //I added this.  I don't instantiate any classes.  I just added this #include.
    This complies fine under Teensy 3.6. But, under Teensy 4, I get the error below for (seemingly) every class that inherits from AudioStream...it claims that it does't know about F_CPU_ACTUAL:

    Code:
    In file included from C:\Users\wea\Documents\Arduino\libraries\Tympan_Library\src\AudioStream_F32.h:18:0,
    
                     from C:\Users\wea\Documents\Arduino\libraries\Tympan_Library\src\AudioMixer_F32.h:21,
    
                     from C:\Users\wea\Documents\Arduino\libraries\Tympan_Library\src\AudioMixer_F32.cpp:1:
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h: In member function 'int AudioStream::processorUsage()':
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:108:50: error: 'F_CPU_ACTUAL' was not declared in this scope
    
     #define CYCLE_COUNTER_APPROX_PERCENT(n) (((n) + (F_CPU_ACTUAL / 32 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100)) / (F_CPU_ACTUAL / 16 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100))
    Similarly, I also get the error below for many (all?) of the files that inherit from AudioStream...it claims that it doesn't know IRQ_SOFTWARE:

    Code:
    In file included from C:\Users\wea\Documents\Arduino\libraries\Tympan_Library\src\AudioStream_F32.h:18:0,
    
                     from C:\Users\wea\Documents\Arduino\libraries\Tympan_Library\src\AudioMixer_F32.h:21,
    
                     from C:\Users\wea\Documents\Arduino\libraries\Tympan_Library\src\AudioMixer_F32.cpp:1:
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h: In static member function 'static void AudioStream::update_all()':
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:162:50: error: 'IRQ_SOFTWARE' was not declared in this scope
    
      static void update_all(void) { NVIC_SET_PENDING(IRQ_SOFTWARE); }
    
                                                      ^
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:162:62: error: 'NVIC_SET_PENDING' was not declared in this scope
    
      static void update_all(void) { NVIC_SET_PENDING(IRQ_SOFTWARE); }
    Why would this compile fine under Teensy 3.6 but break under Teensy 4.0?

    Thanks,

    Chip

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,426
    Often times it is hard to know without actually seeing the sources and the like. It is probably simply that these defines are needed for T4 are not included in the header files that your class is using...

    That is for example the define: extern volatile uint32_t F_CPU_ACTUAL;
    Is in the file core_pins.h in the Cores\teensy4 directory. So your code is not including this file directly or indirectly.

    So you might simply add this include to your library and see if it helps...

  3. #3
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    190
    Hi KurtE,

    Thanks for the suggestion. I'll give it a try.

    As a point of education for myself...and stepping away from my own code to just focus on the stock Teensy code...how does AudioStream.h know these quantities? Neither the Teensy3 version and the Teensy4 version have much of a #include list...

    Teensy3 AudioStream.h: https://github.com/PaulStoffregen/co.../AudioStream.h
    Teensy4 AudioStream.h: https://github.com/PaulStoffregen/co.../AudioStream.h

    When these are computing CYCLE_COUNTER_APPROX_PERCENT, how do they know what F_CPU_ACTUAL is?

    Curiously, I see that Teensy3 uses F_CPU whereas Teensy4 uses F_CPU_ACTUAL. Why the difference?

    (Again, this is me trying to learn more of the guts so that I can contribute more usefully...)

    Chip

  4. #4
    CPU freq stuff is almost always specified as a compiler option, which is then visible from within code.

    Another example would be the chip. For teensy 4, a compiler option like "-D__IMXRT1062__" will be added, that's how "#ifdef __IMXRT1062__" works throughout the teensy 4 core code.

    The way I pick code apart to figure out how it works is use either an IDE with a "search in files" capability, or if you're on linux/mac, use grep to find whatever it is you're interested in.

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,586
    So many questions. I'll briefly comment on this one.

    Quote Originally Posted by chipaudette View Post
    Curiously, I see that Teensy3 uses F_CPU whereas Teensy4 uses F_CPU_ACTUAL. Why the difference?
    We're trying to better support dynamic CPU frequency changes on Teensy 4.0.

    This wasn't really feasible on Teensy 3.x, because nearly everything's clock is integer division from the CPU clock. Change the CPU clock and suddenly audio is at the wrong speed, baud rates are messed up, and so on. So F_CPU is a preprocessor constant on Teensy 3.x, just like it is on pretty much all Arduino compatible boards. All the software is designed around the assumption that F_CPU never changes.

    Teensy 4.0 has 7 PLLs, where 1 PLL is used for the CPU and 6 more plus a ton of dividers and muxes create the frequencies for all the speed sensitive peripherals. See the "CCM Clock Tree" in the reference manual to get a visual idea. While there are some small caveats, this hardware allows the CPU to change speed while pretty much all the timing sensitive peripherals keep running as their intended speeds.

    F_CPU_ACTUAL tries allow the software to adapt, so stuff like millis(), elapsedMicros, etc still work properly as the CPU speed changes. F_CPU_ACTUAL is a uint32_t that gives the current CPU speed in Hz. Initially I tried making F_CPU a variable. But the Arduino ecosystem is filled with code assuming it's a preprocessor macro, so we have a somewhat confusing situation where we have a meaningless F_CPU for the sake of compatibility. F_CPU_ACTUAL is what really matters on Teensy 4.0. It's not a constant. It tells you the current speed. You can expect the speed to change dynamically. In most cases you'd use it (read only) just like you would F_CPU, at least in equations. But don't use F_CPU_ACTUAL in #if checks for conditional compilation, because it's not a constant and not a preprocessor macro like F_CPU.

    Hopefully this explanation helps you understand the rationale, and the reason why I had to use 2 different names.
    Last edited by PaulStoffregen; 08-15-2019 at 03:31 PM.

  6. #6
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    190
    Cool explanation! Thanks!

  7. #7
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    676
    Good info. I feel like this bit of information and many others like it, would be most useful if collected together in one place, some kind of Teensy owner's manual.

    A while back I had a Teensy "Tips and Tricks" FAQ, actually it's still there https://forum.pjrc.com/threads/25395...ips-and-Tricks but I can no longer edit it, maybe because it dates from 2014 and the forum doesn't like edits on 5-year-old posts (?)

  8. #8
    Senior Member
    Join Date
    May 2016
    Posts
    220
    I got the same error last night when attempting my first port:

    Code:
    In file included from C:\Users\Derek\AppData\Local\Temp\arduino_build_495648\sketch\AudioSDR.h:31:0,
                     from C:\Users\Derek\AppData\Local\Temp\arduino_build_495648\sketch\AudioSDR.cpp:33:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h: In member function 'int AudioStream::processorUsage()':
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:108:50: error: 'F_CPU_ACTUAL' was not declared in this scope
     #define CYCLE_COUNTER_APPROX_PERCENT(n) (((n) + (F_CPU_ACTUAL / 32 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100)) / (F_CPU_ACTUAL / 16 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100))
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:142:36: note: in expansion of macro 'CYCLE_COUNTER_APPROX_PERCENT'
      int processorUsage(void) { return CYCLE_COUNTER_APPROX_PERCENT(cpu_cycles); }
                                        ^
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h: In member function 'int AudioStream::processorUsageMax()':
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:108:50: error: 'F_CPU_ACTUAL' was not declared in this scope
     #define CYCLE_COUNTER_APPROX_PERCENT(n) (((n) + (F_CPU_ACTUAL / 32 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100)) / (F_CPU_ACTUAL / 16 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100))
                                                      ^
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:143:39: note: in expansion of macro 'CYCLE_COUNTER_APPROX_PERCENT'
      int processorUsageMax(void) { return CYCLE_COUNTER_APPROX_PERCENT(cpu_cycles_max); }
                                           ^
    It was late so I left it there!

    I've made attempt to modify audiostream, or anything else in the Audio library, but the audio object AudioSDR is my own creation (it has worked fine for 15 months on T3.6). I haven't had time to look at it today: just wanted to let Chip know that he is not alone...

  9. #9
    Senior Member
    Join Date
    Oct 2015
    Location
    Vermont, USA
    Posts
    190
    Including core_pins.h helped. It cured a bunch (not all) of my compilation problems.

    Chip

  10. #10
    Senior Member
    Join Date
    May 2016
    Posts
    220
    Seems like it might be a problem for all "home-brew" audio objects! I've tried several, here is the simplest example I can think of - a do-nothing pass-through object:

    Code:
    //----------------------------------------------------
    // Test for Teensy 4 "home brew" Audio object 
    // compilation.
    // Derek Rowell     8/15/2019
    //====================================================
    #include <Audio.h>
    #include "AudioPassthru.h"
    #include <Wire.h>
    #include <SPI.h>
    #include <SerialFlash.h>
    //
    AudioInputI2S     input;
    AudioOutputI2S    output;
    AudioPassthru     passthru;
    
    AudioConnection c1(input,0,    passthru,0);
    AudioConnection c2(input,1,    passthru,1);
    AudioConnection c3(passthru,0, output,0);
    AudioConnection c4(passthru,1, output,1);
    AudioControlSGTL5000 codec;
    //----------
    void setup() {
      Serial.begin(57600);
      delay(2000);
      codec.enable();
      AudioMemory(20);
      codec.volume(1.0);
    }
    //---------------
    void loop() {}
    //---------------
    with the home-grown code::
    Code:
    //----------------------------------------
    //        *** AudioPassthru.h ***
    //---------------------------------------
    #ifndef audio_passthru_h_
      #define audio_passthru_h_
      #include "AudioStream.h"
      #include "Arduino.h"
      //
      //--- 
      class AudioPassthru : public AudioStream {
        public:
          AudioPassthru() : AudioStream(2, inputQueueArray){}
          virtual void update(void);
        // ----
        private:
          audio_block_t *inputQueueArray[2];
      };
    #endif
    and
    Code:
    //----------------------------------------
    //           *** AudioPassthru.cpp ***
    //---------------------------------------
    #include "AudioPassthru.h"
    void AudioPassthru::update(void) { 
      audio_block_t *blockI, *blockQ;
      blockI = receiveWritable(0);
      blockQ = receiveWritable(1);
      //
      if (!blockI && !blockQ) return;
      if ( blockQ && !blockI) {release(blockQ); return;}
      if ( blockI && !blockQ) {release(blockI); return;}
      //-- Do absolutely nothing!!!
      transmit(blockI, 0);
      transmit(blockQ, 1);
      //
      release(blockI);
      release(blockQ);
      return;}
    It compiles and runs just fine on the T3.6, but gives the same errors as above when compiling for the T4:

    Code:
     In file included from C:\Users\Derek\AppData\Local\Temp\arduino_build_103058\sketch\AudioPassthru.h:7:0,
                     from C:\Users\Derek\AppData\Local\Temp\arduino_build_103058\sketch\AudioPassthru.cpp:4:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h: In member function 'int AudioStream::processorUsage()':
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:108:50: error: 'F_CPU_ACTUAL' was not declared in this scope
     #define CYCLE_COUNTER_APPROX_PERCENT(n) (((n) + (F_CPU_ACTUAL / 32 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100)) / (F_CPU_ACTUAL / 16 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100))
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:142:36: note: in expansion of macro 'CYCLE_COUNTER_APPROX_PERCENT'
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:108:50: error: 'F_CPU_ACTUAL' was not declared in this scope
     #define CYCLE_COUNTER_APPROX_PERCENT(n) (((n) + (F_CPU_ACTUAL / 32 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100)) / (F_CPU_ACTUAL / 16 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100))
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:143:39: note: in expansion of macro 'CYCLE_COUNTER_APPROX_PERCENT'
      int processorUsageMax(void) { return CYCLE_COUNTER_APPROX_PERCENT(cpu_cycles_max); }
    
    In file included from C:\Users\Derek\AppData\Local\Temp\arduino_build_103058\sketch\AudioPassthru.h:7:0,
                     from C:\Users\Derek\AppData\Local\Temp\arduino_build_103058\sketch\AudioPassthru.cpp:4:
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h: In static member function 'static void AudioStream::update_all()':
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:162:50: error: 'IRQ_SOFTWARE' was not declared in this scope
      static void update_all(void) { NVIC_SET_PENDING(IRQ_SOFTWARE); }
    
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4/AudioStream.h:162:62: error: 'NVIC_SET_PENDING' was not declared in this scope
      static void update_all(void) { NVIC_SET_PENDING(IRQ_SOFTWARE); }

  11. #11
    Senior Member
    Join Date
    May 2016
    Posts
    220
    A couple of more data points:
    1. The audio passthrough example in the IDE Teeny4-->Audio-->HardwareTesting--> PassThroughStereo compiles without problem (it's almost the same as mine above!!!)
    2. It's NOT just the use of home grown Audio objects, the completely vanilla code below also fails to compile:
    Code:
    //---------------------------------------------
    // Test for Teensy 4 Audio compilation problem
    //       *** THIS FAILS TO COMPILE! ***
    //=============================================
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SerialFlash.h>
    //
    AudioSynthWaveformSine sine;
    AudioOutputI2S         output;
    // -----
    AudioConnection c1(sine,0, output,0);
    AudioControlSGTL5000 codec;
    
    //----
    void setup() {
      Serial.begin(57600);
      delay(2000);
      AudioMemory(20);
      codec.enable();
      codec.volume(1.0);
      sine.amplitude(0.5);
      sine.frequency(1000.0);
    }
    
    //----
    void loop() {}
    Any help would be welcome...

  12. #12
    Senior Member
    Join Date
    May 2016
    Posts
    220
    Resolved - see new thread

  13. #13

  14. #14
    Senior Member
    Join Date
    May 2016
    Posts
    220
    Quote Originally Posted by defragster View Post
    Yes - sorry.

Posting Permissions

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