Forum Rule: Always post complete source code & details to reproduce any issue!
Page 36 of 167 FirstFirst ... 26 34 35 36 37 38 46 86 136 ... LastLast
Results 876 to 900 of 4161

Thread: Teensy 4.0 First Beta Test

  1. #876
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,077
    Hi Frank, current one is posted in #861 - But Paul's version is probably close enough...
    https://github.com/KurtE/SPI/tree/T4-SerialFlash-fix

    This last change was to make it such that SerialFlash can build.

  2. #877
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    Kurt, the TCR has a bit RMSK:
    Receive Data Mask
    When set, receive data is masked (receive data is not stored in receive FIFO).
    0b - Normal transfer
    1b - Receive data is masked
    This might be better for DMA than my initial NOSTALL
    Setting the CONT bit has the effect, that the transfers do not start... hm... I'm missing something..

  3. #878
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    @KurtE
    @PaulStoffregen
    Don't forget my PR https://github.com/PaulStoffregen/SPI/pull/39
    At a minimum cherry pick the IRQ stuff. It is tested and working with UHS3.

    NOTE! The added macros are important too!
    Resolved merge conflict with upstream.
    Last edited by xxxajk; 01-14-2019 at 04:05 PM.

  4. #879
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,093
    ACMP and DAC

    Here is a simple sketch to demonstrate ACMP using 6-bit DAC as reference/comparison voltage.
    https://github.com/manitou48/teensy4...er/acmpdac.ino

    Sketch uses ACMP3-0 which corresponds to A4, and the DAC output should be visible on pin 26 (backside). Jumper A4 to either GND or 3v3 to see printed output change. I don't have any easy way to get at underside pins, so if someone with breakout can check voltage on pin 26 (should be 3.3/2 v), that would be nice. I didn't configure pin 26 for anything (OUTPUT?), so that may need to be added ?? Doesn't appear to be an ALT mode for "DAC out". May be possible to manipulate DAC output without enabling ACMP?

    EDIT i now have breakout board, so I can try get pin 26 pogo, and I can try GPT capture on pin 30

    I clipped on to pin 26, and verified if i did digitalWrite(26,HIGH), my meter was seeing 3.3v. But meter shows 0v when ACMP sketch is running. I configured pin 26 MUX (ALT 1), and meter shows 0v or 3v3 depending on ACMP result. So can't get DAC voltage from pin 26, only the result of the ACMP.
    Last edited by manitou; 01-21-2019 at 12:18 PM. Reason: pin 26 shows ACMP result

  5. #880
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    465

    Interval Timer again

    I did some more tests on the low performance of the IntervalTimer and found something strange. It looks like the ISR is called two two times in a row.

    To dig further into this I did a minimal example showing the effect without using IntervalTimer at all. I just set the corresponding registers. The code sets up the PIT and channel 1 with a reload value of 100 (T=4.1Ás). In the PIT ISR I loop through all four channels and generate a pulse if the TFLAG of a channel is set. The pulse pin number (0..3) corresponds to the PIT channel number. The strange thing is tht, after the first call of the ISR (with the correct TFLAG set), the ISR is called again. This time without any TFLAG set so that the code falls through the loop and pulses on pin 4.

    This behavior might be the reason for the suboptimal performance of the IntervallTimer (see #830). The code in the corresponding ISR from the interval timer needs to cycle through all the channels two times which costs about 1Ás in total. Here the simple test code:

    Code:
    void pitIsr()
    {
      for (int i = 0; i < 4; i++)
      {
        if (IMXRT_PIT_CHANNELS[i].TFLG == 1) // if channel TFLG is set, delete it and generate pulse on pin i
        {
          IMXRT_PIT_CHANNELS[i].TFLG = 1;
          digitalWriteFast(i, HIGH);
          digitalWriteFast(i, LOW);
          return;
        }
      }
      //why is the code below called?
      digitalWriteFast(4, HIGH);
      digitalWriteFast(4, LOW);
    }
    
    void beginPIT(uint32_t cycles)
    {
      CCM_CCGR1 |= CCM_CCGR1_PIT(CCM_CCGR_ON);
      PIT_MCR = 0;
    
      IMXRT_PIT_CHANNELS[0].LDVAL = cycles;
      IMXRT_PIT_CHANNELS[0].TFLG = 1;
      IMXRT_PIT_CHANNELS[0].TCTRL = PIT_TCTRL_TEN | PIT_TCTRL_TIE;
    
      attachInterruptVector(IRQ_PIT, pitIsr);
      NVIC_ENABLE_IRQ(IRQ_PIT);
    }
    
    void setup()
    {
      pinMode(LED_BUILTIN, OUTPUT);
      for (int i = 0; i < 5; i++) pinMode(i, OUTPUT);
    
      beginPIT(100);
    }
    
    void loop()
    {
      digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
      delay(250);
    }
    Click image for larger version. 

Name:	itimer3.jpg 
Views:	30 
Size:	57.2 KB 
ID:	15598

  6. #881
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    Quote Originally Posted by luni View Post
    I did some more tests on the low performance of the IntervalTimer and found something strange. It looks like the ISR is called two two times in a row.

    To dig further into this I did a minimal example showing the effect without using IntervalTimer at all. I just set the corresponding registers. The code sets up the PIT and channel 1 with a reload value of 100 (T=4.1Ás). In the PIT ISR I loop through all four channels and generate a pulse if the TFLAG of a channel is set. The pulse pin number (0..3) corresponds to the PIT channel number. The strange thing is tht, after the first call of the ISR (with the correct TFLAG set), the ISR is called again. This time without any TFLAG set so that the code falls through the loop and pulses on pin 4.

    This behavior might be the reason for the suboptimal performance of the IntervallTimer (see #830). The code in the corresponding ISR from the interval timer needs to cycle through all the channels two times which costs about 1Ás in total. Here the simple test code:

    Code:
    void pitIsr()
    {
      for (int i = 0; i < 4; i++)
      {
        if (IMXRT_PIT_CHANNELS[i].TFLG == 1) // if channel TFLG is set, delete it and generate pulse on pin i
        {
          IMXRT_PIT_CHANNELS[i].TFLG = 1;
          digitalWriteFast(i, HIGH);
          digitalWriteFast(i, LOW);
          return;
        }
      }
      //why is the code below called?
      digitalWriteFast(4, HIGH);
      digitalWriteFast(4, LOW);
    }
    
    void beginPIT(uint32_t cycles)
    {
      CCM_CCGR1 |= CCM_CCGR1_PIT(CCM_CCGR_ON);
      PIT_MCR = 0;
    
      IMXRT_PIT_CHANNELS[0].LDVAL = cycles;
      IMXRT_PIT_CHANNELS[0].TFLG = 1;
      IMXRT_PIT_CHANNELS[0].TCTRL = PIT_TCTRL_TEN | PIT_TCTRL_TIE;
    
      attachInterruptVector(IRQ_PIT, pitIsr);
      NVIC_ENABLE_IRQ(IRQ_PIT);
    }
    
    void setup()
    {
      pinMode(LED_BUILTIN, OUTPUT);
      for (int i = 0; i < 5; i++) pinMode(i, OUTPUT);
    
      beginPIT(100);
    }
    
    void loop()
    {
      digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
      delay(250);
    }
    Click image for larger version. 

Name:	itimer3.jpg 
Views:	30 
Size:	57.2 KB 
ID:	15598
    Have you tried to add asm volatile ("dsb")) ?

  7. #882
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    465
    At the end of the ISR?

  8. #883
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,093
    Re: double interrupts
    There were earlier posts about double-interrupts. I had to spin waiting on the interrupt flag to clear. Discussion about dsb at
    https://community.arm.com/processors...gle-core-parts

    do a "search thread" for DSB on this thread.

  9. #884
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    465
    Perfect, that fixes it.

    Code:
    for (int i = 0; i < 4; i++)
      {
        if (IMXRT_PIT_CHANNELS[i].TFLG == 1) // if channel TFLG is set, delete it and generate pulse on pin i
        {
          IMXRT_PIT_CHANNELS[i].TFLG = 1;
          digitalWriteFast(i, HIGH);
          digitalWriteFast(i, LOW);
          asm volatile ("dsb") ;  // <------ That fixes it. 
          return;
        }
      }

  10. #885
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    great.
    I've read, sometimes it's better / faster to read a register of the device instead of using "dsb" - perhaps try " /*dummy = */ IMXRT_PIT_CHANNELS[i].TFLG;", too ?
    Would be interesting to know what is better in this case..

  11. #886
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,093
    Quote Originally Posted by Frank B View Post
    great.
    I've read, sometimes it's better / faster to read a register of the device instead of using "dsb" - perhaps try " /*dummy = */ IMXRT_PIT_CHANNELS[i].TFLG;", too ?
    Would be interesting to know what is better in this case..
    My one data point was that DSB was faster than polling
    https://forum.pjrc.com/threads/54711...l=1#post194815
    but the reference in post #883 suggested DSB may not always work

  12. #887
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    Is it needed to poll ? maybe a simple, single read is enough?

  13. #888
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    465
    With DSB I can go down to a LDVAL of 4 (~2MHz). Polling seems to be slightly slower but whats worse: Polling does not seem to work for all timings. E.g. LDVAL = 5 leads to a double interrupt every 5th ISR call. LDVAL=6 gives one double every 1100 calls :-/

    Edit: did a single read into a volatile unsigned, not a real polling

  14. #889
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,704
    Quote Originally Posted by manitou View Post
    As I recall ping lib uses pulseIn() which in turn uses micros(). But on T4, micros() only has 10us resolution so I wonder how ping distance calculations are affected. (i'd really prefer systick ran at current CPU clock speed so we could get microsecond resolution from micros(). if CPU clock is changed, function could take care of updating systick rate.)
    I did a little reading (always dangerous in my case) and tried this sketch:
    Code:
    void setup() {
      pinMode(3, OUTPUT);
    }
    
    void loop() {
      digitalWrite(3, HIGH);
      delayUS_DWT(1000000);
      digitalWrite(3, LOW);
      delayUS_DWT(1000000);
    }
    
    void delayUS_DWT(uint32_t us) {
      volatile uint32_t cycles = (600000000L/1000000L)*us;
      volatile uint32_t start = ARM_DWT_CYCCNT;
      do  {
      } while(ARM_DWT_CYCCNT - start < cycles);
    }
    Put it on scope and looked pretty good, or am I reading it wrong

  15. #890
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    The better way is to fix micros() - it's used by user-programs, too. Maybe we can use a different timer (?)

  16. #891
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,093
    Quote Originally Posted by Frank B View Post
    The better way is to fix micros() - it's used by user-programs, too. Maybe we can use a different timer (?)
    When i want 1 us resolution micros() i paste in GPT code (have to init GPT in startup() ) but it works in a pinch.
    https://github.com/manitou48/teensy4...gpt_micros.ino
    There are two GPT timers on T4

  17. #892
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    Using a GPT is better than defective micros What would be the reasons not to use it - are there libraries that need a GPT, or both GPT?

  18. #893
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,093
    Quote Originally Posted by Frank B View Post
    Using a GPT is better than defective micros What would be the reasons not to use it - are there libraries that need a GPT, or both GPT?
    Nothing uses GPTn as far as I know ... which goes to Paul's need to have a "timers consumers list" to know what is using which timers (PIT, GPT, QTMR, flexPWM) ... IntervalTimer, Tone, PWM, IRremote ...

  19. #894
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    465
    Really? Using a "precious" 32bit timer/counter for micros? That would definitely eliminate the timer for any other general use. Just thought of using them for TeensyStep instead of the slow T4 Intervall-timers....

  20. #895
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,704
    Quote Originally Posted by manitou View Post
    Nothing uses GPTn as far as I know ... which goes to Paul's need to have a "timers consumers list" to know what is using which timers (PIT, GPT, QTMR, flexPWM) ... IntervalTimer, Tone, PWM, IRremote ...
    I started looking at the different timers now and was going to play around with them and threw what I did to start the conversation. I can start going through the libraries and see what they are using if I can sort it out of course

  21. #896
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,073
    Quote Originally Posted by Frank B View Post
    Using a GPT is better than defective micros What would be the reasons not to use it - are there libraries that need a GPT, or both GPT?
    That would also be a great fix for ElapsedMicros too as it suffers the same problem and using CycleCounter wraps in under 7.2 seconds with F_CPU==600MHz

  22. #897
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    @luni, depends on what is considered more important - having working micros() or having a spare timer (Pauls decision).. You can never please everyone anyway.

  23. #898
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,704
    Quote Originally Posted by defragster View Post
    That would also be a great fix for ElapsedMicros too as it suffers the same problem and using CycleCounter wraps in under 7.2 seconds with F_CPU==600MHz
    Tim, just curious why would you want to use elapsed micros to count to 7.2 seconds? Do you have a use case?

    Mike

  24. #899
    Senior Member+
    Join Date
    Jul 2014
    Location
    New York
    Posts
    3,704
    Quote Originally Posted by mjs513 View Post
    I started looking at the different timers now and was going to play around with them and threw what I did to start the conversation. I can start going through the libraries and see what they are using if I can sort it out of course
    Started with some of the libraries I touched so far:
    Click image for larger version. 

Name:	Capture.JPG 
Views:	35 
Size:	38.4 KB 
ID:	15599

    Comments - suggestions?

  25. #900
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,073
    Quote Originally Posted by mjs513 View Post
    Tim, just curious why would you want to use elapsed micros to count to 7.2 seconds? Do you have a use case?

    Mike
    Nothing in particular - just that that it would rollover and be confusing. I was perhaps conflating it with micros rolling in ~87 secs where it was used for longer as a reference.

    Also the quick look I gave to the elapsedus code didn't turn out right - given everything coming or going needs to be handled with 1/F_CPU_ACTUAL in the proper fashion. Having a steady 1 MHz value to feed it would make it fit in less code and run faster. The T_3.x version of elapsedus and micros goes to some effort to resolve/round the current value - running overhead extra code.

    Mike, does NeoPixel modifiy the CycleCounter or just start and use it as a running value? <edit> seems to have two places it starts it and then just reads it for it's value. Though it uses F_CPU for resolution that will be wrong.
    Last edited by defragster; 01-14-2019 at 08:38 PM.

Posting Permissions

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