Hi,
I am desperately trying to access the GPIOs in a fast way to be able to measure the MIPS numbers accurately. I got it working from within setup(), but accessing the same memory locations from within render() is not working. Below the test code - anyone has an idea?
// This is an example how to trigger I/O pins on the board to e.g. measure realtime load with a logic analyzer
// To try it you must activate "Use Digital" - else system error #135 pops up trying to use gpio2
// (Anyone knows why this is the case?)
#include <Bela.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <iostream>
#define OE_ADDR 0x134
#define GPIO_DATAOUT 0x13C
#define GPIO_DATAIN 0x138
#define GPIO_CLEARDATAOUT 0x190
#define GPIO_SETDATAOUT 0x194
#define GPIO0_ADDR 0x44E07000
#define GPIO1_ADDR 0x4804C000
#define GPIO2_ADDR 0x481AC000
#define GPIO3_ADDR 0x481AF000
int fd;
volatile ulong* gpio1conf;
volatile ulong* gpio2conf;
bool setup(BelaContext *context, void *userData)
{
fprintf(stdout, "Attention - GPIO settings only work within setup()\n");
fprintf(stdout, "So until the message appears that setup is finished the pins toggle, then not any more\n");
fprintf(stdout, "I also tried initializing the memory within render once at the first call - also did not work\n");
fprintf(stdout, "I left the program here in case someone has a good idea and might fix it\n");
fd = open("/dev/mem",O_RDWR | O_SYNC);
gpio1conf = (ulong*) mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO1_ADDR);
gpio2conf = (ulong*) mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO2_ADDR);
fprintf(stdout, "gpio1_oe= %lx gpio1_dataout = %lx gpio2_oe= %lx gpio2_dataout = %lx \n",
gpio1conf[OE_ADDR>>2],gpio1conf[GPIO_DATAOUT>>2],gpio2conf[OE_ADDR>>2],gpio2conf[GPIO_DATAOUT>>2]);
gpio1conf[OE_ADDR>>2] &= 0xFFFFFFFF ^(1<<28); // This sets GPIO1_28 to output which maps to 1*32+28=60 and is located on pin 12 on P9
gpio2conf[OE_ADDR>>2] &= 0xFFFFFFFF ^(1<<2); // This sets GPIO2_2 to output which maps to 2*32+2=66 and is located on pin 7 on P8
gpio2conf[OE_ADDR>>2] &= 0xFFFFFFFF ^(1<<3); // This sets GPIO2_3 to output which maps to 2*32+3=67 and is located on pin 8 on P8
usleep(100);
gpio1conf[GPIO_DATAOUT>>2] |= (0x1<<28); // This activates GPIO1_28 which maps to 1*32+28=60 and is located on pin 12 on P9
gpio2conf[GPIO_DATAOUT>>2] |= (0x1<<2); // This activates GPIO2_2 which maps to 2*32+2=66 and is located on pin 7 on P8
gpio2conf[GPIO_DATAOUT>>2] |= (0x1<<3); // This activates GPIO2_3 which maps to 2*32+3=67 and is located on pin 8 on P8
for (int i=0; i<100000; i++)
{
// The following line seems to take 0.375 us which corresponds to 375 cycles!!!
// If gpio1conf is not declared volatile it is around twice as fast but then the optimizer seems to remove if if directly 2 lines after each other
gpio1conf[GPIO_DATAOUT>>2] ^= (0x1<<28); // This toggles GPIO1_28 which maps to 1*32+28=60 and is located on pin 12 on P9
gpio2conf[GPIO_DATAOUT>>2] ^= (0x1<<2); // This toggles GPIO2_2 which maps to 2*32+2=66 and is located on pin 7 on P8
gpio2conf[GPIO_DATAOUT>>2] ^= (0x1<<3); // This toggles GPIO2_3 which maps to 2*32+3=67 and is located on pin 8 on P8
usleep(100);
}
fprintf(stdout, "Setup finished, now moving to render where GPIOs are not toggling any more\n");
return true;
}
void render(BelaContext *context, void *userData)
{
// The following line seems to take 0.375 us which corresponds to 375 cycles!!!
// If gpio1conf is not declared volatile it is around twice as fast but then the optimizer seems to remove if if directly 2 lines after each other
gpio1conf[GPIO_DATAOUT>>2] ^= (0x1<<28); // This toggles GPIO1_28 which maps to 1*32+28=60 and is located on pin 12 on P9
gpio2conf[GPIO_DATAOUT>>2] ^= (0x1<<2); // This toggles GPIO2_2 which maps to 2*32+2=66 and is located on pin 7 on P8
gpio2conf[GPIO_DATAOUT>>2] ^= (0x1<<3); // This toggles GPIO2_3 which maps to 2*32+3=67 and is located on pin 8 on P8
}
void cleanup(BelaContext *context, void *userData)
{
close(fd);
}