BeagleBoardPinMux

 NEWS: Zippy2 100baseT Expansion boards for the BeagleBoard are now available from Digikey!

This page is about Pin Multiplex (PinMux) on the BeagleBoard. The OMAP3 chip has fewer balls (pins) than the internal logic which provides functionality. So each ball (pin) of the OMAP3 can have different functionality (e.g. GPIO or I2C.TX). This is controlled by internal OMAP3 registers. This page tries to give some details of where some information about OMAP3 pin mux can be found in hardware and how this is controlled by software, mainly by U-Boot and the Linux kernel. The information on this page can be used then e.g. to re-configure pins exposed on Beagle's expansion connector.

=Hardware=

This section tries to give an idea how pin mux on OMAP3 works, and looks at the Beagle-specific hardware documentation for the expansion connector.

OMAP3
Details of OMAP35x PinMux can be found in OMAP35x Applications Processor TRM (spruf98b.pdf) in section 7.4.4.3 Pad Multiplexing Register Fields (page 814) (or, if you are using the BeagleBoard-xM it's section 13.4.4.3 on page 2434 of the DM3730 TRM):


 * Each pad (ball, pin) can (but must not) have up to 8 different functionalities assigned to. These are called Mode 0 to Mode 7.
 * Each pad (ball, pin) muxing is controlled by 16bit. So two pads (balls, pins) are controlled by one 32bit register inside OMAP3. Each register can be written/read by 16bit or 32bit accesses.
 * The name of the register is normally formed by the name of Mode0 pad (ball, pin) functionality which is controlled by the lower 16bit of the 32bit register ([15-0]). So don't be confused by register name: The register can configure functionality which isn't reflected by the name.
 * The physical address of the register is given in the table, too. To configure the pad (ball, pin) which is controlled by the upper 16bit of the register ([31-16]) you can do this by a 16bit access to physical_register_address + 0x2
 * Note that the same functionality can be at different pads. E.g. UART1_TX functionality can be on pad controlled by CONTROL_PADCONF_UART1_TX register (Mode0) or CONTROL_PADCONF_DSS_DATA6 (Mode2). Make sure that you only configure each logical function on a single pin.

Details of the PinMux register itself be found in same TRM (spruf98b.pdf) in section 7.4.4 Pad functional Multiplexing and Configuration (page 810, or Section 13.4.4 page 2430 for the -xM):


 * Bits [2-0] and bits [18-16] control the MuxMode of pad A and pad B controlled by this register. Here you can select one of the 8 MuxModes Mode0 to Mode7 you get from table discussed above.
 * Bit [3] and bit [19] select if OMAP3 internal pull-up/-down should be enabled. If pull-up/-down is enabled by this bit, bit [4] and bit [20] configure if it should be a pull-up or a pull-down.
 * Bit [8] and bit [24] select if the pin is an input or a bi-directional pin.

Off- and wake configuration is possible, too, but isn't discussed here.

Beagle
Details of the Beagle's expansion header usage can be found in the BeagleBoard System Reference Manual in Table 20 Expansion connector signals (page 96). This expansion exposes 22 pads (balls, pins) of the OMAP3 for your individual use. If you need signals that are not muxed by default, you have to configure the pins yourself.


 * Table 20 (page 96) in Beagle SRM gives you an overview of which signals can be muxed to which expansion pin.
 * MUX:0, MUX:1, MUX:2 and MUX:3 in table 20 in Beagle SRM correspond to what is called Mode0 to Mode4 in OMAP35x Applications Processor TRM.
 * To get an idea which CONTROL_PADCONF_xxx you have to touch for correct pin mux, take signal name of Beagle SRM MUX:0 and look for the same Mode0 in the OMAP35x Applications Processor TRM. Example:
 * Table 20 in Beagle SRM MUX:0: MMC2_DAT7 -> Table 7-4 in OMAP35x Applications Processor TRM Mode0 MMC2_DAT7: CONTROL_PADCONF_MMC2_DAT6 register, physical 16bit address 0x4800216A.
 * Table 21 (page 97) in Beagle SRM gives an overview of expansion header signals from functionality group point of view.

Warning: The expansion header is 1.8V! In most cases you will need to apply level shifting to make use of its signals. See hardware interfacing for hardware suggestions for level shifting.

0.1"/2.54mm Headers

 * Male Header Major Leage TSHS-114-D-06-A-T-LF
 * Female Header Major League LSWSS-114-D-02-T-LF

0.05"/1.27mm Headers

 * Male Header
 * Samtec FTSH-110-01-F-D
 * FCI 20021111-00020T4LF
 * Female Header
 * Samtec SFMC-110-T1-F-D
 * FCI 20021311-00020T4LF

=Software=

Controlling the hardware interface (i.e. writing the registers with appropriate values) described above can be done by any software. Up to now, default configuration is that initial pin mux is done by bootloader, U-Boot, and can be later overwritten by the Linux kernel.


 * Default configuration is that pin mux is set board specific by U-Boot and kernel's pin mux is disabled (i.e. kernel's CONFIG_OMAP_MUX is not set, see below).
 * Older Linux kernel's pin mux was somewhat broken. While different boards need different configuration, the Linux kernel had only one pin mux configuration (in ), which then obviously didn't fit any specific board. Therefore, kernel's pin mux (see below) is disabled unless you enable it intentionally.
 * Recent (2.6.32 at least) kernels place the mux configuration in individual board files (for the Beagle, this is ).  You will still need to make sure that the CONFIG_OMAP_MUX option is set, however.  See below for how to modify this file.

