Nov 16, 2014
TechnologyPWM
Simply enable the P9_21
to PWM, then connect to the LED. The LED connection could refer to EBC Exercises on BBB - Control LED
SLOTS=/sys/devices/bone_capemgr.*/slots
echo am33xx_pwm > $SLOTS
echo bone_pwm_P9_21 > $SLOTS
cd /sys/devices/ocp.3/pwm_test_P9_21.15/
echo 1000000000 > period
echo 250000000 > duty
echo 1 > run
From now you could see the LED begin to flash. In fact using this pwm we could control servo motor:
http://www.linux.com/learn/tutorials/776799-servo-control-from-the-beaglebone-black/
Nov 16, 2014
TechnologyOperate On Device Tree
Turn off the trigger and then shine on the LED USR3 via following command:
root@arm:~# cd /sys/class/leds/beaglebone\:green\:usr3
root@arm:/sys/class/leds/beaglebone:green:usr3# ls
brightness device max_brightness power subsystem trigger uevent
root@arm:/sys/class/leds/beaglebone:green:usr3# echo none > trigger
root@arm:/sys/class/leds/beaglebone:green:usr3# echo 1 > brightness
We could find the gpio is attached to which pin:
# ./findGPIO.js USR3
{ name: 'USR3',
gpio: 56,
led: 'usr3',
mux: 'gpmc_a8',
key: 'USR3',
muxRegOffset: '0x060',
options:
[ 'gpmc_a8',
'gmii2_rxd3',
'rgmii2_rd3',
'mmc2_dat6',
'gpmc_a24',
'pr1_mii1_rxd0',
'mcasp0_aclkx',
'gpio1_24' ] }
USR3 (gpio 56) mode: 7 (gpio1_24) 0x060 pullup
pin 24 (44e10860): (MUX UNCLAIMED) (GPIO UNCLAIMED)
gpio1_24
is what we want. Then refer Memory Map table in the Technical Reference Manual, its base address is 0x4804c000.
devmem2
An easy way to read the contents of a memory location is with devmem2:
root@arm:~/code/gpio# devmem2 0x4804c13c
/dev/mem opened.
Memory mapped at address 0xb6fea000.
Value at address 0x4804C13C (0xb6fea13c): 0x9A00000
Light ON the USR3 led:
root@arm:~/code/gpio# devmem2 0x4804c190 w 0x01000000
/dev/mem opened.
Memory mapped at address 0xb6f52000.
Value at address 0x4804C190 (0xb6f52190): 0x9800000
Written 0x1000000; readback 0x1000000
Light OFF the USR3 led:
root@arm:~/code/gpio# devmem2 0x4804c194 w 0x01000000
/dev/mem opened.
Memory mapped at address 0xb6f1c000.
Value at address 0x4804C194 (0xb6f1c194): 0x8A00000
Written 0x1000000; readback 0x1000000
mmap code
The critical Code:
int fd = open("/dev/mem", O_RDWR);
gpio_addr = mmap(0, GPIO1_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO1_START_ADDR);
gpio_oe_addr = gpio_addr + GPIO_OE;
gpio_setdataout_addr = gpio_addr + GPIO_SETDATAOUT;
gpio_cleardataout_addr = gpio_addr + GPIO_CLEARDATAOUT;
// Set USR3 to be an output pin
reg = *gpio_oe_addr;
printf("GPIO1 configuration: %X\n", reg);
reg &= ~USR3; // Set USR3 bit to 0
*gpio_oe_addr = reg;
printf("GPIO1 configuration: %X\n", reg);
printf("Start blinking LED USR3\n");
while(keepgoing) {
// printf("ON\n");
*gpio_setdataout_addr = USR3;
usleep(250000);
// printf("OFF\n");
*gpio_cleardataout_addr = USR3;
usleep(250000);
}
Run the program and see its heartbeat:
# ./gpioToggle
Mapping 4804C000 - 4804E000 (size: 2000)
GPIO mapped to 0xb6f91000
GPIO OE mapped to 0xb6f91134
GPIO SETDATAOUTADDR mapped to 0xb6f91194
GPIO CLEARDATAOUT mapped to 0xb6f91190
GPIO1 configuration: F60FFFFF
GPIO1 configuration: F60FFFFF
Start blinking LED USR3
gpioThru
This example need to be clearly written later.
Nov 16, 2014
TechnologyConnection
HMC5883L magnetometer runs in 400KHZ I2C bus, it’s for measuring the magnetic field vector in 3 dimensions.
We use its 4 ports: VCC,GND,SDA, SCL. SDA is for Data, while SCL is for Clock.
Use P9 for connecting the HMC5883L.
P9_02(GND) <----> GND
P9_04(VCC) <----> VCC
P9_19(I2C2_SCL) <----> SCL I2C bus 2(pin 19 on header p9 to SCL)
P9_20(I2C2_SDA) <----> SDA
I2C Detect
First you should install i2cdetect, then list the avaiable i2c bus via following command:
root@arm:~# i2cdetect -l
i2c-0 i2c OMAP I2C adapter I2C adapter
i2c-1 i2c OMAP I2C adapter I2C adapter
We choose i2c bus2, thus the command for detecting the connected device should be:
root@arm:~# i2cdetect -y -r 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
The address should be 0x1e.
Communicate with HMC5883L
The registers are listed as following, notice eavh value for each axis are 16-bits, thus we have to read them seperately and combine them:
Address Name Access
00 Configuration Register A Read/Write
01 Configuration Register B Read/Write
02 Mode Register Read/Write
03 Data Output X MSB Register Read
04 Data Output X LSB Register Read
05 Data Output Z MSB Register Read
06 Data Output Z LSB Register Read
07 Data Output Y MSB Register Read
08 Data Output Y LSB Register Read
09 Status Register Read
10 Identification register A Read
11 Identification register B Read
12 Identification register C Read
Thus we could read out the X MSB Restier and X LSB Register via:
root@arm:~# i2cget -y 1 0x1e 3
0xfe
root@arm:~# i2cget -y 1 0x1e 4
0x91
Different Mode
Notice Mode Register, this will set the mesurement mode.
From the above table, we know for setting the lower 2 bits we could enable the operation mode of HMC5883L.
Now we set to single measurement mode, for one-time measure.
# i2cset -y 1 0x1e 2 1
2 means we set the register 2, and its number equals to 01(Single-Measurement Mode). After one-time measurement, it wil fall back to idle Mode.
After one-time measurement, get the register mode:
root@arm:~# i2cget -y 1 0x1e 2
0x03
Get the value of x-axis:
root@arm:~# i2cget -y 1 0x1e 3
0xfe
root@arm:~# i2cget -y 1 0x1e 4
0x77
C Code
Running Result:
root@arm:~/code/i2c# ./myi2cget 1 30 2
0x03 (3)
root@arm:~/code/i2c# ./myi2cget 1 30 34
0x00 (0)
root@arm:~/code/i2c# ./myi2cget 1 30 4
0x77 (119)
Critical Code:
Open the i2c-xxx:
sprintf(filename, "/dev/i2c-%d", i2cbus);
file = open(filename, O_RDWR);
ioctl for setting the address:
if (ioctl(file, I2C_SLAVE, address) < 0) {
Now read the byte from:
res = i2c_smbus_read_byte_data(file, daddress);
Comparing the official i2cget, myi2cget could print out the human-readable format of data.
Web Displaying
Git clone the following project form github.com:
# git clone https://github.com/duganje/ECE497_duganje.git
# cd ECE497_duganje/
# ls
MiniProject01 MiniProject02 MiniProject03 MiniProject04 README.md
Upload the project MiniProject04 to the BBB board.
Notice change the code in buttonBox.js from i2cset -y 3
to i2cset -y 1 and
i2cget -y 3to
i2cget -y 1`
After modification, run buttonBox.js via:
$ node buttonBox.js
Now visit the http://xx.xx.xx.xxx:8081/buttonBox.html
you could see the data displayed as following:
Nov 13, 2014
TechnologyTips on Building Kenrel
Via following commands you could build the 3.8 kernel for BBB:
$ git clone git://github.com/RobertCNelson/linux-dev.git
$ cd linux-dev
$ git checkout origin/am33x-v3.8 -b am33x-v3.8
$ time git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
$ cp system.sh.sample system.sh
$ diff system.sh*
15c15
< CC=arm-linux-gnueabi-
---
> #CC=arm-linux-gnueabi-
21c21
< LINUX_GIT=~/BeagleBoard/linux-stable/
---
> #LINUX_GIT=/home/user/linux-stable/
31c31
< ZRELADDR=0x80008000
---
> #ZRELADDR=0x80008000
$ ./build_kernel.sh
U-boot Cross-compile
Download the U-boot and cross-compile it.
# git clone git://git.denx.de/u-boot.git
# cd u-boot/
# git checkout v2013.07 -b tmp
# wget https://raw.github.com/eewiki/u-boot-patches/master/v2013.07/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
# patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
# setpogo # For setting my cross-compiler to arm-linux-gnueabi-
# export ARCH=arm
# export CROSS_COMPILE=arm-linux-gnueabi-
# make
After building you will get MLO and u-boot.img.
Test on NFS
Prepare the NFS File System.
mkdir dtbs
tar xzvf 3.8.13-bone53-dtbs.tar.gz -C ./dtbs
cp dtbs/am335x-boneblack.dtb /srv/tftp/
cp 3.8.13-bone53.zImage /srv/tftp/
mkimage -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008000 -n "Linux" -d /srv/tftp/3.8.13-bone53.zImage /srv/tftp/uImage
tar xJvf ubuntu-14.04-console-armhf-2014-08-13.tar.xz -C /srv/nfs4/
cd /srv/nfs4/ubuntu-14.04-console-armhf-2014-08-13
tar xvf armhf-rootfs-ubuntu-trusty.tar -C ../Ubuntu_fs/
chmod 777 -R Ubuntu_fs/
Then boot the system from U-boot Via:
setenv ipaddr 192.168.1.16
setenv serverip 192.168.1.221
tftpboot ${fdtaddr} am335x-boneblack.dtb
tftpboot ${kloadaddr} uImage
setenv bootargs console=ttyO0,115200n8 root=/dev/nfs rootfstype=nfs rw nfsroot=192.168.1.221:/srv/nfs4/Ubuntu_fs ip=192.168.1.1
bootm ${kloadaddr} - ${fdtaddr}
Now boot the BBB and we got the ssh enabled, via ssh ubuntu@192.168.1.1, password is temppwd.
Sometimes you will meet sudo problem, just chown and chmod is OK
# chmod 4755 some_related_file
# chown root some_related_file
Since NFS gonna the write priviledge error, go back for SD card.
SD Card
FileSystem Preparation:
$ export DISK=/dev/mmcblk0
$ dd if=/dev/zero of=${DISK} bs=1M count=10
$ dd if=./u-boot/MLO of=${DISK} count=1 seek=1 conv=notrunc bs=128k
$ dd if=./u-boot/u-boot.img of=${DISK} count=2 seek=1 conv=notrunc bs=384k
sfdisk --in-order --Linux --unit M ${DISK} <<-__EOF__
1,,0x83,*
__EOF__
$ mkfs.ext4 /dev/mmcblk0p1 -L rootfs
Copy the Operating system into the sd card partition 1, later we will use /mnt for mounting the partition 1:
# mount /dev/mmcblk0p1 /mnt
# cd ubuntu-14.04.1-console-armhf-2014-10-29
# tar xvf armhf-rootfs-ubuntu-trusty.tar -C /mnt/
# sync
Now install the kernel image into the ubuntu system. Imagine your SD is mount to /mnt/
cp /media/y/embedded/BBB/EBC/3.8Kernel/linux-dev/deploy/3.8.13-bone53.zImage /mnt/boot/vmlinuz-3.8.13-bone53
tar xzvf /media/y/embedded/BBB/EBC/3.8Kernel/linux-dev/deploy/3.8.13-bone53-dtbs.tar.gz -C /mnt/boot/dtbs/
Now create the following uEnv.txt located in /mnt/boot/ and /mnt/:
##This will work with: Angstrom's 2013.06.20 u-boot.
loadaddr=0x82000000
fdtaddr=0x88000000
rdaddr=0x88080000
initrd_high=0xffffffff
fdt_high=0xffffffff
console=ttyO0,115200n8
mmcroot=/dev/mmcblk0p1 ro
loadximage=load mmc 0:1 ${loadaddr} /boot/vmlinuz-3.8.13-bone53
loadxfdt=load mmc 0:1 ${fdtaddr} /boot/dtbs/3.8.13-bone53/am335x-boneblack.dtb
loadxrd=load mmc 0:1 ${rdaddr} /boot/initrd.img-${uname_r}; setenv rdsize ${filesize}
loaduEnvtxt=load mmc 0:1 ${loadaddr} /boot/uEnv.txt ; env import -t ${loadaddr} ${filesize};
loadall=run loaduEnvtxt; run loadximage; run loadxfdt;
mmcargs=setenv bootargs console=tty0 console=${console} ${optargs} ${cape_disable} ${cape_enable} root=${mmcroot} rootfstype=${mmcrootfstype} ${cmdline}
uenvcmd=run loadall; run mmcargs; bootz ${loadaddr} - ${fdtaddr};
optargs="debug"
Enable the dhcp, /mnt/etc/network/interfaces:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
Enable the serial port:
$ sudo vim /mnt/etc/init/serial.conf
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
respawn
exec /sbin/getty 115200 ttyO0
Now restart and you got the 3.8 kernel enabled, so next time if you want to change the kernel, simply change the uEnv.txt file is OK.
ubuntu@arm:/boot$ uname -a
Linux arm 3.8.13-bone53 #1 SMP Tue Nov 11 18:40:19 CST 2014 armv7l armv7l armv7l GNU/Linux
Nov 13, 2014
TechnologyUsing Sysfs
The easiest way to do general purpose I/O(gpio) on BBB is through the terminal and shell command. sysfs is the virtual file system which exposes the drivers for the hardware so you can directly use them.
# cd /sys/class/leds
# ls
# beaglebone:green:usr0 beaglebone:green:usr1 beaglebone:green:usr2 beaglebone:green:usr3
# cd beaglebone\:green\:usr0
# cat trigger
none nand-disk mmc0 mmc1 timer oneshot [heartbeat] backlight gpio cpu0 default-on transient
If you want to disable the heartbeat:
# echo none > trigger
# cat trigger
[none] nand-disk mmc0 mmc1 timer oneshot heartbeat backlight gpio cpu0 default-on transient
Turn on/off the led via:
# echo 1 > brightness
# echo 0 > brightness
More trigger options via:
# echo timer>trigger
# cat trigger
none nand-disk mmc0 mmc1 [timer] oneshot heartbeat backlight gpio cpu0 default-on transient
Set the deplay frequency:
echo 100>delay_on
echo 900>delay_off
Adding Own LED
Add the connection of LED.
P9 Pin1 –> 220 ohm –> LED Negative Pin
P9 Pin 12 -> Led Positive Pin
Pin 12 in the table is shown in table as GPIO1_28. Bank of 32 each, so find the gpio number via:
1*32+28=60.
We have to turn this pin on.
Turn it ON
export/unexport, turn on/off of the LED via following command:
$ cd /sys/class/gpio/
$ echo 60 > export
$ cd gpio60/
$ echo out > direction
$ echo 1 > value
$ echo 0 > value
$ cd ..
$ ls
export gpio60 gpiochip0 gpiochip32 gpiochip64 gpiochip96 unexport
$ echo 60 > unexport
$ ls -F
export gpiochip0@ gpiochip32@ gpiochip64@ gpiochip96@ unexport
Add Own Key
Connection for the key:
P9 Pin 3(3.3V) –>220 ohm –> Key 1
P9 Pin 42 –> Key 2
Pin 42 is GPIO0_7, then the actual gpio number is Just 7.
Read Value
export/unexport, read value via following command:
# cd /sys/class/gpio/
# echo 7 > export
# cd gpio7/
# echo in > direction
# cat value
# cat value
0
Hold down the button and see the result:
# cat value
1
The script for reading the gpio value:
# ./readgpio.sh 7
sh: echo: I/O error
trap: SIGINT: bad trap
__________________________|^^^^^^^^^^^^^^^^^^^^^^^|__________|^^^^^^^^^^|___
___|^^^^^^^|______|^^^^^^^|______|^^^^^^^|______|^^^^^^^|______|^^^^^^^|______|^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|____|^^^^^^^^|____|^^|__|^^|_|^^^^^^|___|^^
|__|^|__|^|__|^|__|^^|___|^|_|^|___|^|_|^|_|^|_|^^|_|^|_|^|_|^^|_|^^^^^^^^^^^^^|______|^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^|____|^^^^^^^^^^^|_____|^^^^^^^^^^^^^^|____|^^^^^^^^^^
^^^|___|^^^^^^^^^^^^|____|^^^^^^^^^^^^|__|^^^^^^^^^^|__|^^^^^^^^|__|^^^^^^^|___|^^^^
^|_____|^^^^^|____|^^^^^^^^^^^^^^^^^^^^^^^|___|^^^^^^^^^^^^^^^^^|___|^^^^^^^^^^^
|_^C
This seems like a little game.