Jump to content

How can I set a NanoPi Neo's PIO as output on hardware level in C++?


Lukas

Recommended Posts

I'm trying to set the Pin G11 on a NanoPi Neo, previously configured as input, to output in C++ by mapping the PIO function register into the virtual memory with mmap and setting a single bit.
 

As per the Allwinner H3 Datasheet the following hardware addresses are specified:

 

PIO Base Address: 0x01C20800 (p. 316)
PG Configure Register 1 offset: 0xDC (p. 338)
PG11 bits: 14:12 (p. 338)
 
Similar to the Raspberry Pi's function register, the Pin knows at least two states:
  • 000: input
  • 001: output
  • ...
In my Script, I'm therefore trying to set the 12th bit of the PG Configure Register 1. Here's my C++ code:

 

  struct peripheral {
      unsigned long addr_hardware;
      int map_size;
      int mem_fd;
      void *mem_map;
      volatile unsigned long *addr_virtual;

      int map() {
          if ((mem_fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0) return -1;
          // map addr_hardware=0x01C20000 into /dev/mem
          if ((mem_map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, addr_hardware)) == MAP_FAILED) return -1;
          // store virtual address with offset of 0x800, which was rounded down before
          addr_virtual = (volatile unsigned long *) mem_map + 0x800;
          return 0;
      };
      void unmap() {
          munmap(mem_map, map_size);
          close(mem_fd);
      };
  };

  int main() {
      // initialize peripheral at rounded down PIO base address
      peripheral gpio {0x01C20000, 4096 * 10};
      // map PIOs into virtual memory
      if (gpio.map() == -1) return -1;

      // output current value of PG Configure Register 1
      cout << bitset<32>(*(gpio.addr_virtual + 0xDC)) << endl;
      // set 12th bit
      *(gpio.addr_virtual + 0xDC) |= (1 << 12);
      // output value of register after setting the 12th bit
      cout << bitset<32>(*(gpio.addr_virtual + 0xDC)) << endl;

      gpio.unmap();
      return 0;
  }

 
Unfortunately, my code does not work. When I configure the Pin G11 as Output (via WiringNP), the displayed value doesn't change. I'm checking the proper functionality of my code with an LED (it should turn on when state is changed from IN to OUT because it is set to HIGH).
 
When I run the script again, the content of the PIO Configure Register has changed to its previous state.
When altering the map_size, I get the following results (spaces added for better readability):
 
  > gpio {0x01C20000, 4096 * 2}
  < 00000000 00000000 00000000 00000000
  < 00000000 00000000 00010000 00000000

  > gpio {0x01C20000, 4096 * 10}
  < 00000000 00000000 00000000 00110011
  < 00000000 00000000 00000000 00110011
 
I am expecting the following result:
 
  > gpio {0x01C20000, 4096 * 10}
  < 00000000 00000000 00000000 00110011
  < 00000000 00000000 00010000 00110011
 

Any help would be very appreciated :)

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines