Lukas Posted January 6, 2017 Posted January 6, 2017 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
Recommended Posts