mmap mux settings for PWM with BeagleBone

I am trying to configure the mux for PWM on my BeagleBone A3 in C using mmap

What I Think I Know

Using Table 2-2 from SRUH73C (Tech Ref Manual) i have determined the Control Module Register Start Address to be 0x44e1_0000 with a length of 128k or 128*1024=131072 Bytes

Using Table 13 from BBONE_SRM (Beaglebone A3 System Ref Manual) I have determined the register I am looking for to be “gpmc_a2” with a required value of 6 to pass through the ehrpwm1A_mux1 to Port 9 Pin 14

Using Table 9-8 from SRUH73C I have determined the register offset to be 848h for “conf_gpmc_a2”

Using Section 9.3.1.50 from SRUH73C I have determined that I want to set the last 3 bits to 6h

How I have tried to implement this (from my main routine)

//Control Module Registers for multiplexing
#define CONT_MOD_REG_START 0x44e10000 // The start of the PWM0 Config Registers //From Page see http://www.ti.com/lit/ug/spruh73c/spruh73c.pdf 213
#define CONT_MOD_REG_LENGTH 131072 //The length for the Control Module Registry in Bytes see http://www.ti.com/lit/ug/spruh73c/spruh73c.pdf page 210

volatile uint32_t *MemMapAddressContMod; //mmap pointer for the Control Module Registers

//Create a file handle for the memort
MemoryFileDescriptor = open("/dev/mem", O_RDWR); //Establish connection between file and file descriptor as read/write
//Check that the file opened properly
if (MemoryFileDescriptor == -1) {
perror (“Failed to Open /dev/mem file descriptor\n”);
return 1;
}

//Open Control Module mmap from the memory file descriptor
//Open the map in read/write mode, shared=change the actual object, using file descripter from above and offseting to the register.
MemMapAddressContMod = (volatile uint32_t *)mmap (NULL, CONT_MOD_REG_LENGTH, PROT_WRITE, MAP_SHARED, MemoryFileDescriptor, CONT_MOD_REG_START);
if (MemMapAddressContMod == (volatile uint32_t *)MAP_FAILED) {
perror (“mmap failed for Control Module Registers”);
close (MemoryFileDescriptor);
return 1;
}

//Set Port 9 Pin 14 to ehrpwm1A_mux1
printf (“Setting Mux - Port 9 Pin 14 to ehrpwm1A_mux1\n”);
MemMapAddressContMod[0x848] = 0x6;
printf (“After write read the value back %x\n”,MemMapAddressContMod[0x848]);

//Close the Control Module mmap
munmap ((void *)MemMapAddressContMod, CONT_MOD_REG_LENGTH);

//Close the Memory File Descriptor
close (MemoryFileDescriptor);

The Results of the above code

When Run the above code tries to read the value back after setting it, this always returns with MemMapAddressContMod[0x848] = 0

When I run “tail /sys/kernel/debug/omap_mux/gpmc_ad2” it tells me that the register has not changed

When I run “echo 6 > /sys/kernel/debug/omap_mux/gpmc_a2” I can change the port without issue.

Details of the setup

I am running the latest beaglebone Angstrom Demo SystemD image

Code is compiled on beaglebone using gcc from “opkg install task-native-sdk”

All operations performed via SSH logged in as root

If any one can let me know what I am missing as I have been working on this for hours with little success.
I understand that I could just use the echo to filesystem instead of mmap but as the next step is to get high speed PWM I wanted to start here with mmap.

Hi!

MemMapAddressContMod is a uint32_t * pointer, so when using it as an array (MemMapAddressContMod[0x848]), you actually access the physical memory at 0x44e10000 + (0x848 * 4).
Replacing it with “MemMapAddressContMod[0x848 >> 2]” will most likely fix your issue.