U-Boot
Primary PinMux configuration in done in bootloader U-Boot. For beagle, see file board/ti/beagle/beagle.h in the U-Boot sources.

To do pin mux as described above U-Boot uses some macro magic to configure what is given by OMAP3 hardware. E.g.:

MUX_VAL(CP(MCBSP3_DX),        (IEN | PTD | DIS | M4)) /*GPIO_140*/\


 * MCBSP3_DX: This is the register name without CONTROL_PADCONF_*. I.e. looking into OMAP3xx TRM, this is CONTROL_PADCONF_MCBSP3_DX[15:0] register at physical address 0x4800216C. Mux mode for this pad is
 * MODE0: MCBPS3_TX
 * MODE1: UART2_CTS
 * MODE4: GPIO_140
 * M4: Here, mux MODE4 is selected, enabling GPIO_140 functionality on this pin. This is marked by the trailing comment.
 * IEN: This enables input, i.e. this is pad is configured bi-directional
 * DIS: Disable pull-up/pull-down
 * PTD: Pull type down, ignored if pull is disabled by DIS

Older Kernels
Some additional PinMux configuration is done by the Linux kernel, too. Note that this has to be enabled by CONFIG_OMAP_MUX, else this isn't executed. This is done in file arch/arm/mach-omap2/mux.c (section CONFIG_ARCH_OMAP34XX).

Linux kernel uses some different syntax compared to U-Boot for pin mux, but logic is the same. E.g.

