In case you want to add additional hardware to your MIRO robot, you can do so by using the provided.
The P3 board has an UC13:J10 that can be configured in various combinations. It is the 12-way connector marked in blue in the photo alongside. You can access this port from your own software running on-board P3, or provide an interface to expose it to the network allowing you to access it from off-board.at
The pinout of the port is as follows (note that the physical port is numbered 1-12 from top to bottom, which is upside-down in comparison with this table):
|Pinning for UC13:J10|
|pin no||pin name||AM335x ball||AM335x functions||offset||AM335x function at boot|
|3||IO0||M17 (MDIO)||uart5_rxd(2), gpio0_0(7)||0x148||uart5 rx|
|4||IO1||M18 (MDC)||uart5_txd(2), gpio0_1(7)||0x14C||uart5 tx|
|5||IO2||A17 (SPI0_SCLK)||spi0_sclk(0), uart2_rxd(1), I2C2_SDA(2), gpio0_2(7)||0x150||uart2 rx|
|6||IO3||B17 (SPI0_D0)||spi0_d0(0), uart2_txd(1), I2C2_SCL(2), gpio0_3(7)||0x154||uart2 tx|
|7||IO4||B16 (SPI0_D1)||spi0_d1(0), I2C1_SDA(2), gpio0_4(7)||0x158||gpio0_4|
|8||IO5||A16 (SPI0_CS0)||spi0_cs0(0), I2C1_SCL(2), gpio0_5(7)||0x15C||gpio0_5|
|9||IO6||J18 (MII1_TXD3)||uart4_rxd(3), gpio0_16(7)||0x11C||gpio0_16|
|10||IO7||K15 (MII1_TXD2)||uart4_txd(3), gpio0_17(7)||0x120||gpio0_17|
The numbers in brackets after AM335x functions are the indices of the function into the pinmux (used below when reconfiguring the port). Thus, UC13:J10 can be configured as an SPI port and two UARTs, as three UARTs and an I2C, as eight digital I/O ports, or as some other combination of these ingredients.
By default, pins IO0 through IO3 are configured as two UARTs: UART5 (IO0/1) is connected to the bluetooth module, and UART2 (IO2/3) is available for use. Pins IO4 through IO7 are configured as GPIO inputs.
You can configure UART2 physically as a "loop back" by simply connecting pins IO2 and IO3 together. Data sent on IO3 will be received at IO2. Open two terminals on P3, and proceed as follows.
In the first, configure the port (disable echo and text translation, set speed) and start listening.
In the second, send some messages into the port.
If all is well, you'll see the messages appear in the first terminal. If, meanwhile, you scope the loop back line, you'll see bursts of characters such as that shown in the image alongside for "ABC".
Test GPIO in
To listen to the four GPIO inputs, as they are initially configured, on IO4 through IO7, you can run the prepared script, as follows.
If you connect any of the pins IO4 through IO7 to a GND pin (either pin 2 or pin 11 of the) you will see the corresponding indicator go to "0"; during the above recording, each pin was touched in turn by a ground wire. The GPIO pins are configured, by default, with a pull-up resistor, so they read "1" when nothing is connected to them.
Test GPIO out
Any or all of IO4 through IO7 can be reconfigured as outputs easily without rebuilding the device tree. Connect together pins IO4 and IO5, and run the prepared script, as follows.
The script configures IO4 as an output, and listens to IO5 through IO7. Since IO4 is connected to IO5, you can see the state toggling on each cycle.
Reconfiguring Expansion Port
Theis configured through the Linux Device Tree mechanism.
Review pin configuration
Since device tree operation is somewhat opaque, you may wish to follow the effect that your configuration changes have on the physical device. Proceed as follows to review the pin control registers for pins IO0 through IO7.
The above command queries the state of the pinmux interface of the AM3358 control module. See Chapter 9 of the device Technical Manual (the register addresses are listed in table 9-10) and Chapter 2 of the device datasheet (Table 2-7 lists the eight multiplexed functions available on each physical pin). The above is the default configuration for P3.
For instance, pin IO0 is at offset 0x148 (from base address 0x44E10800), which TM 9-10 indicates is for pin
mdio appears in DS 2-7 at ZCZ ball number M17; function 2 of that pin is
uart5_rxd. Therefore, the pin control register at offset 0x148 needs to have muxed function 2 selected. Table 9-60 indicates how to read the register value: "0x32" reads back as "receiver enabled, pullup selected, pullup/pulldown enabled, mux function 2", which amounts to a GPIO input pin.
/syssomewhere (see the documentation for the particular peripheral interface for details).
Rebuild device tree
The device tree is stored in binary form on the SD card in
To modify it, you will decompile the device tree binary (.dtb) to a device tree source (.dts) file, make your changes, and then recompile back to binary, before installing the resulting file back to
/boot. The device tree compiler
dtc is available on-board, but it does not interact with the system so you may find it easier to use your workstation to make modifications. Either way, the procedure is as follows.
To decompile the .dtb to a .dts, use a command of this form.
Modify source file
The source file is plain text—modify it in any text editor.
To recompile the modified .dts to a .dtb, use a command of this form.
Install new binary
Copy the new .dtb to
/boot on the SD card, and reboot MIRO to effect the changes.
/mnt/rootfs/boot/am335x-miro.dtbfrom the copy in the MDK at
Modify device tree
Below are a few examples for modifying your device tree.
Before we can enable UART4, we first need to disable GPIO pins gpio0_16 and gpio0_17, which share physical pins IO6/7. To do this, search in the .dts for the token
expansion_port_pins. Within that section, find the field
pinctrl-single,pins, which by default reads
<0x158 0x37 0x15c 0x37 0x11c 0x37 0x120 0x37>. Each enabled GPIO pin is represented by a pair in this field, and the first value in each pair is the offset value from the table at the top of this page. Delete the last four entries in this field to deconfigure gpio0_16 and gpio0_17.
To enable UART4, we first have to configure the pinmux. Find the token
pinmux_uart5_pins in the .dts, and copy it to a section just above. Rename the section to
pinmux_uart4_pins: pinmux_uart4_pins, delete the two lines containing the token
phandle, and change the
pinctrl-single,pins field to read
<0x11c 0x33 0x120 0x3>. Note that we have based the value for this field on that used for UART5, with the offsets changes to
0x120 (see table) and the pinmux fields both changed to 3, the mux index (see table).
Next we have to enable the peripheral UART4; internally, this is known as uart5 (
ti,hwmods = "uart5"), which you'll find listed under the token
serial@481a8000. Simply change the
status field to read
okay rather than
disabled, and add a reference to the pinmux section at the bottom (two lines starting
pinctrl) so that the pinmux gets actioned.
Recompile and install the device tree to
/boot, then reboot your MIRO. When it starts up again, confirm the new pinmux configuration:
Note that the last two pins have changed from pinmux 7 to pinmux 3, reflecting their switch over to the UART peripheral.
To test the new UART port, connect a loop back cable between pins IO6 and IO7, and then run the transmitter and receiver in two separate P3 login terminals, as follows.
More or less GPIO
You can disable all the UARTs and just have eight GPIO pins. Update the field
expansion_port_pins to read
<0x148 0x37 0x14C 0x37 0x150 0x37 0x154 0x37 0x158 0x37 0x15c 0x37 0x11c 0x37 0x120 0x37>. Disable UART2 and UART5, which are known internally as "uart3" and "uart6"; set the field
status to read
disabled under sections
serial@481aa000. Reboot, and see the scripts
test_gpio_*.sh to get started.
To have less GPIO, you can remove entries from the
pinctrl-single,pins field. To have none at all, however, you can simply find the section
expansion_port_pins_helper and set
disabled; this frees all GPIO pins for other uses.
I2C1 is section
i2c@4802a000 and I2C2 is section
i2c@4819c000. To enable the former, first remove the entries
0x158 0x37 0x15c 0x37 from
expansion_port_pins to release the pins from use by the GPIO module, then change
okay. Rebuild, reboot, and IO4/5 are now configured as I2C1, the interface for which will appear at
We can test this interface by running the detection program
clock-frequency(for example, use
clock-frequency = <0x61a80>for 400kHz).
i2c@4802a000is known internally as "i2c2", and
i2c@4819c000as "i2c3"; try to ignore this, these refer to physical devices I2C1 and I2C2, respectively. I2C0 (aka "i2c1") is used on-board UC13 and its configuration should not be changed.
To use the SPI port, find
spi@48030000 and set the field
serial@48024000 (UART2) and set
disabled. After installing the .dtb and rebooting, you'll see a pin configuration like this:
If you followed the instructions above exactly, you'll see that SPI is now configured on IO2-IO5, but that IO6 and IO7 are not configured as GPIO anymore. That's because the device tree is still requesting pins IO4 through IO7 for GPIO, and IO4 and IO5 are not available (they are configured as SPI). To reinstate the GPIO function on IO6 and IO7, you need to remove the IO4 and IO5 configuration from
expansion_port_pins, as above (remove the first four entries of eight from
You will now find a device at
/dev/spidev*. Learn more about that device here. You can test the SPI interface as follows.
One possible way to use thewould be to write a daemon to run on P3 that exposes the port to the network, publishing its state on a ROS node and/or receiving signals through the ROS interface to push onto the port. More generally, you could incorporate use of the GPIO port into the wider control system of your robot or robots. Of course, you can exchange data to or from any of the available peripherals in a similar way.
A very simple port reading daemon is supplied; try it out as follows. Pin IO4 should be configured as a GPIO input (the default configuration for this pin).
First, on your workstation, run
roscore. Next, on MIRO, enable and test the GPIO input pin.
Thirdly and finally, compile and start the daemon on MIRO:
Now you can run
rostopic echo /miro_robot_daemon_test on your workstation to observe the outgoing signal. If you touch a wire between pin IO4 and GND (available on pin 2 or pin 11 of the ), you'll see the signal change at your workstation (pin IO4 is configured with a pull-up resistor, so connecting it to ground will change its level).