Because sysfs is too slow I tried set/clear with direct memory access. It is a IMX6. The gpios used are here
cat /sys/kernel/debug/gpio
gpiochip4: GPIOs 128-159, parent: platform/20ac000.gpio, 20ac000.gpio:
gpio-136 ( |sysfs ) out lo
gpio-137 ( |sysfs ) out lo
gpio-138 ( |sysfs ) out lo
gpio-139 ( |sysfs ) out lo
gpio-140 ( |sysfs ) out lo
gpio-141 ( |sysfs ) out lo
gpio-142 ( |sysfs ) out lo
gpio-143 ( |sysfs ) out lo
gpio-144 ( |sysfs ) out lo
gpio-145 ( |sysfs ) out lo
So I map the physical 0x020ac000 into the virtual address space.
#define GPIO_BASE_ADDR_4 (0x020ac000)
volatile unsigned *gpio_reg;
void* gpio_map;
int mem_fd;
mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
if(mem_fd < 0) {
printf("ERROR could not open gpio mapping");
exit(1);
}
gpio_map = mmap(NULL,
getpagesize(),
(PROT_READ | PROT_WRITE),
MAP_SHARED,
mem_fd,
GPIO_BASE_ADDR_4);
close(mem_fd);
if(gpio_map == MAP_FAILED) {
printf("ERROR could not open gpio mapping");
exit(1);
}
gpio_reg = (volatile unsigned *)gpio_map;
and set/clear the value. e.g. gpioNr is 137 -> (gpioNr-128) = 8. This would be the 8th line in the gpiochip4.
void clear(int gpioNr) {
*(gpio_reg+0x190) = 1<<(gpioNr-128);
}
void set(int gpioNr) {
*(gpio_reg+0x194) = 1<<(gpioNr-128);
}
The program is executed with root privileges. GPIO are exported and set to output at start with sysfs.
- is the mapping correct? did I miss some additional spacing or alignment issues
- is the data register not correct?
Edit 2023-07-05 11:30
Output is now working better. GPIOs are used for a NHD-14432WG LCD display. Some areas are correctly displayed (about 50-70%) the rest is filled with artifacts. Before I used sysfs, there the output was correct but very slow refresh rates.
void clear(int gpioNr) {
int reg_index = (gpioNr - 128) / 32;
int bit_pos = (gpioNr - 128) % 32;
gpio_reg[reg_index] &= ~(1 << bit_pos);
}
void set(int gpioNr) {
int reg_index = (gpioNr - 128) / 32;
int bit_pos = (gpioNr - 128) % 32;
gpio_reg[reg_index] |= (1 << bit_pos);
}