Here is pinmux.c. work in progress. hope it’s useful to someone. wrote it learning about the Beaglebone Black.
typical pinmux output
GPIO | Pin Name | Address | Offset | Value | Mode | PCR
gpio0:0 | GPMC_AD0 P8.25 | 0x44e10800 | 0x0800 | 0x31 | 1 | FRXPULLUP
gpio0:1 | GPMC_AD1 P8.24 | 0x44e10804 | 0x0804 | 0x31 | 1 | FRXPULLUP
gpio0:2 | GPMC_AD2 P8.5 | 0x44e10808 | 0x0808 | 0x31 | 1 | FRXPULLUP
gpio0:3 | GPMC_AD3 P8.6 | 0x44e1080c | 0x080c | 0x31 | 1 | FRXPULLUP
gpio0:4 | GPMC_AD4 P8.23 | 0x44e10810 | 0x0810 | 0x31 | 1 | FRXPULLUP
gpio0:5 | GPMC_AD5 P8.22 | 0x44e10814 | 0x0814 | 0x31 | 1 | FRXPULLUP
gpio0:6 | GPMC_AD6 P8.3 | 0x44e10818 | 0x0818 | 0x31 | 1 | FRXPULLUP
gpio0:7 | GPMC_AD7 P8.4 | 0x44e1081c | 0x081c | 0x31 | 1 | FRXPULLUP
gpio3:22 | GPMC_AD8 P8.19 | 0x44e10820 | 0x0820 | 0x27 | 7 | FRXPULLDN
gpio3:23 | GPMC_AD9 P8.13 | 0x44e10824 | 0x0824 | 0x27 | 7 | FRXPULLDN
gpio3:26 | GPMC_AD10 P8.14 | 0x44e10828 | 0x0828 | 0x27 | 7 | FRXPULLDN
gpio3:27 | GPMC_AD11 P8.17 | 0x44e1082c | 0x082c | 0x27 | 7 | FRXPULLDN
gpio0:12 | GPMC_AD12 P8.12 | 0x44e10830 | 0x0830 | 0x27 | 7 | FRXPULLDN
gpio0:13 | GPMC_AD13 P8.11 | 0x44e10834 | 0x0834 | 0x27 | 7 | FRXPULLDN
gpio0:14 | GPMC_AD14 P8.16 | 0x44e10838 | 0x0838 | 0x27 | 7 | FRXPULLDN
gpio0:15 | GPMC_AD15 P8.15 | 0x44e1083c | 0x083c | 0x27 | 7 | FRXPULLDN
gpio0:16 | GPMC_A0 P9.15 | 0x44e10840 | 0x0840 | 0x27 | 7 | FRXPULLDN
gpio0:17 | GPMC_A1 P9.23 | 0x44e10844 | 0x0844 | 0x27 | 7 | FRXPULLDN
gpio0:18 | GPMC_A2 P9.14 | 0x44e10848 | 0x0848 | 0x27 | 7 | FRXPULLDN
gpio0:19 | GPMC_A3 P9.16 | 0x44e1084c | 0x084c | 0x27 | 7 | FRXPULLDN
hmmm seemed to line up in the shell, ![]()
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "am33xx.h" // get the header file from the source code
// Structure to map offset to pin name
typedef struct {
const char *name;
uint32_t offset;
} pin_map_t;
pin_map_t am33xx_pins[] = {
{"GPMC_AD0 P8.25", AM335X_PIN_GPMC_AD0},
{"GPMC_AD1 P8.24", AM335X_PIN_GPMC_AD1},
{"GPMC_AD2 P8.5", AM335X_PIN_GPMC_AD2},
{"GPMC_AD3 P8.6", AM335X_PIN_GPMC_AD3},
{"GPMC_AD4 P8.23", AM335X_PIN_GPMC_AD4},
{"GPMC_AD5 P8.22", AM335X_PIN_GPMC_AD5},
{"GPMC_AD6 P8.3", AM335X_PIN_GPMC_AD6},
{"GPMC_AD7 P8.4", AM335X_PIN_GPMC_AD7},
{"GPMC_AD8 P8.19", AM335X_PIN_GPMC_AD8},
{"GPMC_AD9 P8.13", AM335X_PIN_GPMC_AD9},
{"GPMC_AD10 P8.14", AM335X_PIN_GPMC_AD10},
{"GPMC_AD11 P8.17", AM335X_PIN_GPMC_AD11},
{"GPMC_AD12 P8.12", AM335X_PIN_GPMC_AD12},
{"GPMC_AD13 P8.11", AM335X_PIN_GPMC_AD13},
{"GPMC_AD14 P8.16", AM335X_PIN_GPMC_AD14},
{"GPMC_AD15 P8.15", AM335X_PIN_GPMC_AD15},
{"GPMC_A0 P9.15", AM335X_PIN_GPMC_A0},
{"GPMC_A1 P9.23", AM335X_PIN_GPMC_A1},
{"GPMC_A2 P9.14", AM335X_PIN_GPMC_A2},
{"GPMC_A3 P9.16", AM335X_PIN_GPMC_A3},
{"GPMC_A4 ", AM335X_PIN_GPMC_A4},
{"GPMC_A5 ", AM335X_PIN_GPMC_A5},
{"GPMC_A6 ", AM335X_PIN_GPMC_A6},
{"GPMC_A7 ", AM335X_PIN_GPMC_A7},
{"GPMC_A8 ", AM335X_PIN_GPMC_A8},
{"GPMC_A9 ", AM335X_PIN_GPMC_A9},
{"GPMC_A10 ", AM335X_PIN_GPMC_A10},
{"GPMC_A11 ", AM335X_PIN_GPMC_A11},
{"GPMC_WAIT0 P9.11", AM335X_PIN_GPMC_WAIT0},
{"GPMC_WPN P9.13", AM335X_PIN_GPMC_WPN},
{"GPMC_BEN1 P9.12", AM335X_PIN_GPMC_BEN1},
{"GPMC_CSN0 P8.26", AM335X_PIN_GPMC_CSN0},
{"GPMC_CSN1 P8.21", AM335X_PIN_GPMC_CSN1},
{"GPMC_CSN2 P8.20", AM335X_PIN_GPMC_CSN2},
{"GPMC_CSN3 ", AM335X_PIN_GPMC_CSN3},
{"GPMC_CLK P8.18", AM335X_PIN_GPMC_CLK},
{"GPMC_ADVN_ALE P8.7", AM335X_PIN_GPMC_ADVN_ALE},
{"GPMC_OEN_REN P8.8", AM335X_PIN_GPMC_OEN_REN},
{"GPMC_WEN P8.10", AM335X_PIN_GPMC_WEN},
{"GPMC_BEN0_CLE P8.9", AM335X_PIN_GPMC_BEN0_CLE},
{"LCD_DATA0 ", AM335X_PIN_LCD_DATA0},
{"LCD_DATA1 P8.46", AM335X_PIN_LCD_DATA1},
{"LCD_DATA2 P8.43", AM335X_PIN_LCD_DATA2},
{"LCD_DATA3 P8.44", AM335X_PIN_LCD_DATA3},
{"LCD_DATA4 P8.41", AM335X_PIN_LCD_DATA4},
{"LCD_DATA5 P8.42", AM335X_PIN_LCD_DATA5},
{"LCD_DATA6 P8.39", AM335X_PIN_LCD_DATA6},
{"LCD_DATA7 P8.40", AM335X_PIN_LCD_DATA7},
{"LCD_DATA8 P8.37", AM335X_PIN_LCD_DATA8},
{"LCD_DATA9 P8.38", AM335X_PIN_LCD_DATA9},
{"LCD_DATA10 P8.36", AM335X_PIN_LCD_DATA10},
{"LCD_DATA11 P8.34", AM335X_PIN_LCD_DATA11},
{"LCD_DATA12 P8.35", AM335X_PIN_LCD_DATA12},
{"LCD_DATA13 P8.33", AM335X_PIN_LCD_DATA13},
{"LCD_DATA14 P8.31", AM335X_PIN_LCD_DATA14},
{"LCD_DATA15 P8.32", AM335X_PIN_LCD_DATA15},
{"LCD_VSYNC P8.27", AM335X_PIN_LCD_VSYNC},
{"LCD_HSYNC P8.29", AM335X_PIN_LCD_HSYNC},
{"LCD_PCLK P8.28", AM335X_PIN_LCD_PCLK},
{"LCD_AC_BIAS_EN P8.30", AM335X_PIN_LCD_AC_BIAS_EN},
{"MMC0_DAT3 ", AM335X_PIN_MMC0_DAT3},
{"MMC0_DAT2 ", AM335X_PIN_MMC0_DAT2},
{"MMC0_DAT1 ", AM335X_PIN_MMC0_DAT1},
{"MMC0_DAT0 ", AM335X_PIN_MMC0_DAT0},
{"MMC0_CLK ", AM335X_PIN_MMC0_CLK},
{"MMC0_CMD ", AM335X_PIN_MMC0_CMD},
{"MII1_COL ", AM335X_PIN_MII1_COL},
{"MII1_CRS ", AM335X_PIN_MII1_CRS},
{"MII1_RX_ER ", AM335X_PIN_MII1_RX_ER},
{"MII1_TX_EN ", AM335X_PIN_MII1_TX_EN},
{"MII1_RX_DV ", AM335X_PIN_MII1_RX_DV},
{"MII1_TXD3 ", AM335X_PIN_MII1_TXD3},
{"MII1_TXD2 ", AM335X_PIN_MII1_TXD2},
{"MII1_TXD1 ", AM335X_PIN_MII1_TXD1},
{"MII1_TXD0 ", AM335X_PIN_MII1_TXD0},
{"MII1_TX_CLK ", AM335X_PIN_MII1_TX_CLK},
{"MII1_RX_CLK ", AM335X_PIN_MII1_RX_CLK},
{"MII1_RXD3 ", AM335X_PIN_MII1_RXD3},
{"MII1_RXD2 ", AM335X_PIN_MII1_RXD2},
{"MII1_RXD1 ", AM335X_PIN_MII1_RXD1},
{"MII1_RXD0 ", AM335X_PIN_MII1_RXD0},
{"RMII1_REF_CLK ", AM335X_PIN_RMII1_REF_CLK},
{"MDIO ", AM335X_PIN_MDIO},
{"MDC ", AM335X_PIN_MDC},
{"SPI0_SCLK P9.22", AM335X_PIN_SPI0_SCLK},
{"SPI0_D0 P9.21", AM335X_PIN_SPI0_D0},
{"SPI0_D1 P9.18", AM335X_PIN_SPI0_D1},
{"SPI0_CS0 P9.17", AM335X_PIN_SPI0_CS0},
{"SPI0_CS1 ", AM335X_PIN_SPI0_CS1},
{"ECAP0_IN_PWM0_OUT P9.42", AM335X_PIN_ECAP0_IN_PWM0_OUT},
{"UART0_CTSN ", AM335X_PIN_UART0_CTSN},
{"UART0_RTSN ", AM335X_PIN_UART0_RTSN},
{"UART0_RXD ", AM335X_PIN_UART0_RXD},
{"UART0_TXD ", AM335X_PIN_UART0_TXD},
{"UART1_CTSN P9.20", AM335X_PIN_UART1_CTSN},
{"UART1_RTSN P9.19", AM335X_PIN_UART1_RTSN},
{"UART1_RXD P9.26", AM335X_PIN_UART1_RXD},
{"UART1_TXD P9.24", AM335X_PIN_UART1_TXD},
{"I2C0_SDA ", AM335X_PIN_I2C0_SDA},
{"I2C0_SCL ", AM335X_PIN_I2C0_SCL},
{"MCASP0_ACLKX P9.31", AM335X_PIN_MCASP0_ACLKX},
{"MCASP0_FSX ", AM335X_PIN_MCASP0_FSX},
{"MCASP0_AXR0 P9.30", AM335X_PIN_MCASP0_AXR0},
{"MCASP0_AHCLKR P9.25", AM335X_PIN_MCASP0_AHCLKR},
{"MCASP0_ACLKR P9.42", AM335X_PIN_MCASP0_ACLKR},
{"MCASP0_FSR P9.27", AM335X_PIN_MCASP0_FSR},
{"MCASP0_AXR1 P9.41", AM335X_PIN_MCASP0_AXR1},
{"MCASP0_AHCLKX ", AM335X_PIN_MCASP0_AHCLKX},
{"XDMA_EVENT_INTR0 ", AM335X_PIN_XDMA_EVENT_INTR0},
{"XDMA_EVENT_INTR1 P9.41", AM335X_PIN_XDMA_EVENT_INTR1},
{"WARMRSTN ", AM335X_PIN_WARMRSTN},
{"NNMI ", AM335X_PIN_NNMI},
{"TMS ", AM335X_PIN_TMS},
{"TDI ", AM335X_PIN_TDI},
{"TDO ", AM335X_PIN_TDO},
{"TCK ", AM335X_PIN_TCK},
{"TRSTN ", AM335X_PIN_TRSTN},
{"EMU0 ", AM335X_PIN_EMU0},
{"EMU1 ", AM335X_PIN_EMU1},
{"RTC_PWRONRSTN ", AM335X_PIN_RTC_PWRONRSTN},
{"PMIC_PMIC_POWER_EN ", AM335X_PIN_PMIC_POWER_EN},
{"EXT_WAKEUP ", AM335X_PIN_EXT_WAKEUP},
{"USB0_DRVVBUS ", AM335X_PIN_USB0_DRVVBUS},
{"USB1_DRVVBUS ", AM335X_PIN_USB1_DRVVBUS},
{NULL, 0}
};
// Decode mux register bits
void decode_mux(uint32_t val) {
// printf(" Decode: ");
uint32_t mode = val & 0x7;
printf(" | %4u ", mode);
uint32_t slow = val & 0b01000000;
uint32_t rx = val & 0b00100000;
uint32_t pullup = val & 0b00010000;
uint32_t pulldisabled = val & 0b00001000;
if(slow) {printf(" | S");} else{printf(" | F");}
if(rx) {printf("RX");} else{printf("TX");}
if(!pulldisabled) {
printf("PULL");
if(pullup) {printf("UP");} else{printf("DN");}
}
printf("\n");
}
// Search for a pin name by offset
const char* find_pin_by_offset(uint32_t offset) {
for (int i = 0; am33xx_pins[i].name != NULL; i++) {
if (am33xx_pins[i].offset == offset) {
return am33xx_pins[i].name;
}
}
return "UNKNOWN";
}
int main() {
FILE *fp = fopen("/sys/kernel/debug/pinctrl/44e10800.pinmux-pinctrl-single/pins", "r");
if (!fp) {
perror("Failed to open pinctrl pins file");
return 1;
}
char line[256];
//printf("GPIO | Pin Name | Address | Offset | Value | Mode | Pull | Direction | Rate \n");
printf("%-8s | %-23s | %-10s | %-6s | %-5s | %-5s | %-9s\n", "GPIO", "Pin Name", "Address", "Offset","Value","Mode","PCR");
while (fgets(line, sizeof(line), fp)) {
char gpio[32];
char addr_str[16];
char val_str[16];
int cline;
if (sscanf(line, "pin %*d (%*[^)]) %d:%31s %15s %15s", &cline, gpio, addr_str, val_str) == 4) {
uint32_t addr = strtoul(addr_str, NULL, 16);
uint32_t val = strtoul(val_str, NULL, 16);
uint32_t offset = addr - 0x44e10000;
const char *pin_name = find_pin_by_offset(offset);
int caseFound=0;
if(strstr(gpio, "0-31")!=NULL) {
printf("gpio0:%-2d | %-23s | 0x%x | 0x%04x | 0x%02x ",
cline, pin_name, addr, offset, val);
caseFound=1;
}
if(strstr(gpio, "32-63")!=NULL) {
printf("gpio1:%-2d | %-23s | 0x%x | 0x%04x | 0x%02x ",
cline, pin_name, addr, offset, val);
caseFound=1;
}
if(strstr(gpio, "64-95")!=NULL) {
printf("gpio2:%-2d | %-23s | 0x%x | 0x%04x | 0x%02x ",
cline, pin_name, addr, offset, val);
caseFound=1;
}
if(strstr(gpio, "96-127")!=NULL) {
printf("gpio3:%-2d | %-23s | 0x%x | 0x%04x | 0x%02x ",
cline, pin_name, addr, offset, val);
caseFound=1;
}
if(!caseFound) {
printf("DIO :%-2d | %-23s | 0x%x | 0x%04x | 0x%02x ",
cline, pin_name, addr, offset, val);
}
decode_mux(val);
}
}
fclose(fp);
return 0;
}