Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 2 FirstFirst 1 2
Results 26 to 30 of 30

Thread: Simultaneously reading 8 GPIO pins

  1. #26
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    1,055
    And for people who think that pointers are needed to speed things up, this takes the same time. And IMO, is clearer and less prone to errors like above.

    Code:
    for (unsigned i = 0; i < BUFFER_SIZE; ++i)
            buffer[i] = GPIO6_PSR;

  2. #27
    Junior Member
    Join Date
    Jul 2021
    Posts
    19
    There seems to be some discrepancy using the ARM_DWT_CYCCNT command to record the number of cycles per instruction (CPI). Running:

    Code:
    const byte InterruptPin = 1;
    
    void setup(){
      pinMode(InterruptPin, INPUT);
      attachInterrupt(digitalPinToInterrupt(InterruptPin), CPI_Time, RISING);
    }
    
    void CPI_Time(){
      int clk_1 = ARM_DWT_CYCCNT;
      asm(
      "nop \n\t"
      "nop \n\t"
      "nop \n\t"
      "nop \n\t"
      "nop"
      );
      int clk_2 = ARM_DWT_CYCCNT;
      Serial.printf("CPI: %d \n", clk_2-clk_1);
    }
    Only prints out:
    Code:
    CPI: 3
    CPI: 3
    CPI: 3
    CPI: 3
    CPI: 3
    ...
    clearly, there are 5 no operation (nop) commands, each using a single CPI, so the output should be 5, no?

  3. #28
    Member
    Join Date
    Jan 2013
    Posts
    29
    The Cortex-M7 is superscalar, i.e. it can process more than one instruction per clock cycle.
    I think that can explain it - see https://en.wikipedia.org/wiki/ARM_Cortex-M#Cortex-M7

    See also https://www.nxp.com/docs/en/white-paper/CORTEXM7WP.pdf:

    "High-performance, 6-stage pipeline with dual-instruction issue, enabling it to execute up to two instructions per clock cycle"

  4. #29
    Junior Member
    Join Date
    Jul 2021
    Posts
    19
    :O you are a genius, yep that appears to be what is happening, it's running 2 instructions at once. Thank you for the info!

    Also, I tried the code from #26 and printed the buffer out after to see what it was capturing, and I am getting a random number on the output for example:
    53792780.

    I know I will need to use IOMUX somehow, to tell port 6 to be GPIO, and I want to use pins:
    17, 16, 22, 23, 20, 21, 26, 27 in that order to get the 8 bits out of GPIO6 since the bits are all pretty close to each other and can be addressed using 0xCFC00000 --> 0B11001111110000000000000000000000

    Any help on how to read and store those specific pins on an interrupt call would be really appreciated. Additionally, I am guessing the two MSB bits will need to be shifted to the right two places somehow to get the 8 bits all together.

  5. #30
    Senior Member
    Join Date
    Jul 2015
    Posts
    118
    Quote Originally Posted by RandoRkt View Post
    I know I will need to use IOMUX somehow, to tell port 6 to be GPIO, and I want to use pins:
    17, 16, 22, 23, 20, 21, 26, 27
    To set the pins as GPIO Inputs:
    Code:
      pinMode(16,  INPUT);
      pinMode(17,  INPUT);
      pinMode(20,  INPUT);
      pinMode(21,  INPUT);
      pinMode(22,  INPUT);
      pinMode(23,  INPUT);
      pinMode(26,  INPUT);
      pinMode(27,  INPUT);
    Quote Originally Posted by RandoRkt View Post
    I want to use pins:
    17, 16, 22, 23, 20, 21, 26, 27 in that order to get the 8 bits out of GPIO6 since the bits are all pretty close to each other and can be addressed using 0xCFC00000 --> 0B11001111110000000000000000000000
    Here's how to move those bits down to the lower 8 bits:
    Code:
        uint32_t sample = GPIO6_PSR;
    
        // shift bits 22-27 to bits 0-5
        buffer[i] = (sample & 0x0FC00000) >> 22;
    
        // shift bits 30-31 to bits 6-7
        buffer[i] = buffer[i] | (sample & 0xC0000000) >> 24;

Posting Permissions

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