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

Thread: Reading from and writing to the GPTx_SR register takes incredibly long

  1. #1
    Junior Member
    Join Date
    Oct 2019
    Posts
    15

    Reading from and writing to the GPTx_SR register takes incredibly long

    I have been working on a project where I use timer controlled interrupts. One of the things necessary for that is to reset the respective bits in the GPT Status Register. Reading a value from that register via

    Code:
    uint32_t value = GPT1_SR;
    or writing to it via

    Code:
    GPT1_SR = 0x00000001;
    takes both about 170 ns. Why is this so slow and is there any way to improve this?

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,473
    It's probably because we're currently running those timers from the 24 MHz clock, and there's probably a multiple-cycle sync going on.

  3. #3
    Junior Member
    Join Date
    Oct 2019
    Posts
    15
    Quote Originally Posted by PaulStoffregen View Post
    It's probably because we're currently running those timers from the 24 MHz clock, and there's probably a multiple-cycle sync going on.
    But I am using the peripheral clock, which runs at 150 MHz...

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,332
    Example code showing your setup and issue?

  5. #5
    Junior Member
    Join Date
    Oct 2019
    Posts
    15
    Update: With the 150 MHz clock it only takes about 80 ns. But that is still way too long for just setting or reading a value.

    This is the sketch I used for testing this:

    Code:
    #include <Arduino.h>
    
    void setup() {
      pinMode(13, OUTPUT);
      CCM_CSCMR1 &= 0xFFFFFFBF;// Use the Root-Clock
      CCM_CCGR1 |= 0x00F00000; // Activate Clock Module for GPT1
      GPT1_CR = 0;      // Reset Control Register
      GPT1_PR = 0;      // Prescaling = 1:1
      GPT1_CR |= 0x00000040;  // Use the peripheral Clock
      GPT1_CR |= 0x00000001;  // Activate Counter GPT1
    }
    
    void loop() {
      digitalWriteFast(13, HIGH);
      GPT1_SR = 0x00000001;
      digitalWriteFast(13, LOW);
      delayMicroseconds(1);
      digitalWriteFast(13, HIGH);
      uint32_t value = GPT1_SR;
      digitalWriteFast(13, LOW);
    }
    I then used an oscilloscope to analyse the signal which gave me the time of ~80 ns.

  6. #6
    Junior Member
    Join Date
    Oct 2019
    Posts
    15
    Here is what the reading of the oscilloscope looks like:
    Click image for larger version. 

Name:	tek00001.png 
Views:	5 
Size:	19.2 KB 
ID:	18746

  7. #7
    Senior Member
    Join Date
    Feb 2015
    Location
    Finland
    Posts
    170
    Could you retest with
    Code:
    void loop() {
      digitalWriteFast(13, HIGH);
      GPT1_SR = 0x00000001;
      digitalWriteFast(13, LOW);
      delayMicroseconds(1);
      digitalWriteFast(13, HIGH);
      uint32_t value = GPT1_SR;
      digitalWriteFast(13, LOW);
      delayMicroseconds(1);
      digitalWriteFast(13, HIGH);
      digitalWriteFast(13, LOW);
    }
    adding a third pulse showing the digitalWriteFast() overhead?

  8. #8
    Junior Member
    Join Date
    Oct 2019
    Posts
    15
    The overhead of digitalWriteFast() is nothing compared to the problem here (3 ns = 150 MHz). Here is what your code produces:

    Click image for larger version. 

Name:	tek00000.png 
Views:	3 
Size:	15.2 KB 
ID:	18748

  9. #9
    Senior Member
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    799
    As Paul already wrote, the timer peripherals are only loosely coupled to the ARM core, thus there is significant time required to synchronize the busses. Writing is cached, so this is fast in principle but you need to wait until the register (e.g. GPT1_SR) actually gets the value, if you leave the ISR too quickly it might fire again. (Search for DSB in the beta thread) Here some in depth info from Joseph Yiu (scroll down to the discussion about slow peripherals): https://community.arm.com/developer/...gle-core-parts.

    And here some forum links regarding the same issue with the interval timers (PIT). It turns out that having 4 interval timers flipping a pin at 100kHz already generate 40% processor load due to the required bus sync.
    https://forum.pjrc.com/threads/57959...l=1#post218577
    https://forum.pjrc.com/threads/58221...l=1#post220355

    So, looks like the timer interrupts are not made for high speed applications on this chip.

    There are also measurement results and comparison to T3.6 with different bus clock speeds on the beta thread.

Posting Permissions

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