MUX_CFG_34XX("AE4_34XX_GPIO136_OUT", 0x164, OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT) MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c, OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT_PULLUP)


 * AE4_34XX_GPIO136_OUT: These are only strings which are used for debug output. This string consists of two parts:
 * the pad name (e.g. AE4) is from OMAP34x and will be different for different OMAPs and different packages
 * the resulting functionality (compare U-Boot's trailing comment)
 * 0x164 and 0x16c: This is the address offset from base address. Looking into OMAP35x TRM this is
 * 0x164: CONTROL_PADCONF_MMC2_DAT4[15:0] at physical address 0x48002164.
 * 0x16c: CONTROL_PADCONF_MCBSP3_DX[15:0] at physical address 0x4800216C.
 * OMAP34XX_MUX_MODE4: Same as M4 like in U-Boot. Configure mux MODE4 here.
 * OMAP34XX_PIN_OUTPUT or OMAP34XX_PIN_INPUT_PULLUP: One macro for the different modes. Done with 3 orred macros in U-Boot.

Recent Kernels
More recent kernels (2.6.32 at least) have improved the infrastructure for pin mux configuration. Follow these directions to perform configuration in these kernels.

NOTE: Although these instructions may be correct, there is a problem with enabling mux-ing in at least some kernels. If your root filesystem will not mount after following these instructions, you can revert to your old kernel and try setting mux values through u-boot. Skip to the next section for this.

1. Determine which pin you wish to mux, and which setting you'd like to use Take a look at the BeagleBoard System Reference Manual, section 8.19, and figure out which pin (2–24) on the expansion header you'd like to configure, and to which setting you'd like it to be set. The newer versions of the SRM are preferable, since they list the name of the ball on the OMAP associated with that pin (under the OMAP column). (N.B.: in the C4 SRM, see page 96.)

2. Figure out the name the kernel uses for that ball

In your kernel tree, open up the file. This contains a bunch of preprocessor magic which is intended to make your life easier.

First locate the appropriate ball definition for the OMAP package being used. The following are available:

~/omap-2.6.32 $ grep -n omap_ball arch/arm/mach-omap2/mux34xx.c 677:struct omap_ball __initdata omap3_cbc_ball[] = { 1033:struct omap_ball __initdata omap3_cus_ball[] = { 1346:struct omap_ball __initdata omap3_cbb_ball[] = { 1774:struct omap_ball __initdata omap36xx_cbp_ball[] = { 2071:  struct omap_ball *package_balls;

The C4 BeagleBoard uses a CBB (the full chip number is OMAP3530DCBB72 according to p. 18 of the C4 SRM, which has a CBB package ). So the correct ball definition may be found starting on line 1346 at the definition of the array.

Using the name of the ball that you found in step one (it'll typically be 2 letters followed by 1 or 2 numbers), search for the lowercase (e.g., if the ball name was AE5, search for ae5). This will bring you to a line with a  macro; the first parameter is what you're interested in, so remember it. In the case of AE5, the first parameter is.

3. Add an entry for each ball you wish to configure to the board_mux array

Search through  until you find an array of type   called. This will likely be in a block conditional on CONFIG_OMAP_MUX, so you need to have the CONFIG_OMAP_MUX option set in your kernel config. There will likely only be one entry, which will look like:

{.reg_offset = OMAP_MUX_TERMINATOR },

You will add one entry for each ball to this array, before that terminating element.

To do this, use the  helper macro, which takes two parameters; the first is the name you found in the previous step (e.g. ), and the second is the mux mode you desire. This mux mode takes the form of, where x is the mode.

As an all encompassing example, say you want to set pin 8 on the expansion header to mode 1, in order to have  muxed in on that pin. You would add:

OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1),

to the  array.

But, were you to try that, it wouldn't work! That's because a must be set as an input in order to receive data. Take a look at, which defines the valid modes to be used in the helper. In this example, we want, but your application may differ. So, the final  array would be:

static struct omap_board_mux board_mux[] __initdata = { OMAP3_MUX(MCBSP3_FSX, OMAP_MUX_MODE1 | OMAP_PIN_INPUT), { .reg_offset = OMAP_MUX_TERMINATOR }, };

Setting Mux Through u-boot
Some quick instructions on how to use u-boot to mux pins. This assumes you are using OpenEmbedded and bitbake.

Start by: bitbake u-boot -c configure gvim tmp/work/beagleboard-angstrom-linux-gnueabi/u-boot-/git/board/ti/beagle/beagle.h

Look in the table in 'Pin Mux Cross Reference Table' and find the pin you want to use. In my case I want to use pin 24. This is BB Description I2C2_SCL and GPIO 168.

Find the BB Description in the beagle.h file and alter it's Mux setting from (probably) M0 to M4. I found: MUX_VAL(CP(I2C2_SCL),      (IEN  | PTU | EN  | M0)) /*I2C2_SCL*/\ and changed it to: MUX_VAL(CP(I2C2_SCL),      (IEN  | PTU | EN  | M4)) /*I2C2_SCL*/\

Now: bitbake u-boot -c compile cd tmp/work/beagleboard-angstrom-linux-gnueabi/u-boot-/git (assuming your boot flash partition is mounted as /media/boot) cp u-boot.bin /media/boot

Boot up and log in to your Beagleboard. Now we'll do a simple test: cd /sys/class/gpio/ echo 168 > export cd gpio168 echo out > direction echo 1 > value echo 0 > value

A word of warning about beagle.h
Be careful when editing. A giving pin may appear in more than one place. Changing the first occurrence may not make the change you want. For example, I wanted to use PWMs. Lines 228-230 MUX_VAL(CP(UART2_RTS),		(IEN | PTD | DIS | M4)) /*GPIO_145*/\ MUX_VAL(CP(UART2_TX),		(IEN | PTD | DIS | M4)) /*GPIO_146*/\ MUX_VAL(CP(UART2_RX),		(IEN | PTD | DIS | M4)) /*GPIO_147*/\ looked like the right place to switch from Mode 4 to Mode 2. However later in the file were MUX_VAL(CP(UART2_CTS),		(IEN | PTU | EN  | M2)) /*UART2_CTS*/\ MUX_VAL(CP(UART2_RTS),		(IDIS | PTD | DIS | M2)) /*UART2_RTS*/\ MUX_VAL(CP(UART2_TX),		(IDIS | PTD | DIS | M2)) /*UART2_TX*/ and MUX_VAL(CP(UART2_CTS),		(IEN | PTU | EN  | M2)) /*UART2_CTS*/\ MUX_VAL(CP(UART2_RTS),		(IDIS | PTD | DIS | M2)) /*UART2_RTS*/\ MUX_VAL(CP(UART2_TX),		(IDIS | PTD | DIS | M2)) /*UART2_TX*/\ The first group starts at line 388 and the second line 400. Note the UART2_TX and UART2_RTS are overwritten (thought a quick grep shows that UART_RX is not). To use all three PWMs, I use the lines above to switch to Mode 2. (I didn't have to use the UART2_CTS line, but decided to keep all the UART2 lines together.)

Pin Mux Cross Reference Table
Note: BB J3 - Pin number on the BeagleBoard Expansion connector BB Description - BeagleBoard System Reference Manual Figure 46 RevB GPIO - GPIO on BeagleBoard RevB expansion connector RevC GPIO - GPIO on BeagleBoard RevC expansion connector OMAP35xx Pin RevB - OMAP Processor pin number for RevB Board OMAP35xx Pin RevC - OMAP Processor pin number for RevC Board U-BOOT - Pin description as defined in /board/omap3/beagle/beagle.h KERNEL - Pin description as defined in /arch/arm/mach-omap2/mux.c - Angstrom Kernel V2.6.29-R42 OFFSET - Offset as defined in OMAP35xx Technical Reference Manual Section 7.4.4.3

=Examples=

Add your examples here: What has to be changed to get which signal on expansion connector

MMC2 via TXS0206 or TXS02612
MUX_VAL(CP(MMC2_CLK),		(IEN | PTU | EN  | M0)) /*MMC2_CLK*/\ MUX_VAL(CP(MMC2_CMD),		(IEN | PTU | EN  | M0)) /*MMC2_CMD*/\ MUX_VAL(CP(MMC2_DAT0),		(IEN | PTU | EN  | M0)) /*MMC2_DAT0*/\ MUX_VAL(CP(MMC2_DAT1),		(IEN | PTU | EN  | M0)) /*MMC2_DAT1*/\ MUX_VAL(CP(MMC2_DAT2),		(IEN | PTU | EN  | M0)) /*MMC2_DAT2*/\ MUX_VAL(CP(MMC2_DAT3),		(IEN | PTU | EN  | M0)) /*MMC2_DAT3*/\ MUX_VAL(CP(MMC2_DAT4),		(IEN | PTU | EN  | M7)) /*GPIO_136 reserved*/\ MUX_VAL(CP(MMC2_DAT5),		(IEN | PTU | EN  | M7)) /*GPIO_137 reserved*/\ MUX_VAL(CP(MMC2_DAT6),		(IEN | PTU | EN  | M7)) /*GPIO_138 reserved*/\ MUX_VAL(CP(MMC2_DAT7),		(IEN | PTU | EN  | M7)) /*GPIO_139 reserved*/\

NOTE: This example is for 4-bit interface. IEN has to be set for bi-directional lines including CLK

UART2
This example uses kernel pin mux to enable configure UART2. These changes were made to a Rev B6, so be sure to check your reference manual and TRM from TI for the proper pins.

Begin by navigating to your kernel's /arch/arm/mach-omap2 folder and edit mux.c as follows:

MUX_CFG_34XX("AF6_34XX_GPIO140_UP", 0x16c,               OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_INPUT_PULLUP) MUX_CFG_34XX("AE6_34XX_GPIO141", 0x16e,               OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_INPUT) MUX_CFG_34XX("AF5_34XX_GPIO142", 0x170,               OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_OUTPUT) MUX_CFG_34XX("AE5_34XX_GPIO143", 0x172,               OMAP34XX_MUX_MODE1 | OMAP34XX_PIN_INPUT)

This will change MUX pins 140, 141, 142, and 143 to mode 1, which is defined in the TRM from TI as UART2 functionality. The next thing you will need to do is define another pin as UART2_RX won't work unless you define it, so do this:

MUX_CFG_34XX("AD25_34XX_GPIO147", 0x17a, 		OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)

This defines it so that UART2_RX is only being used once as RX. Now you need to invoke these changes, while in the mach-omap2 folder, edit board-omap3beagle.c. Add the following lines to the omap3_beagle_init(void) function after omap_cfg_reg(J25_34XX_GPIO170); :

omap_cfg_reg(AF6_34XX_GPIO140); //CTS omap_cfg_reg(AE6_34XX_GPIO141); //RTS omap_cfg_reg(AF5_34XX_GPIO142); //TX omap_cfg_reg(AE5_34XX_GPIO143); //RX omap_cfg_reg(AD25_34XX_GPIO147);

This invokes the changes to the pin settings that we made in mux.c. Now navigate to arch/arm/plat-omap/include/mach/mux.h and add the following line to the enum at the bottom:

AD25_34XX_GPIO147,

Now you must use kernel's make menuconfig to enable (hit 'Y') kernel pin mux and gpio support as follows:

System Type --> TI OMAP Implementations --> OMAP multiplexing support Device Drivers --> GPIO Support --> /sys/class/gpio/... (sysfs interface)

With these changes, compilie the Linux kernel following the steps on making the uImage.

Now copy the resulting uImage file to your SD card and reboot. When running the console image of Angstrom, you may need to run the command: stty -F /dev/ttyS1 -crtscts This will turn of the RTS/CTS handshaking, and allow the UART to run properly.

That should be it, an easy way to test is to run the command "echo "test" > /dev/ttyS1" and monitor the TX line with an oscilloscope.

UART2 enabling within U-boot
This example is made for revision C4, please check reference manual and TI TRM for proper pins.

As a general rule, in order to get u-boot multiplexing work you need to disable kernel multiplexer.

To do so use kernel make menuconfig and set:

Symbol: OMAP_MUX [=n] Location: System Type -> TI OMAP Common Features

Go to u-boot sources (the example is for v2010.03), navigate to board/ti/beagle/ and open beagle.h header file. Here are defined a set of macros used for multiplexer setup. Those macros are used by u-boot board init functions, defined in beagle.c in the same directory. Find the macro related to you board revision (MUX_BEAGLE_C in the example) and add the following lines at its end:

/*UART2 on bb pins 4 (CTS) 6 (TX) 8 (RX) 10 (RTS) */\ MUX_VAL(CP(UART2_CTS),		(IDIS | PTU | EN | M4)) /*UART2_CTS*/\ MUX_VAL(CP(UART2_RTS),		(IDIS | PTU | DIS | M4)) /*UART2_RTS*/\ MUX_VAL(CP(UART2_TX),		(IDIS | PTD | DIS | M0)) /*UART2_TX*/\ MUX_VAL(CP(MCBSP3_FSX), 	(IEN | PTD | DIS | M1)) /*UART2_RX*/ \ /*unset alternative UART2 pins, to avoid double muxing*/ \ MUX_VAL(CP(UART2_RX),		(IDIS | PTD | DIS | M4)) /*alternative UART2_RX*/\ MUX_VAL(CP(MCBSP3_DX),		(IEN | PTD | DIS | M4)) /*OLD UART2_CTS*/\ MUX_VAL(CP(MCBSP3_DR),		(IDIS | PTD | DIS | M4)) /*OLD UART2_RTS*/\ MUX_VAL(CP(MCBSP3_CLKX),	(IDIS | PTD | DIS | M4)) /*OLD UART2_TX*/\

(please note that MCBSP3_DX, MCBSP3_DR and MCBSP3_CLKX UART2 functionalities are not listed in BeagleBoard reference manual, but only in TI's TRM) '''Warning: when disabling alternative functionalities for some pin (UART2_RX, in example) do not set safe mode (M7), but use M4 instead. That's because some pins are also used for other functions. UART2_RX pin is used for enabling EHCI hub, and if set to M7 EHCI will stop working.''' Macro's syntax is described here.

Now save you work and close. Rebuild u-boot and copy the resulting u-boot.bin to your sd card; reboot and test uart2 the usual way, shorting Rx and Tx pins and echoing something to /dev/ttyS1, or as explained before using stty command.

=Main Board=

Board IDs
=Expansion boards=

Using Beagle's expansion connector, different expansion boards with different functionality can be added. Depending on expansion's functionality, different pin mux for signals on expansion connector might be needed. To be able to auto-configure this expansion header pin mux by software, it was decided that all expansion boards shall have an EEPROM connected to expansions I2C containing a vendor and device ID. Based on this ID, readable by software, the pin mux can be configured.

Hardware
EEPROM used for this is AT24 EEPROM (AT24C01B). By three pins (A0 to A2) the I2C address can be configured to I2C address 0x50. Via Beagle's expansion header it is connected to OMAP3 I2C bus #2.


 * EEPROM: AT24C01B
 * I2C bus: 2
 * I2C address: 0x50

Note: I2C address 0x50 conflicts with DVI/HDMI EDID.

EEPROM content

 * Vendor ID is a 16bit Manufacturer Identification
 * Product ID is a 16bit Product Identification
 * Rev Num is a 8bit Product Revision Number
 * Content is a 8bit Number which describes the content of the remaining EEPROM Data

tbd: Add details

Allocation of vendor and device IDs
Vendor and device IDs of the expansion boards are self managed by the vendors. If you are a developer of a expansion board for BeagleBoards and want to allocate a vendor ID, then just add a row to the list of expansionboards and pick a yet unused number (e.g. max(vendorID) + 1) as your vendor ID. This ID should be used for all expansion boards you build for the BeagleBoard. The device ID is used to differentiate the expansion boards of the same vendor.

TinCantools Zippy
The BeagleBuddy Zippy Ethernet Combo Board is an expansion board for the BeagleBoard that adds the following:
 * Battery Backed RTC
 * Second MMC slot
 * 10BaseT Ethernet(ENC28j60)
 * Second RS-232
 * +5V level I2C
 * AT24 EEPROM

See Beagle Zippy page for more details.

PinMux: See Zippy PinMux patch.

TinCantools Zippy2
The BeagleBuddy Zippy2 Ethernet Combo Board is an expansion board for the BeagleBoard that adds the following:
 * Battery Backed RTC
 * Second MMC slot
 * 100BaseT Ethernet(Micrell Part)
 * Second RS-232
 * +5V level I2C
 * AT24 EEPROM

tbd: Add pin mux description for this board.

TinCantools Trainer
The Trainer Board is an expansion board for the BeagleBoard that adds an I2C interface(+3.3v or +5v selectable), SPI(+3.3v), GPIO's(+3.3v), and an Atmega168(+3.3v or +5v selectable) connected via the second uart to the BeagleBoard. Includes a large 0.1" prototype matrix and power bus.

tbd: Add pin mux description for this board.

TinCantools ShowDog
The ShowDog Board is an expansion board for the BeagleBoard that provides support for a LCD and keyboard matrix.

tbd: Add pin mux description for this board.

Beagle VGA Board
VGA Adaptor board to interface Beagle and standard VGA monitors

http://www.beagleboardtoys.com/

Liquidware BeagleTouch
The BeagleTouch is a 480×272 resolution and 262K color touchscreen OLED display, with a 20 mm speaker, 1-Watt audio driver codec, USB serial terminal interface, the BeagleTouch snaps directly onto the BeagleBoard to help create a handheld tablet computer.

BeagleTouch BeagleBoardPinMUX
=Weblinks=
 * HY research pin mux article
 * eLinux BeagleBoard page

=References=