#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#define CONTROL_MODULE_START ((uint32_t)0x44E10000)
#define CONTROL_MODULE_END ((uint32_t)0x44E11FFF)
#define CONTROL_MODULE_LENGTH (CONTROL_MODULE_END - CONTROL_MODULE_START + 1)
// Official pin name for pr1_edio_data_out0 is SPI0_D1 in Mode 6
// Official pin name for pr1_edio_data_out1 is SPI0_CS0 in Mode 6
#define CONF_SPI0_D1_OFFSET 0x958
#define CONF_SPI0_CS0_OFFSET 0x95C
#define MODE_1 0x1
#define MODE_4 0x4
#define MODE_6 0x6
int main(int argc, char *argv[])
{
uint32_t volatile * control_mode_mapped_base = NULL;
int fd = open("/dev/mem", O_RDWR);
printf("/dev/mem opened: %d\n", fd);
printf("Mapping %X - %X (size: %X)\n", CONTROL_MODULE_START, CONTROL_MODULE_END, CONTROL_MODULE_LENGTH);
uint32_t volatile * const control_module_mapped_base = mmap(NULL, CONTROL_MODULE_LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, CONTROL_MODULE_START);
printf("Mapped base to: %p\n", control_module_mapped_base);
assert(control_mode_mapped_base != ((uint32_t volatile * const)(-1)));
uint32_t volatile * const u32_control_P9_17 = (control_module_mapped_base + (CONF_SPI0_CS0_OFFSET/4)); // / 4 is due to the way C handles a pointer to uint32_t
uint32_t volatile * const u32_control_P9_18 = (control_module_mapped_base + (CONF_SPI0_D1_OFFSET/4));
*u32_control_P9_17 = MODE_1; // Fails to write
*u32_control_P9_18 = MODE_1;
printf("Mode for P9_17: %X\n", (*u32_control_P9_17 & 0x7)); // Read is fine--config-pin will cause this to change apropriately
printf("Mode for P9_18: %X\n", (*u32_control_P9_18 & 0x7));
assert((*u32_control_P9_17 & 0x7) == MODE_1);
assert((*u32_control_P9_18 & 0x7) == MODE_1);
munmap((void *)control_mode_mapped_base, CONTROL_MODULE_LENGTH);
close(fd);
}
Well, sort of, except you omit the *EXTREMELY* important point that you install a custom kernel module in order to expose the clock activation and pinmux system to all users.
Okay, yes, if I build a kernel module I now have full access to all registers on the system with no restrictions. That's sort of like swatting a fly with an H-Bomb, but it will work.
This means that config-pin has a fairly significant bug in not being able to route the IEP pins. Has that bug ever been filed anywhere?
Okay, yes, if I build a kernel module I now have full access to all registers on the system with no restrictions. That's sort of like swatting a fly with an H-Bomb, but it will work.
sudo apt-get install libpruio-modules-`uname -r`
It was your idea to use the PRU-IEP module. I recommended to use a pin on a GPIO-SS.